mirror of
https://gitlab.com/allianceauth/allianceauth.git
synced 2026-02-05 14:46:20 +01:00
Compare commits
75 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7dec4deb70 | ||
|
|
d511221899 | ||
|
|
d2b7de5221 | ||
|
|
79c5be02e2 | ||
|
|
09df37438d | ||
|
|
8561e4c6fd | ||
|
|
976cb4d988 | ||
|
|
20f7d5103c | ||
|
|
d049ec2832 | ||
|
|
00fe2a527e | ||
|
|
f53ec3b43e | ||
|
|
4d0417f114 | ||
|
|
00903b64db | ||
|
|
a3038cad00 | ||
|
|
ef99f1afac | ||
|
|
cc00d4bd04 | ||
|
|
250f26ff6f | ||
|
|
62b786ca4a | ||
|
|
9cfb47e658 | ||
|
|
ccef27b637 | ||
|
|
8dee61fd39 | ||
|
|
ae64bd0e19 | ||
|
|
a75e93dbfc | ||
|
|
0aa66c5729 | ||
|
|
4c2434219d | ||
|
|
8c65fda33b | ||
|
|
14f2751bbb | ||
|
|
d37a543c39 | ||
|
|
4947e0c483 | ||
|
|
f87c630b86 | ||
|
|
73789ea734 | ||
|
|
5a16c9c495 | ||
|
|
9dd8357f67 | ||
|
|
623e77a268 | ||
|
|
73403b98df | ||
|
|
7aa1a2f336 | ||
|
|
08e42d2f56 | ||
|
|
69248fd7bb | ||
|
|
0af188c6ab | ||
|
|
8b6d32d0d1 | ||
|
|
3c11c25d69 | ||
|
|
12e6cc63e8 | ||
|
|
d429c8b59a | ||
|
|
ddd7a3551b | ||
|
|
49ede92e06 | ||
|
|
b813213328 | ||
|
|
14065b3ca9 | ||
|
|
41f9dc490a | ||
|
|
48d25ca73f | ||
|
|
e49e04034c | ||
|
|
c7860f8e5c | ||
|
|
adb982114a | ||
|
|
5b8983deac | ||
|
|
1730bc3b98 | ||
|
|
4374064d98 | ||
|
|
c1d7994045 | ||
|
|
7bda367cc8 | ||
|
|
3de7a2ccd2 | ||
|
|
9cc278df31 | ||
|
|
a0bab07e2f | ||
|
|
149bbd92ca | ||
|
|
1de3c989d7 | ||
|
|
2e547945e2 | ||
|
|
4d4a9a27af | ||
|
|
5b41d0995f | ||
|
|
ab98d72022 | ||
|
|
8a7cd3f74d | ||
|
|
35cb56d6e9 | ||
|
|
a7a2ffd16b | ||
|
|
dbeda324e0 | ||
|
|
bf1fe99d98 | ||
|
|
41429ec7c7 | ||
|
|
c8ad1dcc7a | ||
|
|
0b7520e3b1 | ||
|
|
48c8ccfe97 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -62,3 +62,5 @@ celerybeat-schedule
|
|||||||
|
|
||||||
#pycharm
|
#pycharm
|
||||||
.idea/*
|
.idea/*
|
||||||
|
|
||||||
|
/nbproject/
|
||||||
|
|||||||
41
.gitlab-ci.yml
Normal file
41
.gitlab-ci.yml
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
# Official language image. Look for the different tagged releases at:
|
||||||
|
# https://hub.docker.com/r/library/python/tags/
|
||||||
|
|
||||||
|
.job_template: &job_definition
|
||||||
|
# Change pip's cache directory to be inside the project directory since we can
|
||||||
|
# only cache local items.
|
||||||
|
variables:
|
||||||
|
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache"
|
||||||
|
|
||||||
|
# Pip's cache doesn't store the python packages
|
||||||
|
# https://pip.pypa.io/en/stable/reference/pip_install/#caching
|
||||||
|
#
|
||||||
|
# If you want to also cache the installed packages, you have to install
|
||||||
|
# them in a virtualenv and cache it as well.
|
||||||
|
cache:
|
||||||
|
paths:
|
||||||
|
- .cache/pip
|
||||||
|
- venv/
|
||||||
|
|
||||||
|
before_script:
|
||||||
|
- python -V # Print out python version for debugging
|
||||||
|
- pip install virtualenv tox
|
||||||
|
- virtualenv venv
|
||||||
|
- source venv/bin/activate
|
||||||
|
|
||||||
|
coverage: '/TOTAL.+ ([0-9]{1,3}%)/'
|
||||||
|
|
||||||
|
|
||||||
|
py36-dj111:
|
||||||
|
<<: *job_definition
|
||||||
|
image: python:3.6-stretch
|
||||||
|
script:
|
||||||
|
- export TOXENV=py36-dj111
|
||||||
|
- tox
|
||||||
|
|
||||||
|
py36-dj20:
|
||||||
|
<<: *job_definition
|
||||||
|
image: python:3.6-stretch
|
||||||
|
script:
|
||||||
|
- export TOXENV=py36-dj20
|
||||||
|
- tox
|
||||||
17
README.md
17
README.md
@@ -1,28 +1,29 @@
|
|||||||
Alliance Auth
|
Alliance Auth
|
||||||
============
|
============
|
||||||
|
|
||||||
[](https://gitter.im/R4stl1n/allianceauth?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
[](https://discord.gg/fjnHAmk)
|
||||||
[](http://allianceauth.readthedocs.io/?badge=latest)
|
[](http://allianceauth.readthedocs.io/?badge=latest)
|
||||||
[](https://travis-ci.org/allianceauth/allianceauth)
|
[](https://gitlab.com/allianceauth/allianceauth/commits/master)
|
||||||
[](https://coveralls.io/github/allianceauth/allianceauth?branch=master)
|
[](https://gitlab.com/allianceauth/allianceauth/commits/master)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
An auth system for EVE Online to help in-game organizations manage online service access.
|
An auth system for EVE Online to help in-game organizations manage online service access.
|
||||||
|
|
||||||
[Read the docs here.](http://allianceauth.rtfd.io)
|
[Read the docs here.](http://allianceauth.rtfd.io)
|
||||||
|
|
||||||
[Get help on gitter](https://gitter.im/R4stl1n/allianceauth) or submit an Issue.
|
[Get help on Discord](https://discord.gg/fjnHAmk) or submit an Issue.
|
||||||
|
|
||||||
|
|
||||||
Active Developers:
|
Active Developers:
|
||||||
|
|
||||||
- [Adarnof](https://github.com/adarnof/)
|
- [Adarnof](https://gitlab.com/adarnof/)
|
||||||
- [Basraah](https://github.com/basraah/)
|
- [Basraah](https://gitlab.com/basraah/)
|
||||||
|
|
||||||
Beta Testers / Bug Fixers:
|
Beta Testers / Bug Fixers:
|
||||||
|
|
||||||
- [ghoti](https://github.com/ghoti/)
|
- [ghoti](https://gitlab.com/ChainsawMcGinny/)
|
||||||
- [mmolitor87](https://github.com/mmolitor87/)
|
- [mmolitor87](https://gitlab.com/mmolitor87/)
|
||||||
- [TargetZ3R0](https://github.com/TargetZ3R0)
|
- [TargetZ3R0](https://github.com/TargetZ3R0)
|
||||||
- [kaezon](https://github.com/kaezon/)
|
- [kaezon](https://github.com/kaezon/)
|
||||||
- [orbitroom](https://github.com/orbitroom/)
|
- [orbitroom](https://github.com/orbitroom/)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# This will make sure the app is always imported when
|
# This will make sure the app is always imported when
|
||||||
# Django starts so that shared_task will use this app.
|
# Django starts so that shared_task will use this app.
|
||||||
|
|
||||||
__version__ = '2.0.4'
|
__version__ = '2.1.1'
|
||||||
NAME = 'Alliance Auth v%s' % __version__
|
NAME = 'Alliance Auth v%s' % __version__
|
||||||
default_app_config = 'allianceauth.apps.AllianceAuthConfig'
|
default_app_config = 'allianceauth.apps.AllianceAuthConfig'
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
from django.conf.urls import include
|
from django.conf.urls import include
|
||||||
|
from django.contrib.auth.decorators import user_passes_test
|
||||||
|
from django.core.exceptions import PermissionDenied
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
from django.shortcuts import redirect
|
from django.shortcuts import redirect
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
@@ -35,3 +37,32 @@ def main_character_required(view_func):
|
|||||||
messages.error(request, _('A main character is required to perform that action. Add one below.'))
|
messages.error(request, _('A main character is required to perform that action. Add one below.'))
|
||||||
return redirect('authentication:dashboard')
|
return redirect('authentication:dashboard')
|
||||||
return login_required(_wrapped_view)
|
return login_required(_wrapped_view)
|
||||||
|
|
||||||
|
|
||||||
|
def permissions_required(perm, login_url=None, raise_exception=False):
|
||||||
|
"""
|
||||||
|
Decorator for views that checks whether a user has a particular permission
|
||||||
|
enabled, redirecting to the log-in page if necessary.
|
||||||
|
If the raise_exception parameter is given the PermissionDenied exception
|
||||||
|
is raised.
|
||||||
|
|
||||||
|
This decorator is identical to the django permission_required except it
|
||||||
|
allows for passing a tuple/list of perms that will return true if any one
|
||||||
|
of them is present.
|
||||||
|
"""
|
||||||
|
def check_perms(user):
|
||||||
|
if isinstance(perm, str):
|
||||||
|
perms = (perm,)
|
||||||
|
else:
|
||||||
|
perms = perm
|
||||||
|
# First check if the user has the permission (even anon users)
|
||||||
|
for perm_ in perms:
|
||||||
|
perm_ = (perm_,)
|
||||||
|
if user.has_perms(perm_):
|
||||||
|
return True
|
||||||
|
# In case the 403 handler should be called raise the exception
|
||||||
|
if raise_exception:
|
||||||
|
raise PermissionDenied
|
||||||
|
# As the last resort, show the login form
|
||||||
|
return False
|
||||||
|
return user_passes_test(check_perms, login_url=login_url)
|
||||||
|
|||||||
@@ -16,10 +16,16 @@ class CorpStatsQuerySet(models.QuerySet):
|
|||||||
assert char
|
assert char
|
||||||
# build all accepted queries
|
# build all accepted queries
|
||||||
queries = [models.Q(token__user=user)]
|
queries = [models.Q(token__user=user)]
|
||||||
if user.has_perm('corputils.view_corp_corpstats'):
|
|
||||||
queries.append(models.Q(corp__corporation_id=char.corporation_id))
|
|
||||||
if user.has_perm('corputils.view_alliance_corpstats'):
|
if user.has_perm('corputils.view_alliance_corpstats'):
|
||||||
queries.append(models.Q(corp__alliance__alliance_id=char.alliance_id))
|
if char.alliance_id is not None:
|
||||||
|
queries.append(models.Q(corp__alliance__alliance_id=char.alliance_id))
|
||||||
|
else:
|
||||||
|
queries.append(models.Q(corp__corporation_id=char.corporation_id))
|
||||||
|
if user.has_perm('corputils.view_corp_corpstats'):
|
||||||
|
if user.has_perm('corputils.view_alliance_corpstats'):
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
queries.append(models.Q(corp__corporation_id=char.corporation_id))
|
||||||
if user.has_perm('corputils.view_state_corpstats'):
|
if user.has_perm('corputils.view_state_corpstats'):
|
||||||
queries.append(models.Q(corp__in=user.profile.state.member_corporations.all()))
|
queries.append(models.Q(corp__in=user.profile.state.member_corporations.all()))
|
||||||
queries.append(models.Q(corp__alliance__in=user.profile.state.member_alliances.all()))
|
queries.append(models.Q(corp__alliance__in=user.profile.state.member_alliances.all()))
|
||||||
|
|||||||
@@ -15,9 +15,11 @@ SWAGGER_SPEC_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'sw
|
|||||||
"""
|
"""
|
||||||
Swagger spec operations:
|
Swagger spec operations:
|
||||||
|
|
||||||
|
Character
|
||||||
get_characters_character_id
|
get_characters_character_id
|
||||||
get_corporations_corporation_id_members
|
get_corporations_corporation_id_members
|
||||||
get_characters_names
|
Universe
|
||||||
|
post_universe_names
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
@@ -55,11 +57,11 @@ class CorpStats(models.Model):
|
|||||||
# the swagger spec doesn't have a maxItems count
|
# the swagger spec doesn't have a maxItems count
|
||||||
# manual testing says we can do over 350, but let's not risk it
|
# manual testing says we can do over 350, but let's not risk it
|
||||||
member_id_chunks = [member_ids[i:i + 255] for i in range(0, len(member_ids), 255)]
|
member_id_chunks = [member_ids[i:i + 255] for i in range(0, len(member_ids), 255)]
|
||||||
member_name_chunks = [c.Character.get_characters_names(character_ids=id_chunk).result() for id_chunk in
|
member_name_chunks = [c.Universe.post_universe_names(ids=id_chunk).result() for id_chunk in
|
||||||
member_id_chunks]
|
member_id_chunks]
|
||||||
member_list = {}
|
member_list = {}
|
||||||
for name_chunk in member_name_chunks:
|
for name_chunk in member_name_chunks:
|
||||||
member_list.update({m['character_id']: m['character_name'] for m in name_chunk})
|
member_list.update({m['id']: m['name'] for m in name_chunk})
|
||||||
|
|
||||||
# bulk create new member models
|
# bulk create new member models
|
||||||
missing_members = [m_id for m_id in member_ids if
|
missing_members = [m_id for m_id in member_ids if
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -86,7 +86,7 @@ class CorpStatsUpdateTestCase(TestCase):
|
|||||||
def test_update_add_member(self, SwaggerClient):
|
def test_update_add_member(self, SwaggerClient):
|
||||||
SwaggerClient.from_spec.return_value.Character.get_characters_character_id.return_value.result.return_value = {'corporation_id': 2}
|
SwaggerClient.from_spec.return_value.Character.get_characters_character_id.return_value.result.return_value = {'corporation_id': 2}
|
||||||
SwaggerClient.from_spec.return_value.Corporation.get_corporations_corporation_id_members.return_value.result.return_value = [1]
|
SwaggerClient.from_spec.return_value.Corporation.get_corporations_corporation_id_members.return_value.result.return_value = [1]
|
||||||
SwaggerClient.from_spec.return_value.Character.get_characters_names.return_value.result.return_value = [{'character_id': 1, 'character_name': 'test character'}]
|
SwaggerClient.from_spec.return_value.Universe.post_universe_names.return_value.result.return_value = [{'id': 1, 'name': 'test character'}]
|
||||||
self.corpstats.update()
|
self.corpstats.update()
|
||||||
self.assertTrue(CorpMember.objects.filter(character_id='1', character_name='test character', corpstats=self.corpstats).exists())
|
self.assertTrue(CorpMember.objects.filter(character_id='1', character_name='test character', corpstats=self.corpstats).exists())
|
||||||
|
|
||||||
@@ -95,7 +95,7 @@ class CorpStatsUpdateTestCase(TestCase):
|
|||||||
CorpMember.objects.create(character_id='2', character_name='old test character', corpstats=self.corpstats)
|
CorpMember.objects.create(character_id='2', character_name='old test character', corpstats=self.corpstats)
|
||||||
SwaggerClient.from_spec.return_value.Character.get_characters_character_id.return_value.result.return_value = {'corporation_id': 2}
|
SwaggerClient.from_spec.return_value.Character.get_characters_character_id.return_value.result.return_value = {'corporation_id': 2}
|
||||||
SwaggerClient.from_spec.return_value.Corporation.get_corporations_corporation_id_members.return_value.result.return_value = [1]
|
SwaggerClient.from_spec.return_value.Corporation.get_corporations_corporation_id_members.return_value.result.return_value = [1]
|
||||||
SwaggerClient.from_spec.return_value.Character.get_characters_names.return_value.result.return_value = [{'character_id': 1, 'character_name': 'test character'}]
|
SwaggerClient.from_spec.return_value.Universe.post_universe_names.return_value.result.return_value = [{'id': 1, 'name': 'test character'}]
|
||||||
self.corpstats.update()
|
self.corpstats.update()
|
||||||
self.assertFalse(CorpMember.objects.filter(character_id='2', corpstats=self.corpstats).exists())
|
self.assertFalse(CorpMember.objects.filter(character_id='2', corpstats=self.corpstats).exists())
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 2.0.6 on 2018-08-03 04:30
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('fleetactivitytracking', '0005_remove_fat_name'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='fat',
|
||||||
|
name='shiptype',
|
||||||
|
field=models.CharField(max_length=100),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -24,7 +24,7 @@ class Fat(models.Model):
|
|||||||
character = models.ForeignKey(EveCharacter, on_delete=models.CASCADE)
|
character = models.ForeignKey(EveCharacter, on_delete=models.CASCADE)
|
||||||
fatlink = models.ForeignKey(Fatlink, on_delete=models.CASCADE)
|
fatlink = models.ForeignKey(Fatlink, on_delete=models.CASCADE)
|
||||||
system = models.CharField(max_length=30)
|
system = models.CharField(max_length=30)
|
||||||
shiptype = models.CharField(max_length=30)
|
shiptype = models.CharField(max_length=100)
|
||||||
station = models.CharField(max_length=125)
|
station = models.CharField(max_length=125)
|
||||||
user = models.ForeignKey(User, on_delete=models.CASCADE)
|
user = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||||
|
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ def fatlink_statistics_corp_view(request, corpid, year=None, month=None):
|
|||||||
start_of_next_month = first_day_of_next_month(year, month)
|
start_of_next_month = first_day_of_next_month(year, month)
|
||||||
start_of_previous_month = first_day_of_previous_month(year, month)
|
start_of_previous_month = first_day_of_previous_month(year, month)
|
||||||
fat_stats = {}
|
fat_stats = {}
|
||||||
corp_members = CharacterOwnership.objects.filter(character__corporation_id=corpid).values('user_id').distinct()
|
corp_members = CharacterOwnership.objects.filter(character__corporation_id=corpid).order_by('user_id').values('user_id').distinct()
|
||||||
|
|
||||||
for member in corp_members:
|
for member in corp_members:
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
{% for char_name, user_id in member_list %}
|
{% for char_name, user_id in member_list %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<img src="http://image.eveonline.com/Character/{{ user_id.char_id }}_32.jpg" class="img-circle">
|
<img src="https://imageserver.eveonline.com/Character/{{ user_id.char_id }}_32.jpg" class="img-circle">
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<p>{{ user_id.char_name }}</p>
|
<p>{{ user_id.char_name }}</p>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="col-lg-12">
|
<div class="col-lg-12">
|
||||||
{% include "fleetup/menu.html" %}
|
{% include "fleetup/menu.html" %}
|
||||||
<div class="panel">
|
<div>
|
||||||
{% for a, j in doctrine.items %}
|
{% for a, j in doctrine.items %}
|
||||||
{% regroup j.Data|dictsort:"Role" by Role as role_list %}
|
{% regroup j.Data|dictsort:"Role" by Role as role_list %}
|
||||||
|
|
||||||
|
|||||||
@@ -8,12 +8,12 @@
|
|||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="col-lg-12">
|
<div class="col-lg-12">
|
||||||
{% include "fleetup/menu.html" %}
|
{% include "fleetup/menu.html" %}
|
||||||
<div class="panel">
|
<div>
|
||||||
{% if doctrines_list %}
|
{% if doctrines_list %}
|
||||||
{% for a, j in doctrines_list.items %}
|
{% for a, j in doctrines_list.items %}
|
||||||
{% regroup j|dictsort:"FolderName" by FolderName as folder_list %}
|
{% regroup j|dictsort:"FolderName" by FolderName as folder_list %}
|
||||||
{% for FolderName in folder_list %}
|
{% for FolderName in folder_list %}
|
||||||
<div class="col-lg-8">
|
<div>
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<h3 class="panel-title"><b>{{ FolderName.grouper }}</b></h3>
|
<h3 class="panel-title"><b>{{ FolderName.grouper }}</b></h3>
|
||||||
|
|||||||
@@ -8,9 +8,9 @@
|
|||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="col-lg-12">
|
<div class="col-lg-12">
|
||||||
{% include "fleetup/menu.html" %}
|
{% include "fleetup/menu.html" %}
|
||||||
<div class="tab-content">
|
<div class="tab-content row">
|
||||||
<div id="fit" class="tab-pane fade in active">
|
<div id="fit" class="tab-pane fade in active">
|
||||||
<div class="col-lg-3">
|
<div class="col-lg-4">
|
||||||
{% for x, y in fitting_data.items %}
|
{% for x, y in fitting_data.items %}
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
@@ -18,22 +18,24 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
{% for doctrin in y.Doctrines %}
|
{% for doctrin in y.Doctrines %}
|
||||||
<h4>{{ doctrin.Name }}</h4>
|
<div class="clearfix">
|
||||||
<div class="col-lg-12">
|
<h4>{{ doctrin.Name }}</h4>
|
||||||
<p>{% trans "Role in doctrine:" %} {{ doctrin.Role }}</p>
|
<div class="col-lg-12">
|
||||||
</div>
|
<p>{% trans "Role in doctrine:" %} {{ doctrin.Role }}</p>
|
||||||
<div class="col-lg-4">
|
</div>
|
||||||
<p>{% trans "Priority:" %}</p>
|
<div class="col-lg-4">
|
||||||
</div>
|
<p>{% trans "Priority:" %}</p>
|
||||||
<div class="col-lg-8">
|
</div>
|
||||||
<div class="progress">
|
<div class="col-lg-8">
|
||||||
<div class="progress-bar progress-bar-striped" role="progressbar" aria-valuenow="{{ doctrin.Priority }}" aria-valuemin="0" aria-valuemax="5" style="width: {% widthratio doctrin.Priority 5 100 %}%;">
|
<div class="progress">
|
||||||
{{ doctrin.Priority }}/5
|
<div class="progress-bar progress-bar-striped" role="progressbar" aria-valuenow="{{ doctrin.Priority }}" aria-valuemin="0" aria-valuemax="5" style="width: {% widthratio doctrin.Priority 5 100 %}%;">
|
||||||
|
{{ doctrin.Priority }}/5
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="pull-right">
|
||||||
<div class="pull-right">
|
<a class="btn btn-primary" href="{% url 'fleetup:doctrine' doctrin.DoctrineId %}">{% trans "See doctrine" %}</a>
|
||||||
<a class="btn btn-primary" href="{% url 'fleetup:doctrine' doctrin.DoctrineId %}">{% trans "See doctrine" %}</a>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
@@ -108,7 +110,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-lg-3">
|
<div class="col-lg-4">
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<h3 class="panel-title">{% trans "EFT/Export" %}</h3>
|
<h3 class="panel-title">{% trans "EFT/Export" %}</h3>
|
||||||
|
|||||||
@@ -8,15 +8,15 @@
|
|||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="col-lg-12">
|
<div class="col-lg-12">
|
||||||
{% include "fleetup/menu.html" %}
|
{% include "fleetup/menu.html" %}
|
||||||
<div class="panel">
|
<div>
|
||||||
<ul class="nav nav-tabs">
|
<ul class="nav nav-tabs">
|
||||||
<li class="active"><a data-toggle="tab" href="#operations">{% trans "Operations" %}</a></li>
|
<li class="active"><a data-toggle="tab" href="#operations">{% trans "Operations" %}</a></li>
|
||||||
<li><a data-toggle="tab" href="#timers">{% trans "Timers" %}</a></li>
|
<li><a data-toggle="tab" href="#timers">{% trans "Timers" %}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<div class="tab-content">
|
<div class="tab-content row">
|
||||||
<div id="operations" class="tab-pane fade in active">
|
<div id="operations" class="tab-pane fade in active">
|
||||||
<div class="col-lg-7">
|
<div class="col-lg-8">
|
||||||
{% if operations_list %}
|
{% if operations_list %}
|
||||||
{% for subject, start in operations_list %}
|
{% for subject, start in operations_list %}
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
@@ -43,9 +43,8 @@
|
|||||||
<td class="col-md-6"></td>
|
<td class="col-md-6"></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
<p>{{ start.details }}</p>
|
{{ start.details|linebreaks }}
|
||||||
|
|
||||||
<div class="col-lg-12">
|
|
||||||
<table class="table table-condensed table-striped">
|
<table class="table table-condensed table-striped">
|
||||||
<tr>
|
<tr>
|
||||||
<th class="col-md-4">{% trans "Location" %}</th>
|
<th class="col-md-4">{% trans "Location" %}</th>
|
||||||
@@ -81,7 +80,6 @@
|
|||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
@@ -89,7 +87,7 @@
|
|||||||
<h3>{% trans "There seems to be no Operations in the near future." %}</h3>
|
<h3>{% trans "There seems to be no Operations in the near future." %}</h3>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-3">
|
<div class="col-lg-4">
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<h2 class="panel-title">{% trans "Current Eve Time:" %}</h2>
|
<h2 class="panel-title">{% trans "Current Eve Time:" %}</h2>
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ from .models import GroupRequest
|
|||||||
|
|
||||||
class AuthGroupInlineAdmin(admin.StackedInline):
|
class AuthGroupInlineAdmin(admin.StackedInline):
|
||||||
model = AuthGroup
|
model = AuthGroup
|
||||||
filter_horizontal = ('group_leaders',)
|
filter_horizontal = ('group_leaders', 'states',)
|
||||||
fields = ('description', 'group_leaders', 'internal', 'hidden', 'open', 'public')
|
fields = ('description', 'group_leaders', 'states', 'internal', 'hidden', 'open', 'public')
|
||||||
verbose_name_plural = 'Auth Settings'
|
verbose_name_plural = 'Auth Settings'
|
||||||
verbose_name = ''
|
verbose_name = ''
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
from django.contrib.auth.models import Group
|
from django.contrib.auth.models import Group
|
||||||
|
from django.db.models import Q
|
||||||
|
|
||||||
|
|
||||||
class GroupManager:
|
class GroupManager:
|
||||||
@@ -6,7 +7,12 @@ class GroupManager:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_joinable_groups():
|
def get_joinable_groups(state):
|
||||||
|
return Group.objects.select_related('authgroup').exclude(authgroup__internal=True)\
|
||||||
|
.filter(Q(authgroup__states=state) | Q(authgroup__states=None))
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_all_non_internal_groups():
|
||||||
return Group.objects.select_related('authgroup').exclude(authgroup__internal=True)
|
return Group.objects.select_related('authgroup').exclude(authgroup__internal=True)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@@ -14,13 +20,35 @@ class GroupManager:
|
|||||||
return Group.objects.select_related('authgroup').filter(authgroup__group_leaders__in=[user])
|
return Group.objects.select_related('authgroup').filter(authgroup__group_leaders__in=[user])
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def joinable_group(group):
|
def joinable_group(group, state):
|
||||||
"""
|
"""
|
||||||
Check if a group is a user joinable group, i.e.
|
Check if a group is a user/state joinable group, i.e.
|
||||||
not an internal group for Corp, Alliance, Members etc
|
not an internal group for Corp, Alliance, Members etc,
|
||||||
|
or restricted from the user's current state.
|
||||||
:param group: django.contrib.auth.models.Group object
|
:param group: django.contrib.auth.models.Group object
|
||||||
|
:param state: allianceauth.authentication.State object
|
||||||
:return: bool True if its joinable, False otherwise
|
:return: bool True if its joinable, False otherwise
|
||||||
"""
|
"""
|
||||||
|
if len(group.authgroup.states.all()) != 0 and state not in group.authgroup.states.all():
|
||||||
|
return False
|
||||||
|
return not group.authgroup.internal
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def check_internal_group(group):
|
||||||
|
"""
|
||||||
|
Check if a group is auditable, i.e not an internal group
|
||||||
|
:param group: django.contrib.auth.models.Group object
|
||||||
|
:return: bool True if it is auditable, false otherwise
|
||||||
|
"""
|
||||||
|
return not group.authgroup.internal
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def check_internal_group(group):
|
||||||
|
"""
|
||||||
|
Check if a group is auditable, i.e not an internal group
|
||||||
|
:param group: django.contrib.auth.models.Group object
|
||||||
|
:return: bool True if it is auditable, false otherwise
|
||||||
|
"""
|
||||||
return not group.authgroup.internal
|
return not group.authgroup.internal
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|||||||
28
allianceauth/groupmanagement/migrations/0009_requestlog.py
Normal file
28
allianceauth/groupmanagement/migrations/0009_requestlog.py
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
# Generated by Django 2.0.6 on 2018-06-04 02:45
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('auth', '0008_alter_user_username_max_length'),
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
('groupmanagement', '0008_remove_authgroup_permissions'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='RequestLog',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('request_type', models.NullBooleanField(default=0)),
|
||||||
|
('request_info', models.CharField(max_length=254)),
|
||||||
|
('action', models.BooleanField(default=0)),
|
||||||
|
('group', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='auth.Group')),
|
||||||
|
('request_actor', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
# Generated by Django 2.0.6 on 2018-07-11 00:17
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('authentication', '0016_ownershiprecord'),
|
||||||
|
('groupmanagement', '0009_requestlog'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='authgroup',
|
||||||
|
name='states',
|
||||||
|
field=models.ManyToManyField(blank=True, help_text='States listed here will have the ability to join this group provided they have the proper permissions.', related_name='valid_states', to='authentication.State'),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -3,6 +3,7 @@ from django.contrib.auth.models import User
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db.models.signals import post_save
|
from django.db.models.signals import post_save
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
|
from allianceauth.authentication.models import State
|
||||||
|
|
||||||
|
|
||||||
class GroupRequest(models.Model):
|
class GroupRequest(models.Model):
|
||||||
@@ -23,6 +24,37 @@ class GroupRequest(models.Model):
|
|||||||
return self.user.username + ":" + self.group.name
|
return self.user.username + ":" + self.group.name
|
||||||
|
|
||||||
|
|
||||||
|
class RequestLog(models.Model):
|
||||||
|
request_type = models.NullBooleanField(default=0)
|
||||||
|
group = models.ForeignKey(Group, on_delete=models.CASCADE)
|
||||||
|
request_info = models.CharField(max_length=254)
|
||||||
|
action = models.BooleanField(default=0)
|
||||||
|
request_actor = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||||
|
|
||||||
|
def requestor(self):
|
||||||
|
return self.request_info.split(":")[0]
|
||||||
|
|
||||||
|
def type_to_str(self):
|
||||||
|
if self.request_type is None:
|
||||||
|
return "Removed"
|
||||||
|
elif self.request_type is True:
|
||||||
|
return "Leave"
|
||||||
|
elif self.request_type is False:
|
||||||
|
return "Join"
|
||||||
|
|
||||||
|
def action_to_str(self):
|
||||||
|
if self.action is True:
|
||||||
|
return "Accept"
|
||||||
|
elif self.action is False:
|
||||||
|
return "Reject"
|
||||||
|
|
||||||
|
def req_char(self):
|
||||||
|
usr = self.requestor()
|
||||||
|
user = User.objects.get(username=usr)
|
||||||
|
return user.profile.main_character
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class AuthGroup(models.Model):
|
class AuthGroup(models.Model):
|
||||||
"""
|
"""
|
||||||
Extends Django Group model with a one-to-one field
|
Extends Django Group model with a one-to-one field
|
||||||
@@ -65,6 +97,10 @@ class AuthGroup(models.Model):
|
|||||||
"specifically. Use the auth.group_management permission to allow "
|
"specifically. Use the auth.group_management permission to allow "
|
||||||
"a user to manage all groups.")
|
"a user to manage all groups.")
|
||||||
|
|
||||||
|
states = models.ManyToManyField(State, related_name='valid_states', blank=True,
|
||||||
|
help_text="States listed here will have the ability to join this group provided "
|
||||||
|
"they have the proper permissions.")
|
||||||
|
|
||||||
description = models.CharField(max_length=512, blank=True, help_text="Description of the group shown to users.")
|
description = models.CharField(max_length=512, blank=True, help_text="Description of the group shown to users.")
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
{% extends "allianceauth/base.html" %}
|
||||||
|
{% load staticfiles %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% block page_title %}{{ group }} {% trans "Audit Log" %}{% endblock page_title %}
|
||||||
|
{% block extra_css %}{% endblock extra_css %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="col-lg-12">
|
||||||
|
<br>
|
||||||
|
{% include 'groupmanagement/menu.html' %}
|
||||||
|
<div>
|
||||||
|
{% if entries %}
|
||||||
|
<h3>{{ group }} Audit Log</h3>
|
||||||
|
<table class="table">
|
||||||
|
<tr>
|
||||||
|
<th class="text-center">{% trans "Requestor" %}</th>
|
||||||
|
<th class="text-center">{% trans "Main Character" %}</th>
|
||||||
|
<th class="text-center">{% trans "Group" %}</th>
|
||||||
|
<th class="text-center">{% trans "Type" %}</th>
|
||||||
|
<th class="text-center">{% trans "Action" %}</th>
|
||||||
|
<th class="text-center">{% trans "Actor" %}</th>
|
||||||
|
</tr>
|
||||||
|
{% for entry in entries %}
|
||||||
|
<tr>
|
||||||
|
<td class="text-center">{{ entry.requestor }}</td>
|
||||||
|
<td class="text-center">{{ entry.req_char }}</td>
|
||||||
|
<td class="text-center">{{ entry.group }}</td>
|
||||||
|
<td class="text-center">{{ entry.type_to_str }}</td>
|
||||||
|
<td class="text-center">{{ entry.action_to_str }}</td>
|
||||||
|
<td class="text-center">{{ entry.request_actor }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
{% else %}
|
||||||
|
<div class="alert alert-warning text-center">{% trans "No entries found." %}</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock content %}
|
||||||
@@ -41,6 +41,9 @@
|
|||||||
title="{% trans "View Members" %}">
|
title="{% trans "View Members" %}">
|
||||||
<i class="glyphicon glyphicon-eye-open"></i>
|
<i class="glyphicon glyphicon-eye-open"></i>
|
||||||
</a>
|
</a>
|
||||||
|
<a href="{% url "groupmanagement:audit_log" group.id %}" class="btn btn-info" title="{% trans "Audit Members" %}">
|
||||||
|
<i class="glyphicon glyphicon-list-alt"></i>
|
||||||
|
</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ urlpatterns = [
|
|||||||
name='membership'),
|
name='membership'),
|
||||||
url(r'^membership/(\w+)/$', views.group_membership_list,
|
url(r'^membership/(\w+)/$', views.group_membership_list,
|
||||||
name='membership_list'),
|
name='membership_list'),
|
||||||
|
url(r'^membership/(\w+)/audit/', views.group_membership_audit, name="audit_log"),
|
||||||
url(r'^membership/(\w+)/remove/(\w+)/$', views.group_membership_remove,
|
url(r'^membership/(\w+)/remove/(\w+)/$', views.group_membership_remove,
|
||||||
name='membership_remove'),
|
name='membership_remove'),
|
||||||
url(r'^request_add/(\w+)', views.group_request_add,
|
url(r'^request_add/(\w+)', views.group_request_add,
|
||||||
|
|||||||
@@ -10,10 +10,12 @@ from django.http import Http404
|
|||||||
from django.shortcuts import render, redirect, get_object_or_404
|
from django.shortcuts import render, redirect, get_object_or_404
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from .managers import GroupManager
|
from .managers import GroupManager
|
||||||
from .models import GroupRequest
|
from .models import GroupRequest, RequestLog
|
||||||
|
|
||||||
from allianceauth.notifications import notify
|
from allianceauth.notifications import notify
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@@ -53,7 +55,7 @@ def group_membership(request):
|
|||||||
# Get all open and closed groups
|
# Get all open and closed groups
|
||||||
if GroupManager.has_management_permission(request.user):
|
if GroupManager.has_management_permission(request.user):
|
||||||
# Full access
|
# Full access
|
||||||
groups = GroupManager.get_joinable_groups()
|
groups = GroupManager.get_all_non_internal_groups()
|
||||||
else:
|
else:
|
||||||
# Group leader specific
|
# Group leader specific
|
||||||
groups = GroupManager.get_group_leaders_groups(request.user)
|
groups = GroupManager.get_group_leaders_groups(request.user)
|
||||||
@@ -65,6 +67,32 @@ def group_membership(request):
|
|||||||
return render(request, 'groupmanagement/groupmembership.html', context=render_items)
|
return render(request, 'groupmanagement/groupmembership.html', context=render_items)
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
@user_passes_test(GroupManager.can_manage_groups)
|
||||||
|
def group_membership_audit(request, group_id):
|
||||||
|
logger.debug("group_management_audit called by user %s" % request.user)
|
||||||
|
group = get_object_or_404(Group, id=group_id)
|
||||||
|
try:
|
||||||
|
|
||||||
|
# Check its a joinable group i.e. not corp or internal
|
||||||
|
# And the user has permission to manage it
|
||||||
|
if not GroupManager.check_internal_group(group) or not GroupManager.can_manage_group(request.user, group):
|
||||||
|
logger.warning("User %s attempted to view the membership of group %s but permission was denied" %
|
||||||
|
(request.user, group_id))
|
||||||
|
raise PermissionDenied
|
||||||
|
|
||||||
|
except ObjectDoesNotExist:
|
||||||
|
raise Http404("Group does not exist")
|
||||||
|
|
||||||
|
entries = RequestLog.objects.filter(group=group)
|
||||||
|
|
||||||
|
render_items = {'entries': entries, 'group': group.name}
|
||||||
|
|
||||||
|
return render(request, 'groupmanagement/audit.html', context=render_items)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@user_passes_test(GroupManager.can_manage_groups)
|
@user_passes_test(GroupManager.can_manage_groups)
|
||||||
def group_membership_list(request, group_id):
|
def group_membership_list(request, group_id):
|
||||||
@@ -74,7 +102,7 @@ def group_membership_list(request, group_id):
|
|||||||
|
|
||||||
# Check its a joinable group i.e. not corp or internal
|
# Check its a joinable group i.e. not corp or internal
|
||||||
# And the user has permission to manage it
|
# And the user has permission to manage it
|
||||||
if not GroupManager.joinable_group(group) or not GroupManager.can_manage_group(request.user, group):
|
if not GroupManager.check_internal_group(group) or not GroupManager.can_manage_group(request.user, group):
|
||||||
logger.warning("User %s attempted to view the membership of group %s but permission was denied" %
|
logger.warning("User %s attempted to view the membership of group %s but permission was denied" %
|
||||||
(request.user, group_id))
|
(request.user, group_id))
|
||||||
raise PermissionDenied
|
raise PermissionDenied
|
||||||
@@ -105,13 +133,16 @@ def group_membership_remove(request, group_id, user_id):
|
|||||||
try:
|
try:
|
||||||
# Check its a joinable group i.e. not corp or internal
|
# Check its a joinable group i.e. not corp or internal
|
||||||
# And the user has permission to manage it
|
# And the user has permission to manage it
|
||||||
if not GroupManager.joinable_group(group) or not GroupManager.can_manage_group(request.user, group):
|
if not GroupManager.check_internal_group(group) or not GroupManager.can_manage_group(request.user, group):
|
||||||
logger.warning("User %s attempted to remove a user from group %s but permission was denied" % (request.user,
|
logger.warning("User %s attempted to remove a user from group %s but permission was denied" % (request.user,
|
||||||
group_id))
|
group_id))
|
||||||
raise PermissionDenied
|
raise PermissionDenied
|
||||||
|
|
||||||
try:
|
try:
|
||||||
user = group.user_set.get(id=user_id)
|
user = group.user_set.get(id=user_id)
|
||||||
|
request_info = user.username + ":" + group.name
|
||||||
|
log = RequestLog(request_type=None,group=group,request_info=request_info,action=1,request_actor=request.user)
|
||||||
|
log.save()
|
||||||
# Remove group from user
|
# Remove group from user
|
||||||
user.groups.remove(group)
|
user.groups.remove(group)
|
||||||
logger.info("User %s removed user %s from group %s" % (request.user, user, group))
|
logger.info("User %s removed user %s from group %s" % (request.user, user, group))
|
||||||
@@ -133,12 +164,14 @@ def group_accept_request(request, group_request_id):
|
|||||||
try:
|
try:
|
||||||
group, created = Group.objects.get_or_create(name=group_request.group.name)
|
group, created = Group.objects.get_or_create(name=group_request.group.name)
|
||||||
|
|
||||||
if not GroupManager.joinable_group(group_request.group) or \
|
if not GroupManager.joinable_group(group_request.group, group_request.user.profile.state) or \
|
||||||
not GroupManager.can_manage_group(request.user, group_request.group):
|
not GroupManager.can_manage_group(request.user, group_request.group):
|
||||||
raise PermissionDenied
|
raise PermissionDenied
|
||||||
|
|
||||||
group_request.user.groups.add(group)
|
group_request.user.groups.add(group)
|
||||||
group_request.user.save()
|
group_request.user.save()
|
||||||
|
log = RequestLog(request_type=group_request.leave_request,group=group,request_info=group_request.__str__(),action=1,request_actor=request.user)
|
||||||
|
log.save()
|
||||||
group_request.delete()
|
group_request.delete()
|
||||||
logger.info("User %s accepted group request from user %s to group %s" % (
|
logger.info("User %s accepted group request from user %s to group %s" % (
|
||||||
request.user, group_request.user, group_request.group.name))
|
request.user, group_request.user, group_request.group.name))
|
||||||
@@ -172,6 +205,8 @@ def group_reject_request(request, group_request_id):
|
|||||||
if group_request:
|
if group_request:
|
||||||
logger.info("User %s rejected group request from user %s to group %s" % (
|
logger.info("User %s rejected group request from user %s to group %s" % (
|
||||||
request.user, group_request.user, group_request.group.name))
|
request.user, group_request.user, group_request.group.name))
|
||||||
|
log = RequestLog(request_type=group_request.leave_request,group=group_request.group,request_info=group_request.__str__(),action=0,request_actor=request.user)
|
||||||
|
log.save()
|
||||||
group_request.delete()
|
group_request.delete()
|
||||||
notify(group_request.user, "Group Application Rejected", level="danger",
|
notify(group_request.user, "Group Application Rejected", level="danger",
|
||||||
message="Your application to %s has been rejected." % group_request.group)
|
message="Your application to %s has been rejected." % group_request.group)
|
||||||
@@ -204,6 +239,8 @@ def group_leave_accept_request(request, group_request_id):
|
|||||||
group, created = Group.objects.get_or_create(name=group_request.group.name)
|
group, created = Group.objects.get_or_create(name=group_request.group.name)
|
||||||
group_request.user.groups.remove(group)
|
group_request.user.groups.remove(group)
|
||||||
group_request.user.save()
|
group_request.user.save()
|
||||||
|
log = RequestLog(request_type=group_request.leave_request,group=group_request.group,request_info=group_request.__str__(),action=1,request_actor=request.user)
|
||||||
|
log.save()
|
||||||
group_request.delete()
|
group_request.delete()
|
||||||
logger.info("User %s accepted group leave request from user %s to group %s" % (
|
logger.info("User %s accepted group leave request from user %s to group %s" % (
|
||||||
request.user, group_request.user, group_request.group.name))
|
request.user, group_request.user, group_request.group.name))
|
||||||
@@ -236,6 +273,8 @@ def group_leave_reject_request(request, group_request_id):
|
|||||||
raise PermissionDenied
|
raise PermissionDenied
|
||||||
|
|
||||||
if group_request:
|
if group_request:
|
||||||
|
log = RequestLog(request_type=group_request.leave_request,group=group_request.group,request_info=group_request.__str__(),action=0,request_actor=request.user)
|
||||||
|
log.save()
|
||||||
group_request.delete()
|
group_request.delete()
|
||||||
logger.info("User %s rejected group leave request from user %s for group %s" % (
|
logger.info("User %s rejected group leave request from user %s for group %s" % (
|
||||||
request.user, group_request.user, group_request.group.name))
|
request.user, group_request.user, group_request.group.name))
|
||||||
@@ -262,7 +301,7 @@ def groups_view(request):
|
|||||||
logger.debug("groups_view called by user %s" % request.user)
|
logger.debug("groups_view called by user %s" % request.user)
|
||||||
groups = []
|
groups = []
|
||||||
|
|
||||||
group_query = GroupManager.get_joinable_groups()
|
group_query = GroupManager.get_joinable_groups(request.user.profile.state)
|
||||||
|
|
||||||
if not request.user.has_perm('groupmanagement.request_groups'):
|
if not request.user.has_perm('groupmanagement.request_groups'):
|
||||||
# Filter down to public groups only for non-members
|
# Filter down to public groups only for non-members
|
||||||
@@ -284,11 +323,18 @@ def groups_view(request):
|
|||||||
def group_request_add(request, group_id):
|
def group_request_add(request, group_id):
|
||||||
logger.debug("group_request_add called by user %s for group id %s" % (request.user, group_id))
|
logger.debug("group_request_add called by user %s for group id %s" % (request.user, group_id))
|
||||||
group = Group.objects.get(id=group_id)
|
group = Group.objects.get(id=group_id)
|
||||||
if not GroupManager.joinable_group(group):
|
state = request.user.profile.state
|
||||||
|
if not GroupManager.joinable_group(group, state):
|
||||||
logger.warning("User %s attempted to join group id %s but it is not a joinable group" %
|
logger.warning("User %s attempted to join group id %s but it is not a joinable group" %
|
||||||
(request.user, group_id))
|
(request.user, group_id))
|
||||||
messages.warning(request, _("You cannot join that group"))
|
messages.warning(request, _("You cannot join that group"))
|
||||||
return redirect('groupmanagement:groups')
|
return redirect('groupmanagement:groups')
|
||||||
|
if group in request.user.groups.all():
|
||||||
|
# User is already a member of this group.
|
||||||
|
logger.warning("User %s attempted to join group id %s but they are already a member." %
|
||||||
|
(request.user, group_id))
|
||||||
|
messages.warning(request, "You are already a member of that group.")
|
||||||
|
return redirect('groupmanagement:groups')
|
||||||
if not request.user.has_perm('groupmanagement.request_groups') and not group.authgroup.public:
|
if not request.user.has_perm('groupmanagement.request_groups') and not group.authgroup.public:
|
||||||
# Does not have the required permission, trying to join a non-public group
|
# Does not have the required permission, trying to join a non-public group
|
||||||
logger.warning("User %s attempted to join group id %s but it is not a public group" %
|
logger.warning("User %s attempted to join group id %s but it is not a public group" %
|
||||||
@@ -299,6 +345,11 @@ def group_request_add(request, group_id):
|
|||||||
logger.info("%s joining %s as is an open group" % (request.user, group))
|
logger.info("%s joining %s as is an open group" % (request.user, group))
|
||||||
request.user.groups.add(group)
|
request.user.groups.add(group)
|
||||||
return redirect("groupmanagement:groups")
|
return redirect("groupmanagement:groups")
|
||||||
|
req = GroupRequest.objects.filter(user=request.user, group=group)
|
||||||
|
if len(req) > 0:
|
||||||
|
logger.info("%s attempted to join %s but already has an open application" % (request.user, group))
|
||||||
|
messages.warning(request, "You already have a pending application for that group.")
|
||||||
|
return redirect("groupmanagement:groups")
|
||||||
grouprequest = GroupRequest()
|
grouprequest = GroupRequest()
|
||||||
grouprequest.status = _('Pending')
|
grouprequest.status = _('Pending')
|
||||||
grouprequest.group = group
|
grouprequest.group = group
|
||||||
@@ -314,7 +365,7 @@ def group_request_add(request, group_id):
|
|||||||
def group_request_leave(request, group_id):
|
def group_request_leave(request, group_id):
|
||||||
logger.debug("group_request_leave called by user %s for group id %s" % (request.user, group_id))
|
logger.debug("group_request_leave called by user %s for group id %s" % (request.user, group_id))
|
||||||
group = Group.objects.get(id=group_id)
|
group = Group.objects.get(id=group_id)
|
||||||
if not GroupManager.joinable_group(group):
|
if not GroupManager.check_internal_group(group):
|
||||||
logger.warning("User %s attempted to leave group id %s but it is not a joinable group" %
|
logger.warning("User %s attempted to leave group id %s but it is not a joinable group" %
|
||||||
(request.user, group_id))
|
(request.user, group_id))
|
||||||
messages.warning(request, _("You cannot leave that group"))
|
messages.warning(request, _("You cannot leave that group"))
|
||||||
@@ -328,6 +379,15 @@ def group_request_leave(request, group_id):
|
|||||||
logger.info("%s leaving %s as is an open group" % (request.user, group))
|
logger.info("%s leaving %s as is an open group" % (request.user, group))
|
||||||
request.user.groups.remove(group)
|
request.user.groups.remove(group)
|
||||||
return redirect("groupmanagement:groups")
|
return redirect("groupmanagement:groups")
|
||||||
|
req = GroupRequest.objects.filter(user=request.user, group=group)
|
||||||
|
if len(req) > 0:
|
||||||
|
logger.info("%s attempted to leave %s but already has an pending leave request." % (request.user, group))
|
||||||
|
messages.warning(request, "You already have a pending leave request for that group.")
|
||||||
|
return redirect("groupmanagement:groups")
|
||||||
|
if getattr(settings, 'AUTO_LEAVE', False):
|
||||||
|
logger.info("%s leaving joinable group %s due to auto_leave" % (request.user, group))
|
||||||
|
request.user.groups.remove(group)
|
||||||
|
return redirect('groupmanagement:groups')
|
||||||
grouprequest = GroupRequest()
|
grouprequest = GroupRequest()
|
||||||
grouprequest.status = _('Pending')
|
grouprequest.status = _('Pending')
|
||||||
grouprequest.group = group
|
grouprequest.group = group
|
||||||
|
|||||||
@@ -355,11 +355,14 @@ class DiscourseManager:
|
|||||||
user_groups = DiscourseManager.__get_user_groups(username)
|
user_groups = DiscourseManager.__get_user_groups(username)
|
||||||
add_groups = [group_dict[x] for x in group_dict if not group_dict[x] in user_groups]
|
add_groups = [group_dict[x] for x in group_dict if not group_dict[x] in user_groups]
|
||||||
rem_groups = [x for x in user_groups if x not in inv_group_dict]
|
rem_groups = [x for x in user_groups if x not in inv_group_dict]
|
||||||
if add_groups or rem_groups:
|
if add_groups:
|
||||||
logger.info(
|
logger.info(
|
||||||
"Updating discourse user %s groups: adding %s, removing %s" % (username, add_groups, rem_groups))
|
"Updating discourse user %s groups: adding %s" % (username, add_groups))
|
||||||
for g in add_groups:
|
for g in add_groups:
|
||||||
DiscourseManager.__add_user_to_group(g, username)
|
DiscourseManager.__add_user_to_group(g, username)
|
||||||
|
if rem_groups:
|
||||||
|
logger.info(
|
||||||
|
"Updating discourse user %s groups: removing %s" % (username, rem_groups))
|
||||||
for g in rem_groups:
|
for g in rem_groups:
|
||||||
DiscourseManager.__remove_user_from_group(g, username)
|
DiscourseManager.__remove_user_from_group(g, username)
|
||||||
|
|
||||||
|
|||||||
@@ -67,6 +67,8 @@ class Teamspeak3Manager:
|
|||||||
group_cache = self.server.send_command('servergrouplist')
|
group_cache = self.server.send_command('servergrouplist')
|
||||||
logger.debug("Received group cache from server: %s" % group_cache)
|
logger.debug("Received group cache from server: %s" % group_cache)
|
||||||
for group in group_cache:
|
for group in group_cache:
|
||||||
|
if group['keys']['type'] != '1':
|
||||||
|
continue
|
||||||
logger.debug("Checking group %s" % group)
|
logger.debug("Checking group %s" % group)
|
||||||
if group['keys']['name'] == groupname:
|
if group['keys']['name'] == groupname:
|
||||||
logger.debug("Found group %s, returning id %s" % (groupname, group['keys']['sgid']))
|
logger.debug("Found group %s, returning id %s" % (groupname, group['keys']['sgid']))
|
||||||
@@ -124,6 +126,8 @@ class Teamspeak3Manager:
|
|||||||
outlist = {}
|
outlist = {}
|
||||||
if group_cache:
|
if group_cache:
|
||||||
for group in group_cache:
|
for group in group_cache:
|
||||||
|
if group['keys']['type'] != '1':
|
||||||
|
continue
|
||||||
logger.debug("Assigning name/id dict: %s = %s" % (group['keys']['name'], group['keys']['sgid']))
|
logger.debug("Assigning name/id dict: %s = %s" % (group['keys']['name'], group['keys']['sgid']))
|
||||||
outlist[group['keys']['name']] = group['keys']['sgid']
|
outlist[group['keys']['name']] = group['keys']['sgid']
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -1,9 +1,15 @@
|
|||||||
from allianceauth import NAME
|
from allianceauth import NAME
|
||||||
|
from esi.clients import esi_client_factory
|
||||||
import requests
|
import requests
|
||||||
import logging
|
import logging
|
||||||
|
import os
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
SWAGGER_SPEC_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'swagger.json')
|
||||||
|
"""
|
||||||
|
Swagger Operations:
|
||||||
|
get_killmails_killmail_id_killmail_hash
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
class SRPManager:
|
class SRPManager:
|
||||||
@@ -18,7 +24,7 @@ class SRPManager:
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_kill_data(kill_id):
|
def get_kill_data(kill_id):
|
||||||
url = ("https://www.zkillboard.com/api/killID/%s/" % kill_id)
|
url = ("https://zkillboard.com/api/killID/%s/" % kill_id)
|
||||||
headers = {
|
headers = {
|
||||||
'User-Agent': NAME,
|
'User-Agent': NAME,
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
@@ -26,12 +32,20 @@ class SRPManager:
|
|||||||
r = requests.get(url, headers=headers)
|
r = requests.get(url, headers=headers)
|
||||||
result = r.json()[0]
|
result = r.json()[0]
|
||||||
if result:
|
if result:
|
||||||
ship_type = result['victim']['ship_type_id']
|
killmail_id = result['killmail_id']
|
||||||
|
killmail_hash = result['zkb']['hash']
|
||||||
|
c = esi_client_factory(spec_file=SWAGGER_SPEC_PATH)
|
||||||
|
km = c.Killmails.get_killmails_killmail_id_killmail_hash(killmail_id=killmail_id,
|
||||||
|
killmail_hash=killmail_hash).result()
|
||||||
|
else:
|
||||||
|
raise ValueError("Invalid Kill ID")
|
||||||
|
if km:
|
||||||
|
ship_type = km['victim']['ship_type_id']
|
||||||
logger.debug("Ship type for kill ID %s is %s" % (kill_id, ship_type))
|
logger.debug("Ship type for kill ID %s is %s" % (kill_id, ship_type))
|
||||||
ship_value = result['zkb']['totalValue']
|
ship_value = result['zkb']['totalValue']
|
||||||
logger.debug("Total loss value for kill id %s is %s" % (kill_id, ship_value))
|
logger.debug("Total loss value for kill id %s is %s" % (kill_id, ship_value))
|
||||||
victim_id = result['victim']['character_id']
|
victim_id = km['victim']['character_id']
|
||||||
return ship_type, ship_value, victim_id
|
return ship_type, ship_value, victim_id
|
||||||
else:
|
else:
|
||||||
raise ValueError("Invalid Kill ID")
|
raise ValueError("Invalid Kill ID or Hash.")
|
||||||
|
|
||||||
|
|||||||
1
allianceauth/srp/swagger.json
Normal file
1
allianceauth/srp/swagger.json
Normal file
File diff suppressed because one or more lines are too long
@@ -17,6 +17,8 @@
|
|||||||
<a href="{% url 'srp:all' %}" class="btn btn-primary">
|
<a href="{% url 'srp:all' %}" class="btn btn-primary">
|
||||||
{% trans "View All" %}
|
{% trans "View All" %}
|
||||||
</a>
|
</a>
|
||||||
|
{% endif %}
|
||||||
|
{% if perms.srp.add_srpfleetmain or perms.auth.srp_management %}
|
||||||
<a href="{% url 'srp:add' %}" class="btn btn-success">
|
<a href="{% url 'srp:add' %}" class="btn btn-success">
|
||||||
{% trans "Add SRP Fleet" %}
|
{% trans "Add SRP Fleet" %}
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ from django.shortcuts import render, redirect, get_object_or_404
|
|||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from django.db.models import Sum
|
from django.db.models import Sum
|
||||||
|
from allianceauth.authentication.decorators import permissions_required
|
||||||
from allianceauth.eveonline.providers import provider
|
from allianceauth.eveonline.providers import provider
|
||||||
from allianceauth.notifications import notify
|
from allianceauth.notifications import notify
|
||||||
from .form import SrpFleetMainForm
|
from .form import SrpFleetMainForm
|
||||||
@@ -59,7 +60,7 @@ def srp_fleet_view(request, fleet_id):
|
|||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@permission_required('auth.srp_management')
|
@permissions_required(('auth.srp_management', 'srp.add_srpfleetmain'))
|
||||||
def srp_fleet_add_view(request):
|
def srp_fleet_add_view(request):
|
||||||
logger.debug("srp_fleet_add_view called by user %s" % request.user)
|
logger.debug("srp_fleet_add_view called by user %s" % request.user)
|
||||||
completed = False
|
completed = False
|
||||||
|
|||||||
@@ -8,19 +8,19 @@
|
|||||||
<ul class="list-group">
|
<ul class="list-group">
|
||||||
{% for notif in notifications %}
|
{% for notif in notifications %}
|
||||||
<li class="list-group-item">
|
<li class="list-group-item">
|
||||||
{% if notif.state == 'open' %}
|
{% if notif.state == 'opened' %}
|
||||||
<span class="label label-success">{% trans "Open" %}</span>
|
<span class="label label-success">{% trans "Open" %}</span>
|
||||||
{% else %}
|
{% else %}
|
||||||
<span class="label label-danger">{% trans "Closed" %}</span>
|
<span class="label label-danger">{% trans "Closed" %}</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<a href="{{ notif.html_url }}" target="_blank">#{{ notif.number }} {{ notif.title }}</a>
|
<a href="{{ notif.web_url }}" target="_blank">#{{ notif.iid }} {{ notif.title }}</a>
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-right" style="position:absolute;bottom:5px;right:5px;">
|
<div class="text-right" style="position:absolute;bottom:5px;right:5px;">
|
||||||
<a href="https://github.com/allianceauth/allianceauth/issues"><span class="label label-default">
|
<a href="https://gitlab.com/allianceauth/allianceauth/issues"><span class="label" style="background-color:#e65328;">
|
||||||
<i class="fa fa-github" aria-hidden="true"></i> Powered by Github</span>
|
<i class="fa fa-gitlab" aria-hidden="true"></i> Powered by GitLab</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -39,7 +39,7 @@
|
|||||||
<li class="list-group-item list-group-item-{% if latest_major %}success{% else %}warning{% endif %}">
|
<li class="list-group-item list-group-item-{% if latest_major %}success{% else %}warning{% endif %}">
|
||||||
<h4 class="list-group-item-heading">{% trans "Latest Major" %}</h4>
|
<h4 class="list-group-item-heading">{% trans "Latest Major" %}</h4>
|
||||||
<p class="list-group-item-text">
|
<p class="list-group-item-text">
|
||||||
<a href="{{ latest_major_url }}" style="color:#000"><i class="fa fa-github" aria-hidden="true"></i>
|
<a href="https://gitlab.com/allianceauth/allianceauth/tags" style="color:#000"><i class="fa fa-gitlab" aria-hidden="true"></i>
|
||||||
{{ latest_major_version }}
|
{{ latest_major_version }}
|
||||||
</a>
|
</a>
|
||||||
{% if not latest_major %}<br>{% trans "Update available" %}{% endif %}
|
{% if not latest_major %}<br>{% trans "Update available" %}{% endif %}
|
||||||
@@ -48,7 +48,7 @@
|
|||||||
<li class="list-group-item list-group-item-{% if latest_minor %}success{% else %}warning{% endif %}">
|
<li class="list-group-item list-group-item-{% if latest_minor %}success{% else %}warning{% endif %}">
|
||||||
<h4 class="list-group-item-heading">{% trans "Latest Minor" %}</h4>
|
<h4 class="list-group-item-heading">{% trans "Latest Minor" %}</h4>
|
||||||
<p class="list-group-item-text">
|
<p class="list-group-item-text">
|
||||||
<a href="{{ latest_minor_url }}" style="color:#000"><i class="fa fa-github" aria-hidden="true"></i>
|
<a href="https://gitlab.com/allianceauth/allianceauth/tags" style="color:#000"><i class="fa fa-gitlab" aria-hidden="true"></i>
|
||||||
{{ latest_minor_version }}
|
{{ latest_minor_version }}
|
||||||
</a>
|
</a>
|
||||||
{% if not latest_minor %}<br>{% trans "Update available" %}{% endif %}
|
{% if not latest_minor %}<br>{% trans "Update available" %}{% endif %}
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
<li class="list-group-item list-group-item-{% if latest_patch %}success{% else %}danger{% endif %}">
|
<li class="list-group-item list-group-item-{% if latest_patch %}success{% else %}danger{% endif %}">
|
||||||
<h4 class="list-group-item-heading">{% trans "Latest Patch" %}</h4>
|
<h4 class="list-group-item-heading">{% trans "Latest Patch" %}</h4>
|
||||||
<p class="list-group-item-text">
|
<p class="list-group-item-text">
|
||||||
<a href="{{ latest_patch_url }}" style="color:#000"><i class="fa fa-github" aria-hidden="true"></i>
|
<a href="https://gitlab.com/allianceauth/allianceauth/tags" style="color:#000"><i class="fa fa-gitlab" aria-hidden="true"></i>
|
||||||
{{ latest_patch_version }}
|
{{ latest_patch_version }}
|
||||||
</a>
|
</a>
|
||||||
{% if not latest_patch %}<br>{% trans "Update available" %}{% endif %}
|
{% if not latest_patch %}<br>{% trans "Update available" %}{% endif %}
|
||||||
|
|||||||
@@ -17,16 +17,16 @@ NOTIFICATION_CACHE_TIME = 300 # 5 minutes
|
|||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def get_github_tags():
|
def get_git_tags():
|
||||||
request = requests.get('https://api.github.com/repos/allianceauth/allianceauth/releases')
|
request = requests.get('https://gitlab.com/api/v4/projects/allianceauth%2Fallianceauth/repository/tags')
|
||||||
request.raise_for_status()
|
request.raise_for_status()
|
||||||
return request.json()
|
return request.json()
|
||||||
|
|
||||||
|
|
||||||
def get_github_notification_issues():
|
def get_notification_issues():
|
||||||
# notification
|
# notification
|
||||||
request = requests.get(
|
request = requests.get(
|
||||||
'https://api.github.com/repos/allianceauth/allianceauth/issues?labels=announcement&state=all')
|
'https://gitlab.com/api/v4/projects/allianceauth%2Fallianceauth/issues?labels=announcement')
|
||||||
request.raise_for_status()
|
request.raise_for_status()
|
||||||
return request.json()
|
return request.json()
|
||||||
|
|
||||||
@@ -68,12 +68,12 @@ def get_notifications():
|
|||||||
'notifications': list(),
|
'notifications': list(),
|
||||||
}
|
}
|
||||||
try:
|
try:
|
||||||
notifications = cache.get_or_set('github_notification_issues', get_github_notification_issues,
|
notifications = cache.get_or_set('gitlab_notification_issues', get_notification_issues,
|
||||||
NOTIFICATION_CACHE_TIME)
|
NOTIFICATION_CACHE_TIME)
|
||||||
# Limit notifications to those posted by repo owners and members
|
# Limit notifications to those posted by repo owners and members
|
||||||
response['notifications'] += [n for n in notifications if n['author_association'] in ['OWNER', 'MEMBER']][:5]
|
response['notifications'] += notifications[:5]
|
||||||
except requests.RequestException:
|
except requests.RequestException:
|
||||||
logger.exception('Error while getting github notifications')
|
logger.exception('Error while getting gitlab notifications')
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
@@ -85,7 +85,7 @@ def get_version_info():
|
|||||||
'current_version': __version__,
|
'current_version': __version__,
|
||||||
}
|
}
|
||||||
try:
|
try:
|
||||||
tags = cache.get_or_set('github_release_tags', get_github_tags, TAG_CACHE_TIME)
|
tags = cache.get_or_set('git_release_tags', get_git_tags, TAG_CACHE_TIME)
|
||||||
current_ver = semver.Version.coerce(__version__)
|
current_ver = semver.Version.coerce(__version__)
|
||||||
|
|
||||||
# Set them all to the current version to start
|
# Set them all to the current version to start
|
||||||
@@ -102,7 +102,7 @@ def get_version_info():
|
|||||||
})
|
})
|
||||||
|
|
||||||
for tag in tags:
|
for tag in tags:
|
||||||
tag_name = tag.get('tag_name')
|
tag_name = tag.get('name')
|
||||||
if tag_name[0] == 'v':
|
if tag_name[0] == 'v':
|
||||||
# Strip 'v' off front of verison if it exists
|
# Strip 'v' off front of verison if it exists
|
||||||
tag_name = tag_name[1:]
|
tag_name = tag_name[1:]
|
||||||
@@ -114,24 +114,21 @@ def get_version_info():
|
|||||||
if latest_major is None or tag_ver > latest_major:
|
if latest_major is None or tag_ver > latest_major:
|
||||||
latest_major = tag_ver
|
latest_major = tag_ver
|
||||||
response['latest_major_version'] = tag_name
|
response['latest_major_version'] = tag_name
|
||||||
response['latest_major_url'] = tag['html_url']
|
|
||||||
if tag_ver.major > current_ver.major:
|
if tag_ver.major > current_ver.major:
|
||||||
response['latest_major'] = False
|
response['latest_major'] = False
|
||||||
elif tag_ver.major == current_ver.major:
|
elif tag_ver.major == current_ver.major:
|
||||||
if latest_minor is None or tag_ver > latest_minor:
|
if latest_minor is None or tag_ver > latest_minor:
|
||||||
latest_minor = tag_ver
|
latest_minor = tag_ver
|
||||||
response['latest_minor_version'] = tag_name
|
response['latest_minor_version'] = tag_name
|
||||||
response['latest_minor_url'] = tag['html_url']
|
|
||||||
if tag_ver.minor > current_ver.minor:
|
if tag_ver.minor > current_ver.minor:
|
||||||
response['latest_minor'] = False
|
response['latest_minor'] = False
|
||||||
elif tag_ver.minor == current_ver.minor:
|
elif tag_ver.minor == current_ver.minor:
|
||||||
if latest_patch is None or tag_ver > latest_patch:
|
if latest_patch is None or tag_ver > latest_patch:
|
||||||
latest_patch = tag_ver
|
latest_patch = tag_ver
|
||||||
response['latest_patch_version'] = tag_name
|
response['latest_patch_version'] = tag_name
|
||||||
response['latest_patch_url'] = tag['html_url']
|
|
||||||
if tag_ver.patch > current_ver.patch:
|
if tag_ver.patch > current_ver.patch:
|
||||||
response['latest_patch'] = False
|
response['latest_patch'] = False
|
||||||
|
|
||||||
except requests.RequestException:
|
except requests.RequestException:
|
||||||
logger.exception('Error while getting github release tags')
|
logger.exception('Error while getting gitlab release tags')
|
||||||
return response
|
return response
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ class TimerForm(forms.ModelForm):
|
|||||||
|
|
||||||
structure_choices = [('POCO', 'POCO'),
|
structure_choices = [('POCO', 'POCO'),
|
||||||
('I-HUB', 'I-HUB'),
|
('I-HUB', 'I-HUB'),
|
||||||
|
('TCU', 'TCU'),
|
||||||
('POS[S]', 'POS[S]'),
|
('POS[S]', 'POS[S]'),
|
||||||
('POS[M]', 'POS[M]'),
|
('POS[M]', 'POS[M]'),
|
||||||
('POS[L]', 'POS[L]'),
|
('POS[L]', 'POS[L]'),
|
||||||
@@ -45,8 +46,9 @@ class TimerForm(forms.ModelForm):
|
|||||||
('Engineering Complex[XL]', 'Engineering Complex[XL]'),
|
('Engineering Complex[XL]', 'Engineering Complex[XL]'),
|
||||||
('Refinery[M]', 'Refinery[M]'),
|
('Refinery[M]', 'Refinery[M]'),
|
||||||
('Refinery[L]', 'Refinery[L]'),
|
('Refinery[L]', 'Refinery[L]'),
|
||||||
('Station', 'Station'),
|
('Cyno Beacon','Cyno Beacon'),
|
||||||
('TCU', 'TCU'),
|
('Cyno Jammer','Cyno Jammer'),
|
||||||
|
('Jump Gate','Jump Gate'),
|
||||||
('Moon Mining Cycle', 'Moon Mining Cycle'),
|
('Moon Mining Cycle', 'Moon Mining Cycle'),
|
||||||
(_('Other'), _('Other'))]
|
(_('Other'), _('Other'))]
|
||||||
objective_choices = [('Friendly', _('Friendly')),
|
objective_choices = [('Friendly', _('Friendly')),
|
||||||
|
|||||||
@@ -64,14 +64,19 @@
|
|||||||
href="http://evemaps.dotlan.net/system/{{ timer.system }}">{{ timer.system }} {{ timer.planet_moon }} </a>
|
href="http://evemaps.dotlan.net/system/{{ timer.system }}">{{ timer.system }} {{ timer.planet_moon }} </a>
|
||||||
</td>
|
</td>
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
|
{% ifequal timer.structure "POCO" %}
|
||||||
|
<div class="label label-info">
|
||||||
|
POCO
|
||||||
|
</div>
|
||||||
|
{% endifequal %}
|
||||||
{% ifequal timer.structure "I-HUB" %}
|
{% ifequal timer.structure "I-HUB" %}
|
||||||
<div class="label label-warning">
|
<div class="label label-warning">
|
||||||
I-HUB
|
I-HUB
|
||||||
</div>
|
</div>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
{% ifequal timer.structure "POCO" %}
|
{% ifequal timer.structure "TCU" %}
|
||||||
<div class="label label-success">
|
<div class="label label-danger">
|
||||||
POCO
|
TCU
|
||||||
</div>
|
</div>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
{% ifequal timer.structure "POS[S]" %}
|
{% ifequal timer.structure "POS[S]" %}
|
||||||
@@ -119,16 +124,6 @@
|
|||||||
Engineering Complex [XL]
|
Engineering Complex [XL]
|
||||||
</div>
|
</div>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
{% ifequal timer.structure "Station" %}
|
|
||||||
<div class="label label-danger">
|
|
||||||
Station
|
|
||||||
</div>
|
|
||||||
{% endifequal %}
|
|
||||||
{% ifequal timer.structure "TCU" %}
|
|
||||||
<div class="label label-danger">
|
|
||||||
TCU
|
|
||||||
</div>
|
|
||||||
{% endifequal %}
|
|
||||||
{% ifequal timer.structure "Refinery[M]" %}
|
{% ifequal timer.structure "Refinery[M]" %}
|
||||||
<div class="label label-warning">
|
<div class="label label-warning">
|
||||||
Refinery [M]
|
Refinery [M]
|
||||||
@@ -139,6 +134,21 @@
|
|||||||
Refinery [L]
|
Refinery [L]
|
||||||
</div>
|
</div>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
|
{% ifequal timer.structure "Cyno Beacon" %}
|
||||||
|
<div class="label label-warning">
|
||||||
|
Cyno Beacon
|
||||||
|
</div>
|
||||||
|
{% endifequal %}
|
||||||
|
{% ifequal timer.structure "Cyno Jammer" %}
|
||||||
|
<div class="label label-warning">
|
||||||
|
Cyno Jammer
|
||||||
|
</div>
|
||||||
|
{% endifequal %}
|
||||||
|
{% ifequal timer.structure "Jump Gate" %}
|
||||||
|
<div class="label label-warning">
|
||||||
|
Jump Gate
|
||||||
|
</div>
|
||||||
|
{% endifequal %}
|
||||||
{% ifequal timer.structure "Moon Mining Cycle" %}
|
{% ifequal timer.structure "Moon Mining Cycle" %}
|
||||||
<div class="label label-success">
|
<div class="label label-success">
|
||||||
Moon Mining Cycle
|
Moon Mining Cycle
|
||||||
@@ -213,91 +223,101 @@
|
|||||||
<a href="http://evemaps.dotlan.net/system/{{ timer.system }}">{{ timer.system }} {{ timer.planet_moon }}</a>
|
<a href="http://evemaps.dotlan.net/system/{{ timer.system }}">{{ timer.system }} {{ timer.planet_moon }}</a>
|
||||||
</td>
|
</td>
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
{% ifequal timer.structure "I-HUB" %}
|
{% ifequal timer.structure "POCO" %}
|
||||||
<div class="label label-warning">
|
<div class="label label-info">
|
||||||
I-HUB
|
POCO
|
||||||
</div>
|
</div>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
{% ifequal timer.structure "POCO" %}
|
{% ifequal timer.structure "I-HUB" %}
|
||||||
<div class="label label-success">
|
<div class="label label-warning">
|
||||||
POCO
|
I-HUB
|
||||||
</div>
|
</div>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
{% ifequal timer.structure "POS[S]" %}
|
{% ifequal timer.structure "TCU" %}
|
||||||
<div class="label label-info">
|
<div class="label label-danger">
|
||||||
POS [S]
|
TCU
|
||||||
</div>
|
</div>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
{% ifequal timer.structure "POS[M]" %}
|
{% ifequal timer.structure "POS[S]" %}
|
||||||
<div class="label label-info">
|
<div class="label label-info">
|
||||||
POS [M]
|
POS [S]
|
||||||
</div>
|
</div>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
{% ifequal timer.structure "POS[L]" %}
|
{% ifequal timer.structure "POS[M]" %}
|
||||||
<div class="label label-info">
|
<div class="label label-info">
|
||||||
POS [L]
|
POS [M]
|
||||||
</div>
|
</div>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
{% ifequal timer.structure "Citadel[M]" %}
|
{% ifequal timer.structure "POS[L]" %}
|
||||||
<div class="label label-danger">
|
<div class="label label-info">
|
||||||
Citadel [M]
|
POS [L]
|
||||||
</div>
|
</div>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
{% ifequal timer.structure "Citadel[L]" %}
|
{% ifequal timer.structure "Citadel[M]" %}
|
||||||
<div class="label label-danger">
|
<div class="label label-danger">
|
||||||
Citadel [L]
|
Citadel [M]
|
||||||
</div>
|
</div>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
{% ifequal timer.structure "Citadel[XL]" %}
|
{% ifequal timer.structure "Citadel[L]" %}
|
||||||
<div class="label label-danger">
|
<div class="label label-danger">
|
||||||
Citadel [XL]
|
Citadel [L]
|
||||||
</div>
|
</div>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
{% ifequal timer.structure "Engineering Complex[M]" %}
|
{% ifequal timer.structure "Citadel[XL]" %}
|
||||||
<div class="label label-warning">
|
<div class="label label-danger">
|
||||||
Engineering Complex [M]
|
Citadel [XL]
|
||||||
</div>
|
</div>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
{% ifequal timer.structure "Engineering Complex[L]" %}
|
{% ifequal timer.structure "Engineering Complex[M]" %}
|
||||||
<div class="label label-warning">
|
<div class="label label-warning">
|
||||||
Engineering Complex [L]
|
Engineering Complex [M]
|
||||||
</div>
|
</div>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
{% ifequal timer.structure "Engineering Complex[XL]" %}
|
{% ifequal timer.structure "Engineering Complex[L]" %}
|
||||||
<div class="label label-warning">
|
<div class="label label-warning">
|
||||||
Engineering Complex [XL]
|
Engineering Complex [L]
|
||||||
</div>
|
</div>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
{% ifequal timer.structure "Station" %}
|
{% ifequal timer.structure "Engineering Complex[XL]" %}
|
||||||
<div class="label label-danger">
|
<div class="label label-warning">
|
||||||
Station
|
Engineering Complex [XL]
|
||||||
</div>
|
</div>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
{% ifequal timer.structure "TCU" %}
|
{% ifequal timer.structure "Refinery[M]" %}
|
||||||
<div class="label label-danger">
|
<div class="label label-warning">
|
||||||
TCU
|
Refinery [M]
|
||||||
</div>
|
</div>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
{% ifequal timer.structure "Refinery[M]" %}
|
{% ifequal timer.structure "Refinery[L]" %}
|
||||||
<div class="label label-warning">
|
<div class="label label-warning">
|
||||||
Refinery [M]
|
Refinery [L]
|
||||||
</div>
|
</div>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
{% ifequal timer.structure "Refinery[L]" %}
|
{% ifequal timer.structure "Cyno Beacon" %}
|
||||||
<div class="label label-warning">
|
<div class="label label-warning">
|
||||||
Refinery [L]
|
Cyno Beacon
|
||||||
</div>
|
</div>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
{% ifequal timer.structure "Moon Mining Cycle" %}
|
{% ifequal timer.structure "Cyno Jammer" %}
|
||||||
<div class="label label-success">
|
<div class="label label-warning">
|
||||||
Moon Mining Cycle
|
Cyno Jammer
|
||||||
</div>
|
</div>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
{% ifequal timer.structure "Other" %}
|
{% ifequal timer.structure "Jump Gate" %}
|
||||||
<div class="label label-default">
|
<div class="label label-warning">
|
||||||
Other
|
Jump Gate
|
||||||
</div>
|
</div>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
|
{% ifequal timer.structure "Moon Mining Cycle" %}
|
||||||
|
<div class="label label-success">
|
||||||
|
Moon Mining Cycle
|
||||||
|
</div>
|
||||||
|
{% endifequal %}
|
||||||
|
{% ifequal timer.structure "Other" %}
|
||||||
|
<div class="label label-default">
|
||||||
|
Other
|
||||||
|
</div>
|
||||||
|
{% endifequal %}
|
||||||
</td>
|
</td>
|
||||||
<td class="text-center" nowrap>{{ timer.eve_time | date:"Y-m-d H:i" }}</td>
|
<td class="text-center" nowrap>{{ timer.eve_time | date:"Y-m-d H:i" }}</td>
|
||||||
<td class="text-center" nowrap>
|
<td class="text-center" nowrap>
|
||||||
@@ -364,91 +384,101 @@
|
|||||||
<a href="http://evemaps.dotlan.net/system/{{ timer.system }}">{{ timer.system }} {{ timer.planet_moon }}</a>
|
<a href="http://evemaps.dotlan.net/system/{{ timer.system }}">{{ timer.system }} {{ timer.planet_moon }}</a>
|
||||||
</td>
|
</td>
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
{% ifequal timer.structure "I-HUB" %}
|
{% ifequal timer.structure "POCO" %}
|
||||||
<div class="label label-warning">
|
<div class="label label-info">
|
||||||
I-HUB
|
POCO
|
||||||
</div>
|
</div>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
{% ifequal timer.structure "POCO" %}
|
{% ifequal timer.structure "I-HUB" %}
|
||||||
<div class="label label-success">
|
<div class="label label-warning">
|
||||||
POCO
|
I-HUB
|
||||||
</div>
|
</div>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
{% ifequal timer.structure "POS[S]" %}
|
{% ifequal timer.structure "TCU" %}
|
||||||
<div class="label label-info">
|
<div class="label label-danger">
|
||||||
POS [S]
|
TCU
|
||||||
</div>
|
</div>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
{% ifequal timer.structure "POS[M]" %}
|
{% ifequal timer.structure "POS[S]" %}
|
||||||
<div class="label label-info">
|
<div class="label label-info">
|
||||||
POS [M]
|
POS [S]
|
||||||
</div>
|
</div>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
{% ifequal timer.structure "POS[L]" %}
|
{% ifequal timer.structure "POS[M]" %}
|
||||||
<div class="label label-info">
|
<div class="label label-info">
|
||||||
POS [L]
|
POS [M]
|
||||||
</div>
|
</div>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
{% ifequal timer.structure "Citadel[M]" %}
|
{% ifequal timer.structure "POS[L]" %}
|
||||||
<div class="label label-danger">
|
<div class="label label-info">
|
||||||
Citadel [M]
|
POS [L]
|
||||||
</div>
|
</div>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
{% ifequal timer.structure "Citadel[L]" %}
|
{% ifequal timer.structure "Citadel[M]" %}
|
||||||
<div class="label label-danger">
|
<div class="label label-danger">
|
||||||
Citadel [L]
|
Citadel [M]
|
||||||
</div>
|
</div>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
{% ifequal timer.structure "Citadel[XL]" %}
|
{% ifequal timer.structure "Citadel[L]" %}
|
||||||
<div class="label label-danger">
|
<div class="label label-danger">
|
||||||
Citadel [XL]
|
Citadel [L]
|
||||||
</div>
|
</div>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
{% ifequal timer.structure "Engineering Complex[M]" %}
|
{% ifequal timer.structure "Citadel[XL]" %}
|
||||||
<div class="label label-warning">
|
<div class="label label-danger">
|
||||||
Engineering Complex [M]
|
Citadel [XL]
|
||||||
</div>
|
</div>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
{% ifequal timer.structure "Engineering Complex[L]" %}
|
{% ifequal timer.structure "Engineering Complex[M]" %}
|
||||||
<div class="label label-warning">
|
<div class="label label-warning">
|
||||||
Engineering Complex [L]
|
Engineering Complex [M]
|
||||||
</div>
|
</div>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
{% ifequal timer.structure "Engineering Complex[XL]" %}
|
{% ifequal timer.structure "Engineering Complex[L]" %}
|
||||||
<div class="label label-warning">
|
<div class="label label-warning">
|
||||||
Engineering Complex [XL]
|
Engineering Complex [L]
|
||||||
</div>
|
</div>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
{% ifequal timer.structure "Station" %}
|
{% ifequal timer.structure "Engineering Complex[XL]" %}
|
||||||
<div class="label label-danger">
|
<div class="label label-warning">
|
||||||
Station
|
Engineering Complex [XL]
|
||||||
</div>
|
</div>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
{% ifequal timer.structure "TCU" %}
|
{% ifequal timer.structure "Refinery[M]" %}
|
||||||
<div class="label label-danger">
|
<div class="label label-warning">
|
||||||
TCU
|
Refinery [M]
|
||||||
</div>
|
</div>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
{% ifequal timer.structure "Refinery[M]" %}
|
{% ifequal timer.structure "Refinery[L]" %}
|
||||||
<div class="label label-warning">
|
<div class="label label-warning">
|
||||||
Refinery [M]
|
Refinery [L]
|
||||||
</div>
|
</div>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
{% ifequal timer.structure "Refinery[L]" %}
|
{% ifequal timer.structure "Cyno Beacon" %}
|
||||||
<div class="label label-warning">
|
<div class="label label-warning">
|
||||||
Refinery [L]
|
Cyno Beacon
|
||||||
</div>
|
</div>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
{% ifequal timer.structure "Moon Mining Cycle" %}
|
{% ifequal timer.structure "Cyno Jammer" %}
|
||||||
<div class="label label-success">
|
<div class="label label-warning">
|
||||||
Moon Mining Cycle
|
Cyno Jammer
|
||||||
</div>
|
</div>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
{% ifequal timer.structure "Other" %}
|
{% ifequal timer.structure "Jump Gate" %}
|
||||||
<div class="label label-default">
|
<div class="label label-warning">
|
||||||
Other
|
Jump Gate
|
||||||
</div>
|
</div>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
|
{% ifequal timer.structure "Moon Mining Cycle" %}
|
||||||
|
<div class="label label-success">
|
||||||
|
Moon Mining Cycle
|
||||||
|
</div>
|
||||||
|
{% endifequal %}
|
||||||
|
{% ifequal timer.structure "Other" %}
|
||||||
|
<div class="label label-default">
|
||||||
|
Other
|
||||||
|
</div>
|
||||||
|
{% endifequal %}
|
||||||
</td>
|
</td>
|
||||||
<td class="text-center" nowrap>{{ timer.eve_time | date:"Y-m-d H:i" }}</td>
|
<td class="text-center" nowrap>{{ timer.eve_time | date:"Y-m-d H:i" }}</td>
|
||||||
<td class="text-center" nowrap>
|
<td class="text-center" nowrap>
|
||||||
|
|||||||
@@ -202,7 +202,7 @@ If you intend to use this account as your personal auth account you need to add
|
|||||||
|
|
||||||
## Updating
|
## Updating
|
||||||
|
|
||||||
Periodically [new releases](https://github.com/allianceauth/allianceauth/releases/) are issued with bug fixes and new features. To update your install, simply activate your virtual environment and update with `pip install --upgrade allianceauth`. Be sure to read the release notes which will highlight changes.
|
Periodically [new releases](https://gitlab.com/allianceauth/allianceauth/tags) are issued with bug fixes and new features. To update your install, simply activate your virtual environment and update with `pip install --upgrade allianceauth`. Be sure to read the release notes which will highlight changes.
|
||||||
|
|
||||||
Some releases come with changes to settings: update your project's settings with `allianceauth update /home/allianceserver/myauth`.
|
Some releases come with changes to settings: update your project's settings with `allianceauth update /home/allianceserver/myauth`.
|
||||||
|
|
||||||
|
|||||||
@@ -82,4 +82,4 @@ A similar process can be used to ensure users who may have lost service permissi
|
|||||||
|
|
||||||
## Help
|
## Help
|
||||||
|
|
||||||
If something goes wrong during the migration reach out for help on [Gitter](https://gitter.im/R4stl1n/allianceauth) or open an [issue](https://github.com/allianceauth/allianceauth/issues).
|
If something goes wrong during the migration reach out for help on [Gitter](https://gitter.im/R4stl1n/allianceauth) or open an [issue](https://gitlab.com/allianceauth/allianceauth/issues).
|
||||||
|
|||||||
@@ -1,161 +1,7 @@
|
|||||||
# Alliance Market
|
# Alliance Market
|
||||||
|
|
||||||
## Dependencies
|
## Deprecation
|
||||||
Alliance Market requires PHP installed in your web server. Apache has `mod_php`, NGINX requires `php-fpm`.
|
|
||||||
|
|
||||||
## Prepare Your Settings
|
Alliance Market relies on the now non-functional XML API.
|
||||||
In your auth project's settings file, do the following:
|
|
||||||
- Add `'allianceauth.services.modules.market',` to your `INSTALLED_APPS` list
|
|
||||||
- Append the following to the bottom of the settings file
|
|
||||||
|
|
||||||
|
Please remove this service data with `python manage.py migrate appname zero` and then remove from your `INSTALLED_APPS` list.
|
||||||
# Alliance Market
|
|
||||||
MARKET_URL = ''
|
|
||||||
DATABASES['market'] = {
|
|
||||||
'ENGINE': 'django.db.backends.mysql',
|
|
||||||
'NAME': 'alliance_market',
|
|
||||||
'USER': 'allianceserver-market',
|
|
||||||
'PASSWORD': 'password',
|
|
||||||
'HOST': '127.0.0.1',
|
|
||||||
'PORT': '3306',
|
|
||||||
}
|
|
||||||
|
|
||||||
## Setup Alliance Market
|
|
||||||
Alliance Market needs a database. Create one in MySQL/MariaDB. Default name is `alliance_market`:
|
|
||||||
|
|
||||||
mysql -u root -p
|
|
||||||
create database alliance_market;
|
|
||||||
grant all privileges on alliance_market . * to 'allianceserver'@'localhost';
|
|
||||||
exit;
|
|
||||||
|
|
||||||
Install required packages to clone the repository:
|
|
||||||
|
|
||||||
apt-get install mercurial meld
|
|
||||||
|
|
||||||
Change to the web folder:
|
|
||||||
|
|
||||||
cd /var/www
|
|
||||||
|
|
||||||
Now clone the repository
|
|
||||||
|
|
||||||
hg clone https://bitbucket.org/krojew/evernus-alliance-market
|
|
||||||
|
|
||||||
Make cache and log directories
|
|
||||||
|
|
||||||
mkdir evernus-alliance-market/app/cache
|
|
||||||
mkdir evernus-alliance-market/app/logs
|
|
||||||
chmod -R 777 evernus-alliance-market/app/cache
|
|
||||||
chmod -R 777 evernus-alliance-market/app/logs
|
|
||||||
|
|
||||||
Change ownership to apache
|
|
||||||
|
|
||||||
chown -R www-data:www-data evernus-alliance-market
|
|
||||||
|
|
||||||
Enter directory
|
|
||||||
|
|
||||||
cd evernus-alliance-market
|
|
||||||
|
|
||||||
Set environment variable
|
|
||||||
|
|
||||||
export SYMFONY_ENV=prod
|
|
||||||
|
|
||||||
Copy configuration
|
|
||||||
|
|
||||||
cp app/config/parameters.yml.dist app/config/parameters.yml
|
|
||||||
|
|
||||||
Edit, changing the following:
|
|
||||||
- `database_name` to `alliance_market`
|
|
||||||
- `database_user` to your MySQL user (usually `allianceserver`)
|
|
||||||
- `database_password` to your MySQL user password
|
|
||||||
- email settings, eg Gmail/Mailgun etc.
|
|
||||||
|
|
||||||
Edit `app/config/config.yml` and add the following:
|
|
||||||
|
|
||||||
services:
|
|
||||||
fos_user.doctrine_registry:
|
|
||||||
alias: doctrine
|
|
||||||
|
|
||||||
Install composer [as per these instructions.](https://getcomposer.org/download/)
|
|
||||||
|
|
||||||
Update dependencies.
|
|
||||||
|
|
||||||
php composer.phar update --optimize-autoloader
|
|
||||||
|
|
||||||
Prepare the cache:
|
|
||||||
|
|
||||||
php app/console cache:clear --env=prod --no-debug
|
|
||||||
|
|
||||||
|
|
||||||
Dump assets:
|
|
||||||
|
|
||||||
php app/console assetic:dump --env=prod --no-debug
|
|
||||||
|
|
||||||
|
|
||||||
Create DB entries
|
|
||||||
|
|
||||||
php app/console doctrine:schema:update --force
|
|
||||||
|
|
||||||
Install SDE:
|
|
||||||
|
|
||||||
php app/console evernus:update:sde
|
|
||||||
|
|
||||||
Configure your web server to serve alliance market.
|
|
||||||
|
|
||||||
A minimal Apache config might look like:
|
|
||||||
|
|
||||||
<VirtualHost *:80>
|
|
||||||
ServerName market.example.com
|
|
||||||
DocumentRoot /var/www/evernus-alliance-market/web
|
|
||||||
<Directory "/var/www/evernus-alliance-market/web/">
|
|
||||||
DirectoryIndex app.php
|
|
||||||
Require all granted
|
|
||||||
AllowOverride all
|
|
||||||
</Directory>
|
|
||||||
</VirtualHost>
|
|
||||||
|
|
||||||
A minimal Nginx config might look like:
|
|
||||||
|
|
||||||
server {
|
|
||||||
listen 80;
|
|
||||||
server_name market.example.com;
|
|
||||||
root /var/www/evernus-alliance-market/web;
|
|
||||||
index app.php;
|
|
||||||
access_log /var/logs/market.access.log;
|
|
||||||
|
|
||||||
# strip app.php/ prefix if it is present
|
|
||||||
rewrite ^/app\.php/?(.*)$ /$1 permanent;
|
|
||||||
|
|
||||||
location / {
|
|
||||||
index app.php;
|
|
||||||
try_files $uri @rewriteapp;
|
|
||||||
}
|
|
||||||
|
|
||||||
location @rewriteapp {
|
|
||||||
rewrite ^(.*)$ /app.php/$1 last;
|
|
||||||
}
|
|
||||||
|
|
||||||
# pass the PHP scripts to FastCGI server from upstream phpfcgi
|
|
||||||
location ~ ^/(app|app_dev|config)\.php(/|$) {
|
|
||||||
fastcgi_pass 127.0.0.1:9000;
|
|
||||||
fastcgi_split_path_info ^(.+\.php)(/.*)$;
|
|
||||||
include fastcgi_params;
|
|
||||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
|
||||||
fastcgi_param HTTPS off;
|
|
||||||
}
|
|
||||||
|
|
||||||
location ~ /\.ht {
|
|
||||||
deny all;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Once again, set cache permissions:
|
|
||||||
|
|
||||||
chown -R www-data:www-data app/
|
|
||||||
|
|
||||||
Add a user account through auth, then make it a superuser:
|
|
||||||
|
|
||||||
php app/console fos:user:promote your_username --super
|
|
||||||
|
|
||||||
Now edit your auth project's settings file and fill in the web URL to your market as well as the database details.
|
|
||||||
|
|
||||||
Finally run migrations and restart Gunicorn and Celery.
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ Now two packages need to be installed:
|
|||||||
|
|
||||||
apt-get install python-software-properties mumble-server
|
apt-get install python-software-properties mumble-server
|
||||||
|
|
||||||
Download the appropriate authenticator release from [the authenticator repository](https://github.com/allianceauth/mumble-authenticator) and install the python dependencies for it:
|
Download the appropriate authenticator release from [the authenticator repository](https://gitlab.com/allianceauth/mumble-authenticator) and install the python dependencies for it:
|
||||||
|
|
||||||
pip install -r requirements.txt
|
pip install -r requirements.txt
|
||||||
|
|
||||||
|
|||||||
@@ -144,5 +144,15 @@ You can allow members to overwrite the portrait with a custom image if desired.
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
## Setting the default theme
|
||||||
|
|
||||||
|
Users generated via Alliance Auth do not have a default theme set. You will need to set this on the phpbb_users table in SQL
|
||||||
|
|
||||||
|
mysql -u root -p
|
||||||
|
use alliance_forum;
|
||||||
|
alter table phpbb_users change user_style user_style int not null default 1
|
||||||
|
|
||||||
|
If you would like to use a theme that is NOT prosilver or theme "1". You will need to deactivate prosilver, this will then fall over to the set forum wide default.
|
||||||
|
|
||||||
### Prepare Auth
|
### Prepare Auth
|
||||||
Once settings have been configured, run migrations and restart Gunicorn and Celery.
|
Once settings have been configured, run migrations and restart Gunicorn and Celery.
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
## Something broken? Stuck on an issue? Can't get it set up?
|
## Something broken? Stuck on an issue? Can't get it set up?
|
||||||
|
|
||||||
Start by checking the [issues](https://github.com/allianceauth/allianceauth/issues?q=is%3Aissue) - especially closed ones.
|
Start by checking the [issues](https://gitlab.com/allianceauth/allianceauth/issues?scope=all&utf8=%E2%9C%93&state=all&search=my+issue) - especially closed ones.
|
||||||
|
|
||||||
No answer?
|
No answer?
|
||||||
- open an [issue](https://github.com/allianceauth/allianceauth/issues)
|
- open an [issue](https://gitlab.com/allianceauth/allianceauth/issues)
|
||||||
- harass us on [gitter](https://gitter.im/R4stl1n/allianceauth)
|
- harass us on [gitter](https://gitter.im/R4stl1n/allianceauth)
|
||||||
|
|
||||||
## Logging
|
## Logging
|
||||||
|
|||||||
8
setup.py
8
setup.py
@@ -12,16 +12,16 @@ install_requires = [
|
|||||||
'requests-oauthlib',
|
'requests-oauthlib',
|
||||||
'semantic_version',
|
'semantic_version',
|
||||||
|
|
||||||
'redis',
|
'redis<=2.10.6',
|
||||||
'celery>=4.0.2',
|
'celery>=4.0.2',
|
||||||
'celery_once',
|
'celery_once',
|
||||||
|
|
||||||
'django>=1.11',
|
'django>=1.11,<=2.0.8',
|
||||||
'django-bootstrap-form',
|
'django-bootstrap-form',
|
||||||
'django-registration==2.4',
|
'django-registration==2.4',
|
||||||
'django-sortedm2m',
|
'django-sortedm2m',
|
||||||
'django-redis-cache>=1.7.1',
|
'django-redis-cache>=1.7.1',
|
||||||
'django-celery-beat',
|
'django-celery-beat<=1.1.1',
|
||||||
|
|
||||||
'openfire-restapi',
|
'openfire-restapi',
|
||||||
'sleekxmpp',
|
'sleekxmpp',
|
||||||
@@ -50,7 +50,7 @@ setup(
|
|||||||
python_requires='~=3.4',
|
python_requires='~=3.4',
|
||||||
license='GPLv2',
|
license='GPLv2',
|
||||||
packages=['allianceauth'],
|
packages=['allianceauth'],
|
||||||
url='https://github.com/allianceauth/allianceauth',
|
url='https://gitlab.com/allianceauth/allianceauth',
|
||||||
zip_safe=False,
|
zip_safe=False,
|
||||||
include_package_data=True,
|
include_package_data=True,
|
||||||
entry_points="""
|
entry_points="""
|
||||||
|
|||||||
4
tox.ini
4
tox.ini
@@ -17,4 +17,6 @@ deps=
|
|||||||
py37: https://github.com/yaml/pyyaml/zipball/master#egg=pyyaml
|
py37: https://github.com/yaml/pyyaml/zipball/master#egg=pyyaml
|
||||||
py37: https://github.com/celery/kombu/zipball/master#egg=kombu
|
py37: https://github.com/celery/kombu/zipball/master#egg=kombu
|
||||||
install_command = pip install -e ".[testing]" -U {opts} {packages}
|
install_command = pip install -e ".[testing]" -U {opts} {packages}
|
||||||
commands=coverage run runtests.py -v 2
|
commands =
|
||||||
|
coverage run runtests.py -v 2
|
||||||
|
coverage report -m
|
||||||
|
|||||||
Reference in New Issue
Block a user