diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 348e31a1..154e7208 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -25,7 +25,7 @@ before_script: pre-commit-check: <<: *only-default stage: pre-commit - image: python:3.12-bookworm + image: python:3.11-trixie # variables: # PRE_COMMIT_HOME: ${CI_PROJECT_DIR}/.cache/pre-commit # cache: @@ -53,7 +53,7 @@ secret_detection: test-3.10-core: <<: *only-default - image: python:3.10-bookworm + image: python:3.10-trixie script: - tox -e py310-core artifacts: @@ -65,7 +65,7 @@ test-3.10-core: test-3.11-core: <<: *only-default - image: python:3.11-bookworm + image: python:3.11-trixie script: - tox -e py311-core artifacts: @@ -77,7 +77,7 @@ test-3.11-core: test-3.12-core: <<: *only-default - image: python:3.12-bookworm + image: python:3.12-trixie script: - tox -e py312-core artifacts: @@ -89,7 +89,7 @@ test-3.12-core: test-3.13-core: <<: *only-default - image: python:3.13-rc-bookworm + image: python:3.13-trixie script: - tox -e py313-core artifacts: @@ -99,9 +99,21 @@ test-3.13-core: coverage_format: cobertura path: coverage.xml +test-3.14-core: + <<: *only-default + image: python:3.14-trixie + script: + - tox -e py314-core + artifacts: + when: always + reports: + coverage_report: + coverage_format: cobertura + path: coverage.xml + test-3.10-all: <<: *only-default - image: python:3.10-bookworm + image: python:3.10-trixie script: - tox -e py310-all artifacts: @@ -113,7 +125,7 @@ test-3.10-all: test-3.11-all: <<: *only-default - image: python:3.11-bookworm + image: python:3.11-trixie script: - tox -e py311-all artifacts: @@ -126,7 +138,7 @@ test-3.11-all: test-3.12-all: <<: *only-default - image: python:3.12-bookworm + image: python:3.12-trixie script: - tox -e py312-all artifacts: @@ -138,7 +150,7 @@ test-3.12-all: test-3.13-all: <<: *only-default - image: python:3.13-rc-bookworm + image: python:3.13-trixie script: - tox -e py313-all artifacts: @@ -148,9 +160,21 @@ test-3.13-all: coverage_format: cobertura path: coverage.xml +test-3.14-all: + <<: *only-default + image: python:3.14-trixie + script: + - tox -e py314-all + artifacts: + when: always + reports: + coverage_report: + coverage_format: cobertura + path: coverage.xml + build-test: stage: test - image: python:3.12-bookworm + image: python:3.12-trixie before_script: - python -m pip install --upgrade pip @@ -169,13 +193,13 @@ build-test: test-docs: <<: *only-default - image: python:3.12-bookworm + image: python:3.12-trixie script: - tox -e docs deploy_production: stage: deploy - image: python:3.12-bookworm + image: python:3.12-trixie before_script: - python -m pip install --upgrade pip diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index abebc6f7..75405373 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -26,7 +26,7 @@ exclude: | repos: # Code Upgrades - repo: https://github.com/adamchainz/django-upgrade - rev: 1.25.0 + rev: 1.29.0 hooks: - id: django-upgrade args: [--target-version=5.2] @@ -38,7 +38,7 @@ repos: # Formatting - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v5.0.0 + rev: v6.0.0 hooks: # Identify invalid files - id: check-ast @@ -56,8 +56,6 @@ repos: # - id: check-docstring-first - id: debug-statements # - id: requirements-txt-fixer - - id: fix-encoding-pragma - args: [--remove] - id: fix-byte-order-marker # General quality checks - id: mixed-line-ending @@ -67,7 +65,7 @@ repos: - id: check-executables-have-shebangs - id: end-of-file-fixer - repo: https://github.com/editorconfig-checker/editorconfig-checker.python - rev: 3.2.1 + rev: 3.4.0 hooks: - id: editorconfig-checker - repo: https://github.com/igorshubovych/markdownlint-cli @@ -80,17 +78,13 @@ repos: # Infrastructure - repo: https://github.com/tox-dev/pyproject-fmt - rev: v2.6.0 + rev: v2.11.0 hooks: - id: pyproject-fmt args: - --indent=4 additional_dependencies: - - tox==4.26.0 # https://github.com/tox-dev/tox/releases/latest - - repo: https://github.com/tox-dev/tox-ini-fmt - rev: 1.5.0 - hooks: - - id: tox-ini-fmt + - tox==4.32.0 # https://github.com/tox-dev/tox/releases/latest - repo: https://github.com/abravalheri/validate-pyproject rev: v0.24.1 hooks: diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 00000000..bad2fe03 --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1 @@ +* @allianceauth diff --git a/README.md b/README.md index 31557bc5..426f0fec 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,6 @@ Alliance Auth is maintained and developed by the community and we welcome every To see what needs to be worked on please review our issue list or chat with our active developers on Discord. -Also, please make sure you have signed the [License Agreement](https://developers.eveonline.com/resource/license-agreement) by logging in at [https://developers.eveonline.com](https://developers.eveonline.com) before submitting any pull requests. +Also, please make sure you have signed the [License Agreement](https://developers.eveonline.com/license-agreement) by logging in at [https://developers.eveonline.com](https://developers.eveonline.com) before submitting any pull requests. In addition to the core AA system we also very much welcome contributions to our growing list of 3rd party services and plugin apps. Please see [AA Community Creations](https://gitlab.com/allianceauth/community-creations) for details. diff --git a/allianceauth/__init__.py b/allianceauth/__init__.py index 1b5e038c..e87679d9 100644 --- a/allianceauth/__init__.py +++ b/allianceauth/__init__.py @@ -6,6 +6,7 @@ manage online service access. # Django starts so that shared_task will use this app. __version__ = '5.0.0a3' -__title__ = 'AllianceAuth' +__title__ = 'Alliance Auth' +__title_useragent__ = 'AllianceAuth' __url__ = 'https://gitlab.com/allianceauth/allianceauth' NAME = f'{__title__} v{__version__}' diff --git a/allianceauth/admin_status/templates/admin-status/celery_bar_partial.html b/allianceauth/admin_status/templates/admin-status/celery_bar_partial.html index b926917f..7af2712f 100644 --- a/allianceauth/admin_status/templates/admin-status/celery_bar_partial.html +++ b/allianceauth/admin_status/templates/admin-status/celery_bar_partial.html @@ -2,6 +2,7 @@ {% load admin_status %}
- {% widthratio tasks_count tasks_total 100 %}% + {% widthratio tasks_count tasks_total 100 %}%
diff --git a/allianceauth/admin_status/templates/admin-status/esi_check.html b/allianceauth/admin_status/templates/admin-status/esi_check.html index 9c7f1605..14fbc96e 100644 --- a/allianceauth/admin_status/templates/admin-status/esi_check.html +++ b/allianceauth/admin_status/templates/admin-status/esi_check.html @@ -1,37 +1,32 @@ {% load i18n %} +

{% translate 'Your Server received an ESI error response code of ' %}?



     
-
- + + diff --git a/allianceauth/admin_status/templates/admin-status/overview.html b/allianceauth/admin_status/templates/admin-status/overview.html index f305c7b5..c7086d52 100644 --- a/allianceauth/admin_status/templates/admin-status/overview.html +++ b/allianceauth/admin_status/templates/admin-status/overview.html @@ -1,6 +1,44 @@ {% load i18n %} {% load humanize %} +{% get_current_language as LANGUAGE_CODE %} + +{% comment %} +Some translations used in the HTML and JavaScript code below. +We define them here so that they can be used in the JavaScript code as well with +the escapejs filter without having to redefine them later. +{% endcomment %} +{% translate "second" as l10nSecondSingular %} +{% translate "seconds" as l10nSecondPlural %} +{% translate "minute" as l10nMinuteSingular %} +{% translate "minutes" as l10nMinutePlural %} +{% translate "hour" as l10nHourSingular %} +{% translate "hours" as l10nHourPlural %} +{% translate "N/A" as l10nNA %} +{% translate "ERROR" as l10nError %} +{% translate "running" as l10nRunning %} +{% translate "queued" as l10nQueued %} +{% translate "succeeded" as l10nSucceeded %} +{% translate "retried" as l10nRetried %} +{% translate "failed" as l10nFailed %} + +{% if debug %} +
+
+
+ {% translate "Debug mode" as widget_title %} + {% include "framework/dashboard/widget-title.html" with title=widget_title %} + +
+

+ {% translate "Debug mode is currently turned on!
Make sure to turn it off as soon as you are finished testing." %} +

+
+
+
+
+{% endif %} + {% if notifications %}
@@ -94,23 +132,27 @@

{% blocktranslate with total=tasks_total|intcomma latest=earliest_task|timesince|default:"?" %} - Status of {{ total }} processed tasks • last {{ latest }} + Status of ? processed tasks • last ? {% endblocktranslate %}

- {% include "admin-status/celery_bar_partial.html" with label="suceeded" level="success" tasks_count=tasks_succeeded %} - {% include "admin-status/celery_bar_partial.html" with label="retried" level="info" tasks_count=tasks_retried %} - {% include "admin-status/celery_bar_partial.html" with label="failed" level="danger" tasks_count=tasks_failed %} + {% include "allianceauth/admin-status/celery_bar_partial.html" with label="succeeded" level="success" tasks_count=0 %} + {% include "allianceauth/admin-status/celery_bar_partial.html" with label="retried" level="info" tasks_count=0 %} + {% include "allianceauth/admin-status/celery_bar_partial.html" with label="failed" level="danger" tasks_count=0 %}

- ? {% translate 'running' %} | - ? {% translate 'queued' %} + ? {{ l10nRunning }} | + ? {{ l10nQueued }} | + ? {{ l10nSucceeded }} | + ? {{ l10nRetried }} | + ? {{ l10nFailed }}

@@ -133,34 +175,24 @@
+{% include "bundles/auth-dashboard-task-queue-js.html" %} diff --git a/allianceauth/admin_status/templatetags/admin_status.py b/allianceauth/admin_status/templatetags/admin_status.py index af1f8f48..9446397c 100644 --- a/allianceauth/admin_status/templatetags/admin_status.py +++ b/allianceauth/admin_status/templatetags/admin_status.py @@ -49,6 +49,7 @@ def status_overview() -> dict: "tasks_total": 0, "tasks_hours": 0, "earliest_task": None, + "debug": settings.DEBUG if settings.DISPLAY_DEBUG else False, } response.update(_current_notifications()) response.update(_current_version_summary()) diff --git a/allianceauth/authentication/middleware.py b/allianceauth/authentication/middleware.py index 15f0b431..2f93c9e9 100644 --- a/allianceauth/authentication/middleware.py +++ b/allianceauth/authentication/middleware.py @@ -52,4 +52,10 @@ class UserSettingsMiddleware(MiddlewareMixin): except Exception as e: logger.exception(e) + # Minimize Menu + try: + request.session["MINIMIZE_SIDEBAR"] = request.user.profile.minimize_sidebar + except Exception as e: + pass # We don't care that an anonymous user has no profile (not logged in) + return response diff --git a/allianceauth/authentication/migrations/0025_userprofile_minimize_sidebar.py b/allianceauth/authentication/migrations/0025_userprofile_minimize_sidebar.py new file mode 100644 index 00000000..bbd28732 --- /dev/null +++ b/allianceauth/authentication/migrations/0025_userprofile_minimize_sidebar.py @@ -0,0 +1,22 @@ +# Generated by Django 4.2.25 on 2025-10-14 22:02 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("authentication", "0024_alter_userprofile_language"), + ] + + operations = [ + migrations.AddField( + model_name="userprofile", + name="minimize_sidebar", + field=models.BooleanField( + default=False, + help_text="Keep the sidebar menu minimized", + verbose_name="Minimize Sidebar Menu", + ), + ), + ] diff --git a/allianceauth/authentication/models.py b/allianceauth/authentication/models.py index 9670376b..52724636 100644 --- a/allianceauth/authentication/models.py +++ b/allianceauth/authentication/models.py @@ -96,7 +96,8 @@ class UserProfile(models.Model): on_delete=models.SET_DEFAULT, default=get_guest_state_pk) language = models.CharField( - _("Language"), max_length=10, + _("Language"), + max_length=10, choices=Language.choices, blank=True, default='') @@ -110,6 +111,12 @@ class UserProfile(models.Model): blank=True, help_text="Bootstrap 5 Themes from https://bootswatch.com/ or Community Apps" ) + minimize_sidebar = models.BooleanField( + _("Minimize Sidebar Menu"), + default=False, + help_text=_("Keep the sidebar menu minimized") + ) + class Meta: default_permissions = ('change',) diff --git a/allianceauth/authentication/task_statistics/counters.py b/allianceauth/authentication/task_statistics/counters.py index 3d146343..b8f8ef86 100644 --- a/allianceauth/authentication/task_statistics/counters.py +++ b/allianceauth/authentication/task_statistics/counters.py @@ -27,7 +27,7 @@ def dashboard_results(hours: int) -> _TaskCounts: my_earliest = events.first_event(earliest=earliest) return [my_earliest] if my_earliest else [] - earliest = dt.datetime.utcnow() - dt.timedelta(hours=hours) + earliest = dt.datetime.now(dt.timezone.utc) - dt.timedelta(hours=hours) earliest_events = [] succeeded_count = succeeded_tasks.count(earliest=earliest) earliest_events += earliest_if_exists(succeeded_tasks, earliest) diff --git a/allianceauth/authentication/task_statistics/event_series.py b/allianceauth/authentication/task_statistics/event_series.py index b602ef04..ef46c270 100644 --- a/allianceauth/authentication/task_statistics/event_series.py +++ b/allianceauth/authentication/task_statistics/event_series.py @@ -41,7 +41,7 @@ class EventSeries: - event_time: timestamp of event. Will use current time if not specified. """ if not event_time: - event_time = dt.datetime.utcnow() + event_time = dt.datetime.now(dt.timezone.utc) my_id = self._redis.incr(self._key_counter) self._redis.zadd(self._key_sorted_set, {my_id: event_time.timestamp()}) diff --git a/allianceauth/authentication/templates/public/lang_select.html b/allianceauth/authentication/templates/public/lang_select.html index eb71d6b0..8c06d862 100644 --- a/allianceauth/authentication/templates/public/lang_select.html +++ b/allianceauth/authentication/templates/public/lang_select.html @@ -3,7 +3,7 @@