Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/automated-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,5 @@ jobs:
token: ${{ secrets.GITHUB_TOKEN }}
# The name of the file(s) to upload
files: |
dist/*
dist/*.tar.gz
dist/*.whl
10 changes: 6 additions & 4 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 5 additions & 7 deletions sovtimer/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion sovtimer/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
16 changes: 8 additions & 8 deletions sovtimer/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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()

Expand All @@ -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)
Expand All @@ -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(
Expand All @@ -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()
Expand Down Expand Up @@ -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()

Expand Down
4 changes: 2 additions & 2 deletions sovtimer/tests/test_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand Down
12 changes: 6 additions & 6 deletions sovtimer/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
9 changes: 4 additions & 5 deletions sovtimer/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,16 +102,16 @@ 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'<a href="{defender_url}" target="_blank" rel="noopener noreferer">'
f'<img class="aa-sovtimer-entity-logo-left me-2" src="{defender_logo_url}" '
f'alt="{defender_name}">{defender_name}</a>'
)

# Region / System / Constellation URLs and HTML (compute region_url once)
region_url = dotlan_region_url(eve_obj=region.id)
region_url = dotlan_region_url(eve_obj=region.pk)
campaign_system_name = solar_system.name
solar_system_url = f"{region_url}/{campaign_system_name}"
solar_system_name_html = f'<a href="{solar_system_url}" target="_blank" rel="noopener noreferer">{campaign_system_name}</a>'
Expand Down Expand Up @@ -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}</i>'
)

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'<img src="{static("sovtimer/images/zkillboard.png")}" alt="zKillboard">'
constellation_killboard_link = (
f'<a href="{zkb_href}" target="_blank" rel="noopener noreferer" '
Expand Down
Loading