mirror of
https://gitlab.com/allianceauth/allianceauth.git
synced 2025-07-09 20:40:17 +02:00
Merge branch 'sanity-checks-and-editorconfig' into 'v2.9.x'
Basic code sanity checks and editorconfig See merge request allianceauth/allianceauth!1316
This commit is contained in:
commit
a0a497ab33
24
.editorconfig
Normal file
24
.editorconfig
Normal file
@ -0,0 +1,24 @@
|
||||
# http://editorconfig.org
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
tab_width = 4
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.{yaml,yml,less}]
|
||||
indent_size = 2
|
||||
|
||||
[*.md]
|
||||
indent_size = 2
|
||||
|
||||
# Makefiles always use tabs for indentation
|
||||
[Makefile]
|
||||
indent_style = tab
|
||||
|
||||
[*.bat]
|
||||
indent_style = tab
|
@ -1,4 +1,5 @@
|
||||
stages:
|
||||
- pre-commit
|
||||
- gitlab
|
||||
- test
|
||||
- deploy
|
||||
@ -13,6 +14,18 @@ before_script:
|
||||
- python -V
|
||||
- pip install wheel tox
|
||||
|
||||
pre-commit-check:
|
||||
stage: pre-commit
|
||||
image: python:3.6-buster
|
||||
variables:
|
||||
PRE_COMMIT_HOME: ${CI_PROJECT_DIR}/.cache/pre-commit
|
||||
cache:
|
||||
paths:
|
||||
- ${PRE_COMMIT_HOME}
|
||||
script:
|
||||
- pip install pre-commit
|
||||
- pre-commit run --all-files
|
||||
|
||||
sast:
|
||||
stage: gitlab
|
||||
before_script: []
|
||||
|
28
.pre-commit-config.yaml
Normal file
28
.pre-commit-config.yaml
Normal file
@ -0,0 +1,28 @@
|
||||
# Apply to all files without committing:
|
||||
# pre-commit run --all-files
|
||||
# Update this file:
|
||||
# pre-commit autoupdate
|
||||
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.0.1
|
||||
hooks:
|
||||
- id: check-case-conflict
|
||||
- id: check-json
|
||||
- id: check-xml
|
||||
- id: check-yaml
|
||||
- id: fix-byte-order-marker
|
||||
- id: trailing-whitespace
|
||||
exclude: (\.min\.css|\.min\.js|\.mo|\.po|swagger\.json)$
|
||||
- id: end-of-file-fixer
|
||||
exclude: (\.min\.css|\.min\.js|\.mo|\.po|swagger\.json)$
|
||||
- id: mixed-line-ending
|
||||
args: [ '--fix=lf' ]
|
||||
- id: fix-encoding-pragma
|
||||
args: [ '--remove' ]
|
||||
|
||||
- repo: https://github.com/editorconfig-checker/editorconfig-checker.python
|
||||
rev: 2.3.5
|
||||
hooks:
|
||||
- id: editorconfig-checker
|
||||
exclude: ^(LICENSE|allianceauth\/static\/css\/themes\/bootstrap-locals.less|allianceauth\/eveonline\/swagger.json|(.*.po)|(.*.mo))
|
1
LICENSE
1
LICENSE
@ -337,4 +337,3 @@ proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
|
||||
|
@ -43,4 +43,3 @@ AUTHENTICATION_ADMIN_USERS_MAX_GROUPS = \
|
||||
|
||||
AUTHENTICATION_ADMIN_USERS_MAX_CHARS = \
|
||||
_clean_setting('AUTHENTICATION_ADMIN_USERS_MAX_CHARS', 5)
|
||||
|
||||
|
@ -23,8 +23,7 @@ class CharacterOwnershipManager(Manager):
|
||||
def create_by_token(self, token):
|
||||
if not EveCharacter.objects.filter(character_id=token.character_id).exists():
|
||||
EveCharacter.objects.create_character(token.character_id)
|
||||
return self.create(character=EveCharacter.objects.get(character_id=token.character_id), user=token.user,
|
||||
owner_hash=token.character_owner_hash)
|
||||
return self.create(character=EveCharacter.objects.get(character_id=token.character_id), user=token.user, owner_hash=token.character_owner_hash)
|
||||
|
||||
|
||||
class StateQuerySet(QuerySet):
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.1 on 2016-09-05 21:38
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.1 on 2016-09-07 19:14
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.1 on 2016-09-09 20:29
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.1 on 2016-09-09 23:19
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.1 on 2016-09-09 23:11
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.1 on 2016-09-10 05:42
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.1 on 2016-09-10 21:50
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.1 on 2016-09-12 13:04
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.2 on 2016-10-21 02:28
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.1 on 2017-01-07 06:47
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.1 on 2017-01-07 07:11
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.5 on 2017-01-12 00:59
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.2 on 2016-12-11 23:14
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.1 on 2016-09-09 23:19
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.5 on 2017-03-22 23:09
|
||||
from __future__ import unicode_literals
|
||||
|
||||
@ -107,8 +106,8 @@ def populate_ownerships(apps, schema_editor):
|
||||
EveCharacter = apps.get_model('eveonline', 'EveCharacter')
|
||||
|
||||
unique_character_owners = [t['character_id'] for t in
|
||||
Token.objects.all().values('character_id').annotate(n=models.Count('user')) if
|
||||
t['n'] == 1 and EveCharacter.objects.filter(character_id=t['character_id']).exists()]
|
||||
Token.objects.all().values('character_id').annotate(n=models.Count('user')) if
|
||||
t['n'] == 1 and EveCharacter.objects.filter(character_id=t['character_id']).exists()]
|
||||
|
||||
tokens = Token.objects.filter(character_id__in=unique_character_owners)
|
||||
for c_id in unique_character_owners:
|
||||
@ -171,8 +170,7 @@ def recreate_authservicesinfo(apps, schema_editor):
|
||||
|
||||
# repopulate main characters
|
||||
for profile in UserProfile.objects.exclude(main_character__isnull=True).select_related('user', 'main_character'):
|
||||
AuthServicesInfo.objects.update_or_create(user=profile.user,
|
||||
defaults={'main_char_id': profile.main_character.character_id})
|
||||
AuthServicesInfo.objects.update_or_create(user=profile.user, defaults={'main_char_id': profile.main_character.character_id})
|
||||
|
||||
# repopulate states we understand
|
||||
for profile in UserProfile.objects.exclude(state__name='Guest').filter(
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations
|
||||
|
@ -14,15 +14,11 @@ logger = logging.getLogger(__name__)
|
||||
class State(models.Model):
|
||||
name = models.CharField(max_length=20, unique=True)
|
||||
permissions = models.ManyToManyField(Permission, blank=True)
|
||||
priority = models.IntegerField(unique=True,
|
||||
help_text="Users get assigned the state with the highest priority available to them.")
|
||||
priority = models.IntegerField(unique=True, help_text="Users get assigned the state with the highest priority available to them.")
|
||||
|
||||
member_characters = models.ManyToManyField(EveCharacter, blank=True,
|
||||
help_text="Characters to which this state is available.")
|
||||
member_corporations = models.ManyToManyField(EveCorporationInfo, blank=True,
|
||||
help_text="Corporations to whose members this state is available.")
|
||||
member_alliances = models.ManyToManyField(EveAllianceInfo, blank=True,
|
||||
help_text="Alliances to whose members this state is available.")
|
||||
member_characters = models.ManyToManyField(EveCharacter, blank=True, help_text="Characters to which this state is available.")
|
||||
member_corporations = models.ManyToManyField(EveCorporationInfo, blank=True, help_text="Corporations to whose members this state is available.")
|
||||
member_alliances = models.ManyToManyField(EveAllianceInfo, blank=True, help_text="Alliances to whose members this state is available.")
|
||||
public = models.BooleanField(default=False, help_text="Make this state available to any character.")
|
||||
|
||||
objects = StateManager()
|
||||
|
@ -75,8 +75,7 @@ def create_required_models(sender, instance, created, *args, **kwargs):
|
||||
@receiver(post_save, sender=Token)
|
||||
def record_character_ownership(sender, instance, created, *args, **kwargs):
|
||||
if created:
|
||||
logger.debug('New token for {0} character {1} saved. Evaluating ownership.'.format(instance.user,
|
||||
instance.character_name))
|
||||
logger.debug('New token for {0} character {1} saved. Evaluating ownership.'.format(instance.user, instance.character_name))
|
||||
if instance.user:
|
||||
query = Q(owner_hash=instance.character_owner_hash) & Q(user=instance.user)
|
||||
else:
|
||||
@ -85,18 +84,14 @@ def record_character_ownership(sender, instance, created, *args, **kwargs):
|
||||
CharacterOwnership.objects.filter(character__character_id=instance.character_id).exclude(query).delete()
|
||||
# create character if needed
|
||||
if EveCharacter.objects.filter(character_id=instance.character_id).exists() is False:
|
||||
logger.debug('Token is for a new character. Creating model for {0} ({1})'.format(instance.character_name,
|
||||
instance.character_id))
|
||||
logger.debug('Token is for a new character. Creating model for {0} ({1})'.format(instance.character_name, instance.character_id))
|
||||
EveCharacter.objects.create_character(instance.character_id)
|
||||
char = EveCharacter.objects.get(character_id=instance.character_id)
|
||||
# check if we need to create ownership
|
||||
if instance.user and not CharacterOwnership.objects.filter(
|
||||
character__character_id=instance.character_id).exists():
|
||||
logger.debug("Character {0} is not yet owned. Assigning ownership to {1}".format(instance.character_name,
|
||||
instance.user))
|
||||
CharacterOwnership.objects.update_or_create(character=char,
|
||||
defaults={'owner_hash': instance.character_owner_hash,
|
||||
'user': instance.user})
|
||||
logger.debug("Character {0} is not yet owned. Assigning ownership to {1}".format(instance.character_name, instance.user))
|
||||
CharacterOwnership.objects.update_or_create(character=char, defaults={'owner_hash': instance.character_owner_hash, 'user': instance.user})
|
||||
|
||||
|
||||
@receiver(pre_delete, sender=CharacterOwnership)
|
||||
|
@ -138,7 +138,7 @@ class TestAuthenticate(TestCase):
|
||||
|
||||
def test_iterate_username(self):
|
||||
t = Token(character_id=self.unclaimed_character.character_id,
|
||||
character_name=self.unclaimed_character.character_name, character_owner_hash='3')
|
||||
character_name=self.unclaimed_character.character_name, character_owner_hash='3')
|
||||
username = StateBackend().authenticate(token=t).username
|
||||
t.character_owner_hash = '4'
|
||||
username_1 = StateBackend().authenticate(token=t).username
|
||||
|
@ -80,11 +80,11 @@ class StateTestCase(TestCase):
|
||||
def setUpTestData(cls):
|
||||
cls.user = AuthUtils.create_user('test_user', disconnect_signals=True)
|
||||
AuthUtils.add_main_character(cls.user, 'Test Character', '1', corp_id='1', alliance_id='1',
|
||||
corp_name='Test Corp', alliance_name='Test Alliance')
|
||||
corp_name='Test Corp', alliance_name='Test Alliance')
|
||||
cls.guest_state = get_guest_state()
|
||||
cls.test_character = EveCharacter.objects.get(character_id='1')
|
||||
cls.test_corporation = EveCorporationInfo.objects.create(corporation_id='1', corporation_name='Test Corp',
|
||||
corporation_ticker='TEST', member_count=1)
|
||||
corporation_ticker='TEST', member_count=1)
|
||||
cls.test_alliance = EveAllianceInfo.objects.create(alliance_id='1', alliance_name='Test Alliance',
|
||||
alliance_ticker='TEST', executor_corp_id='1')
|
||||
cls.member_state = State.objects.create(
|
||||
@ -215,7 +215,7 @@ class CharacterOwnershipCheckTestCase(TestCase):
|
||||
def setUpTestData(cls):
|
||||
cls.user = AuthUtils.create_user('test_user', disconnect_signals=True)
|
||||
AuthUtils.add_main_character(cls.user, 'Test Character', '1', corp_id='1', alliance_id='1',
|
||||
corp_name='Test Corp', alliance_name='Test Alliance')
|
||||
corp_name='Test Corp', alliance_name='Test Alliance')
|
||||
cls.character = EveCharacter.objects.get(character_id=1)
|
||||
cls.token = Token.objects.create(
|
||||
user=cls.user,
|
||||
|
@ -186,7 +186,7 @@ class ActivationView(BaseActivationView):
|
||||
def validate_key(self, activation_key):
|
||||
try:
|
||||
dump = signing.loads(activation_key, salt=REGISTRATION_SALT,
|
||||
max_age=settings.ACCOUNT_ACTIVATION_DAYS * 86400)
|
||||
max_age=settings.ACCOUNT_ACTIVATION_DAYS * 86400)
|
||||
return dump
|
||||
except signing.BadSignature:
|
||||
return None
|
||||
|
@ -6,11 +6,13 @@ from allianceauth.corputils import urls
|
||||
|
||||
class CorpStats(MenuItemHook):
|
||||
def __init__(self):
|
||||
MenuItemHook.__init__(self,
|
||||
_('Corporation Stats'),
|
||||
'fas fa-share-alt fa-fw',
|
||||
'corputils:view',
|
||||
navactive=['corputils:'])
|
||||
MenuItemHook.__init__(
|
||||
self,
|
||||
_('Corporation Stats'),
|
||||
'fas fa-share-alt fa-fw',
|
||||
'corputils:view',
|
||||
navactive=['corputils:']
|
||||
)
|
||||
|
||||
def render(self, request):
|
||||
if request.user.has_perm('corputils.view_corp_corpstats') or request.user.has_perm(
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.1 on 2016-12-14 21:36
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.1 on 2016-12-14 21:48
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.5 on 2017-03-22 23:35
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.5 on 2017-03-26 20:13
|
||||
from __future__ import unicode_literals
|
||||
|
||||
@ -13,8 +12,7 @@ def convert_json_to_members(apps, schema_editor):
|
||||
for cs in CorpStats.objects.all():
|
||||
members = json.loads(cs._members)
|
||||
CorpMember.objects.bulk_create(
|
||||
[CorpMember(corpstats=cs, character_id=member_id, character_name=member_name) for member_id, member_name in
|
||||
members.items()]
|
||||
[CorpMember(corpstats=cs, character_id=member_id, character_name=member_name) for member_id, member_name in members.items()]
|
||||
)
|
||||
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.2 on 2017-06-10 15:34
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -6,8 +6,7 @@ from bravado.exception import HTTPForbidden
|
||||
from django.db import models
|
||||
from esi.errors import TokenError
|
||||
from esi.models import Token
|
||||
from allianceauth.eveonline.models import EveCorporationInfo, EveCharacter,\
|
||||
EveAllianceInfo
|
||||
from allianceauth.eveonline.models import EveCorporationInfo, EveCharacter, EveAllianceInfo
|
||||
from allianceauth.notifications import notify
|
||||
|
||||
from allianceauth.corputils.managers import CorpStatsManager
|
||||
@ -49,8 +48,7 @@ class CorpStats(models.Model):
|
||||
def update(self):
|
||||
try:
|
||||
c = self.token.get_esi_client(spec_file=SWAGGER_SPEC_PATH)
|
||||
assert c.Character.get_characters_character_id(character_id=self.token.character_id).result()[
|
||||
'corporation_id'] == int(self.corp.corporation_id)
|
||||
assert c.Character.get_characters_character_id(character_id=self.token.character_id).result()['corporation_id'] == int(self.corp.corporation_id)
|
||||
member_ids = c.Corporation.get_corporations_corporation_id_members(
|
||||
corporation_id=self.corp.corporation_id).result()
|
||||
|
||||
@ -58,18 +56,15 @@ class CorpStats(models.Model):
|
||||
# the swagger spec doesn't have a maxItems count
|
||||
# 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_name_chunks = [c.Universe.post_universe_names(ids=id_chunk).result() for id_chunk in
|
||||
member_id_chunks]
|
||||
member_name_chunks = [c.Universe.post_universe_names(ids=id_chunk).result() for id_chunk in member_id_chunks]
|
||||
member_list = {}
|
||||
for name_chunk in member_name_chunks:
|
||||
member_list.update({m['id']: m['name'] for m in name_chunk})
|
||||
|
||||
# bulk create new member models
|
||||
missing_members = [m_id for m_id in member_ids if
|
||||
not CorpMember.objects.filter(corpstats=self, character_id=m_id).exists()]
|
||||
missing_members = [m_id for m_id in member_ids if not CorpMember.objects.filter(corpstats=self, character_id=m_id).exists()]
|
||||
CorpMember.objects.bulk_create(
|
||||
[CorpMember(character_id=m_id, character_name=member_list[m_id], corpstats=self) for m_id in
|
||||
missing_members])
|
||||
[CorpMember(character_id=m_id, character_name=member_list[m_id], corpstats=self) for m_id in missing_members])
|
||||
|
||||
# purge old members
|
||||
self.members.exclude(character_id__in=member_ids).delete()
|
||||
@ -80,21 +75,22 @@ class CorpStats(models.Model):
|
||||
except TokenError as e:
|
||||
logger.warning("%s failed to update: %s" % (self, e))
|
||||
if self.token.user:
|
||||
notify(self.token.user, "%s failed to update with your ESI token." % self,
|
||||
message="Your token has expired or is no longer valid. Please add a new one to create a new CorpStats.",
|
||||
level="error")
|
||||
notify(
|
||||
self.token.user, "%s failed to update with your ESI token." % self,
|
||||
message="Your token has expired or is no longer valid. Please add a new one to create a new CorpStats.",
|
||||
level="error")
|
||||
self.delete()
|
||||
except HTTPForbidden as e:
|
||||
logger.warning("%s failed to update: %s" % (self, e))
|
||||
if self.token.user:
|
||||
notify(self.token.user, "%s failed to update with your ESI token." % self,
|
||||
message="%s: %s" % (e.status_code, e.message), level="error")
|
||||
notify(self.token.user, "%s failed to update with your ESI token." % self, message="%s: %s" % (e.status_code, e.message), level="error")
|
||||
self.delete()
|
||||
except AssertionError:
|
||||
logger.warning("%s token character no longer in corp." % self)
|
||||
if self.token.user:
|
||||
notify(self.token.user, "%s cannot update with your ESI token." % self,
|
||||
message="%s cannot update with your ESI token as you have left corp." % self, level="error")
|
||||
notify(
|
||||
self.token.user, "%s cannot update with your ESI token." % self,
|
||||
message="%s cannot update with your ESI token as you have left corp." % self, level="error")
|
||||
self.delete()
|
||||
|
||||
@property
|
||||
@ -127,9 +123,7 @@ class CorpStats(models.Model):
|
||||
|
||||
@property
|
||||
def mains(self):
|
||||
return self.members.filter(pk__in=[m.pk for m in self.members.all() if
|
||||
m.main_character and int(m.main_character.character_id) == int(
|
||||
m.character_id)])
|
||||
return self.members.filter(pk__in=[m.pk for m in self.members.all() if m.main_character and int(m.main_character.character_id) == int(m.character_id)])
|
||||
|
||||
def visible_to(self, user):
|
||||
return CorpStats.objects.filter(pk=self.pk).visible_to(user).exists()
|
||||
|
@ -58,8 +58,7 @@
|
||||
{% for id, main in mains.items %}
|
||||
<tr>
|
||||
<td class="text-center" style="vertical-align:middle">
|
||||
<div class="thumbnail"
|
||||
style="border: 0 none; box-shadow: none; background: transparent;">
|
||||
<div class="thumbnail" style="border: 0 none; box-shadow: none; background: transparent;">
|
||||
<img src="{{ main.main.portrait_url_64 }}" class="img-circle">
|
||||
<div class="caption text-center">
|
||||
{{ main.main }}
|
||||
@ -88,8 +87,7 @@
|
||||
<td class="text-center" style="width:30%">{{ alt.corporation_name }}</td>
|
||||
<td class="text-center" style="width:30%">{{ alt.alliance_name }}</td>
|
||||
<td class="text-center" style="width:5%">
|
||||
<a href="https://zkillboard.com/character/{{ alt.character_id }}/"
|
||||
class="label label-danger" target="_blank">
|
||||
<a href="https://zkillboard.com/character/{{ alt.character_id }}/" class="label label-danger" target="_blank">
|
||||
{% trans "Killboard" %}
|
||||
</a>
|
||||
</td>
|
||||
@ -123,10 +121,9 @@
|
||||
<tr>
|
||||
<td><img src="{{ member.portrait_url }}" class="img-circle"></td>
|
||||
<td class="text-center">{{ member }}</td>
|
||||
<td class="text-center"><a
|
||||
href="https://zkillboard.com/character/{{ member.character_id }}/"
|
||||
class="label label-danger"
|
||||
target="_blank">{% trans "Killboard" %}</a></td>
|
||||
<td class="text-center">
|
||||
<a href="https://zkillboard.com/character/{{ member.character_id }}/" class="label label-danger" target="_blank">{% trans "Killboard" %}</a>
|
||||
</td>
|
||||
<td class="text-center">{{ member.character_ownership.user.profile.main_character.character_name }}</td>
|
||||
<td class="text-center">{{ member.character_ownership.user.profile.main_character.corporation_name }}</td>
|
||||
<td class="text-center">{{ member.character_ownership.user.profile.main_character.alliance_name }}</td>
|
||||
@ -136,10 +133,9 @@
|
||||
<tr class="danger">
|
||||
<td><img src="{{ member.portrait_url }}" class="img-circle"></td>
|
||||
<td class="text-center">{{ member.character_name }}</td>
|
||||
<td class="text-center"><a
|
||||
href="https://zkillboard.com/character/{{ member.character_id }}/"
|
||||
class="label label-danger"
|
||||
target="_blank">{% trans "Killboard" %}</a></td>
|
||||
<td class="text-center">
|
||||
<a href="https://zkillboard.com/character/{{ member.character_id }}/" class="label label-danger" target="_blank">{% trans "Killboard" %}</a>
|
||||
</td>
|
||||
<td class="text-center"></td>
|
||||
<td class="text-center"></td>
|
||||
<td class="text-center"></td>
|
||||
@ -167,9 +163,7 @@
|
||||
<td><img src="{{ member.portrait_url }}" class="img-circle"></td>
|
||||
<td class="text-center">{{ member.character_name }}</td>
|
||||
<td class="text-center">
|
||||
<a href="https://zkillboard.com/character/{{ member.character_id }}/"
|
||||
class="label label-danger"
|
||||
target="_blank">
|
||||
<a href="https://zkillboard.com/character/{{ member.character_id }}/" class="label label-danger" target="_blank">
|
||||
{% trans "Killboard" %}
|
||||
</a>
|
||||
</td>
|
||||
|
@ -96,7 +96,7 @@ def corpstats_view(request, corp_id=None):
|
||||
character_ownership__user__profile__main_character__corporation_id=corpstats.corp.corporation_id)
|
||||
|
||||
linked_chars = linked_chars.select_related('character_ownership',
|
||||
'character_ownership__user__profile__main_character') \
|
||||
'character_ownership__user__profile__main_character') \
|
||||
.prefetch_related('character_ownership__user__character_ownerships') \
|
||||
.prefetch_related('character_ownership__user__character_ownerships__character')
|
||||
|
||||
|
@ -31,12 +31,11 @@ class AutogroupsConfigAdmin(admin.ModelAdmin):
|
||||
def get_actions(self, request):
|
||||
actions = super(AutogroupsConfigAdmin, self).get_actions(request)
|
||||
actions['sync_user_groups'] = (sync_user_groups,
|
||||
'sync_user_groups',
|
||||
'Sync all users groups for this Autogroup Config')
|
||||
'sync_user_groups',
|
||||
'Sync all users groups for this Autogroup Config')
|
||||
return actions
|
||||
|
||||
|
||||
admin.site.register(AutogroupsConfig, AutogroupsConfigAdmin)
|
||||
admin.site.register(ManagedCorpGroup)
|
||||
admin.site.register(ManagedAllianceGroup)
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.6 on 2017-12-23 04:30
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -57,25 +57,21 @@ class AutogroupsConfig(models.Model):
|
||||
|
||||
states = models.ManyToManyField(State, related_name='autogroups')
|
||||
|
||||
corp_groups = models.BooleanField(default=False,
|
||||
help_text="Setting this to false will delete all the created groups.")
|
||||
corp_groups = models.BooleanField(default=False, help_text="Setting this to false will delete all the created groups.")
|
||||
corp_group_prefix = models.CharField(max_length=50, default='Corp ', blank=True)
|
||||
corp_name_source = models.CharField(max_length=20, choices=NAME_OPTIONS, default=OPT_NAME)
|
||||
|
||||
alliance_groups = models.BooleanField(default=False,
|
||||
help_text="Setting this to false will delete all the created groups.")
|
||||
alliance_groups = models.BooleanField(default=False, help_text="Setting this to false will delete all the created groups.")
|
||||
alliance_group_prefix = models.CharField(max_length=50, default='Alliance ', blank=True)
|
||||
alliance_name_source = models.CharField(max_length=20, choices=NAME_OPTIONS, default=OPT_NAME)
|
||||
|
||||
corp_managed_groups = models.ManyToManyField(
|
||||
Group, through='ManagedCorpGroup', related_name='corp_managed_config',
|
||||
help_text='A list of corporation groups created and maintained by this AutogroupConfig. '
|
||||
'You should not edit this list unless you know what you\'re doing.')
|
||||
help_text='A list of corporation groups created and maintained by this AutogroupConfig. You should not edit this list unless you know what you\'re doing.')
|
||||
|
||||
alliance_managed_groups = models.ManyToManyField(
|
||||
Group, through='ManagedAllianceGroup', related_name='alliance_managed_config',
|
||||
help_text='A list of alliance groups created and maintained by this AutogroupConfig. '
|
||||
'You should not edit this list unless you know what you\'re doing.')
|
||||
help_text='A list of alliance groups created and maintained by this AutogroupConfig. You should not edit this list unless you know what you\'re doing.')
|
||||
|
||||
replace_spaces = models.BooleanField(default=False)
|
||||
replace_spaces_with = models.CharField(
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.1 on 2016-09-05 21:39
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.1 on 2016-09-10 20:20
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.2 on 2016-10-26 01:49
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.2 on 2016-11-01 04:20
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.1 on 2016-12-16 23:22
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.1 on 2017-01-02 19:23
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.5 on 2017-01-18 13:20
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.5 on 2017-03-22 23:09
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.5 on 2017-09-28 02:16
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -91,9 +91,7 @@ class EveCorporationInfo(models.Model):
|
||||
provider = EveCorporationProviderManager()
|
||||
|
||||
class Meta:
|
||||
indexes = [
|
||||
models.Index(fields=['ceo_id',]),
|
||||
]
|
||||
indexes = [models.Index(fields=['ceo_id',]),]
|
||||
|
||||
def update_corporation(self, corp: providers.Corporation = None):
|
||||
if corp is None:
|
||||
@ -157,11 +155,11 @@ class EveCharacter(models.Model):
|
||||
|
||||
class Meta:
|
||||
indexes = [
|
||||
models.Index(fields=['corporation_id',]),
|
||||
models.Index(fields=['alliance_id',]),
|
||||
models.Index(fields=['corporation_name',]),
|
||||
models.Index(fields=['alliance_name',]),
|
||||
]
|
||||
models.Index(fields=['corporation_id',]),
|
||||
models.Index(fields=['alliance_id',]),
|
||||
models.Index(fields=['corporation_name',]),
|
||||
models.Index(fields=['alliance_name',]),
|
||||
]
|
||||
|
||||
@property
|
||||
def alliance(self) -> Union[EveAllianceInfo, None]:
|
||||
|
@ -1,2 +0,0 @@
|
||||
|
||||
|
@ -5,6 +5,4 @@ from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
class FatlinkForm(forms.Form):
|
||||
fleet = forms.CharField(label=_("Fleet Name"), max_length=50)
|
||||
duration = forms.IntegerField(label=_("Duration of fat-link"), required=True, initial=30, min_value=1,
|
||||
max_value=2147483647, help_text=_('minutes'))
|
||||
|
||||
duration = forms.IntegerField(label=_("Duration of fat-link"), required=True, initial=30, min_value=1, max_value=2147483647, help_text=_('minutes'))
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.1 on 2016-09-05 21:39
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.1 on 2016-09-05 22:20
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.1 on 2016-09-06 23:54
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.5 on 2017-03-22 23:35
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
<div class="panel-heading">{{ character_name }}</div>
|
||||
<div class="panel-body">
|
||||
<div class="col-lg-2 col-sm-2">
|
||||
<img class="ra-avatar img-responsive" src="{{ character_portrait_url }}">
|
||||
<img class="ra-avatar img-responsive" src="{{ character_portrait_url }}">
|
||||
</div>
|
||||
<div class="col-lg-10 col-sm-2">
|
||||
<div class="alert alert-danger" role="alert">{% trans "Character not registered!" %}</div>
|
||||
|
@ -30,4 +30,3 @@
|
||||
</div>
|
||||
|
||||
{% endblock content %}
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
<th class="col-md-2 text-center">{% trans "Characters" %}</th>
|
||||
<th class="col-md-2 text-center">{% trans "Fats" %}</th>
|
||||
<th class="col-md-2 text-center">{% trans "Average fats" %}
|
||||
<i class="glyphicon glyphicon-question-sign" rel="tooltip" title="Fats ÷ Characters"></i>
|
||||
<i class="glyphicon glyphicon-question-sign" rel="tooltip" title="Fats ÷ Characters"></i>
|
||||
</th>
|
||||
</tr>
|
||||
{% for memberStat in fatStats %}
|
||||
|
@ -24,7 +24,7 @@
|
||||
<th class="col-md-2 text-center">{% trans "Members" %}</th>
|
||||
<th class="col-md-2 text-center">{% trans "Fats" %}</th>
|
||||
<th class="col-md-2 text-center">{% trans "Average fats" %}
|
||||
<i class="glyphicon glyphicon-question-sign" rel="tooltip" title="Fats ÷ Characters"></i>
|
||||
<i class="glyphicon glyphicon-question-sign" rel="tooltip" title="Fats ÷ Characters"></i>
|
||||
</th>
|
||||
</tr>
|
||||
{% for corpStat in fatStats %}
|
||||
|
@ -135,8 +135,7 @@ def fatlink_statistics_corp_view(request, corpid, year=None, month=None):
|
||||
stat_list.sort(key=lambda stat: stat.mainchar.character_name)
|
||||
stat_list.sort(key=lambda stat: (stat.n_fats, stat.avg_fat), reverse=True)
|
||||
|
||||
context = {'fatStats': stat_list, 'month': start_of_month.strftime("%B"), 'year': year,
|
||||
'previous_month': start_of_previous_month, 'corpid': corpid}
|
||||
context = {'fatStats': stat_list, 'month': start_of_month.strftime("%B"), 'year': year, 'previous_month': start_of_previous_month, 'corpid': corpid}
|
||||
if datetime.datetime.now() > start_of_next_month:
|
||||
context.update({'next_month': start_of_next_month})
|
||||
|
||||
@ -163,16 +162,14 @@ def fatlink_statistics_view(request, year=datetime.date.today().year, month=date
|
||||
|
||||
for fat in fats_in_span.exclude(character__corporation_id__in=fat_stats):
|
||||
if EveCorporationInfo.objects.filter(corporation_id=fat.character.corporation_id).exists():
|
||||
fat_stats[fat.character.corporation_id] = CorpStat(fat.character.corporation_id, start_of_month,
|
||||
start_of_next_month)
|
||||
fat_stats[fat.character.corporation_id] = CorpStat(fat.character.corporation_id, start_of_month, start_of_next_month)
|
||||
|
||||
# collect and sort stats
|
||||
stat_list = [fat_stats[x] for x in fat_stats]
|
||||
stat_list.sort(key=lambda stat: stat.corp.corporation_name)
|
||||
stat_list.sort(key=lambda stat: (stat.n_fats, stat.avg_fat), reverse=True)
|
||||
|
||||
context = {'fatStats': stat_list, 'month': start_of_month.strftime("%B"), 'year': year,
|
||||
'previous_month': start_of_previous_month}
|
||||
context = {'fatStats': stat_list, 'month': start_of_month.strftime("%B"), 'year': year, 'previous_month': start_of_previous_month}
|
||||
if datetime.datetime.now() > start_of_next_month:
|
||||
context.update({'next_month': start_of_next_month})
|
||||
|
||||
@ -199,8 +196,7 @@ def fatlink_personal_statistics_view(request, year=datetime.date.today().year):
|
||||
monthlystats = [(i + 1, datetime.date(year, i + 1, 1).strftime("%h"), monthlystats[i]) for i in range(12)]
|
||||
|
||||
if datetime.datetime.now() > datetime.datetime(year + 1, 1, 1):
|
||||
context = {'user': user, 'monthlystats': monthlystats, 'year': year, 'previous_year': year - 1,
|
||||
'next_year': year + 1}
|
||||
context = {'user': user, 'monthlystats': monthlystats, 'year': year, 'previous_year': year - 1, 'next_year': year + 1}
|
||||
else:
|
||||
context = {'user': user, 'monthlystats': monthlystats, 'year': year, 'previous_year': year - 1}
|
||||
|
||||
@ -229,9 +225,11 @@ def fatlink_monthly_personal_statistics_view(request, year, month, char_id=None)
|
||||
for fat in personal_fats:
|
||||
ship_statistics[fat.shiptype] = ship_statistics.setdefault(fat.shiptype, 0) + 1
|
||||
n_fats += 1
|
||||
context = {'user': user, 'shipStats': sorted(ship_statistics.items()), 'month': start_of_month.strftime("%h"),
|
||||
'year': year, 'n_fats': n_fats, 'char_id': char_id, 'previous_month': start_of_previous_month,
|
||||
'next_month': start_of_next_month}
|
||||
context = {
|
||||
'user': user, 'shipStats': sorted(ship_statistics.items()), 'month': start_of_month.strftime("%h"),
|
||||
'year': year, 'n_fats': n_fats, 'char_id': char_id, 'previous_month': start_of_previous_month,
|
||||
'next_month': start_of_next_month
|
||||
}
|
||||
|
||||
created_fats = Fatlink.objects.filter(creator=user).filter(fatdatetime__gte=start_of_month).filter(
|
||||
fatdatetime__lt=start_of_next_month)
|
||||
@ -257,8 +255,7 @@ def click_fatlink_view(request, token, fat_hash=None):
|
||||
location = c.Location.get_characters_character_id_location(character_id=token.character_id).result()
|
||||
ship = c.Location.get_characters_character_id_ship(character_id=token.character_id).result()
|
||||
location['solar_system_name'] = \
|
||||
c.Universe.get_universe_systems_system_id(system_id=location['solar_system_id']).result()[
|
||||
'name']
|
||||
c.Universe.get_universe_systems_system_id(system_id=location['solar_system_id']).result()['name']
|
||||
if location['station_id']:
|
||||
location['station_name'] = \
|
||||
c.Universe.get_universe_stations_station_id(station_id=location['station_id']).result()['name']
|
||||
|
@ -45,7 +45,7 @@ class GroupManager:
|
||||
@staticmethod
|
||||
def get_group_leaders_groups(user: User):
|
||||
return Group.objects.select_related('authgroup').filter(authgroup__group_leaders__in=[user]) | \
|
||||
Group.objects.select_related('authgroup').filter(authgroup__group_leader_groups__in=user.groups.all())
|
||||
Group.objects.select_related('authgroup').filter(authgroup__group_leader_groups__in=user.groups.all())
|
||||
|
||||
@staticmethod
|
||||
def joinable_group(group: Group, state: State) -> bool:
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.1 on 2016-09-05 21:39
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.1 on 2016-09-06 23:54
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.1 on 2016-09-09 23:22
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.2 on 2016-12-04 10:25
|
||||
from __future__ import unicode_literals
|
||||
|
||||
@ -61,8 +60,7 @@ def reverse_group_models(apps, schema_editor):
|
||||
pass
|
||||
|
||||
if len(group.authgroup.description):
|
||||
GroupDescription.objects.update_or_create(group=group,
|
||||
defaults={'description': group.authgroup.description})
|
||||
GroupDescription.objects.update_or_create(group=group, defaults={'description': group.authgroup.description})
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
@ -77,8 +75,7 @@ class Migration(migrations.Migration):
|
||||
migrations.CreateModel(
|
||||
name='AuthGroup',
|
||||
fields=[
|
||||
('group', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, primary_key=True,
|
||||
serialize=False, to='auth.Group')),
|
||||
('group', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, primary_key=True, serialize=False, to='auth.Group')),
|
||||
('internal', models.BooleanField(default=True, help_text='Internal group, users cannot see, join or request to join this group.<br>Used for groups such as Members, Corp_*, Alliance_* etc.<br><b>Overrides Hidden and Open options when selected.</b>')),
|
||||
('hidden', models.BooleanField(default=True, help_text='Group is hidden from users but can still join with the correct link.')),
|
||||
('open', models.BooleanField(default=False, help_text='Group is open and users will be automatically added upon request. <br>If the group is not open users will need their request manually approved.')),
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.5 on 2017-02-04 06:11
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.5 on 2017-02-04 07:17
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.5 on 2017-09-28 02:16
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.10 on 2018-02-23 23:09
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -79,33 +79,32 @@ class AuthGroup(models.Model):
|
||||
group = models.OneToOneField(Group, on_delete=models.CASCADE, primary_key=True)
|
||||
|
||||
internal = models.BooleanField(default=True,
|
||||
help_text="Internal group, users cannot see, join or request to join this group.<br>"
|
||||
"Used for groups such as Members, Corp_*, Alliance_* etc.<br>"
|
||||
"<b>Overrides Hidden and Open options when selected.</b>")
|
||||
hidden = models.BooleanField(default=True,
|
||||
help_text="Group is hidden from users but can still join with the correct link.")
|
||||
help_text="Internal group, users cannot see, join or request to join this group.<br>"
|
||||
"Used for groups such as Members, Corp_*, Alliance_* etc.<br>"
|
||||
"<b>Overrides Hidden and Open options when selected.</b>")
|
||||
hidden = models.BooleanField(default=True, help_text="Group is hidden from users but can still join with the correct link.")
|
||||
open = models.BooleanField(default=False,
|
||||
help_text="Group is open and users will be automatically added upon request. <br>"
|
||||
"If the group is not open users will need their request manually approved.")
|
||||
help_text="Group is open and users will be automatically added upon request. <br>"
|
||||
"If the group is not open users will need their request manually approved.")
|
||||
public = models.BooleanField(default=False,
|
||||
help_text="Group is public. Any registered user is able to join this group, with "
|
||||
"visibility based on the other options set for this group.<br> Auth will "
|
||||
"not remove users from this group automatically when they are no longer "
|
||||
"authenticated.")
|
||||
help_text="Group is public. Any registered user is able to join this group, with "
|
||||
"visibility based on the other options set for this group.<br> Auth will "
|
||||
"not remove users from this group automatically when they are no longer "
|
||||
"authenticated.")
|
||||
# Group leaders have management access to this group
|
||||
group_leaders = models.ManyToManyField(User, related_name='leads_groups', blank=True,
|
||||
help_text="Group leaders can process group requests for this group "
|
||||
"specifically. Use the auth.group_management permission to allow "
|
||||
"a user to manage all groups.")
|
||||
help_text="Group leaders can process group requests for this group "
|
||||
"specifically. Use the auth.group_management permission to allow "
|
||||
"a user to manage all groups.")
|
||||
# allow groups to be *group leads*
|
||||
group_leader_groups = models.ManyToManyField(Group, related_name='leads_group_groups', blank=True,
|
||||
help_text="Group leaders can process group requests for this group "
|
||||
"specifically. Use the auth.group_management permission to allow "
|
||||
"a user to manage all groups.")
|
||||
help_text="Group leaders can process group requests for this group "
|
||||
"specifically. Use the auth.group_management permission to allow "
|
||||
"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.")
|
||||
"they have the proper permissions.")
|
||||
|
||||
description = models.TextField(max_length=512, blank=True, help_text="Short description <i>(max. 512 characters)</i> of the group shown to users.")
|
||||
|
||||
|
@ -97,4 +97,3 @@ class TestCheckGroupsOnStateChange(TestCase):
|
||||
self.assertEqual(self.user.profile.state, self.test_state_2)
|
||||
groups = self.user.groups.all()
|
||||
self.assertIn(state_group, groups)
|
||||
|
@ -78,8 +78,7 @@ def group_membership_audit(request, group_id):
|
||||
# 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))
|
||||
logger.warning("User %s attempted to view the membership of group %s but permission was denied" % (request.user, group_id))
|
||||
raise PermissionDenied
|
||||
|
||||
except ObjectDoesNotExist:
|
||||
@ -140,15 +139,13 @@ def group_membership_list(request, group_id):
|
||||
@login_required
|
||||
@user_passes_test(GroupManager.can_manage_groups)
|
||||
def group_membership_remove(request, group_id, user_id):
|
||||
logger.debug("group_membership_remove called by user %s for group id %s on user id %s" %
|
||||
(request.user, group_id, user_id))
|
||||
logger.debug("group_membership_remove called by user %s for group id %s on user id %s" % (request.user, group_id, user_id))
|
||||
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 remove a user from group %s but permission was denied" % (request.user,
|
||||
group_id))
|
||||
logger.warning("User %s attempted to remove a user from group %s but permission was denied" % (request.user, group_id))
|
||||
raise PermissionDenied
|
||||
|
||||
try:
|
||||
@ -189,13 +186,12 @@ def group_accept_request(request, group_request_id):
|
||||
logger.info("User %s accepted group request from user %s to group %s" % (
|
||||
request.user, group_request.user, group_request.group.name))
|
||||
notify(group_request.user, "Group Application Accepted", level="success",
|
||||
message="Your application to %s has been accepted." % group_request.group)
|
||||
message="Your application to %s has been accepted." % group_request.group)
|
||||
messages.success(request,
|
||||
_('Accepted application from %(mainchar)s to %(group)s.') % {"mainchar": group_request.main_char, "group": group_request.group})
|
||||
_('Accepted application from %(mainchar)s to %(group)s.') % {"mainchar": group_request.main_char, "group": group_request.group})
|
||||
|
||||
except PermissionDenied as p:
|
||||
logger.warning("User %s attempted to accept group join request %s but permission was denied" %
|
||||
(request.user, group_request_id))
|
||||
logger.warning("User %s attempted to accept group join request %s but permission was denied" % (request.user, group_request_id))
|
||||
raise p
|
||||
except:
|
||||
messages.error(request, _('An unhandled error occurred while processing the application from %(mainchar)s to %(group)s.') % {"mainchar": group_request.main_char, "group": group_request.group})
|
||||
@ -221,14 +217,12 @@ def group_reject_request(request, group_request_id):
|
||||
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()
|
||||
notify(group_request.user, "Group Application Rejected", level="danger",
|
||||
message="Your application to %s has been rejected." % group_request.group)
|
||||
notify(group_request.user, "Group Application Rejected", level="danger", message="Your application to %s has been rejected." % group_request.group)
|
||||
messages.success(request,
|
||||
_('Rejected application from %(mainchar)s to %(group)s.') % {"mainchar": group_request.main_char, "group": group_request.group})
|
||||
_('Rejected application from %(mainchar)s to %(group)s.') % {"mainchar": group_request.main_char, "group": group_request.group})
|
||||
|
||||
except PermissionDenied as p:
|
||||
logger.warning("User %s attempted to reject group join request %s but permission was denied" %
|
||||
(request.user, group_request_id))
|
||||
logger.warning("User %s attempted to reject group join request %s but permission was denied" % (request.user, group_request_id))
|
||||
raise p
|
||||
except:
|
||||
messages.error(request, _('An unhandled error occurred while processing the application from %(mainchar)s to %(group)s.') % {"mainchar": group_request.main_char, "group": group_request.group})
|
||||
@ -258,12 +252,11 @@ def group_leave_accept_request(request, group_request_id):
|
||||
logger.info("User %s accepted group leave request from user %s to group %s" % (
|
||||
request.user, group_request.user, group_request.group.name))
|
||||
notify(group_request.user, "Group Leave Request Accepted", level="success",
|
||||
message="Your request to leave %s has been accepted." % group_request.group)
|
||||
message="Your request to leave %s has been accepted." % group_request.group)
|
||||
messages.success(request,
|
||||
_('Accepted application from %(mainchar)s to leave %(group)s.') % {"mainchar": group_request.main_char, "group": group_request.group})
|
||||
_('Accepted application from %(mainchar)s to leave %(group)s.') % {"mainchar": group_request.main_char, "group": group_request.group})
|
||||
except PermissionDenied as p:
|
||||
logger.warning("User %s attempted to accept group leave request %s but permission was denied" %
|
||||
(request.user, group_request_id))
|
||||
logger.warning("User %s attempted to accept group leave request %s but permission was denied" % (request.user, group_request_id))
|
||||
raise p
|
||||
except:
|
||||
messages.error(request, _('An unhandled error occurred while processing the application from %(mainchar)s to leave %(group)s.') % {
|
||||
@ -291,13 +284,11 @@ def group_leave_reject_request(request, group_request_id):
|
||||
group_request.delete()
|
||||
logger.info("User %s rejected group leave request from user %s for group %s" % (
|
||||
request.user, group_request.user, group_request.group.name))
|
||||
notify(group_request.user, "Group Leave Request Rejected", level="danger",
|
||||
message="Your request to leave %s has been rejected." % group_request.group)
|
||||
notify(group_request.user, "Group Leave Request Rejected", level="danger", message="Your request to leave %s has been rejected." % group_request.group)
|
||||
messages.success(request, _('Rejected application from %(mainchar)s to leave %(group)s.') % {
|
||||
"mainchar": group_request.main_char, "group": group_request.group})
|
||||
except PermissionDenied as p:
|
||||
logger.warning("User %s attempted to reject group leave request %s but permission was denied" %
|
||||
(request.user, group_request_id))
|
||||
logger.warning("User %s attempted to reject group leave request %s but permission was denied" % (request.user, group_request_id))
|
||||
raise p
|
||||
except:
|
||||
messages.error(request, _('An unhandled error occurred while processing the application from %(mainchar)s to leave %(group)s.') % {
|
||||
@ -337,20 +328,17 @@ def group_request_add(request, group_id):
|
||||
group = Group.objects.get(id=group_id)
|
||||
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" %
|
||||
(request.user, group_id))
|
||||
logger.warning("User %s attempted to join group id %s but it is not a joinable group" % (request.user, group_id))
|
||||
messages.warning(request, _("You cannot join that group"))
|
||||
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))
|
||||
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:
|
||||
# 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" %
|
||||
(request.user, group_id))
|
||||
logger.warning("User %s attempted to join group id %s but it is not a public group" % (request.user, group_id))
|
||||
messages.warning(request, _("You cannot join that group"))
|
||||
return redirect('groupmanagement:groups')
|
||||
if group.authgroup.open:
|
||||
@ -381,13 +369,11 @@ def group_request_leave(request, 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)
|
||||
if not GroupManager.check_internal_group(group):
|
||||
logger.warning("User %s attempted to leave group id %s but it is not a joinable group" %
|
||||
(request.user, group_id))
|
||||
logger.warning("User %s attempted to leave group id %s but it is not a joinable group" % (request.user, group_id))
|
||||
messages.warning(request, _("You cannot leave that group"))
|
||||
return redirect('groupmanagement:groups')
|
||||
if group not in request.user.groups.all():
|
||||
logger.debug("User %s attempted to leave group id %s but they are not a member" %
|
||||
(request.user, group_id))
|
||||
logger.debug("User %s attempted to leave group id %s but they are not a member" % (request.user, group_id))
|
||||
messages.warning(request, _("You are not a member of that group"))
|
||||
return redirect('groupmanagement:groups')
|
||||
if group.authgroup.open:
|
||||
|
@ -5,16 +5,16 @@ All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of Torchbox nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
3. Neither the name of Torchbox nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
@ -122,4 +122,3 @@ def get_hooks(name):
|
||||
"""
|
||||
register_all_hooks()
|
||||
return _hooks.get(name, [])
|
||||
|
||||
|
@ -9,11 +9,12 @@ from .models import Application
|
||||
|
||||
class ApplicationsMenu(MenuItemHook):
|
||||
def __init__(self):
|
||||
MenuItemHook.__init__(self,
|
||||
_('Applications'),
|
||||
'far fa-file fa-fw',
|
||||
'hrapplications:index',
|
||||
navactive=['hrapplications:'])
|
||||
MenuItemHook.__init__(
|
||||
self,
|
||||
_('Applications'),
|
||||
'far fa-file fa-fw',
|
||||
'hrapplications:index',
|
||||
navactive=['hrapplications:'])
|
||||
|
||||
def render(self, request):
|
||||
app_count = Application.objects.pending_requests_count_for_user(request.user)
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.1 on 2016-09-05 21:39
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.4 on 2017-08-23 19:46
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10 on 2017-10-20 13:51
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.5 on 2017-03-22 23:35
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.5 on 2017-03-27 03:29
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.2 on 2017-06-08 02:54
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -42,14 +42,12 @@
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<a href="{% url 'hrapplications:personal_view' personal_app.id %}"
|
||||
class="btn btn-primary">
|
||||
<a href="{% url 'hrapplications:personal_view' personal_app.id %}" class="btn btn-primary">
|
||||
<span class="glyphicon glyphicon-eye-open"></span>
|
||||
</a>
|
||||
|
||||
{% if personal_app.approved == None %}
|
||||
<a href="{% url 'hrapplications:personal_removal' personal_app.id %}"
|
||||
class="btn btn-danger">
|
||||
<a href="{% url 'hrapplications:personal_removal' personal_app.id %}" class="btn btn-danger">
|
||||
<span class="glyphicon glyphicon-remove"></span>
|
||||
</a>
|
||||
{% endif %}
|
||||
@ -105,8 +103,7 @@
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<a href="{% url 'hrapplications:view' app.id %}"
|
||||
class="btn btn-primary">
|
||||
<a href="{% url 'hrapplications:view' app.id %}" class="btn btn-primary">
|
||||
<span class="glyphicon glyphicon-eye-open"></span>
|
||||
</a>
|
||||
</td>
|
||||
@ -150,13 +147,11 @@
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<a href="{% url 'hrapplications:view' app.id %}"
|
||||
class="btn btn-primary">
|
||||
<a href="{% url 'hrapplications:view' app.id %}" class="btn btn-primary">
|
||||
<span class="glyphicon glyphicon-eye-open"></span>
|
||||
</a>
|
||||
{% if perms.hrapplications.delete_application %}
|
||||
<a href="{% url 'hrapplications:remove' app.id %}"
|
||||
class="btn btn-danger">
|
||||
<a href="{% url 'hrapplications:remove' app.id %}" class="btn btn-danger">
|
||||
<span class="glyphicon glyphicon-remove"></span>
|
||||
</a>
|
||||
{% endif %}
|
||||
@ -175,18 +170,15 @@
|
||||
|
||||
{% if perms.auth.human_resources %}
|
||||
<!-- Modal -->
|
||||
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"
|
||||
aria-hidden="true">
|
||||
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span
|
||||
class="sr-only">{% trans "Close" %}</span></button>
|
||||
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">{% trans "Close" %}</span></button>
|
||||
<h4 class="modal-title" id="myModalLabel">{% trans "Application Search" %}</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form class="form-signin" role="form"
|
||||
action={% url 'hrapplications:search' %} method="POST">
|
||||
<form class="form-signin" role="form" action={% url 'hrapplications:search' %} method="POST">
|
||||
{% csrf_token %}
|
||||
{{ search_form|bootstrap }}
|
||||
<br/>
|
||||
|
@ -56,18 +56,15 @@
|
||||
|
||||
{% if perms.auth.human_resources %}
|
||||
<!-- Modal -->
|
||||
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"
|
||||
aria-hidden="true">
|
||||
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span
|
||||
class="sr-only">{% trans "Close" %}</span></button>
|
||||
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">{% trans "Close" %}</span></button>
|
||||
<h4 class="modal-title" id="myModalLabel">{% trans "Application Search" %}</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form class="form-signin" role="form"
|
||||
action={% url 'hrapplications:search' %} method="POST">
|
||||
<form class="form-signin" role="form" action={% url 'hrapplications:search' %} method="POST">
|
||||
{% csrf_token %}
|
||||
{{ search_form|bootstrap }}
|
||||
<br/>
|
||||
|
@ -49,8 +49,7 @@
|
||||
{% for char in app.characters %}
|
||||
<tr>
|
||||
<td class="text-center">
|
||||
<img class="ra-avatar img-responsive img-circle"
|
||||
src="{{ char.portrait_url_32 }}">
|
||||
<img class="ra-avatar img-responsive img-circle" src="{{ char.portrait_url_32 }}">
|
||||
</td>
|
||||
<td class="text-center">{{ char.character_name }}</td>
|
||||
<td class="text-center">{{ char.corporation_name }}</td>
|
||||
@ -77,25 +76,20 @@
|
||||
{% if app.approved == None %}
|
||||
{% if app.reviewer == user %}
|
||||
{% if perms.hrapplications.approve_application %}
|
||||
<a href="{% url 'hrapplications:approve' app.id %}"
|
||||
class="btn btn-success">{% trans "Approve" %}</a>
|
||||
<a href="{% url 'hrapplications:approve' app.id %}" class="btn btn-success">{% trans "Approve" %}</a>
|
||||
{% endif %}
|
||||
{% if perms.hrapplications.reject_application %}
|
||||
<a href="{% url 'hrapplications:reject' app.id %}"
|
||||
class="btn btn-danger">{% trans "Reject" %}</a>
|
||||
<a href="{% url 'hrapplications:reject' app.id %}" class="btn btn-danger">{% trans "Reject" %}</a>
|
||||
{% endif %}
|
||||
{% if perms.hrapplications.delete_application %}
|
||||
<a href="{% url 'hrapplications:remove' app.id %}"
|
||||
class="btn btn-danger">{% trans "Delete" %}</a>
|
||||
<a href="{% url 'hrapplications:remove' app.id %}" class="btn btn-danger">{% trans "Delete" %}</a>
|
||||
{% endif %}
|
||||
{% elif not app.reviewer %}
|
||||
<a href="{% url 'hrapplications:mark_in_progress' app.id %}"
|
||||
class="btn btn-warning">{% trans "Mark in Progress" %}</a>
|
||||
<a href="{% url 'hrapplications:mark_in_progress' app.id %}" class="btn btn-warning">{% trans "Mark in Progress" %}</a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if perms.hrapplications.add_applicationcomment %}
|
||||
<button type="button" class="btn btn-primary" data-toggle="modal"
|
||||
data-target="#myModal">{% trans "Comment" %}</button>
|
||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#myModal">{% trans "Comment" %}</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
@ -104,15 +98,12 @@
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading" role="tab" id="headingThree">
|
||||
<h4 class="panel-title">
|
||||
<a class="collapsed" data-toggle="collapse" data-parent="#accordion"
|
||||
href="#collapseThree" aria-expanded="false"
|
||||
aria-controls="collapseThree">
|
||||
<a class="collapsed" data-toggle="collapse" data-parent="#accordion" href="#collapseThree" aria-expanded="false" aria-controls="collapseThree">
|
||||
{% trans 'Comments' %} ({{ comments.count }})
|
||||
</a>
|
||||
</h4>
|
||||
</div>
|
||||
<div id="collapseThree" class="panel-collapse collapse" role="tabpanel"
|
||||
aria-labelledby="headingThree">
|
||||
<div id="collapseThree" class="panel-collapse collapse" role="tabpanel" aria-labelledby="headingThree">
|
||||
<div class="panel-body">
|
||||
{% for comment in comments %}
|
||||
<div class="panel panel-default">
|
||||
@ -136,8 +127,7 @@
|
||||
</div>
|
||||
</div>
|
||||
{% if perms.hrapplications.add_applicationcomment %}
|
||||
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"
|
||||
aria-hidden="true">
|
||||
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
|
@ -63,15 +63,13 @@ def hr_application_create_view(request, form_id=None):
|
||||
application.save()
|
||||
for question in app_form.questions.all():
|
||||
response = ApplicationResponse(question=question, application=application)
|
||||
response.answer = "\n".join(request.POST.getlist(str(question.pk),
|
||||
""))
|
||||
response.answer = "\n".join(request.POST.getlist(str(question.pk), ""))
|
||||
response.save()
|
||||
logger.info("%s created %s" % (request.user, application))
|
||||
return redirect('hrapplications:personal_view', application.id)
|
||||
else:
|
||||
questions = app_form.questions.all()
|
||||
return render(request, 'hrapplications/create.html',
|
||||
context={'questions': questions, 'corp': app_form.corp})
|
||||
return render(request, 'hrapplications/create.html', context={'questions': questions, 'corp': app_form.corp})
|
||||
else:
|
||||
choices = []
|
||||
for app_form in ApplicationForm.objects.all():
|
||||
@ -171,8 +169,7 @@ def hr_application_approve(request, app_id):
|
||||
logger.info("User %s approving %s" % (request.user, app))
|
||||
app.approved = True
|
||||
app.save()
|
||||
notify(app.user, "Application Accepted", message="Your application to %s has been approved." % app.form.corp,
|
||||
level="success")
|
||||
notify(app.user, "Application Accepted", message="Your application to %s has been approved." % app.form.corp, level="success")
|
||||
else:
|
||||
logger.warn("User %s not authorized to approve %s" % (request.user, app))
|
||||
return redirect('hrapplications:index')
|
||||
@ -188,8 +185,7 @@ def hr_application_reject(request, app_id):
|
||||
logger.info("User %s rejecting %s" % (request.user, app))
|
||||
app.approved = False
|
||||
app.save()
|
||||
notify(app.user, "Application Rejected", message="Your application to %s has been rejected." % app.form.corp,
|
||||
level="danger")
|
||||
notify(app.user, "Application Rejected", message="Your application to %s has been rejected." % app.form.corp, level="danger")
|
||||
else:
|
||||
logger.warn("User %s not authorized to reject %s" % (request.user, app))
|
||||
return redirect('hrapplications:index')
|
||||
@ -248,8 +244,7 @@ def hr_application_mark_in_progress(request, app_id):
|
||||
app.reviewer = request.user
|
||||
app.reviewer_character = request.user.profile.main_character
|
||||
app.save()
|
||||
notify(app.user, "Application In Progress",
|
||||
message="Your application to %s is being reviewed by %s" % (app.form.corp, app.reviewer_str))
|
||||
notify(app.user, "Application In Progress", message="Your application to %s is being reviewed by %s" % (app.form.corp, app.reviewer_str))
|
||||
else:
|
||||
logger.warn(
|
||||
"User %s unable to mark %s in progress: already being reviewed by %s" % (request.user, app, app.reviewer))
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.1 on 2016-09-05 21:40
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.1 on 2016-09-10 16:49
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.5 on 2017-03-22 23:35
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -18,10 +18,8 @@
|
||||
<li><a data-toggle="pill" href="#read">{% trans "Read" %} <b>({{ read|length }})</b></a>
|
||||
</li>
|
||||
<div class="pull-right">
|
||||
<a href="{% url 'notifications:mark_all_read' %}"
|
||||
class="btn btn-primary">{% trans "Mark All Read" %}</a>
|
||||
<a href="{% url 'notifications:delete_all_read' %}"
|
||||
class="btn btn-danger">{% trans "Delete All Read" %}</a>
|
||||
<a href="{% url 'notifications:mark_all_read' %}" class="btn btn-primary">{% trans "Mark All Read" %}</a>
|
||||
<a href="{% url 'notifications:delete_all_read' %}" class="btn btn-danger">{% trans "Delete All Read" %}</a>
|
||||
</div>
|
||||
</ul>
|
||||
</div>
|
||||
@ -41,12 +39,10 @@
|
||||
<td class="text-center">{{ notif.timestamp }}</td>
|
||||
<td class="text-center">{{ notif.title }}</td>
|
||||
<td class="text-center">
|
||||
<a href="{% url 'notifications:view' notif.id %}"
|
||||
class="btn btn-success" title="View">
|
||||
<a href="{% url 'notifications:view' notif.id %}" class="btn btn-success" title="View">
|
||||
<span class="glyphicon glyphicon-eye-open"></span>
|
||||
</a>
|
||||
<a href="{% url 'notifications:remove' notif.id %}"
|
||||
class="btn btn-danger" title="Remove">
|
||||
<a href="{% url 'notifications:remove' notif.id %}" class="btn btn-danger" title="Remove">
|
||||
<span class="glyphicon glyphicon-remove"></span>
|
||||
</a>
|
||||
</td>
|
||||
@ -73,12 +69,10 @@
|
||||
<td class="text-center">{{ notif.timestamp }}</td>
|
||||
<td class="text-center">{{ notif.title }}</td>
|
||||
<td class="text-center">
|
||||
<a href="{% url 'notifications:view' notif.id %}"
|
||||
class="btn btn-success" title="View">
|
||||
<a href="{% url 'notifications:view' notif.id %}" class="btn btn-success" title="View">
|
||||
<span class="glyphicon glyphicon-eye-open"></span>
|
||||
</a>
|
||||
<a href="{% url 'notifications:remove' notif.id %}"
|
||||
class="btn btn-danger" title="remove">
|
||||
<a href="{% url 'notifications:remove' notif.id %}" class="btn btn-danger" title="remove">
|
||||
<span class="glyphicon glyphicon-remove"></span>
|
||||
</a>
|
||||
</td>
|
||||
|
@ -6,10 +6,12 @@ from . import urls
|
||||
|
||||
class OpTimerboardMenu(MenuItemHook):
|
||||
def __init__(self):
|
||||
MenuItemHook.__init__(self, _('Fleet Operations'),
|
||||
'fas fa-exclamation fa-fw',
|
||||
'optimer:view',
|
||||
navactive=['optimer:'])
|
||||
MenuItemHook.__init__(
|
||||
self, _('Fleet Operations'),
|
||||
'fas fa-exclamation fa-fw',
|
||||
'optimer:view',
|
||||
navactive=['optimer:']
|
||||
)
|
||||
|
||||
def render(self, request):
|
||||
if request.user.has_perm('auth.optimer_view'):
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.1 on 2016-09-05 21:40
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11 on 2017-04-13 04:42
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.5 on 2017-03-22 23:35
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.5 on 2017-09-28 02:16
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
{% load evelinks %}
|
||||
|
||||
{% block content %}
|
||||
<div class="table-responsive">
|
||||
<div class="table-responsive">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
|
@ -4,4 +4,3 @@ from django.apps import AppConfig
|
||||
class PermissionsToolConfig(AppConfig):
|
||||
name = 'allianceauth.permissions_tool'
|
||||
label = 'permissions_tool'
|
||||
|
||||
|
@ -6,12 +6,14 @@ from allianceauth.services.hooks import MenuItemHook, UrlHook
|
||||
|
||||
class PermissionsTool(MenuItemHook):
|
||||
def __init__(self):
|
||||
MenuItemHook.__init__(self,
|
||||
'Permissions Audit',
|
||||
'fas fa-id-card fa-fw',
|
||||
'permissions_tool:overview',
|
||||
order=400,
|
||||
navactive=['permissions_tool:'])
|
||||
MenuItemHook.__init__(
|
||||
self,
|
||||
'Permissions Audit',
|
||||
'fas fa-id-card fa-fw',
|
||||
'permissions_tool:overview',
|
||||
order=400,
|
||||
navactive=['permissions_tool:']
|
||||
)
|
||||
|
||||
def render(self, request):
|
||||
if request.user.has_perm('permissions_tool.audit_permissions'):
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.5 on 2017-02-06 08:58
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
@ -40,8 +40,7 @@ class PermissionsToolViewsTestCase(WebTest):
|
||||
|
||||
response_content = response.content.decode('utf-8')
|
||||
|
||||
self.assertInHTML('<li><a class="active" href="/permissions/overview/">'
|
||||
'<i class="fas fa-id-card fa-fw"></i> Permissions Audit</a></li>', response_content)
|
||||
self.assertInHTML('<li><a class="active" href="/permissions/overview/"><i class="fas fa-id-card fa-fw"></i> Permissions Audit</a></li>', response_content)
|
||||
|
||||
def test_permissions_overview(self):
|
||||
self.app.set_user(self.member)
|
||||
|
@ -47,7 +47,7 @@ def permissions_audit(request, app_label, model, codename):
|
||||
try:
|
||||
perm = Permission.objects\
|
||||
.prefetch_related('group_set', 'user_set', 'state_set',
|
||||
'state_set__userprofile_set', 'group_set__user_set', 'state_set__userprofile_set__user')\
|
||||
'state_set__userprofile_set', 'group_set__user_set', 'state_set__userprofile_set__user')\
|
||||
.get(content_type__app_label=app_label, content_type__model=model, codename=codename)
|
||||
except Permission.DoesNotExist:
|
||||
raise Http404
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
"""
|
||||
DO NOT EDIT THIS FILE
|
||||
|
||||
@ -131,8 +130,10 @@ AUTH_PASSWORD_VALIDATORS = [
|
||||
},
|
||||
]
|
||||
|
||||
AUTHENTICATION_BACKENDS = ['allianceauth.authentication.backends.StateBackend',
|
||||
'django.contrib.auth.backends.ModelBackend']
|
||||
AUTHENTICATION_BACKENDS = [
|
||||
'allianceauth.authentication.backends.StateBackend',
|
||||
'django.contrib.auth.backends.ModelBackend'
|
||||
]
|
||||
|
||||
# Internationalization
|
||||
# https://docs.djangoproject.com/en/1.10/topics/i18n/
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user