diff --git a/.github/workflows/automated-checks.yml b/.github/workflows/automated-checks.yml index 15afedf7..8b536951 100644 --- a/.github/workflows/automated-checks.yml +++ b/.github/workflows/automated-checks.yml @@ -3,7 +3,7 @@ name: Tests env: COVERAGE_DATABASE_VERSION: mariadb:10.11 COVERAGE_PYTHON_VERSION: 3.12 - NODE_VERSION: 24 # [LTS] End of Life: 30 Apr 2028 (https://endoflife.date/nodejs) + NODE_VERSION: 26 # [LTS] End of Life: 30 Apr 2029 (https://endoflife.date/nodejs) REDIS_VERSION: latest on: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index be95e44b..82c638e1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -58,4 +58,5 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} # The name of the file(s) to upload files: | - dist/* + dist/*.tar.gz + dist/*.whl diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1edda5a0..66f8d4ea 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -6,7 +6,7 @@ # Set the default language versions for the hooks default_language_version: python: python3 # Force all Python hooks to use Python 3 - node: 24.14.0 # Force all Node hooks to use this specific Node version + node: 26.3.0 # Force all Node hooks to use this specific Node version # https://pre-commit.ci/ ci: @@ -68,7 +68,7 @@ repos: name: Check for large files description: Check for large files that were added to the repository. args: - - --maxkb=1000 + - --maxkb=2048 # 2 MB - id: detect-private-key name: Detect private key @@ -120,8 +120,10 @@ repos: name: End of file fixer description: Ensure that files end with a newline. - - repo: https://github.com/eslint/eslint - rev: 9089853a593d6c7c0f11367da08a829e0ddfe092 # frozen: v10.6.0 +# - repo: https://github.com/eslint/eslint +# rev: 9089853a593d6c7c0f11367da08a829e0ddfe092 # frozen: v10.6.0 + - repo: https://github.com/pre-commit/mirrors-eslint + rev: 8763fc929b6232999d541a3d8eb49965a6b71afb # frozen: v10.6.0 hooks: - id: eslint name: ESLint diff --git a/CHANGELOG.md b/CHANGELOG.md index 1cb58ec5..81946f10 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,6 +53,7 @@ Section Order: ### Changed +- Use `pk` instead of `id` when referring to the primary key of a model instance, since `id` is not guaranteed to be the primary key in Django. - Migrated to Alliance Auth proxy models for `Permission`, `User` and `Group` ## [5.0.1] - 2026-07-07 diff --git a/sovtimer/models.py b/sovtimer/models.py index 5a7045a1..87ad0455 100644 --- a/sovtimer/models.py +++ b/sovtimer/models.py @@ -80,10 +80,8 @@ def bulk_get_or_create_from_esi( :rtype: dict[int, Alliance] """ - existing_alliances = cls.objects.filter(alliance_id__in=alliance_ids) - existing_alliance_ids = set( - existing_alliances.values_list("alliance_id", flat=True) - ) + existing_alliances = cls.objects.filter(pk__in=alliance_ids) + existing_alliance_ids = set(existing_alliances.values_list("pk", flat=True)) alliances_to_create = set(alliance_ids) - existing_alliance_ids @@ -118,9 +116,9 @@ def bulk_get_or_create_from_esi( created_alliances = cls.objects.bulk_create(new_alliances) # Combine existing and newly created alliances into a single dictionary - all_alliances = { - alliance.alliance_id: alliance for alliance in existing_alliances - } | {alliance.alliance_id: alliance for alliance in created_alliances} + all_alliances = {alliance.pk: alliance for alliance in existing_alliances} | { + alliance.pk: alliance for alliance in created_alliances + } return all_alliances diff --git a/sovtimer/tasks.py b/sovtimer/tasks.py index 822d6cb6..2b908849 100644 --- a/sovtimer/tasks.py +++ b/sovtimer/tasks.py @@ -216,7 +216,7 @@ def update_sov_structures( # pylint: disable=too-many-locals # Fetch solar systems from the database solar_systems = { - ss.id: ss for ss in SolarSystem.objects.filter(id__in=solar_system_ids) + ss.id: ss for ss in SolarSystem.objects.filter(pk__in=solar_system_ids) } esi_structure_ids = set() # Track structure IDs from ESI to avoid duplicates diff --git a/sovtimer/tests/test_models.py b/sovtimer/tests/test_models.py index 01dca9e8..85dae711 100644 --- a/sovtimer/tests/test_models.py +++ b/sovtimer/tests/test_models.py @@ -139,8 +139,8 @@ def test_returns_all_alliances_when_all_ids_exist( """ mock_existing_alliances = [ - Alliance(alliance_id=1, name="Alliance 1"), - Alliance(alliance_id=2, name="Alliance 2"), + Alliance(pk=1, name="Alliance 1"), + Alliance(pk=2, name="Alliance 2"), ] mock_qs = MagicMock() mock_qs.__iter__.return_value = iter(mock_existing_alliances) @@ -154,7 +154,7 @@ def test_returns_all_alliances_when_all_ids_exist( self.assertEqual(len(result), 2) self.assertEqual(result[1].name, "Alliance 1") self.assertEqual(result[2].name, "Alliance 2") - mock_filter.assert_called_once_with(alliance_id__in={1, 2}) + mock_filter.assert_called_once_with(pk__in={1, 2}) mock_bulk_create.assert_not_called() mock_get_alliance.assert_not_called() @@ -178,7 +178,7 @@ def test_creates_new_alliances_when_some_ids_do_not_exist( """ mock_existing_alliances = [ - Alliance(alliance_id=1, name="Alliance 1"), + Alliance(pk=1, name="Alliance 1"), ] mock_qs = MagicMock() mock_qs.__iter__.return_value = iter(mock_existing_alliances) @@ -192,8 +192,8 @@ def test_creates_new_alliances_when_some_ids_do_not_exist( mock_get_alliance.side_effect = [a2, a3] mock_bulk_create.return_value = [ - Alliance(alliance_id=2, name="Alliance 2"), - Alliance(alliance_id=3, name="Alliance 3"), + Alliance(pk=2, name="Alliance 2"), + Alliance(pk=3, name="Alliance 3"), ] result = Alliance.bulk_get_or_create_from_esi( @@ -204,7 +204,7 @@ def test_creates_new_alliances_when_some_ids_do_not_exist( self.assertEqual(result[1].name, "Alliance 1") self.assertEqual(result[2].name, "Alliance 2") self.assertEqual(result[3].name, "Alliance 3") - mock_filter.assert_called_once_with(alliance_id__in={1, 2, 3}) + mock_filter.assert_called_once_with(pk__in={1, 2, 3}) mock_get_alliance.assert_any_call(alliance_id=2, force_refresh=False) mock_get_alliance.assert_any_call(alliance_id=3, force_refresh=False) mock_bulk_create.assert_called_once() @@ -239,7 +239,7 @@ def test_skips_creation_when_esi_returns_no_data( ) self.assertEqual(len(result), 0) - mock_filter.assert_called_once_with(alliance_id__in={1}) + mock_filter.assert_called_once_with(pk__in={1}) mock_get_alliance.assert_called_once_with(alliance_id=1, force_refresh=False) mock_bulk_create.assert_not_called() diff --git a/sovtimer/tests/test_tasks.py b/sovtimer/tests/test_tasks.py index ab08825c..80374f22 100644 --- a/sovtimer/tests/test_tasks.py +++ b/sovtimer/tests/test_tasks.py @@ -144,7 +144,7 @@ def test_processes_structure_with_default_vulnerability( ] mock_bulk_get_or_create.return_value = { - 2001: Alliance(alliance_id=2001, name="Alliance 2001") + 2001: Alliance(pk=2001, name="Alliance 2001") } mock_solar_system_filter.return_value = [SolarSystem(id=3001)] mock_bulk_create.return_value = None @@ -157,7 +157,7 @@ def test_processes_structure_with_default_vulnerability( mock_bulk_get_or_create.assert_called_once_with( alliance_ids={2001}, force_refresh=False ) - mock_solar_system_filter.assert_called_once_with(id__in={3001}) + mock_solar_system_filter.assert_called_once_with(pk__in={3001}) mock_bulk_create.assert_called_once() created = mock_bulk_create.call_args[0][0] self.assertEqual(len(created), 1) diff --git a/sovtimer/tests/test_views.py b/sovtimer/tests/test_views.py index a3d80c40..28bec5f3 100644 --- a/sovtimer/tests/test_views.py +++ b/sovtimer/tests/test_views.py @@ -147,10 +147,10 @@ def test_dashboard_data_includes_active_campaigns( constellation = MagicMock() constellation.name = "Constellation A" - constellation.id = 7002 + constellation.pk = 7002 region = MagicMock() region.name = "Region A" - region.id = 7001 + region.pk = 7001 constellation.region = region solar_system.constellation = constellation structure.solar_system = solar_system @@ -216,7 +216,7 @@ def test_dashboard_data_handles_missing_vulnerability_levels( constellation.name = "Constellation B" region = MagicMock() region.name = "Region B" - region.id = 7003 + region.pk = 7003 constellation.region = region solar_system.constellation = constellation structure.solar_system = solar_system @@ -288,10 +288,10 @@ def test_campaign_status_is_upcoming_when_within_timeframe( constellation = MagicMock() constellation.name = "Constellation U" - constellation.id = 7004 + constellation.pk = 7004 region = MagicMock() region.name = "Region U" - region.id = 7005 + region.pk = 7005 constellation.region = region solar_system.constellation = constellation structure.solar_system = solar_system @@ -354,7 +354,7 @@ def test_sets_attackers_progress_when_previous_progress_is_higher( constellation.name = "Constellation X" region = MagicMock() region.name = "Region X" - region.id = 7006 + region.pk = 7006 constellation.region = region solar_system.constellation = constellation structure.solar_system = solar_system diff --git a/sovtimer/views.py b/sovtimer/views.py index 24c4288c..13a55396 100644 --- a/sovtimer/views.py +++ b/sovtimer/views.py @@ -102,8 +102,8 @@ def dashboard_data( # pylint: disable=too-many-statements too-many-locals # Defender defender_name = alliance.name - defender_url = dotlan_alliance_url(eve_obj=alliance.alliance_id) - defender_logo_url = alliance_logo_url(alliance_id=alliance.alliance_id, size=32) + defender_url = dotlan_alliance_url(eve_obj=alliance.pk) + defender_logo_url = alliance_logo_url(alliance_id=alliance.pk, size=32) defender_name_html = ( f'' f'{campaign_system_name}' @@ -161,8 +161,7 @@ def dashboard_data( # pylint: disable=too-many-statements too-many-locals f'title="{title}" data-bs-tooltip="aa-sovtimer">{icon_name}' ) - constellation_id = constellation.id - zkb_href = f"https://zkillboard.com/constellation/{constellation_id}/" + zkb_href = f"https://zkillboard.com/constellation/{constellation.pk}/" zkb_icon = f'zKillboard' constellation_killboard_link = ( f'