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:
Ariel Rin 2021-06-22 23:38:54 +00:00
commit a0a497ab33
345 changed files with 3044 additions and 3184 deletions

24
.editorconfig Normal file
View 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

View File

@ -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
View 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))

View File

@ -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.

View File

@ -43,4 +43,3 @@ AUTHENTICATION_ADMIN_USERS_MAX_GROUPS = \
AUTHENTICATION_ADMIN_USERS_MAX_CHARS = \
_clean_setting('AUTHENTICATION_ADMIN_USERS_MAX_CHARS', 5)

View File

@ -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):

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.1 on 2016-09-05 21:38
from __future__ import unicode_literals

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.1 on 2016-09-07 19:14
from __future__ import unicode_literals

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.1 on 2016-09-09 20:29
from __future__ import unicode_literals

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.1 on 2016-09-09 23:19
from __future__ import unicode_literals

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.1 on 2016-09-09 23:11
from __future__ import unicode_literals

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.1 on 2016-09-10 05:42
from __future__ import unicode_literals

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.1 on 2016-09-10 21:50
from __future__ import unicode_literals

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.1 on 2016-09-12 13:04
from __future__ import unicode_literals

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.2 on 2016-10-21 02:28
from __future__ import unicode_literals

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.1 on 2017-01-07 06:47
from __future__ import unicode_literals

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.1 on 2017-01-07 07:11
from __future__ import unicode_literals

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.5 on 2017-01-12 00:59
from __future__ import unicode_literals

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.2 on 2016-12-11 23:14
from __future__ import unicode_literals

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.1 on 2016-09-09 23:19
from __future__ import unicode_literals

View File

@ -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(

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations

View File

@ -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()

View File

@ -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)

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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(

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.1 on 2016-12-14 21:36
from __future__ import unicode_literals

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.1 on 2016-12-14 21:48
from __future__ import unicode_literals

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.5 on 2017-03-22 23:35
from __future__ import unicode_literals

View File

@ -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()]
)

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.2 on 2017-06-10 15:34
from __future__ import unicode_literals

View File

@ -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()

View File

@ -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>

View File

@ -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')

View File

@ -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)

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2017-12-23 04:30
from __future__ import unicode_literals

View File

@ -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(

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.1 on 2016-09-05 21:39
from __future__ import unicode_literals

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.1 on 2016-09-10 20:20
from __future__ import unicode_literals

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.2 on 2016-10-26 01:49
from __future__ import unicode_literals

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.2 on 2016-11-01 04:20
from __future__ import unicode_literals

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.1 on 2016-12-16 23:22
from __future__ import unicode_literals

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.1 on 2017-01-02 19:23
from __future__ import unicode_literals

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.5 on 2017-01-18 13:20
from __future__ import unicode_literals

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.5 on 2017-03-22 23:09
from __future__ import unicode_literals

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.5 on 2017-09-28 02:16
from __future__ import unicode_literals

View File

@ -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]:

View File

@ -1,2 +0,0 @@

View File

@ -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'))

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.1 on 2016-09-05 21:39
from __future__ import unicode_literals

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.1 on 2016-09-05 22:20
from __future__ import unicode_literals

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.1 on 2016-09-06 23:54
from __future__ import unicode_literals

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.5 on 2017-03-22 23:35
from __future__ import unicode_literals

View File

@ -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>

View File

@ -30,4 +30,3 @@
</div>
{% endblock content %}

View File

@ -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 %}

View File

@ -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 %}

View File

@ -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']

View File

@ -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:

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.1 on 2016-09-05 21:39
from __future__ import unicode_literals

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.1 on 2016-09-06 23:54
from __future__ import unicode_literals

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.1 on 2016-09-09 23:22
from __future__ import unicode_literals

View File

@ -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.')),

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.5 on 2017-02-04 06:11
from __future__ import unicode_literals

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.5 on 2017-02-04 07:17
from __future__ import unicode_literals

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.5 on 2017-09-28 02:16
from __future__ import unicode_literals

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.10 on 2018-02-23 23:09
from __future__ import unicode_literals

View File

@ -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.")

View File

@ -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)

View File

@ -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:

View File

@ -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, [])

View File

@ -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)

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.1 on 2016-09-05 21:39
from __future__ import unicode_literals

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.4 on 2017-08-23 19:46
from __future__ import unicode_literals

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10 on 2017-10-20 13:51
from __future__ import unicode_literals

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.5 on 2017-03-22 23:35
from __future__ import unicode_literals

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.5 on 2017-03-27 03:29
from __future__ import unicode_literals

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.2 on 2017-06-08 02:54
from __future__ import unicode_literals

View File

@ -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">&times;</span><span
class="sr-only">{% trans "Close" %}</span></button>
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</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/>

View File

@ -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">&times;</span><span
class="sr-only">{% trans "Close" %}</span></button>
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</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/>

View File

@ -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">

View File

@ -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))

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.1 on 2016-09-05 21:40
from __future__ import unicode_literals

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.1 on 2016-09-10 16:49
from __future__ import unicode_literals

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.5 on 2017-03-22 23:35
from __future__ import unicode_literals

View File

@ -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>

View File

@ -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'):

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.1 on 2016-09-05 21:40
from __future__ import unicode_literals

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11 on 2017-04-13 04:42
from __future__ import unicode_literals

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.5 on 2017-03-22 23:35
from __future__ import unicode_literals

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.5 on 2017-09-28 02:16
from __future__ import unicode_literals

View File

@ -2,7 +2,7 @@
{% load evelinks %}
{% block content %}
<div class="table-responsive">
<div class="table-responsive">
<table class="table">
<thead>
<tr>

View File

@ -4,4 +4,3 @@ from django.apps import AppConfig
class PermissionsToolConfig(AppConfig):
name = 'allianceauth.permissions_tool'
label = 'permissions_tool'

View File

@ -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'):

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.5 on 2017-02-06 08:58
from __future__ import unicode_literals

View File

@ -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)

View File

@ -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

View File

@ -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