From 650408f61cfe31fc1a01b1503e1d82a452d3d5ed Mon Sep 17 00:00:00 2001 From: Basraah Date: Tue, 26 Sep 2017 15:13:37 +1000 Subject: [PATCH 1/6] Unit test tweaks --- allianceauth/permissions_tool/tests.py | 28 +++++++++---------- .../services/modules/discord/tests.py | 4 +-- .../services/modules/discourse/tests.py | 4 +-- allianceauth/services/modules/ips4/tests.py | 3 +- allianceauth/services/modules/market/tests.py | 3 +- allianceauth/services/modules/mumble/tests.py | 3 +- .../services/modules/openfire/tests.py | 3 +- allianceauth/services/modules/phpbb3/tests.py | 3 +- allianceauth/services/modules/seat/tests.py | 3 +- allianceauth/services/modules/smf/tests.py | 3 +- .../services/modules/teamspeak3/tests.py | 3 +- .../services/modules/xenforo/tests.py | 3 +- allianceauth/tests/auth_utils.py | 3 +- test_allianceauth/settings.py | 2 +- 14 files changed, 27 insertions(+), 41 deletions(-) diff --git a/allianceauth/permissions_tool/tests.py b/allianceauth/permissions_tool/tests.py index b432fa29..42b35ddf 100644 --- a/allianceauth/permissions_tool/tests.py +++ b/allianceauth/permissions_tool/tests.py @@ -10,7 +10,6 @@ from allianceauth.tests.auth_utils import AuthUtils class PermissionsToolViewsTestCase(TestCase): def setUp(self): self.member = AuthUtils.create_member('auth_member') - self.member.set_password('password') self.member.email = 'auth_member@example.com' self.member.save() self.none_user = AuthUtils.create_user('none_user', disconnect_signals=True) @@ -18,7 +17,6 @@ class PermissionsToolViewsTestCase(TestCase): self.none_user3 = AuthUtils.create_user('none_user3', disconnect_signals=True) self.no_perm_user = AuthUtils.create_user('no_perm_user', disconnect_signals=True) - self.no_perm_user.set_password('password') AuthUtils.disconnect_signals() self.no_perm_group = Group.objects.create(name="No Permission Group") @@ -38,17 +36,16 @@ class PermissionsToolViewsTestCase(TestCase): AuthUtils.connect_signals() def test_menu_item(self): - self.client.login(username=self.member.username, password='password') + self.client.force_login(self.member) response = self.client.get(urls.reverse('permissions_tool:overview')) - response_content = str(response.content, encoding='utf8') + response_content = response.content.decode('utf-8') - self.assertInHTML( - '
  • Permissions Audit
  • ', - response_content) + self.assertInHTML('
  • ' + ' Permissions Audit
  • ', response_content) def test_permissions_overview(self): - self.client.login(username=self.member.username, password='password') + self.client.force_login(self.member) response = self.client.get(urls.reverse('permissions_tool:overview')) @@ -63,22 +60,25 @@ class PermissionsToolViewsTestCase(TestCase): for perm in response.context['permissions']: if perm['permission'] == self.permission: tested_context = True - self.assertDictContainsSubset({'users': 1}, perm) - self.assertDictContainsSubset({'groups': 1}, perm) - self.assertDictContainsSubset({'group_users': 3}, perm) + self.assertIn('users', perm) + self.assertEqual(perm['users'], 1) + self.assertIn('groups', perm) + self.assertEqual(perm['groups'], 1) + self.assertIn('group_users', perm) + self.assertEqual(perm['group_users'], 3) break self.assertTrue(tested_context) def test_permissions_overview_perms(self): # Ensure permission effectively denys access - self.client.login(username=self.no_perm_user.username, password='password') + self.client.force_login(self.no_perm_user) response = self.client.get(urls.reverse('permissions_tool:overview')) self.assertEqual(response.status_code, 302) def test_permissions_audit(self): - self.client.login(username=self.member.username, password='password') + self.client.force_login(self.member) response = self.client.get(urls.reverse('permissions_tool:audit', kwargs={ @@ -99,7 +99,7 @@ class PermissionsToolViewsTestCase(TestCase): def test_permissions_audit_perms(self): # Ensure permission effectively denys access - self.client.login(username=self.no_perm_user.username, password='password') + self.client.force_login(self.no_perm_user) response = self.client.get(urls.reverse('permissions_tool:audit', kwargs={ diff --git a/allianceauth/services/modules/discord/tests.py b/allianceauth/services/modules/discord/tests.py index db255028..e52044fc 100644 --- a/allianceauth/services/modules/discord/tests.py +++ b/allianceauth/services/modules/discord/tests.py @@ -141,12 +141,10 @@ class DiscordHooksTestCase(TestCase): class DiscordViewsTestCase(TestCase): def setUp(self): self.member = AuthUtils.create_member('auth_member') - self.member.set_password('password') - self.member.save() add_permissions() def login(self): - self.client.login(username=self.member.username, password='password') + self.client.force_login(self.member) @mock.patch(MODULE_PATH + '.views.DiscordOAuthManager') def test_activate(self, manager): diff --git a/allianceauth/services/modules/discourse/tests.py b/allianceauth/services/modules/discourse/tests.py index 189a0c55..38eda84f 100644 --- a/allianceauth/services/modules/discourse/tests.py +++ b/allianceauth/services/modules/discourse/tests.py @@ -113,14 +113,12 @@ class DiscourseHooksTestCase(TestCase): class DiscourseViewsTestCase(TestCase): def setUp(self): self.member = AuthUtils.create_member('auth_member') - self.member.set_password('password') - self.member.save() AuthUtils.add_main_character(self.member, 'auth_member', '12345', corp_id='111', corp_name='Test Corporation') add_permissions() @mock.patch(MODULE_PATH + '.tasks.DiscourseManager') def test_sso_member(self, manager): - self.client.login(username=self.member.username, password='password') + self.client.force_login(self.member) data = {'sso': 'bm9uY2U9Y2I2ODI1MWVlZmI1MjExZTU4YzAwZmYxMzk1ZjBjMGI%3D%0A', 'sig': '2828aa29899722b35a2f191d34ef9b3ce695e0e6eeec47deb46d588d70c7cb56'} response = self.client.get('/discourse/sso', data=data, follow=False) diff --git a/allianceauth/services/modules/ips4/tests.py b/allianceauth/services/modules/ips4/tests.py index 613c95d5..e568f0bd 100644 --- a/allianceauth/services/modules/ips4/tests.py +++ b/allianceauth/services/modules/ips4/tests.py @@ -68,14 +68,13 @@ class Ips4HooksTestCase(TestCase): class Ips4ViewsTestCase(TestCase): def setUp(self): self.member = AuthUtils.create_member('auth_member') - self.member.set_password('password') self.member.email = 'auth_member@example.com' self.member.save() AuthUtils.add_main_character(self.member, 'auth_member', '12345', corp_id='111', corp_name='Test Corporation') add_permissions() def login(self): - self.client.login(username=self.member.username, password='password') + self.client.force_login(self.member) @mock.patch(MODULE_PATH + '.views.Ips4Manager') def test_activate(self, manager): diff --git a/allianceauth/services/modules/market/tests.py b/allianceauth/services/modules/market/tests.py index fa463925..71674fe9 100644 --- a/allianceauth/services/modules/market/tests.py +++ b/allianceauth/services/modules/market/tests.py @@ -96,14 +96,13 @@ class MarketHooksTestCase(TestCase): class MarketViewsTestCase(TestCase): def setUp(self): self.member = AuthUtils.create_member('auth_member') - self.member.set_password('password') self.member.email = 'auth_member@example.com' self.member.save() AuthUtils.add_main_character(self.member, 'auth_member', '12345', corp_id='111', corp_name='Test Corporation') add_permissions() def login(self): - self.client.login(username=self.member.username, password='password') + self.client.force_login(self.member) @mock.patch(MODULE_PATH + '.views.MarketManager') def test_activate(self, manager): diff --git a/allianceauth/services/modules/mumble/tests.py b/allianceauth/services/modules/mumble/tests.py index 4cd16cc0..84308d8b 100644 --- a/allianceauth/services/modules/mumble/tests.py +++ b/allianceauth/services/modules/mumble/tests.py @@ -119,7 +119,6 @@ class MumbleHooksTestCase(TestCase): class MumbleViewsTestCase(TestCase): def setUp(self): self.member = AuthUtils.create_member('auth_member') - self.member.set_password('password') self.member.email = 'auth_member@example.com' self.member.save() AuthUtils.add_main_character(self.member, 'auth_member', '12345', corp_id='111', corp_name='Test Corporation', @@ -127,7 +126,7 @@ class MumbleViewsTestCase(TestCase): add_permissions() def login(self): - self.client.login(username=self.member.username, password='password') + self.client.force_login(self.member) def test_activate(self): self.login() diff --git a/allianceauth/services/modules/openfire/tests.py b/allianceauth/services/modules/openfire/tests.py index 503c948c..a2c50a85 100644 --- a/allianceauth/services/modules/openfire/tests.py +++ b/allianceauth/services/modules/openfire/tests.py @@ -123,14 +123,13 @@ class OpenfireHooksTestCase(TestCase): class OpenfireViewsTestCase(TestCase): def setUp(self): self.member = AuthUtils.create_member('auth_member') - self.member.set_password('password') self.member.email = 'auth_member@example.com' self.member.save() AuthUtils.add_main_character(self.member, 'auth_member', '12345', corp_id='111', corp_name='Test Corporation') add_permissions() def login(self): - self.client.login(username=self.member.username, password='password') + self.client.force_login(self.member) @mock.patch(MODULE_PATH + '.tasks.OpenfireManager') @mock.patch(MODULE_PATH + '.views.OpenfireManager') diff --git a/allianceauth/services/modules/phpbb3/tests.py b/allianceauth/services/modules/phpbb3/tests.py index 42feb087..cd5de997 100644 --- a/allianceauth/services/modules/phpbb3/tests.py +++ b/allianceauth/services/modules/phpbb3/tests.py @@ -123,14 +123,13 @@ class Phpbb3HooksTestCase(TestCase): class Phpbb3ViewsTestCase(TestCase): def setUp(self): self.member = AuthUtils.create_member('auth_member') - self.member.set_password('password') self.member.email = 'auth_member@example.com' self.member.save() AuthUtils.add_main_character(self.member, 'auth_member', '12345', corp_id='111', corp_name='Test Corporation') add_permissions() def login(self): - self.client.login(username=self.member.username, password='password') + self.client.force_login(self.member) @mock.patch(MODULE_PATH + '.tasks.Phpbb3Manager') @mock.patch(MODULE_PATH + '.views.Phpbb3Manager') diff --git a/allianceauth/services/modules/seat/tests.py b/allianceauth/services/modules/seat/tests.py index 54a2db0b..ebd13049 100644 --- a/allianceauth/services/modules/seat/tests.py +++ b/allianceauth/services/modules/seat/tests.py @@ -127,14 +127,13 @@ class SeatHooksTestCase(TestCase): class SeatViewsTestCase(TestCase): def setUp(self): self.member = AuthUtils.create_member('auth_member') - self.member.set_password('password') self.member.email = 'auth_member@example.com' self.member.save() AuthUtils.add_main_character(self.member, 'auth_member', '12345', corp_id='111', corp_name='Test Corporation') add_permissions() def login(self): - self.client.login(username=self.member.username, password='password') + self.client.force_login(self.member) @mock.patch(MODULE_PATH + '.tasks.SeatManager') @mock.patch(MODULE_PATH + '.views.SeatManager') diff --git a/allianceauth/services/modules/smf/tests.py b/allianceauth/services/modules/smf/tests.py index c185c407..ed58e818 100644 --- a/allianceauth/services/modules/smf/tests.py +++ b/allianceauth/services/modules/smf/tests.py @@ -123,14 +123,13 @@ class SmfHooksTestCase(TestCase): class SmfViewsTestCase(TestCase): def setUp(self): self.member = AuthUtils.create_member('auth_member') - self.member.set_password('password') self.member.email = 'auth_member@example.com' self.member.save() AuthUtils.add_main_character(self.member, 'auth_member', '12345', corp_id='111', corp_name='Test Corporation') add_permissions() def login(self): - self.client.login(username=self.member.username, password='password') + self.client.force_login(self.member) @mock.patch(MODULE_PATH + '.tasks.SmfManager') @mock.patch(MODULE_PATH + '.views.SmfManager') diff --git a/allianceauth/services/modules/teamspeak3/tests.py b/allianceauth/services/modules/teamspeak3/tests.py index f17b5774..62ac4d88 100644 --- a/allianceauth/services/modules/teamspeak3/tests.py +++ b/allianceauth/services/modules/teamspeak3/tests.py @@ -136,7 +136,6 @@ class Teamspeak3ViewsTestCase(TestCase): # Inert signals before setup begins with mock.patch(MODULE_PATH + '.signals.trigger_all_ts_update') as trigger_all_ts_update: self.member = AuthUtils.create_member('auth_member') - self.member.set_password('password') self.member.email = 'auth_member@example.com' self.member.save() AuthUtils.add_main_character(self.member, 'auth_member', '12345', corp_id='111', corp_name='Test Corporation') @@ -150,7 +149,7 @@ class Teamspeak3ViewsTestCase(TestCase): def login(self, user=None, password=None): if user is None: user = self.member - self.client.login(username=user.username, password=password if password else 'password') + self.client.force_login(user) @mock.patch(MODULE_PATH + '.forms.Teamspeak3Manager') @mock.patch(MODULE_PATH + '.views.Teamspeak3Manager') diff --git a/allianceauth/services/modules/xenforo/tests.py b/allianceauth/services/modules/xenforo/tests.py index 333e10b9..f0814359 100644 --- a/allianceauth/services/modules/xenforo/tests.py +++ b/allianceauth/services/modules/xenforo/tests.py @@ -99,14 +99,13 @@ class XenforoHooksTestCase(TestCase): class XenforoViewsTestCase(TestCase): def setUp(self): self.member = AuthUtils.create_member('auth_member') - self.member.set_password('password') self.member.email = 'auth_member@example.com' self.member.save() AuthUtils.add_main_character(self.member, 'auth_member', '12345', corp_id='111', corp_name='Test Corporation') add_permissions() def login(self): - self.client.login(username=self.member.username, password='password') + self.client.force_login(self.member) @mock.patch(MODULE_PATH + '.tasks.XenForoManager') @mock.patch(MODULE_PATH + '.views.XenForoManager') diff --git a/allianceauth/tests/auth_utils.py b/allianceauth/tests/auth_utils.py index 5ae1d6a9..cc27676a 100644 --- a/allianceauth/tests/auth_utils.py +++ b/allianceauth/tests/auth_utils.py @@ -142,7 +142,6 @@ class AuthUtils: class BaseViewTestCase(TestCase): def setUp(self): self.member = AuthUtils.create_member('auth_member') - self.member.set_password('password') self.member.email = 'auth_member@example.com' self.member.save() AuthUtils.add_main_character(self.member, 'auth_member', '12345', corp_id='111', corp_name='Test Corporation', @@ -150,4 +149,4 @@ class BaseViewTestCase(TestCase): def login(self): token = Token.objects.create(character_id='12345', character_name='auth_member', character_owner_hash='1', user=self.member, access_token='1') - self.client.login(token=token) \ No newline at end of file + self.client.login(token=token) diff --git a/test_allianceauth/settings.py b/test_allianceauth/settings.py index 01b29444..a542b06e 100644 --- a/test_allianceauth/settings.py +++ b/test_allianceauth/settings.py @@ -362,7 +362,7 @@ FLEETUP_API_ID = os.environ.get('AA_FLEETUP_API_ID', '') FLEETUP_GROUP_ID = os.environ.get('AA_FLEETUP_GROUP_ID', '') PASSWORD_HASHERS = [ - 'django.contrib.auth.hashers.MD5PasswordHasher', + 'django.contrib.auth.hashers.UnsaltedMD5PasswordHasher', ] From d993a299ef6c89dcffcc37484890ca81763fdfb9 Mon Sep 17 00:00:00 2001 From: Basraah Date: Sun, 24 Sep 2017 16:07:39 +1000 Subject: [PATCH 2/6] Add pseudo foreign keys to EveCharacter model --- allianceauth/eveonline/models.py | 77 ++++++++----- allianceauth/eveonline/tests/test_models.py | 121 ++++++++++++++++++++ 2 files changed, 170 insertions(+), 28 deletions(-) create mode 100644 allianceauth/eveonline/tests/test_models.py diff --git a/allianceauth/eveonline/models.py b/allianceauth/eveonline/models.py index 43b48500..872c33f1 100644 --- a/allianceauth/eveonline/models.py +++ b/allianceauth/eveonline/models.py @@ -1,4 +1,5 @@ from django.db import models +from typing import Union from .managers import EveCharacterManager, EveCharacterProviderManager from .managers import EveCorporationManager, EveCorporationProviderManager @@ -6,34 +7,6 @@ from .managers import EveAllianceManager, EveAllianceProviderManager from . import providers -class EveCharacter(models.Model): - character_id = models.CharField(max_length=254, unique=True) - character_name = models.CharField(max_length=254, unique=True) - corporation_id = models.CharField(max_length=254) - corporation_name = models.CharField(max_length=254) - corporation_ticker = models.CharField(max_length=254) - alliance_id = models.CharField(max_length=254, blank=True, null=True, default='') - alliance_name = models.CharField(max_length=254, blank=True, null=True, default='') - - objects = EveCharacterManager() - provider = EveCharacterProviderManager() - - def update_character(self, character: providers.Character = None): - if character is None: - character = self.provider.get_character(self.character_id) - self.character_name = character.name - self.corporation_id = character.corp.id - self.corporation_name = character.corp.name - self.corporation_ticker = character.corp.ticker - self.alliance_id = character.alliance.id - self.alliance_name = character.alliance.name - self.save() - return self - - def __str__(self): - return self.character_name - - class EveAllianceInfo(models.Model): alliance_id = models.CharField(max_length=254, unique=True) alliance_name = models.CharField(max_length=254, unique=True) @@ -86,3 +59,51 @@ class EveCorporationInfo(models.Model): def __str__(self): return self.corporation_name + + +class EveCharacter(models.Model): + character_id = models.CharField(max_length=254, unique=True) + character_name = models.CharField(max_length=254, unique=True) + corporation_id = models.CharField(max_length=254) + corporation_name = models.CharField(max_length=254) + corporation_ticker = models.CharField(max_length=254) + alliance_id = models.CharField(max_length=254, blank=True, null=True, default='') + alliance_name = models.CharField(max_length=254, blank=True, null=True, default='') + + objects = EveCharacterManager() + provider = EveCharacterProviderManager() + + @property + def alliance(self) -> Union[EveAllianceInfo, None]: + """ + Pseudo foreign key from alliance_id to EveAllianceInfo + :raises: EveAllianceInfo.DoesNotExist + :return: EveAllianceInfo or None + """ + if self.alliance_id is None: + return None + return EveAllianceInfo.objects.get(alliance_id=self.alliance_id) + + @property + def corporation(self) -> EveCorporationInfo: + """ + Pseudo foreign key from corporation_id to EveCorporationInfo + :raises: EveCorporationInfo.DoesNotExist + :return: EveCorporationInfo + """ + return EveCorporationInfo.objects.get(corporation_id=self.corporation_id) + + def update_character(self, character: providers.Character = None): + if character is None: + character = self.provider.get_character(self.character_id) + self.character_name = character.name + self.corporation_id = character.corp.id + self.corporation_name = character.corp.name + self.corporation_ticker = character.corp.ticker + self.alliance_id = character.alliance.id + self.alliance_name = character.alliance.name + self.save() + return self + + def __str__(self): + return self.character_name diff --git a/allianceauth/eveonline/tests/test_models.py b/allianceauth/eveonline/tests/test_models.py new file mode 100644 index 00000000..3471a588 --- /dev/null +++ b/allianceauth/eveonline/tests/test_models.py @@ -0,0 +1,121 @@ +from django.test import TestCase + +from ..models import EveCharacter, EveCorporationInfo, EveAllianceInfo + + +class EveCharacterTestCase(TestCase): + def test_corporation_prop(self): + """ + Test that the correct corporation is returned by the corporation property + """ + character = EveCharacter.objects.create( + character_id='1234', + character_name='character.name', + corporation_id='2345', + corporation_name='character.corp.name', + corporation_ticker='character.corp.ticker', + alliance_id='character.alliance.id', + alliance_name='character.alliance.name', + ) + + expected = EveCorporationInfo.objects.create( + corporation_id='2345', + corporation_name='corp.name', + corporation_ticker='corp.ticker', + member_count=10, + alliance=None, + ) + + incorrect = EveCorporationInfo.objects.create( + corporation_id='9999', + corporation_name='corp.name1', + corporation_ticker='corp.ticker1', + member_count=10, + alliance=None, + ) + + self.assertEqual(character.corporation, expected) + self.assertNotEqual(character.corporation, incorrect) + + def test_corporation_prop_exception(self): + """ + Check that an exception is raised when the expected + object is not in the database + """ + character = EveCharacter.objects.create( + character_id='1234', + character_name='character.name', + corporation_id='2345', + corporation_name='character.corp.name', + corporation_ticker='character.corp.ticker', + alliance_id='character.alliance.id', + alliance_name='character.alliance.name', + ) + + with self.assertRaises(EveCorporationInfo.DoesNotExist): + result = character.corporation + + def test_alliance_prop(self): + """ + Test that the correct alliance is returned by the alliance property + """ + character = EveCharacter.objects.create( + character_id='1234', + character_name='character.name', + corporation_id='2345', + corporation_name='character.corp.name', + corporation_ticker='character.corp.ticker', + alliance_id='3456', + alliance_name='character.alliance.name', + ) + + expected = EveAllianceInfo.objects.create( + alliance_id='3456', + alliance_name='alliance.name', + alliance_ticker='alliance.ticker', + executor_corp_id='alliance.executor_corp_id', + ) + + incorrect = EveAllianceInfo.objects.create( + alliance_id='9001', + alliance_name='alliance.name1', + alliance_ticker='alliance.ticker1', + executor_corp_id='alliance.executor_corp_id1', + ) + + self.assertEqual(character.alliance, expected) + self.assertNotEqual(character.alliance, incorrect) + + def test_alliance_prop_exception(self): + """ + Check that an exception is raised when the expected + object is not in the database + """ + character = EveCharacter.objects.create( + character_id='1234', + character_name='character.name', + corporation_id='2345', + corporation_name='character.corp.name', + corporation_ticker='character.corp.ticker', + alliance_id='3456', + alliance_name='character.alliance.name', + ) + + with self.assertRaises(EveAllianceInfo.DoesNotExist): + result = character.alliance + + def test_alliance_prop_none(self): + """ + Check that None is returned when the character has no alliance + """ + character = EveCharacter.objects.create( + character_id='1234', + character_name='character.name', + corporation_id='2345', + corporation_name='character.corp.name', + corporation_ticker='character.corp.ticker', + alliance_id=None, + alliance_name=None, + ) + + self.assertIsNone(character.alliance) From fff2cd32d5bf57939de4951f2aa1d229cf3f24ce Mon Sep 17 00:00:00 2001 From: Basraah Date: Wed, 27 Sep 2017 19:12:07 +1000 Subject: [PATCH 3/6] Update timerboard views Adds basic unit tests Changed to class based views --- allianceauth/timerboard/form.py | 54 +++- allianceauth/timerboard/models.py | 2 +- .../timerboard/templates/timerboard/add.html | 29 --- .../timerboard/templates/timerboard/form.html | 33 +++ .../templates/timerboard/index_button.html | 4 + .../timerboard/timer_confirm_delete.html | 26 ++ .../timerboard/timer_create_form.html | 14 ++ .../timerboard/timer_update_form.html | 14 ++ .../templates/timerboard/update.html | 35 --- .../timerboard/{management.html => view.html} | 8 +- allianceauth/timerboard/tests.py | 232 +++++++++++++++++- allianceauth/timerboard/urls.py | 10 +- allianceauth/timerboard/views.py | 199 +++++---------- setup.py | 1 + 14 files changed, 453 insertions(+), 208 deletions(-) delete mode 100644 allianceauth/timerboard/templates/timerboard/add.html create mode 100644 allianceauth/timerboard/templates/timerboard/form.html create mode 100644 allianceauth/timerboard/templates/timerboard/index_button.html create mode 100644 allianceauth/timerboard/templates/timerboard/timer_confirm_delete.html create mode 100644 allianceauth/timerboard/templates/timerboard/timer_create_form.html create mode 100644 allianceauth/timerboard/templates/timerboard/timer_update_form.html delete mode 100644 allianceauth/timerboard/templates/timerboard/update.html rename allianceauth/timerboard/templates/timerboard/{management.html => view.html} (98%) mode change 100755 => 100644 allianceauth/timerboard/tests.py diff --git a/allianceauth/timerboard/form.py b/allianceauth/timerboard/form.py index 261c11cf..44e4886f 100755 --- a/allianceauth/timerboard/form.py +++ b/allianceauth/timerboard/form.py @@ -1,9 +1,37 @@ +import logging +import datetime from django import forms +from django.utils import timezone from django.core.validators import MaxValueValidator, MinValueValidator from django.utils.translation import ugettext_lazy as _ +from .models import Timer + +logger = logging.getLogger(__name__) + + +class TimerForm(forms.ModelForm): + class Meta: + model = Timer + fields = ('details', 'system', 'planet_moon', 'structure', 'objective', 'important', 'corp_timer') + + def __init__(self, *args, **kwargs): + self.user = kwargs.pop('user', None) + if 'instance' in kwargs and kwargs['instance'] is not None: + # Do conversion from db datetime to days/hours/minutes + # for appropriate fields + current_time = timezone.now() + td = kwargs['instance'].eve_time - current_time + initial = kwargs.pop('initial', dict()) + if 'days_left' not in initial: + initial.update({'days_left': td.days}) + if 'hours_left' not in initial: + initial.update({'hours_left': td.seconds // 3600}) + if 'minutes_left' not in initial: + initial.update({'minutes_left': td.seconds // 60 % 60}) + kwargs.update({'initial': initial}) + super(TimerForm, self).__init__(*args, **kwargs) -class TimerForm(forms.Form): structure_choices = [('POCO', 'POCO'), ('I-HUB', 'I-HUB'), ('POS[S]', 'POS[S]'), ('POS[M]', 'POS[M]'), ('POS[L]', 'POS[L]'), ('Citadel[M]', 'Citadel[M]'), ('Citadel[L]', 'Citadel[L]'), ('Citadel[XL]', 'Citadel[XL]'), @@ -25,3 +53,27 @@ class TimerForm(forms.Form): validators=[MinValueValidator(0), MaxValueValidator(59)]) important = forms.BooleanField(label=_("Important"), required=False) corp_timer = forms.BooleanField(label=_("Corp-Restricted"), required=False) + + def save(self, commit=True): + timer = super(TimerForm, self).save(commit=False) + + # Get character + character = self.user.profile.main_character + corporation = character.corporation + logger.debug("Determined timer save request on behalf " + "of character {} corporation {}".format(character, corporation)) + # calculate future time + future_time = datetime.timedelta(days=self.cleaned_data['days_left'], hours=self.cleaned_data['hours_left'], + minutes=self.cleaned_data['minutes_left']) + current_time = timezone.now() + eve_time = current_time + future_time + logger.debug( + "Determined timer eve time is %s - current time %s, adding %s" % (eve_time, current_time, future_time)) + + timer.eve_time = eve_time + timer.eve_character = character + timer.eve_corp = corporation + timer.user = self.user + if commit: + timer.save() + return timer diff --git a/allianceauth/timerboard/models.py b/allianceauth/timerboard/models.py index d1a10c0f..708e7dc6 100755 --- a/allianceauth/timerboard/models.py +++ b/allianceauth/timerboard/models.py @@ -22,4 +22,4 @@ class Timer(models.Model): user = models.ForeignKey(User) def __str__(self): - return str(self.system) + ' ' + str(self.objective) + return str(self.system) + ' ' + str(self.details) diff --git a/allianceauth/timerboard/templates/timerboard/add.html b/allianceauth/timerboard/templates/timerboard/add.html deleted file mode 100644 index b0ce16ad..00000000 --- a/allianceauth/timerboard/templates/timerboard/add.html +++ /dev/null @@ -1,29 +0,0 @@ -{% extends "allianceauth/base.html" %} -{% load bootstrap %} -{% load staticfiles %} -{% load i18n %} -{% get_current_language as LANGUAGE_CODE %} - -{% block title %}{% trans "Alliance Auth - Structure Timer Create" %}{% endblock %} - -{% block page_title %}{% trans "Timer Create" %}{% endblock page_title %} - -{% block content %} -
    -

    {% trans "Create Structure Timer" %}

    - -
    -
    -
    - -
    -
    -
    -
    - -{% endblock content %} diff --git a/allianceauth/timerboard/templates/timerboard/form.html b/allianceauth/timerboard/templates/timerboard/form.html new file mode 100644 index 00000000..827c06ef --- /dev/null +++ b/allianceauth/timerboard/templates/timerboard/form.html @@ -0,0 +1,33 @@ +{% extends "allianceauth/base.html" %} +{% load bootstrap %} +{% load staticfiles %} +{% load i18n %} + +{% block page_title %} +{% endblock page_title %} + +{% block content %} +
    +

    + {% block page_header %} + {% endblock %} + {% include 'timerboard/index_button.html' %} +

    +
    +
    +
    + +
    +
    +
    +
    + +{% endblock content %} diff --git a/allianceauth/timerboard/templates/timerboard/index_button.html b/allianceauth/timerboard/templates/timerboard/index_button.html new file mode 100644 index 00000000..cf7e20bf --- /dev/null +++ b/allianceauth/timerboard/templates/timerboard/index_button.html @@ -0,0 +1,4 @@ +{% load i18n %} +
    + Back +
    diff --git a/allianceauth/timerboard/templates/timerboard/timer_confirm_delete.html b/allianceauth/timerboard/templates/timerboard/timer_confirm_delete.html new file mode 100644 index 00000000..63265ba8 --- /dev/null +++ b/allianceauth/timerboard/templates/timerboard/timer_confirm_delete.html @@ -0,0 +1,26 @@ +{% extends "allianceauth/base.html" %} +{% load i18n %} + +{% block page_title %} + Delete Timer +{% endblock page_title %} + +{% block content %} +
    +

    + {% trans "Delete Timer" %} + {% include 'timerboard/index_button.html' %} +

    +
    +
    +
    +
    + {% csrf_token %} +

    {% blocktrans %}Are you sure you want to delete timer "{{ object }}"?{% endblocktrans %}

    + +
    +
    +
    +
    +
    +{% endblock content %} diff --git a/allianceauth/timerboard/templates/timerboard/timer_create_form.html b/allianceauth/timerboard/templates/timerboard/timer_create_form.html new file mode 100644 index 00000000..750fab08 --- /dev/null +++ b/allianceauth/timerboard/templates/timerboard/timer_create_form.html @@ -0,0 +1,14 @@ +{% extends "timerboard/form.html" %} +{% load i18n %} + +{% block page_title %} + {% trans "Create Timer" %} +{% endblock page_title %} + +{% block page_header %} + {% trans "Create Structure Timer" %} +{% endblock %} + +{% block submit_button_text %} + {% trans "Create Timer" %} +{% endblock %} diff --git a/allianceauth/timerboard/templates/timerboard/timer_update_form.html b/allianceauth/timerboard/templates/timerboard/timer_update_form.html new file mode 100644 index 00000000..e54bcd7f --- /dev/null +++ b/allianceauth/timerboard/templates/timerboard/timer_update_form.html @@ -0,0 +1,14 @@ +{% extends "timerboard/form.html" %} +{% load i18n %} + +{% block page_title %} + {% trans "Update Structure Timer" %} +{% endblock page_title %} + +{% block page_header %} + {% trans "Update Structure Timer" %} +{% endblock %} + +{% block submit_button_text %} + {% trans "Update Structure Timer" %} +{% endblock %} diff --git a/allianceauth/timerboard/templates/timerboard/update.html b/allianceauth/timerboard/templates/timerboard/update.html deleted file mode 100644 index 1b4482c2..00000000 --- a/allianceauth/timerboard/templates/timerboard/update.html +++ /dev/null @@ -1,35 +0,0 @@ -{% extends "allianceauth/base.html" %} -{% load bootstrap %} -{% load staticfiles %} -{% load i18n %} - -{% block title %}Alliance Auth - Update Structure Timer {% endblock %} - -{% block page_title %}{% trans "Update AAR Link" %}{% endblock page_title %} - -{% block content %} - -
    -

    {% trans "Update Structure Timer" %}

    - -
    -
    -
    - {% if no_fleet_id %} - - {% else %} - - {% endif %} -
    -
    -
    - -
    - -{% endblock content %} diff --git a/allianceauth/timerboard/templates/timerboard/management.html b/allianceauth/timerboard/templates/timerboard/view.html similarity index 98% rename from allianceauth/timerboard/templates/timerboard/management.html rename to allianceauth/timerboard/templates/timerboard/view.html index a63cb810..b5ae816d 100644 --- a/allianceauth/timerboard/templates/timerboard/management.html +++ b/allianceauth/timerboard/templates/timerboard/view.html @@ -3,8 +3,6 @@ {% load i18n %} {% get_current_language as LANGUAGE_CODE %} -{% block title %}Alliance Auth{% endblock %} - {% block page_title %}{% trans "Structure Timer Management" %}{% endblock page_title %} {% block extra_css %}{% endblock extra_css %} @@ -145,7 +143,7 @@ {{ timer.eve_character.character_name }} {% if perms.auth.timer_management %} - + @@ -279,7 +277,7 @@ {{ timer.eve_character.character_name }} {% if perms.auth.timer_management %} - + @@ -415,7 +413,7 @@ {{ timer.eve_character.character_name }} {% if perms.auth.timer_management %} - + diff --git a/allianceauth/timerboard/tests.py b/allianceauth/timerboard/tests.py old mode 100755 new mode 100644 index a39b155a..11e3c90d --- a/allianceauth/timerboard/tests.py +++ b/allianceauth/timerboard/tests.py @@ -1 +1,231 @@ -# Create your tests here. +from django_webtest import WebTest +from django.utils import timezone +from django.core.urlresolvers import reverse +from django.contrib.auth.models import Permission, User +from django.conf import settings + +from datetime import timedelta + +from allianceauth.tests.auth_utils import AuthUtils +from allianceauth.eveonline.models import EveCorporationInfo + +from .models import Timer +from .form import TimerForm + + +class TimerboardViewsTestCase(WebTest): + csrf_checks = False + + def setUp(self): + corp = EveCorporationInfo.objects.create(corporation_id='2345', corporation_name='test corp', + corporation_ticker='testc', member_count=24) + other_corp = EveCorporationInfo.objects.create(corporation_id='9345', corporation_name='other test corp', + corporation_ticker='testd', member_count=1) + self.user = AuthUtils.create_user('test_user') + AuthUtils.add_main_character(self.user, 'test character', '1234', '2345', 'test corp', 'testc') + self.user = User.objects.get_by_natural_key('test_user') + character = self.user.profile.main_character + self.other_user = AuthUtils.create_user('other_test_user') + AuthUtils.add_main_character(self.other_user, 'test character 2', '9234', '9345', 'other test corp', 'testd') + self.other_user = User.objects.get_by_natural_key('other_test_user') + other_character = self.other_user.profile.main_character + + self.timer = Timer.objects.create( + details='details', + system='system', + planet_moon='planet_moon', + structure='structure', + objective='objective', + eve_time=timezone.now() + timedelta(days=30), + important=True, + corp_timer=False, + eve_character=character, + eve_corp=character.corporation, + user=self.user, + ) + self.corp_timer = Timer.objects.create( + details='details', + system='system', + planet_moon='planet_moon', + structure='structure', + objective='objective', + eve_time=timezone.now() + timedelta(days=30), + important=False, + corp_timer=True, + eve_character=character, + eve_corp=character.corporation, + user=self.user, + ) + self.other_corp_timer = Timer.objects.create( + details='details', + system='system', + planet_moon='planet_moon', + structure='structure', + objective='objective', + eve_time=timezone.now() + timedelta(days=30), + important=False, + corp_timer=True, + eve_character=other_character, + eve_corp=other_character.corporation, + user=self.user, + ) + self.expired_timer = Timer.objects.create( + details='details', + system='system', + planet_moon='planet_moon', + structure='structure', + objective='objective', + eve_time=timezone.now() - timedelta(days=30), + important=True, + corp_timer=False, + eve_character=character, + eve_corp=character.corporation, + user=self.user, + ) + + self.view_permission = Permission.objects.get(codename='timer_view') + self.edit_permission = Permission.objects.get(codename='timer_management') + + self.view_url = reverse('timerboard:view') + self.add_url = reverse('timerboard:add') + self.edit_url_name = 'timerboard:edit' + self.delete_url_name = 'timerboard:delete' + + def test_timer_view(self): + self.user.user_permissions.add(self.view_permission) + + self.app.set_user(self.user) + + response = self.app.get(self.view_url) + + context = response.context[-1] + + timers = context['timers'] + corp_timers = context['corp_timers'] + future_timers = context['future_timers'] + past_timers = context['past_timers'] + + self.assertTemplateUsed(response, 'timerboard/view.html') + + self.assertIn(self.timer, timers) + self.assertIn(self.expired_timer, timers) + self.assertNotIn(self.corp_timer, timers) + self.assertNotIn(self.other_corp_timer, timers) + + self.assertNotIn(self.timer, corp_timers) + self.assertNotIn(self.expired_timer, corp_timers) + self.assertIn(self.corp_timer, corp_timers) + self.assertNotIn(self.other_corp_timer, corp_timers) + + self.assertIn(self.timer, future_timers) + self.assertNotIn(self.expired_timer, future_timers) + self.assertNotIn(self.corp_timer, future_timers) + self.assertNotIn(self.other_corp_timer, future_timers) + + self.assertNotIn(self.timer, past_timers) + self.assertIn(self.expired_timer, past_timers) + self.assertNotIn(self.corp_timer, past_timers) + self.assertNotIn(self.other_corp_timer, past_timers) + + def test_timer_view_permission(self): + self.client.force_login(self.user) + response = self.app.get(self.view_url) + self.assertRedirects(response, expected_url=reverse(settings.LOGIN_URL) + '?next=' + self.view_url) + + def test_timer_view_login(self): + response = self.app.get(self.view_url) + self.assertRedirects(response, expected_url=reverse(settings.LOGIN_URL) + '?next=' + self.view_url) + + def test_add_timer_get(self): + self.user.user_permissions.add(self.edit_permission) + self.app.set_user(self.user) + + response = self.app.get(self.add_url) + + self.assertTemplateUsed(response, 'timerboard/timer_create_form.html') + + context = response.context[-1] + + self.assertIs(TimerForm, type(context['form'])) + + def test_add_timer_form_error(self): + self.user.user_permissions.add(self.edit_permission) + self.app.set_user(self.user) + page = self.app.post(self.add_url) + page = page.forms['add-timer-form'].submit() + self.assertContains(page, "This field is required.") + + def test_add_timer_post(self): + self.user.user_permissions.add(self.edit_permission) + self.user.user_permissions.add(self.view_permission) + + self.app.set_user(self.user) + + page = self.app.post(self.add_url) + form = page.forms['add-timer-form'] + + form['details'] = 'details' + form['system'] = 'jita' + form['planet_moon'] = '4-4' + form['structure'] = TimerForm.structure_choices[0][0] + form['objective'] = TimerForm.objective_choices[0][0] + form['days_left'] = 1 + form['hours_left'] = 2 + form['minutes_left'] = 3 + form['important'] = True + form['corp_timer'] = False + + response = form.submit() + + self.assertRedirects(response, self.view_url) + + self.assertTrue(Timer.objects.filter(system='jita', details='details').exists()) + + def test_edit_timer_get(self): + self.user.user_permissions.add(self.edit_permission) + self.app.set_user(self.user) + + response = self.app.get(reverse(self.edit_url_name, args=[self.timer.id])) + context = response.context[-1] + form = context['form'] + data = form.instance + + self.assertTemplateUsed(response, 'timerboard/timer_update_form.html') + self.assertIs(TimerForm, type(form)) + self.assertEqual(data, self.timer) + + def test_edit_timer_post(self): + self.user.user_permissions.add(self.edit_permission) + self.user.user_permissions.add(self.view_permission) + + self.app.set_user(self.user) + + page = self.app.post(reverse(self.edit_url_name, args=[self.timer.id])) + form = page.forms['add-timer-form'] + + form['details'] = 'detailsUNIQUE' + form['system'] = 'jita' + form['planet_moon'] = '4-4' + form['structure'] = TimerForm.structure_choices[0][0] + form['objective'] = TimerForm.objective_choices[0][0] + form['days_left'] = 1 + form['hours_left'] = 2 + form['minutes_left'] = 3 + form['important'] = True + form['corp_timer'] = False + + response = form.submit() + + self.assertRedirects(response, self.view_url) + + self.assertTrue(Timer.objects.filter(system='jita', details='detailsUNIQUE').exists()) + + def test_delete_timer_get(self): + self.user.user_permissions.add(self.edit_permission) + self.app.set_user(self.user) + + response = self.app.get(reverse(self.delete_url_name, args=[self.timer.id])) + + self.assertTemplateUsed(response, 'timerboard/timer_confirm_delete.html') + + self.assertContains(response, 'Are you sure you want to delete timer "'+str(self.timer)) diff --git a/allianceauth/timerboard/urls.py b/allianceauth/timerboard/urls.py index 2a7ef7d6..d4102494 100644 --- a/allianceauth/timerboard/urls.py +++ b/allianceauth/timerboard/urls.py @@ -5,8 +5,8 @@ from . import views app_name = 'timerboard' urlpatterns = [ - url(r'^$', views.timer_view, name='view'), - url(r'^add/$', views.add_timer_view, name='add'), - url(r'^remove/(\w+)$', views.remove_timer, name='remove'), - url(r'^edit/(\w+)$', views.edit_timer, name='edit'), - ] + url(r'^$', views.TimerView.as_view(), name='view'), + url(r'^add/$', views.AddTimerView.as_view(), name='add'), + url(r'^remove/(?P\w+)$', views.RemoveTimerView.as_view(), name='delete'), + url(r'^edit/(?P\w+)$', views.EditTimerView.as_view(), name='edit'), +] diff --git a/allianceauth/timerboard/views.py b/allianceauth/timerboard/views.py index 0e3a06f2..b865978e 100755 --- a/allianceauth/timerboard/views.py +++ b/allianceauth/timerboard/views.py @@ -2,13 +2,14 @@ import datetime import logging from django.contrib import messages -from django.contrib.auth.decorators import login_required -from django.contrib.auth.decorators import permission_required from django.shortcuts import get_object_or_404 from django.shortcuts import render, redirect +from django.views import View +from django.urls import reverse_lazy +from django.views.generic import CreateView, UpdateView, DeleteView +from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin from django.utils import timezone from django.utils.translation import ugettext_lazy as _ -from allianceauth.eveonline.models import EveCorporationInfo from .form import TimerForm from .models import Timer @@ -16,136 +17,72 @@ from .models import Timer logger = logging.getLogger(__name__) -@login_required -@permission_required('auth.timer_view') -def timer_view(request): - logger.debug("timer_view called by user %s" % request.user) - char = request.user.profile.main_character - if char: - corp = EveCorporationInfo.objects.get(corporation_id=char.corporation_id) - else: - corp = None - if corp: - corp_timers = Timer.objects.all().filter(corp_timer=True).filter(eve_corp=corp) - else: - corp_timers = [] - render_items = {'timers': Timer.objects.all().filter(corp_timer=False), - 'corp_timers': corp_timers, - 'future_timers': Timer.objects.all().filter(corp_timer=False).filter( - eve_time__gte=datetime.datetime.now()), - 'past_timers': Timer.objects.all().filter(corp_timer=False).filter( - eve_time__lt=datetime.datetime.now())} - - return render(request, 'timerboard/management.html', context=render_items) +class BaseTimerView(LoginRequiredMixin, PermissionRequiredMixin, View): + pass -@login_required -@permission_required('auth.timer_management') -def add_timer_view(request): - logger.debug("add_timer_view called by user %s" % request.user) - if request.method == 'POST': - form = TimerForm(request.POST) - logger.debug("Request type POST contains form valid: %s" % form.is_valid()) - if form.is_valid(): - # Get character - character = request.user.profile.main_character - corporation = EveCorporationInfo.get_corporation_info_by_id(character.corporation_id) - logger.debug( - "Determined timer add request on behalf of character %s corporation %s" % (character, corporation)) - # calculate future time - future_time = datetime.timedelta(days=form.cleaned_data['days_left'], hours=form.cleaned_data['hours_left'], - minutes=form.cleaned_data['minutes_left']) - current_time = timezone.now() - eve_time = current_time + future_time - logger.debug( - "Determined timer eve time is %s - current time %s, adding %s" % (eve_time, current_time, future_time)) - # handle valid form - timer = Timer() - timer.details = form.cleaned_data['details'] - timer.system = form.cleaned_data['system'] - timer.planet_moon = form.cleaned_data['planet_moon'] - timer.structure = form.cleaned_data['structure'] - timer.objective = form.cleaned_data['objective'] - timer.eve_time = eve_time - timer.important = form.cleaned_data['important'] - timer.corp_timer = form.cleaned_data['corp_timer'] - timer.eve_character = character - timer.eve_corp = corporation - timer.user = request.user - timer.save() - logger.info("Created new timer in %s at %s by user %s" % (timer.system, timer.eve_time, request.user)) - messages.success(request, _('Added new timer in %(system)s at %(time)s.') % {"system": timer.system, "time": timer.eve_time}) - return redirect("timerboard:view") - else: - logger.debug("Returning new TimerForm") - form = TimerForm() +class TimerView(BaseTimerView): + template_name = 'timerboard/view.html' + permission_required = 'auth.timer_view' - render_items = {'form': form} + def get(self, request): + logger.debug("timer_view called by user {}".format(request.user)) + char = request.user.profile.main_character + if char: + corp = char.corporation + else: + corp = None - return render(request, 'timerboard/add.html', context=render_items) - - -@login_required -@permission_required('auth.timer_management') -def remove_timer(request, timer_id): - logger.debug("remove_timer called by user %s for timer id %s" % (request.user, timer_id)) - timer = get_object_or_404(Timer, id=timer_id) - timer.delete() - logger.debug("Deleting timer id %s by user %s" % (timer_id, request.user)) - messages.success(request, _('Deleted timer in %(system)s at %(time)s.') % {'system': timer.system, - 'time': timer.eve_time}) - return redirect("timerboard:view") - - -@login_required -@permission_required('auth.timer_management') -def edit_timer(request, timer_id): - logger.debug("edit_timer called by user %s for timer id %s" % (request.user, timer_id)) - timer = get_object_or_404(Timer, id=timer_id) - if request.method == 'POST': - form = TimerForm(request.POST) - logger.debug("Received POST request containing updated timer form, is valid: %s" % form.is_valid()) - if form.is_valid(): - character = request.user.profile.main_character - corporation = EveCorporationInfo.get_corporation_info_by_id(character.corporation_id) - logger.debug( - "Determined timer edit request on behalf of character %s corporation %s" % (character, corporation)) - # calculate future time - future_time = datetime.timedelta(days=form.cleaned_data['days_left'], hours=form.cleaned_data['hours_left'], - minutes=form.cleaned_data['minutes_left']) - current_time = datetime.datetime.utcnow() - eve_time = current_time + future_time - logger.debug( - "Determined timer eve time is %s - current time %s, adding %s" % (eve_time, current_time, future_time)) - timer.details = form.cleaned_data['details'] - timer.system = form.cleaned_data['system'] - timer.planet_moon = form.cleaned_data['planet_moon'] - timer.structure = form.cleaned_data['structure'] - timer.objective = form.cleaned_data['objective'] - timer.eve_time = eve_time - timer.important = form.cleaned_data['important'] - timer.corp_timer = form.cleaned_data['corp_timer'] - timer.eve_character = character - timer.eve_corp = corporation - logger.info("User %s updating timer id %s " % (request.user, timer_id)) - messages.success(request, _('Saved changes to the timer.')) - timer.save() - return redirect("timerboard:view") - else: - current_time = timezone.now() - td = timer.eve_time - current_time - tddays, tdhours, tdminutes = td.days, td.seconds // 3600, td.seconds // 60 % 60 - data = { - 'details': timer.details, - 'system': timer.system, - 'planet_moon': timer.planet_moon, - 'structure': timer.structure, - 'objective': timer.objective, - 'important': timer.important, - 'corp_timer': timer.corp_timer, - 'days_left': tddays, - 'hours_left': tdhours, - 'minutes_left': tdminutes, + render_items = { + 'timers': Timer.objects.filter(corp_timer=False), + 'corp_timers': Timer.objects.filter(corp_timer=True, eve_corp=corp), + 'future_timers': Timer.objects.filter(corp_timer=False, eve_time__gte=timezone.now()), + 'past_timers': Timer.objects.filter(corp_timer=False, eve_time__lt=timezone.now()), } - form = TimerForm(initial=data) - return render(request, 'timerboard/update.html', context={'form': form}) + + return render(request, self.template_name, context=render_items) + + +class TimerManagementView(BaseTimerView): + permission_required = 'auth.timer_management' + index_redirect = 'timerboard:view' + success_url = reverse_lazy(index_redirect) + model = Timer + form_class = TimerForm + + def get_timer(self, timer_id): + return get_object_or_404(self.model, id=timer_id) + + +class AddUpdateMixin: + def get_form_kwargs(self): + """ + Inject the request user into the kwargs passed to the form + """ + kwargs = super(AddUpdateMixin, self).get_form_kwargs() + kwargs.update({'user': self.request.user}) + return kwargs + + +class AddTimerView(TimerManagementView, AddUpdateMixin, CreateView): + template_name_suffix = '_create_form' + + def form_valid(self, form): + result = super(AddTimerView, self).form_valid(form) + timer = self.object + logger.info("Created new timer in {} at {} by user {}".format(timer.system, timer.eve_time, self.request.user)) + messages.success(self.request, _('Added new timer in %(system)s at %(time)s.') % {"system": timer.system, + "time": timer.eve_time}) + return result + + +class EditTimerView(TimerManagementView, AddUpdateMixin, UpdateView): + template_name_suffix = '_update_form' + + def form_valid(self, form): + messages.success(self.request, _('Saved changes to the timer.')) + return super(EditTimerView, self).form_valid(form) + + +class RemoveTimerView(TimerManagementView, DeleteView): + pass diff --git a/setup.py b/setup.py index b24804d9..fbf65020 100644 --- a/setup.py +++ b/setup.py @@ -33,6 +33,7 @@ testing_extras = [ 'coverage>=4.3.1', 'requests-mock>=1.2.0', 'django-nose', + 'django-webtest', ] setup( From 11fca74fece1d1305bfd0265aefe9fbfdc1773db Mon Sep 17 00:00:00 2001 From: Basraah Date: Thu, 28 Sep 2017 12:32:33 +1000 Subject: [PATCH 4/6] Add required on_delete parameters for Dj2.0 compatibility --- allianceauth/corputils/models.py | 2 +- .../eveonline/migrations/0009_on_delete.py | 21 +++++++++++ allianceauth/eveonline/models.py | 2 +- allianceauth/fleetactivitytracking/models.py | 4 +-- .../migrations/0007_on_delete.py | 36 +++++++++++++++++++ allianceauth/groupmanagement/models.py | 13 +++++-- allianceauth/hrapplications/models.py | 2 +- .../optimer/migrations/0004_on_delete.py | 21 +++++++++++ allianceauth/optimer/models.py | 2 +- .../services/modules/mumble/models.py | 2 +- .../services/modules/teamspeak3/models.py | 4 +-- allianceauth/srp/migrations/0004_on_delete.py | 26 ++++++++++++++ allianceauth/srp/models.py | 6 ++-- .../timerboard/migrations/0003_on_delete.py | 27 ++++++++++++++ allianceauth/timerboard/models.py | 6 ++-- 15 files changed, 156 insertions(+), 18 deletions(-) create mode 100644 allianceauth/eveonline/migrations/0009_on_delete.py create mode 100644 allianceauth/groupmanagement/migrations/0007_on_delete.py create mode 100644 allianceauth/optimer/migrations/0004_on_delete.py create mode 100644 allianceauth/srp/migrations/0004_on_delete.py create mode 100644 allianceauth/timerboard/migrations/0003_on_delete.py diff --git a/allianceauth/corputils/models.py b/allianceauth/corputils/models.py index 58643a67..c07d68c0 100644 --- a/allianceauth/corputils/models.py +++ b/allianceauth/corputils/models.py @@ -18,7 +18,7 @@ logger = logging.getLogger(__name__) class CorpStats(models.Model): token = models.ForeignKey(Token, on_delete=models.CASCADE) - corp = models.OneToOneField(EveCorporationInfo) + corp = models.OneToOneField(EveCorporationInfo, on_delete=models.CASCADE) last_update = models.DateTimeField(auto_now=True) class Meta: diff --git a/allianceauth/eveonline/migrations/0009_on_delete.py b/allianceauth/eveonline/migrations/0009_on_delete.py new file mode 100644 index 00000000..ad534248 --- /dev/null +++ b/allianceauth/eveonline/migrations/0009_on_delete.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.5 on 2017-09-28 02:16 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('eveonline', '0008_remove_apikeys'), + ] + + operations = [ + migrations.AlterField( + model_name='evecorporationinfo', + name='alliance', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='eveonline.EveAllianceInfo'), + ), + ] diff --git a/allianceauth/eveonline/models.py b/allianceauth/eveonline/models.py index 872c33f1..b7754c52 100644 --- a/allianceauth/eveonline/models.py +++ b/allianceauth/eveonline/models.py @@ -41,7 +41,7 @@ class EveCorporationInfo(models.Model): corporation_name = models.CharField(max_length=254, unique=True) corporation_ticker = models.CharField(max_length=254) member_count = models.IntegerField() - alliance = models.ForeignKey(EveAllianceInfo, blank=True, null=True) + alliance = models.ForeignKey(EveAllianceInfo, blank=True, null=True, on_delete=models.SET_NULL) objects = EveCorporationManager() provider = EveCorporationProviderManager() diff --git a/allianceauth/fleetactivitytracking/models.py b/allianceauth/fleetactivitytracking/models.py index 3cf4607d..8bb248b4 100644 --- a/allianceauth/fleetactivitytracking/models.py +++ b/allianceauth/fleetactivitytracking/models.py @@ -23,11 +23,11 @@ class Fatlink(models.Model): class Fat(models.Model): character = models.ForeignKey(EveCharacter, on_delete=models.CASCADE) - fatlink = models.ForeignKey(Fatlink) + fatlink = models.ForeignKey(Fatlink, on_delete=models.CASCADE) system = models.CharField(max_length=30) shiptype = models.CharField(max_length=30) station = models.CharField(max_length=125) - user = models.ForeignKey(User) + user = models.ForeignKey(User, on_delete=models.CASCADE) class Meta: unique_together = (('character', 'fatlink'),) diff --git a/allianceauth/groupmanagement/migrations/0007_on_delete.py b/allianceauth/groupmanagement/migrations/0007_on_delete.py new file mode 100644 index 00000000..022e93bd --- /dev/null +++ b/allianceauth/groupmanagement/migrations/0007_on_delete.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.5 on 2017-09-28 02:16 +from __future__ import unicode_literals + +import django.contrib.auth.models +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('auth', '0008_alter_user_username_max_length'), + ('groupmanagement', '0006_request_groups_perm'), + ] + + operations = [ + migrations.CreateModel( + name='ProxyGroup', + fields=[ + ], + options={ + 'verbose_name': 'group', + 'indexes': [], + 'proxy': True, + 'verbose_name_plural': 'groups', + }, + bases=('auth.group',), + managers=[ + ('objects', django.contrib.auth.models.GroupManager()), + ], + ), + migrations.RemoveField( + model_name='grouprequest', + name='main_char', + ), + ] diff --git a/allianceauth/groupmanagement/models.py b/allianceauth/groupmanagement/models.py index bcb1b24d..ed9310ef 100644 --- a/allianceauth/groupmanagement/models.py +++ b/allianceauth/groupmanagement/models.py @@ -10,9 +10,16 @@ from allianceauth.eveonline.models import EveCharacter class GroupRequest(models.Model): status = models.CharField(max_length=254) leave_request = models.BooleanField(default=0) - user = models.ForeignKey(User) - group = models.ForeignKey(Group) - main_char = models.ForeignKey(EveCharacter) + user = models.ForeignKey(User, on_delete=models.CASCADE) + group = models.ForeignKey(Group, on_delete=models.CASCADE) + + @property + def main_char(self): + """ + Legacy property for main character + :return: self.users main character + """ + return self.user.profile.main_character def __str__(self): return self.user.username + ":" + self.group.name diff --git a/allianceauth/hrapplications/models.py b/allianceauth/hrapplications/models.py index 82317549..a9bf57e8 100755 --- a/allianceauth/hrapplications/models.py +++ b/allianceauth/hrapplications/models.py @@ -23,7 +23,7 @@ class ApplicationChoice(models.Model): class ApplicationForm(models.Model): questions = SortedManyToManyField(ApplicationQuestion) - corp = models.OneToOneField(EveCorporationInfo) + corp = models.OneToOneField(EveCorporationInfo, on_delete=models.CASCADE) def __str__(self): return str(self.corp) diff --git a/allianceauth/optimer/migrations/0004_on_delete.py b/allianceauth/optimer/migrations/0004_on_delete.py new file mode 100644 index 00000000..958cdff8 --- /dev/null +++ b/allianceauth/optimer/migrations/0004_on_delete.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.5 on 2017-09-28 02:16 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('optimer', '0003_make_strings_more_stringy'), + ] + + operations = [ + migrations.AlterField( + model_name='optimer', + name='eve_character', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='eveonline.EveCharacter'), + ), + ] diff --git a/allianceauth/optimer/models.py b/allianceauth/optimer/models.py index fe9d19b9..08a17e3e 100644 --- a/allianceauth/optimer/models.py +++ b/allianceauth/optimer/models.py @@ -17,7 +17,7 @@ class OpTimer(models.Model): operation_name = models.CharField(max_length=254, default="") fc = models.CharField(max_length=254, default="") post_time = models.DateTimeField(default=timezone.now) - eve_character = models.ForeignKey(EveCharacter) + eve_character = models.ForeignKey(EveCharacter, null=True, on_delete=models.SET_NULL) def __str__(self): return self.operation_name diff --git a/allianceauth/services/modules/mumble/models.py b/allianceauth/services/modules/mumble/models.py index 8df6be40..6e0a8e0d 100644 --- a/allianceauth/services/modules/mumble/models.py +++ b/allianceauth/services/modules/mumble/models.py @@ -2,7 +2,7 @@ from django.db import models class MumbleUser(models.Model): - user = models.OneToOneField('auth.User', related_name='mumble', null=True) + user = models.OneToOneField('auth.User', related_name='mumble', null=True, on_delete=models.CASCADE) username = models.CharField(max_length=254, unique=True) pwhash = models.CharField(max_length=80) hashfn = models.CharField(max_length=20, default='sha1') diff --git a/allianceauth/services/modules/teamspeak3/models.py b/allianceauth/services/modules/teamspeak3/models.py index 0aa885f8..2c8e7dc3 100644 --- a/allianceauth/services/modules/teamspeak3/models.py +++ b/allianceauth/services/modules/teamspeak3/models.py @@ -30,7 +30,7 @@ class TSgroup(models.Model): class AuthTS(models.Model): - auth_group = models.ForeignKey('auth.Group') + auth_group = models.ForeignKey('auth.Group', on_delete=models.CASCADE) ts_group = models.ManyToManyField(TSgroup) class Meta: @@ -41,7 +41,7 @@ class AuthTS(models.Model): class UserTSgroup(models.Model): - user = models.ForeignKey('auth.User') + user = models.ForeignKey('auth.User', on_delete=models.CASCADE) ts_group = models.ManyToManyField(TSgroup) class Meta: diff --git a/allianceauth/srp/migrations/0004_on_delete.py b/allianceauth/srp/migrations/0004_on_delete.py new file mode 100644 index 00000000..d4fd505a --- /dev/null +++ b/allianceauth/srp/migrations/0004_on_delete.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.5 on 2017-09-28 02:16 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('srp', '0003_make_strings_more_stringy'), + ] + + operations = [ + migrations.AlterField( + model_name='srpfleetmain', + name='fleet_commander', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='eveonline.EveCharacter'), + ), + migrations.AlterField( + model_name='srpuserrequest', + name='character', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='eveonline.EveCharacter'), + ), + ] diff --git a/allianceauth/srp/models.py b/allianceauth/srp/models.py index 6effbef4..b3ebc7d9 100755 --- a/allianceauth/srp/models.py +++ b/allianceauth/srp/models.py @@ -10,7 +10,7 @@ class SrpFleetMain(models.Model): fleet_time = models.DateTimeField() fleet_srp_code = models.CharField(max_length=254, default="") fleet_srp_status = models.CharField(max_length=254, default="") - fleet_commander = models.ForeignKey(EveCharacter) + fleet_commander = models.ForeignKey(EveCharacter, null=True, on_delete=models.SET_NULL) fleet_srp_aar_link = models.CharField(max_length=254, default="") def __str__(self): @@ -40,8 +40,8 @@ class SrpUserRequest(models.Model): additional_info = models.CharField(max_length=254, default="") srp_status = models.CharField(max_length=8, default="Pending", choices=SRP_STATUS_CHOICES) srp_total_amount = models.BigIntegerField(default=0) - character = models.ForeignKey(EveCharacter) - srp_fleet_main = models.ForeignKey(SrpFleetMain) + character = models.ForeignKey(EveCharacter, null=True, on_delete=models.SET_NULL) + srp_fleet_main = models.ForeignKey(SrpFleetMain, on_delete=models.CASCADE) kb_total_loss = models.BigIntegerField(default=0) srp_ship_name = models.CharField(max_length=254, default="") post_time = models.DateTimeField(default=timezone.now) diff --git a/allianceauth/timerboard/migrations/0003_on_delete.py b/allianceauth/timerboard/migrations/0003_on_delete.py new file mode 100644 index 00000000..899f6dc0 --- /dev/null +++ b/allianceauth/timerboard/migrations/0003_on_delete.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.5 on 2017-09-28 02:16 +from __future__ import unicode_literals + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('timerboard', '0002_make_strings_more_stringy'), + ] + + operations = [ + migrations.AlterField( + model_name='timer', + name='eve_character', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='eveonline.EveCharacter'), + ), + migrations.AlterField( + model_name='timer', + name='user', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/allianceauth/timerboard/models.py b/allianceauth/timerboard/models.py index 708e7dc6..d5391583 100755 --- a/allianceauth/timerboard/models.py +++ b/allianceauth/timerboard/models.py @@ -16,10 +16,10 @@ class Timer(models.Model): objective = models.CharField(max_length=254, default="") eve_time = models.DateTimeField() important = models.BooleanField(default=False) - eve_character = models.ForeignKey(EveCharacter) - eve_corp = models.ForeignKey(EveCorporationInfo) + eve_character = models.ForeignKey(EveCharacter, null=True, on_delete=models.SET_NULL) + eve_corp = models.ForeignKey(EveCorporationInfo, on_delete=models.CASCADE) corp_timer = models.BooleanField(default=False) - user = models.ForeignKey(User) + user = models.ForeignKey(User, null=True, on_delete=models.SET_NULL) def __str__(self): return str(self.system) + ' ' + str(self.details) From 51e4db73f09671c25537dc60934f79b3a89b4c8f Mon Sep 17 00:00:00 2001 From: Basraah Date: Thu, 28 Sep 2017 12:33:46 +1000 Subject: [PATCH 5/6] Add latest django-celery-beat snapshot for Dj2.0 testing --- tox.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/tox.ini b/tox.ini index 4c2b8b9c..6826cc63 100644 --- a/tox.ini +++ b/tox.ini @@ -14,5 +14,6 @@ basepython = deps= dj111: Django>=1.11.1,<2.0 dj20: Django>=2.0a1 + dj20: https://github.com/celery/django-celery-beat/zipball/master#egg=django-celery-beat install_command = pip install -e ".[testing]" -U {opts} {packages} commands=coverage run runtests.py -v 2 From 8864afd784073c63065a595f9e98be833d8cdc43 Mon Sep 17 00:00:00 2001 From: Basraah Date: Thu, 28 Sep 2017 14:47:06 +1000 Subject: [PATCH 6/6] Resolve Dj20 compatibility issues Temporarily use latest snapshot for esi for dj20 Correct admin urls include Manually correct old ts3 table migration Remove obsolete services migrations Remove bootstrap pagination package Fix url namespacing --- alliance_auth/settings.py.example | 1 - allianceauth/authentication/views.py | 2 +- .../fleetactivitytracking/fatlinkmodify.html | 4 -- allianceauth/fleetactivitytracking/views.py | 17 +-------- .../services/migrations/0001_initial.py | 38 ------------------- .../migrations/0002_auto_20161016_0135.py | 22 ----------- .../migrations/0003_delete_groupcache.py | 18 --------- allianceauth/services/migrations/__init__.py | 0 allianceauth/services/modules/discord/urls.py | 4 +- allianceauth/services/modules/example/urls.py | 4 +- allianceauth/services/modules/ips4/urls.py | 4 +- allianceauth/services/modules/market/urls.py | 4 +- allianceauth/services/modules/mumble/urls.py | 4 +- .../services/modules/openfire/urls.py | 4 +- allianceauth/services/modules/phpbb3/urls.py | 4 +- allianceauth/services/modules/seat/urls.py | 4 +- allianceauth/services/modules/smf/urls.py | 4 +- .../teamspeak3/migrations/0001_initial.py | 6 +-- .../services/modules/teamspeak3/models.py | 7 ++-- .../services/modules/teamspeak3/urls.py | 4 +- allianceauth/services/modules/xenforo/urls.py | 4 +- allianceauth/services/urls.py | 4 +- .../navhelper/templatetags/navactive.py | 2 +- allianceauth/timerboard/tests.py | 2 +- allianceauth/urls.py | 6 +-- setup.py | 1 - test_allianceauth/settings.py | 1 - tox.ini | 1 + 28 files changed, 50 insertions(+), 126 deletions(-) delete mode 100644 allianceauth/services/migrations/0001_initial.py delete mode 100644 allianceauth/services/migrations/0002_auto_20161016_0135.py delete mode 100644 allianceauth/services/migrations/0003_delete_groupcache.py delete mode 100644 allianceauth/services/migrations/__init__.py diff --git a/alliance_auth/settings.py.example b/alliance_auth/settings.py.example index e6e2f5a4..1914632c 100644 --- a/alliance_auth/settings.py.example +++ b/alliance_auth/settings.py.example @@ -27,7 +27,6 @@ INSTALLED_APPS = [ 'django.contrib.humanize', 'django_celery_beat', 'bootstrapform', - 'bootstrap_pagination', 'sortedm2m', 'esi', 'allianceauth', diff --git a/allianceauth/authentication/views.py b/allianceauth/authentication/views.py index 7d8c33d5..b2121442 100644 --- a/allianceauth/authentication/views.py +++ b/allianceauth/authentication/views.py @@ -6,7 +6,7 @@ from django.contrib.auth import login, authenticate from django.contrib.auth.decorators import login_required from django.contrib.auth.models import User from django.core import signing -from django.core.urlresolvers import reverse +from django.urls import reverse from django.shortcuts import redirect from django.utils.translation import ugettext_lazy as _ from esi.decorators import token_required diff --git a/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html b/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html index 8b507612..7bb16bf6 100644 --- a/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html +++ b/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html @@ -2,7 +2,6 @@ {% load bootstrap %} {% load staticfiles %} {% load i18n %} -{% load bootstrap_pagination %} {% block title %}Alliance Auth{% endblock %} {% block page_title %}{% trans "Fatlink view" %}{% endblock page_title %} @@ -20,9 +19,6 @@
    {% trans "Registered characters" %}
    -
    - {% bootstrap_paginate registered_fats range=10 %} -
    diff --git a/allianceauth/fleetactivitytracking/views.py b/allianceauth/fleetactivitytracking/views.py index 614f9baa..2d20a666 100644 --- a/allianceauth/fleetactivitytracking/views.py +++ b/allianceauth/fleetactivitytracking/views.py @@ -29,19 +29,6 @@ SWAGGER_SPEC_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'sw logger = logging.getLogger(__name__) -FATS_PER_PAGE = int(getattr(settings, 'FATS_PER_PAGE', 20)) - - -def get_page(model_list, page_num): - p = Paginator(model_list, FATS_PER_PAGE) - try: - fats = p.page(page_num) - except PageNotAnInteger: - fats = p.page(1) - except EmptyPage: - fats = p.page(p.num_pages) - return fats - class CorpStat(object): def __init__(self, corp_id, start_of_month, start_of_next_month, corp=None): @@ -359,8 +346,6 @@ def modify_fatlink_view(request, hash=""): registered_fats = Fat.objects.filter(fatlink=fatlink).order_by('character__character_name') - fat_page = get_page(registered_fats, request.GET.get('page', 1)) - - context = {'fatlink': fatlink, 'registered_fats': fat_page} + context = {'fatlink': fatlink, 'registered_fats': registered_fats} return render(request, 'fleetactivitytracking/fatlinkmodify.html', context=context) diff --git a/allianceauth/services/migrations/0001_initial.py b/allianceauth/services/migrations/0001_initial.py deleted file mode 100644 index a482d393..00000000 --- a/allianceauth/services/migrations/0001_initial.py +++ /dev/null @@ -1,38 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.10.1 on 2016-09-05 21:40 -from __future__ import unicode_literals - -from django.conf import settings -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [ - ('auth', '0008_alter_user_username_max_length'), - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ] - - operations = [ - migrations.CreateModel( - name='DiscordAuthToken', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('email', models.CharField(max_length=254, unique=True)), - ('token', models.CharField(max_length=254)), - ('user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), - ], - ), - migrations.CreateModel( - name='GroupCache', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created', models.DateTimeField(auto_now_add=True)), - ('groups', models.TextField(default={})), - ('service', models.CharField(choices=[(b'discourse', b'discourse'), (b'discord', b'discord')], max_length=254, unique=True)), - ], - ), - ] diff --git a/allianceauth/services/migrations/0002_auto_20161016_0135.py b/allianceauth/services/migrations/0002_auto_20161016_0135.py deleted file mode 100644 index 68749395..00000000 --- a/allianceauth/services/migrations/0002_auto_20161016_0135.py +++ /dev/null @@ -1,22 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.10.1 on 2016-10-16 01:35 -from __future__ import unicode_literals - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('services', '0001_initial'), - ] - - operations = [ - migrations.RemoveField( - model_name='discordauthtoken', - name='user', - ), - migrations.DeleteModel( - name='DiscordAuthToken', - ), - ] diff --git a/allianceauth/services/migrations/0003_delete_groupcache.py b/allianceauth/services/migrations/0003_delete_groupcache.py deleted file mode 100644 index cc949a31..00000000 --- a/allianceauth/services/migrations/0003_delete_groupcache.py +++ /dev/null @@ -1,18 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.10.5 on 2017-09-02 06:07 -from __future__ import unicode_literals - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('services', '0002_auto_20161016_0135'), - ] - - operations = [ - migrations.DeleteModel( - name='GroupCache', - ), - ] diff --git a/allianceauth/services/migrations/__init__.py b/allianceauth/services/migrations/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/allianceauth/services/modules/discord/urls.py b/allianceauth/services/modules/discord/urls.py index 056ebc3e..30f48937 100644 --- a/allianceauth/services/modules/discord/urls.py +++ b/allianceauth/services/modules/discord/urls.py @@ -2,6 +2,8 @@ from django.conf.urls import url, include from . import views +app_name = 'discord' + module_urls = [ # Discord Service Control url(r'^activate/$', views.activate_discord, name='activate'), @@ -12,5 +14,5 @@ module_urls = [ ] urlpatterns = [ - url(r'^discord/', include(module_urls, namespace='discord')) + url(r'^discord/', include((module_urls, app_name), namespace=app_name)) ] diff --git a/allianceauth/services/modules/example/urls.py b/allianceauth/services/modules/example/urls.py index 3df31b1a..f72d9abd 100644 --- a/allianceauth/services/modules/example/urls.py +++ b/allianceauth/services/modules/example/urls.py @@ -1,9 +1,11 @@ from django.conf.urls import url, include +app_name = 'example' + module_urls = [ # Add your module URLs here ] urlpatterns = [ - url(r'^example/', include(module_urls, namespace='example')), + url(r'^example/', include((module_urls, app_name), namespace=app_name)), ] diff --git a/allianceauth/services/modules/ips4/urls.py b/allianceauth/services/modules/ips4/urls.py index f6c65907..a13a98e6 100644 --- a/allianceauth/services/modules/ips4/urls.py +++ b/allianceauth/services/modules/ips4/urls.py @@ -2,6 +2,8 @@ from django.conf.urls import url, include from . import views +app_name = 'ips4' + module_urls = [ # IPS4 Service Control url(r'^activate/$', views.activate_ips4, name='activate'), @@ -11,5 +13,5 @@ module_urls = [ ] urlpatterns = [ - url(r'^ips4/', include(module_urls, namespace='ips4')) + url(r'^ips4/', include((module_urls, app_name), namespace=app_name)) ] diff --git a/allianceauth/services/modules/market/urls.py b/allianceauth/services/modules/market/urls.py index d588c792..3381ec29 100644 --- a/allianceauth/services/modules/market/urls.py +++ b/allianceauth/services/modules/market/urls.py @@ -2,6 +2,8 @@ from django.conf.urls import url, include from . import views +app_name = 'evernusmarket' + module_urls = [ # Alliance Market Control url(r'^activate/$', views.activate_market, name='activate'), @@ -11,5 +13,5 @@ module_urls = [ ] urlpatterns = [ - url(r'^evernus-market/', include(module_urls, namespace='evernusmarket')) + url(r'^evernus-market/', include((module_urls, app_name), namespace=app_name)) ] diff --git a/allianceauth/services/modules/mumble/urls.py b/allianceauth/services/modules/mumble/urls.py index b60034a9..dd0e04ef 100644 --- a/allianceauth/services/modules/mumble/urls.py +++ b/allianceauth/services/modules/mumble/urls.py @@ -2,6 +2,8 @@ from django.conf.urls import url, include from . import views +app_name = 'mumble' + module_urls = [ # Mumble service control url(r'^activate/$', views.activate_mumble, name='activate'), @@ -12,5 +14,5 @@ module_urls = [ ] urlpatterns = [ - url(r'^mumble/', include(module_urls, namespace='mumble')) + url(r'^mumble/', include((module_urls, app_name), namespace=app_name)) ] diff --git a/allianceauth/services/modules/openfire/urls.py b/allianceauth/services/modules/openfire/urls.py index 4e80a4a9..230d9fb4 100644 --- a/allianceauth/services/modules/openfire/urls.py +++ b/allianceauth/services/modules/openfire/urls.py @@ -2,6 +2,8 @@ from django.conf.urls import url, include from . import views +app_name = 'openfire' + module_urls = [ # Jabber Service Control url(r'^activate/$', views.activate_jabber, name='activate'), @@ -12,5 +14,5 @@ module_urls = [ ] urlpatterns = [ - url(r'^openfire/', include(module_urls, namespace='openfire')), + url(r'^openfire/', include((module_urls, app_name), namespace=app_name)), ] diff --git a/allianceauth/services/modules/phpbb3/urls.py b/allianceauth/services/modules/phpbb3/urls.py index fd1840a5..26611469 100644 --- a/allianceauth/services/modules/phpbb3/urls.py +++ b/allianceauth/services/modules/phpbb3/urls.py @@ -2,6 +2,8 @@ from django.conf.urls import url, include from . import views +app_name = 'phpbb3' + module_urls = [ # Forum Service Control url(r'^activate/$', views.activate_forum, name='activate'), @@ -11,5 +13,5 @@ module_urls = [ ] urlpatterns = [ - url(r'^phpbb3/', include(module_urls, namespace='phpbb3')) + url(r'^phpbb3/', include((module_urls, app_name), namespace=app_name)) ] diff --git a/allianceauth/services/modules/seat/urls.py b/allianceauth/services/modules/seat/urls.py index 418f6c6f..c374681c 100644 --- a/allianceauth/services/modules/seat/urls.py +++ b/allianceauth/services/modules/seat/urls.py @@ -2,6 +2,8 @@ from django.conf.urls import url, include from . import views +app_name='seat' + module_urls = [ # SeAT Service Control url(r'^activate/$', views.activate_seat, name='activate'), @@ -11,5 +13,5 @@ module_urls = [ ] urlpatterns = [ - url(r'^seat/', include(module_urls, namespace='seat')), + url(r'^seat/', include((module_urls, app_name), namespace=app_name)), ] diff --git a/allianceauth/services/modules/smf/urls.py b/allianceauth/services/modules/smf/urls.py index 475ee98d..59e396bf 100644 --- a/allianceauth/services/modules/smf/urls.py +++ b/allianceauth/services/modules/smf/urls.py @@ -2,6 +2,8 @@ from django.conf.urls import url, include from . import views +app_name = 'smf' + module_urls = [ # SMF Service Control url(r'^activate/$', views.activate_smf, name='activate'), @@ -11,5 +13,5 @@ module_urls = [ ] urlpatterns = [ - url(r'^smf/', include(module_urls, namespace='smf')), + url(r'^smf/', include((module_urls, app_name), namespace=app_name)), ] diff --git a/allianceauth/services/modules/teamspeak3/migrations/0001_initial.py b/allianceauth/services/modules/teamspeak3/migrations/0001_initial.py index 0e5f552f..a46605d3 100644 --- a/allianceauth/services/modules/teamspeak3/migrations/0001_initial.py +++ b/allianceauth/services/modules/teamspeak3/migrations/0001_initial.py @@ -24,7 +24,7 @@ class Migration(migrations.Migration): ('auth_group', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='auth.Group')), ], options={ - 'db_table': 'services_authts', + 'db_table': 'teamspeak3_authts', 'verbose_name': 'Auth / TS Group', }, ), @@ -35,7 +35,7 @@ class Migration(migrations.Migration): ('ts_group_name', models.CharField(max_length=30)), ], options={ - 'db_table': 'services_tsgroup', + 'db_table': 'teamspeak3_tsgroup', 'verbose_name': 'TS Group', }, ), @@ -47,7 +47,7 @@ class Migration(migrations.Migration): ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), ], options={ - 'db_table': 'services_usertsgroup', + 'db_table': 'teamspeak3_usertsgroup', 'verbose_name': 'User TS Group', }, ), diff --git a/allianceauth/services/modules/teamspeak3/models.py b/allianceauth/services/modules/teamspeak3/models.py index 2c8e7dc3..97e66cfd 100644 --- a/allianceauth/services/modules/teamspeak3/models.py +++ b/allianceauth/services/modules/teamspeak3/models.py @@ -1,8 +1,9 @@ from django.db import models +from django.contrib.auth.models import User, Group class Teamspeak3User(models.Model): - user = models.OneToOneField('auth.User', + user = models.OneToOneField(User, primary_key=True, on_delete=models.CASCADE, related_name='teamspeak3') @@ -30,7 +31,7 @@ class TSgroup(models.Model): class AuthTS(models.Model): - auth_group = models.ForeignKey('auth.Group', on_delete=models.CASCADE) + auth_group = models.ForeignKey(Group, on_delete=models.CASCADE) ts_group = models.ManyToManyField(TSgroup) class Meta: @@ -41,7 +42,7 @@ class AuthTS(models.Model): class UserTSgroup(models.Model): - user = models.ForeignKey('auth.User', on_delete=models.CASCADE) + user = models.ForeignKey(User, on_delete=models.CASCADE) ts_group = models.ManyToManyField(TSgroup) class Meta: diff --git a/allianceauth/services/modules/teamspeak3/urls.py b/allianceauth/services/modules/teamspeak3/urls.py index ba4e00e8..98bf6992 100644 --- a/allianceauth/services/modules/teamspeak3/urls.py +++ b/allianceauth/services/modules/teamspeak3/urls.py @@ -2,6 +2,8 @@ from django.conf.urls import url, include from . import views +app_name = 'teamspeak3' + module_urls = [ # Teamspeak3 service control url(r'^activate/$', views.activate_teamspeak3, @@ -16,5 +18,5 @@ module_urls = [ ] urlpatterns = [ - url(r'^teamspeak3/', include(module_urls, namespace='teamspeak3')), + url(r'^teamspeak3/', include((module_urls, app_name), namespace=app_name)), ] diff --git a/allianceauth/services/modules/xenforo/urls.py b/allianceauth/services/modules/xenforo/urls.py index d63a3bce..123e7bfe 100644 --- a/allianceauth/services/modules/xenforo/urls.py +++ b/allianceauth/services/modules/xenforo/urls.py @@ -2,6 +2,8 @@ from django.conf.urls import url, include from . import views +app_name = 'xenforo' + module_urls = [ # XenForo service control url(r'^activate/$', views.activate_xenforo_forum, name='activate'), @@ -11,5 +13,5 @@ module_urls = [ ] urlpatterns = [ - url(r'^xenforo/', include(module_urls, namespace='xenforo')), + url(r'^xenforo/', include((module_urls, app_name), namespace=app_name)), ] diff --git a/allianceauth/services/urls.py b/allianceauth/services/urls.py index 1a341255..0503d292 100644 --- a/allianceauth/services/urls.py +++ b/allianceauth/services/urls.py @@ -5,11 +5,11 @@ from . import views urlpatterns = [ # Services - url(r'^services/', include([ + url(r'^services/', include(([ url(r'^$', views.services_view, name='services'), # Tools url(r'^tool/fleet_formatter_tool/$', views.fleet_formatter_view, name='fleet_format_tool'), - ], namespace='services')), + ], 'services'), namespace='services')), ] # Append hooked service urls diff --git a/allianceauth/thirdparty/navhelper/templatetags/navactive.py b/allianceauth/thirdparty/navhelper/templatetags/navactive.py index ebd7b83c..89abed90 100644 --- a/allianceauth/thirdparty/navhelper/templatetags/navactive.py +++ b/allianceauth/thirdparty/navhelper/templatetags/navactive.py @@ -22,7 +22,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ from django.template import Library -from django.core.urlresolvers import resolve +from django.urls import resolve from django.conf import settings import re diff --git a/allianceauth/timerboard/tests.py b/allianceauth/timerboard/tests.py index 11e3c90d..805e228b 100644 --- a/allianceauth/timerboard/tests.py +++ b/allianceauth/timerboard/tests.py @@ -1,6 +1,6 @@ from django_webtest import WebTest from django.utils import timezone -from django.core.urlresolvers import reverse +from django.urls import reverse from django.contrib.auth.models import Permission, User from django.conf import settings diff --git a/allianceauth/urls.py b/allianceauth/urls.py index 65046588..17219a56 100755 --- a/allianceauth/urls.py +++ b/allianceauth/urls.py @@ -23,15 +23,15 @@ urlpatterns = [ url(r'^i18n/', include('django.conf.urls.i18n')), # Authentication - url(r'', include(allianceauth.authentication.urls, namespace='authentication')), + url(r'', include(allianceauth.authentication.urls)), url(r'^account/login/$', TemplateView.as_view(template_name='public/login.html'), name='auth_login_user'), url(r'account/', include(hmac_urls)), # Admin urls - url(r'^admin/', include(admin.site.urls)), + url(r'^admin/', admin.site.urls), # SSO - url(r'^sso/', include(esi.urls, namespace='esi')), + url(r'^sso/', include((esi.urls, 'esi'), namespace='esi')), url(r'^sso/login$', allianceauth.authentication.views.sso_login, name='auth_sso_login'), # Notifications diff --git a/setup.py b/setup.py index fbf65020..a3409457 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,6 @@ install_requires = [ 'django>=1.11', 'django-bootstrap-form', - 'django-bootstrap-pagination', 'django-registration', 'django-sortedm2m', 'django-redis-cache>=1.7.1', diff --git a/test_allianceauth/settings.py b/test_allianceauth/settings.py index a542b06e..739e0daa 100644 --- a/test_allianceauth/settings.py +++ b/test_allianceauth/settings.py @@ -40,7 +40,6 @@ INSTALLED_APPS = [ 'django_celery_beat', 'bootstrapform', 'esi', - 'bootstrap_pagination', 'allianceauth', 'allianceauth.authentication', 'allianceauth.services', diff --git a/tox.ini b/tox.ini index 6826cc63..51d1d1ab 100644 --- a/tox.ini +++ b/tox.ini @@ -15,5 +15,6 @@ deps= dj111: Django>=1.11.1,<2.0 dj20: Django>=2.0a1 dj20: https://github.com/celery/django-celery-beat/zipball/master#egg=django-celery-beat + dj20: https://github.com/Adarnof/adarnauth-esi/zipball/master#egg=adarnauth-esi install_command = pip install -e ".[testing]" -U {opts} {packages} commands=coverage run runtests.py -v 2
    {% trans "User" %}