Compare commits

...

12 Commits

Author SHA1 Message Date
Ariel Rin
ec02c0d985 Merge branch 'translations_7f31a07ccd4e4a66b1dd7b6bc2dbddb5' into 'master'
Updates for project Alliance Auth

See merge request allianceauth/allianceauth!1725
2025-06-19 10:31:28 +00:00
Joel Falknau
aaf718fe4d
update pre-commit 2025-06-19 20:30:37 +10:00
Joel Falknau
a193d9959b
makemessages 2025-06-19 20:23:21 +10:00
Ariel Rin
12250ef0c2 Merge branch 'exclude-biomassed-characters' into 'master'
[ADD] `exclude_biomassed` to `EveCharacterManager`

See merge request allianceauth/allianceauth!1727
2025-06-19 10:13:47 +00:00
Ariel Rin
bde9802583 Merge branch 'user-menu-fixes' into 'master'
[CHANGE] User Menu Template Improvements

See merge request allianceauth/allianceauth!1728
2025-06-19 10:12:16 +00:00
Ariel Rin
1b30b86d2b Merge branch 'improve-get_all_characters_from_user' into 'master'
[CHANGE] Improve `get_all_characters_from_user`

See merge request allianceauth/allianceauth!1729
2025-06-19 10:11:43 +00:00
Ariel Rin
0707b9b98c Merge branch 'error-not-warning' into 'master'
[FIX] Error codes should trigger errors, not warnings

See merge request allianceauth/allianceauth!1730
2025-06-19 10:11:09 +00:00
Peter Pfeufer
b22a379db2
[FIX] Error codes should trigger errors, not warnings 2025-06-17 17:27:51 +02:00
Peter Pfeufer
bb2e0aabbc
[CHANGE] Improve get_all_characters_from_user
### Added

- `main_first` option to move the main character to the first position of the character list

### Changed

- Character list sorted alphabetically
2025-06-17 16:38:55 +02:00
Peter Pfeufer
449991d846
[FIX] Several HTML fixes
- Remove unnecessary HTML tags
- Remove unnecessary Bootstrap classes
- Add title attributes
- Make strings translatable
2025-06-15 12:15:14 +02:00
Peter Pfeufer
dd42c2b074
[CHANGE] Only show theme selection if more than 1 theme is available 2025-06-15 12:10:44 +02:00
Peter Pfeufer
abff1b0add
[ADD] exclude_biomassed to EveCharacterManager 2025-06-13 11:29:05 +02:00
13 changed files with 217 additions and 89 deletions

View File

@ -25,12 +25,12 @@ exclude: |
repos:
# Code Upgrades
- repo: https://github.com/asottile/pyupgrade
rev: v3.19.1
rev: v3.20.0
hooks:
- id: pyupgrade
args: [--py38-plus]
- repo: https://github.com/adamchainz/django-upgrade
rev: 1.22.2
rev: 1.25.0
hooks:
- id: django-upgrade
args: [--target-version=4.2]
@ -66,11 +66,11 @@ repos:
- id: check-executables-have-shebangs
- id: end-of-file-fixer
- repo: https://github.com/editorconfig-checker/editorconfig-checker.python
rev: 3.2.0
rev: 3.2.1
hooks:
- id: editorconfig-checker
- repo: https://github.com/igorshubovych/markdownlint-cli
rev: v0.44.0
rev: v0.45.0
hooks:
- id: markdownlint
language: node
@ -78,7 +78,7 @@ repos:
- --disable=MD013
# Infrastructure
- repo: https://github.com/tox-dev/pyproject-fmt
rev: v2.5.0
rev: v2.6.0
hooks:
- id: pyproject-fmt
name: pyproject.toml formatter
@ -88,7 +88,7 @@ repos:
additional_dependencies:
- tox==4.24.1 # https://github.com/tox-dev/tox/releases/latest
- repo: https://github.com/abravalheri/validate-pyproject
rev: v0.23
rev: v0.24.1
hooks:
- id: validate-pyproject
name: Validate pyproject.toml

View File

@ -1,7 +1,6 @@
{% load i18n %}
<div class="dropdown">
<form action="{% url 'set_language' %}" method="post">
<form class="dropdown-item" action="{% url 'set_language' %}" method="post">
{% csrf_token %}
<select class="form-select" onchange="this.form.submit()" class="form-control" id="lang-select" name="language">
@ -13,5 +12,4 @@
</option>
{% endfor %}
</select>
</form>
</div>
</form>

View File

@ -14,6 +14,16 @@ class EveCharacterProviderManager:
class EveCharacterManager(models.Manager):
provider = EveCharacterProviderManager()
def exclude_biomassed(self):
"""
Get a queryset of EveCharacter objects, excluding the "Doomheim" corporation (1000001).
:return:
:rtype:
"""
return self.exclude(corporation_id=1000001)
def create_character(self, character_id) -> models.Model:
return self.create_character_obj(self.provider.get_character(character_id))

View File

@ -10,23 +10,38 @@ from allianceauth.authentication.models import CharacterOwnership
from allianceauth.eveonline.models import EveCharacter
def get_all_characters_from_user(user: User) -> list:
def get_all_characters_from_user(user: User, main_first: bool = False) -> list:
"""
Get all characters from a user or an empty list
when no characters are found for the user or the user is None
Get all characters from a user
This function retrieves all characters associated with a given user, optionally ordering them
with the main character first.
If the user is None, an empty list is returned.
:param user:
:type user:
:return:
:rtype:
:param user: The user whose characters are to be retrieved
:type user: User
:param main_first: If True, the main character will be listed first
:type main_first: bool
:return: A list of EveCharacter objects associated with the user
:rtype: list[EveCharacter]
"""
if user is None:
return []
try:
if main_first:
characters = [
char.character for char in CharacterOwnership.objects.filter(user=user)
char.character
for char in CharacterOwnership.objects.filter(user=user).order_by(
"-character__userprofile", "character__character_name"
)
]
else:
characters = [
char.character
for char in CharacterOwnership.objects.filter(user=user).order_by(
"character__character_name"
)
]
except AttributeError:
return []

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-05-24 16:55+1000\n"
"POT-Creation-Date: 2025-06-19 20:23+1000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -121,7 +121,7 @@ msgid "Simplified Chinese"
msgstr ""
#: allianceauth/authentication/models.py:100
#: allianceauth/menu/templates/menu/menu-user.html:42
#: allianceauth/menu/templates/menu/menu-user.html:67
msgid "Language"
msgstr ""
@ -131,7 +131,7 @@ msgid "Night Mode"
msgstr ""
#: allianceauth/authentication/models.py:109
#: allianceauth/menu/templates/menu/menu-user.html:46
#: allianceauth/theme/templates/theme/theme_select.html:4
msgid "Theme"
msgstr ""
@ -202,6 +202,8 @@ msgstr ""
#: allianceauth/authentication/templates/authentication/tokens.html:7
#: allianceauth/authentication/templates/authentication/tokens.html:11
#: allianceauth/menu/templates/menu/menu-user.html:133
#: allianceauth/menu/templates/menu/menu-user.html:136
#: allianceauth/templates/allianceauth/top-menu-user-dropdown.html:62
msgid "Token Management"
msgstr ""
@ -1465,20 +1467,38 @@ msgstr ""
msgid "Notifications"
msgstr ""
#: allianceauth/menu/templates/menu/menu-user.html:56
#: allianceauth/menu/templates/menu/menu-user.html:77
msgid "Super User"
msgstr ""
#: allianceauth/menu/templates/menu/menu-user.html:70
#: allianceauth/menu/templates/menu/menu-user.html:83
#: allianceauth/menu/templates/menu/menu-user.html:86
msgid "Alliance Auth Documentation"
msgstr ""
#: allianceauth/menu/templates/menu/menu-user.html:94
#: allianceauth/menu/templates/menu/menu-user.html:97
msgid "Alliance Auth Discord"
msgstr ""
#: allianceauth/menu/templates/menu/menu-user.html:105
#: allianceauth/menu/templates/menu/menu-user.html:108
msgid "Alliance Auth Git"
msgstr ""
#: allianceauth/menu/templates/menu/menu-user.html:118
#: allianceauth/menu/templates/menu/menu-user.html:121
#: allianceauth/templates/allianceauth/top-menu-admin.html:9
msgid "Admin"
msgstr ""
#: allianceauth/menu/templates/menu/menu-user.html:82
#: allianceauth/menu/templates/menu/menu-user.html:144
#: allianceauth/menu/templates/menu/menu-user.html:147
msgid "Sign Out"
msgstr ""
#: allianceauth/menu/templates/menu/menu-user.html:86
#: allianceauth/menu/templates/menu/menu-user.html:155
#: allianceauth/menu/templates/menu/menu-user.html:158
#: allianceauth/templates/allianceauth/top-menu-rh-default.html:17
#: allianceauth/templates/allianceauth/top-menu-rh-default.html:18
msgid "Sign In"
@ -2645,7 +2665,7 @@ msgstr ""
msgid "Toggle navigation"
msgstr ""
#: allianceauth/theme/templates/theme/theme_select.html:7
#: allianceauth/theme/templates/theme/theme_select.html:11
msgid "Select Theme"
msgstr ""

View File

@ -2,28 +2,51 @@
{% load evelinks %}
{% load theme_tags %}
<div id="aa-user-info" class="w-100 d-flex flex-column justify-content-center align-items-center text-center py-1 border-top border-secondary {% if not user.is_authenticated %}position-absolute bottom-0{% endif %}">
<div
id="aa-user-info"
class="w-100 d-flex flex-column justify-content-center align-items-center text-center py-1 border-top border-secondary {% if not user.is_authenticated %}position-absolute bottom-0{% endif %}"
>
<div class="d-flex mb-0 w-100">
<div class="p-2 position-relative m-2">
{% if user.is_authenticated %}
{% with request.user.profile.main_character as main %}
<img class="rounded-circle" src="{{ main.character_id|character_portrait_url:64 }}" alt="{{ main.character_name }}">
<img class="rounded-circle position-absolute bottom-0 start-0" src="{{ main.corporation_logo_url_32 }}" alt="{{ main.corporation_name }}">
<img
class="rounded-circle"
src="{{ main.character_id|character_portrait_url:64 }}"
alt="{{ main.character_name }}"
>
<img
class="rounded-circle position-absolute bottom-0 start-0"
src="{{ main.corporation_logo_url_32 }}"
alt="{{ main.corporation_name }}"
>
{% if main.alliance_id %}
<img class="rounded-circle position-absolute bottom-0 end-0" src="{{ main.alliance_logo_url_32 }}" alt="{{ main.alliance_name }}">
<img
class="rounded-circle position-absolute bottom-0 end-0"
src="{{ main.alliance_logo_url_32 }}"
alt="{{ main.alliance_name }}"
>
{% elif main.faction_id %}
<img class="rounded-circle position-absolute bottom-0 end-0" src="{{ main.faction_logo_url_32 }}" alt="{{ main.faction_name }}">
<img
class="rounded-circle position-absolute bottom-0 end-0"
src="{{ main.faction_logo_url_32 }}"
alt="{{ main.faction_name }}"
>
{% endif %}
{% endwith %}
{% else %}
{% include "bundles/image-auth-logo.html" with logo_width="64px" %}
{% endif %}
</div>
<div class="align-self-center text-start">
{% if user.is_authenticated %}
{% with request.user.profile.main_character as main %}
<h5 class="m-0">{{ main.character_name }}</h5>
<p class="m-0 small">{{ main.corporation_name }}</p>
{% if main.alliance_id %}
<p class="m-0 small">{{ main.alliance_name }}</p>
{% elif main.faction_id %}
@ -34,56 +57,106 @@
<h5 class="m-0">{{ SITE_NAME }}</h5>
{% endif %}
</div>
<div class="ms-auto dropup">
<button type="button" class="h-100 btn" data-bs-toggle="dropdown" aria-expanded="false">
<i class="fa-solid fa-gear fa-fw text-light"></i>
</button>
<ul class="dropdown-menu" style="min-width: 200px;">
<li><h6 class="dropdown-header">{% translate "Language" %}</h6></li>
<li>
<a class="dropdown-item">{% include "public/lang_select.html" %}</a>
</li>
<li><h6 class="dropdown-header">{% translate "Theme" %}</h6></li>
<li>
<a class="dropdown-item">
{% theme_select %}
</a>
{% include "public/lang_select.html" %}
</li>
{% theme_select %}
{% if user.is_superuser %}
<li><hr class="dropdown-divider"></li>
<li><h6 class="dropdown-header">{% translate "Super User" %}</h6></li>
<li>
<a class="dropdown-item" href="https://allianceauth.readthedocs.io/" title="Alliance Auth Documentation"><i class="fa-solid fa-book fa-fw"></i> Alliance Auth Documentation</a>
<a
class="dropdown-item"
href="https://allianceauth.readthedocs.io/"
title="{% translate 'Alliance Auth Documentation' %}"
>
<i class="fa-solid fa-book fa-fw"></i>
{% translate "Alliance Auth Documentation" %}
</a>
</li>
<li>
<a class="dropdown-item" href="https://discord.gg/fjnHAmk" title="Alliance Auth Discord"><i class="fa-brands fa-discord fa-fw"></i> Alliance Auth Discord</a>
<a
class="dropdown-item"
href="https://discord.gg/fjnHAmk"
title="{% translate 'Alliance Auth Discord' %}"
>
<i class="fa-brands fa-discord fa-fw"></i>
{% translate "Alliance Auth Discord" %}
</a>
</li>
<li>
<a class="dropdown-item" href="https://gitlab.com/allianceauth/allianceauth" title="Alliance Auth Git"><i class="fa-brands fa-gitlab fa-fw"></i> Alliance Auth Git</a>
<a
class="dropdown-item"
href="https://gitlab.com/allianceauth/allianceauth"
title="{% translate 'Alliance Auth Git' %}"
>
<i class="fa-brands fa-gitlab fa-fw"></i>
{% translate "Alliance Auth Git" %}
</a>
</li>
{% endif %}
{% if user.is_staff %}
<li>
<a class="dropdown-item" href="{% url 'admin:index' %}">
<i class="fa-solid fa-gear fa-fw"></i> {% translate "Admin" %}
<a
class="dropdown-item"
href="{% url 'admin:index' %}"
title="{% translate 'Admin' %}"
>
<i class="fa-solid fa-gear fa-fw"></i>
{% translate "Admin" %}
</a>
</li>
{% endif %}
<li><hr class="dropdown-divider"></li>
{% if user.is_authenticated %}
<li>
<a class="dropdown-item" href="{% url 'authentication:token_management' %}">
<i class="fa-solid fa-user-lock fa-fw"></i> Token Management
<a
class="dropdown-item"
href="{% url 'authentication:token_management' %}"
title="{% translate 'Token Management' %}"
>
<i class="fa-solid fa-user-lock fa-fw"></i>
{% translate "Token Management" %}
</a>
</li>
<li>
<a class="dropdown-item text-danger" href="{% url 'logout' %}" title="{% translate 'Sign Out' %}"><i class="fa-solid fa-right-from-bracket fa-fw "></i> {% translate 'Sign Out' %}</a>
<a
class="dropdown-item text-danger"
href="{% url 'logout' %}"
title="{% translate 'Sign Out' %}"
>
<i class="fa-solid fa-right-from-bracket fa-fw"></i>
{% translate 'Sign Out' %}
</a>
</li>
{% else %}
<li>
<a class="dropdown-item text-success" href="{% url 'authentication:login' %}" title="{% translate 'Sign In' %}"> <i class="fa-solid fa-right-to-bracket fa-fw "></i> {% translate 'Sign In' %}</a>
<a
class="dropdown-item text-success"
href="{% url 'authentication:login' %}"
title="{% translate 'Sign In' %}"
>
<i class="fa-solid fa-right-to-bracket fa-fw"></i>
{% translate 'Sign In' %}
</a>
</li>
{% endif %}
</ul>

View File

@ -675,7 +675,7 @@ class DiscordClient:
)
logger.debug('%s: response:\n%s', uid, r.text)
if not r.ok:
logger.warning(
logger.error(
'%s: Discord API returned error code %d and this response: %s',
uid,
r.status_code,

View File

@ -1,13 +1,21 @@
{% load i18n %}
<form action="{% url 'theme' %}?next={{ next|urlencode }}" method="post">
{% if themes|length > 1 %}
<li><h6 class="dropdown-header">{% translate "Theme" %}</h6></li>
<li>
<form class="dropdown-item" action="{% url 'theme' %}?next={{ next|urlencode }}" method="post">
{% csrf_token %}
<select name="theme" class="form-select" aria-label="" onchange="this.form.submit()">
<select name="theme" class="form-select" onchange="this.form.submit()">
<option selected>{% translate "Select Theme" %}</option>
{% for theme in themes %}
<option value="{{ theme.get_name }}"{% if selected_theme.name == theme.name %} selected="selected"{% endif %}>{{ theme.name }}</option>
<option value="{{ theme.get_name }}"{% if selected_theme.name == theme.name %} selected="selected"{% endif %}>
{{ theme.name }}
</option>
{% endfor %}
</select>
</form>
</form>
</li>
{% endif %}

View File

@ -43,7 +43,7 @@ if the `EveCharacter` has no user.
### get_all_characters_from_user
This is to get all character objects (`EveCharacter`) of a user.
This is to get all character objects (`EveCharacter`) of a user (alphabetically sorted).
Given we have a `User` object called `my_user` and we want to get all characters:
@ -51,12 +51,16 @@ Given we have a `User` object called `my_user` and we want to get all characters
# Alliance Auth
from allianceauth.framework.api.user import get_all_characters_from_user
characters = get_all_characters_from_user(user=my_user)
characters = get_all_characters_from_user(user=my_user, main_first=False)
```
Now, `characters` is a `list` containing all `EveCharacter` objects of the user.
If the user is `None`, an empty `list` will be returned.
The second parameter `main_first` is optional and defaults to `False`.
If set to `True`, the function will return the main character as the first
item in the list of characters.
### get_main_character_from_user
This is to get the main character object (`EveCharacter`) of a user.

View File

@ -271,14 +271,14 @@ Every Alliance Auth installation will come with a couple of special celery relat
Celery-once is a celery extension "that allows you to prevent multiple execution and queuing of celery tasks". What that means is that you can ensure that only one instance of a celery task runs at any given time. This can be useful, for example, if you do not want multiple instances of your task to talk to the same external service at the same time.
We use a custom backend for celery_once in Alliance Auth defined [here](https://gitlab.com/allianceauth/allianceauth/-/blob/master/allianceauth/services/tasks.py#L14)
We use a custom backend for celery_once in Alliance Auth defined [allianceauth.services.tasks.celery_once](https://gitlab.com/allianceauth/allianceauth/-/blob/master/allianceauth/services/tasks.py#L14)
You can import it for use like so:
```python
from allianceauth.services.tasks import QueueOnce
```
An example of Alliance Auth's use within the `@sharedtask` decorator, can be seen [here](https://gitlab.com/allianceauth/allianceauth/-/blob/master/allianceauth/services/modules/discord/tasks.py#L62) in the discord module
An example of Alliance Auth's use within the `@sharedtask` decorator, can be seen [allianceauth.services.modules.discord.tasks](https://gitlab.com/allianceauth/allianceauth/-/blob/master/allianceauth/services/modules/discord/tasks.py#L62) in the discord module
You can use it like so:
```python

View File

@ -17,7 +17,7 @@ If at any point `docker compose` does not work, but `docker-compose` does, you h
1. run `bash <(curl -s https://gitlab.com/allianceauth/allianceauth/-/raw/master/docker/scripts/download.sh)`. This will download all the files you need to install Alliance Auth and place them in a directory named `aa-docker`. Feel free to rename/move this folder.
1. run `./scripts/prepare-env.sh` to set up your environment
1. (optional) Change `PROTOCOL` to `http://` if not using SSL in `.env`
1. run `docker compose --env-file=.env up -d` (NOTE: if this command hangs, follow the instructions [here](https://www.digitalocean.com/community/tutorials/how-to-setup-additional-entropy-for-cloud-servers-using-haveged))
1. run `docker compose --env-file=.env up -d` (NOTE: if this command hangs, follow the instructions [On This Tutorial](https://www.digitalocean.com/community/tutorials/how-to-setup-additional-entropy-for-cloud-servers-using-haveged))
1. run `docker compose exec allianceauth_gunicorn bash` to open up a terminal inside an auth container
1. run `auth migrate`
1. run `auth collectstatic`

View File

@ -69,7 +69,7 @@ Whatever you decide to use, remember it because we'll need it when configuring y
##### Number of workers
By default, Gunicorn will spawn only one worker. The number you set this to will depend on your own server environment, how many visitors you have etc. Gunicorn suggests `(2 x $num_cores) + 1` for the number of workers. So, for example, if you have 2 cores, you want 2 x 2 + 1 = 5 workers. See [here](https://docs.gunicorn.org/en/stable/design.html#how-many-workers) for the official discussion on this topic.
By default, Gunicorn will spawn only one worker. The number you set this to will depend on your own server environment, how many visitors you have etc. Gunicorn suggests `(2 x $num_cores) + 1` for the number of workers. So, for example, if you have 2 cores, you want 2 x 2 + 1 = 5 workers. See [How Many Workers](https://docs.gunicorn.org/en/stable/design.html#how-many-workers) for the official discussion on this topic.
Change it by adding `--workers=5` to the command.

View File

@ -6,7 +6,7 @@
The default installation will have 3 workers configured for Gunicorn. This will be fine on most systems, but if your system as more than one core than you might want to increase the number of workers to get better response times. Note that more workers will also need more RAM though.
The number you set this to will depend on your own server environment, how many visitors you have etc. Gunicorn suggests `(2 x $num_cores) + 1` for the number of workers. So for example, if you have 2 cores, you want 2 x 2 + 1 = 5 workers. See [here](https://docs.gunicorn.org/en/stable/design.html#how-many-workers) for the official discussion on this topic.
The number you set this to will depend on your own server environment, how many visitors you have etc. Gunicorn suggests `(2 x $num_cores) + 1` for the number of workers. So for example, if you have 2 cores, you want 2 x 2 + 1 = 5 workers. See [How Many Workers](https://docs.gunicorn.org/en/stable/design.html#how-many-workers) for the official discussion on this topic.
::::{tabs}
:::{group-tab} Ubuntu 2204, 2404