Compare commits

...

124 Commits

Author SHA1 Message Date
Ariel Rin
8b895b76b5 Version Bump 3.7.0 2023-10-07 15:27:11 +10:00
Ariel Rin
babd71702f Merge branch 'docs' into 'master'
Remove CentOS Section from NGINX docs

See merge request allianceauth/allianceauth!1531
2023-10-07 04:59:12 +00:00
Ariel Rin
3ec3cbdff7 Merge branch 'fix-tasks-running' into 'master'
Fix tasks running counter

See merge request allianceauth/allianceauth!1529
2023-10-07 04:52:04 +00:00
Erik Kalkoken
51611e1237 Fix tasks running counter 2023-10-07 04:52:03 +00:00
Ariel Rin
39519bab91 Merge branch 'new-discord-username-format' into 'master'
[ADD] Respect and display the new Discord username format when eligible

See merge request allianceauth/allianceauth!1526
2023-10-07 04:40:46 +00:00
Ariel Rin
90dc6a4d4c Merge branch 'fix-reference-before-assignment' into 'master'
[FIX] Reference before assignment

Closes #1369 and #1375

See merge request allianceauth/allianceauth!1530
2023-10-07 04:40:00 +00:00
Ariel Rin
53ffd7f885 Merge branch 'set-lang-attribute' into 'master'
[ADD] Language code to page and language selector

See merge request allianceauth/allianceauth!1528
2023-10-07 04:39:01 +00:00
Ariel Rin
efc7475228 Merge branch 'celery-broker-connection' into 'master'
Prepare our Celery config for Celery 6

See merge request allianceauth/allianceauth!1532
2023-10-07 04:38:21 +00:00
Peter Pfeufer
380c41400b [CHANGE] Updating celery.py to prevent deprecation warning
```
[2023-08-14 06:41:04,904: WARNING/MainProcess] /mnt/sda1/Development/Python/AllianceAuth/venv-3.11/lib/python3.11/site-packages/celery/worker/consumer/consumer.py:498: CPendingDeprecationWarning: The broker_connection_retry configuration setting will no longer determine
whether broker connection retries are made during startup in Celery 6.0 and above.
If you wish to retain the existing behavior for retrying connections on startup,
you should set broker_connection_retry_on_startup to True.
```
2023-09-15 11:42:47 +02:00
colcrunch
079c12a72e Remove CentOS heading and add notes about the differing config methods to the relevant lines in the install section. 2023-09-07 07:11:05 -04:00
Peter Pfeufer
4f1ebedc44 [FIX] Reference before assignment
`ownership` doesn't exist at this point.
To get the main character, `user` is used here.


```
Traceback (most recent call last):
  File "/home/allianceserver/venv/auth/lib/python3.10/site-packages/django/core/handlers/exception.py", line 56, in inner
    response = get_response(request)
  File "/home/allianceserver/venv/auth/lib/python3.10/site-packages/django/core/handlers/base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/allianceserver/venv/auth/lib/python3.10/site-packages/esi/decorators.py", line 116, in _wrapped_view
    return view_func(request, token, *args, **kwargs)
  File "/home/allianceserver/venv/auth/lib/python3.10/site-packages/allianceauth/authentication/views.py", line 156, in sso_login
    user = authenticate(token=token)
  File "/home/allianceserver/venv/auth/lib/python3.10/site-packages/django/views/decorators/debug.py", line 42, in sensitive_variables_wrapper
    return func(*func_args, **func_kwargs)
  File "/home/allianceserver/venv/auth/lib/python3.10/site-packages/django/contrib/auth/__init__.py", line 77, in authenticate
    user = backend.authenticate(request, **credentials)
  File "/home/allianceserver/venv/auth/lib/python3.10/site-packages/allianceauth/authentication/backends.py", line 68, in authenticate
    if ownership.user.profile.main_character.character_id != token.character_id:
UnboundLocalError: local variable 'ownership' referenced before assignment
```
2023-09-01 20:46:00 +02:00
Peter Pfeufer
66822107e3 [ADD] Language code to page and language selector 2023-08-28 21:40:28 +02:00
Peter Pfeufer
7856cd5ce4 [ADD] Respect and display the new Discord username format when eligible 2023-08-26 00:47:08 +02:00
Ariel Rin
36b3077caa Version Bump 3.6.1 2023-08-10 14:37:27 +10:00
Ariel Rin
1786f3a642 Merge branch 'prepare-base-template-for-public-views' into 'master'
[FIX] Templates prepared for public views

See merge request allianceauth/allianceauth!1525
2023-08-10 04:23:48 +00:00
Peter Pfeufer
55927c6f15 [FIX] Allow messages also for non-logged-in user to be displayed 2023-08-08 23:20:43 +02:00
Peter Pfeufer
8fbe0ba45d [CHANGE] Comment 2023-08-07 07:23:21 +02:00
Peter Pfeufer
1563805ddb [ADD] CCP's "No Character" character image as user menu image for public 2023-08-05 18:51:12 +02:00
Ariel Rin
c58ed53369 Merge branch 'fix-negative-running-tasks' into 'master'
Fix negative running tasks

See merge request allianceauth/allianceauth!1524
2023-08-05 09:17:42 +00:00
Peter Pfeufer
32128ace1c [FIX] Better explanation in local.py project template 2023-08-02 23:35:25 +02:00
Peter Pfeufer
7290eaad7e [FIX] Notifications menu item removed in public views 2023-08-02 23:22:14 +02:00
Peter Pfeufer
f23d4f4dd1 [FIX] base.html prepared for public views
Certain things need to be behind `{% if user.is_authenticated %}` in order for the base template to play nice with public views.
2023-08-02 23:17:28 +02:00
ErikKalkoken
ab3f10e6f2 Add more tests for ItemCounter 2023-08-02 16:11:24 +02:00
ErikKalkoken
20187cc73e Add locks to ensure process safety 2023-08-02 15:58:36 +02:00
ErikKalkoken
1f55fbfccc Add minimum to ItemCounter and refactor redis client init 2023-08-02 15:41:47 +02:00
Ariel Rin
12383d79c8 Version Bump 3.6.0 2023-08-01 21:37:25 +10:00
Ariel Rin
56e2875650 Merge branch 'pre-commit-update' into 'master'
`pre-commit` Update and File Permission Fixes (redone)

See merge request allianceauth/allianceauth!1523
2023-08-01 11:22:37 +00:00
Peter Pfeufer
d0118e6c0b [FIX] File permissions 2023-08-01 12:55:19 +02:00
Peter Pfeufer
7075ccdf7a [CHANGE] Django Upgrade checks applied 2023-08-01 12:52:05 +02:00
Ariel Rin
b2d540c010 Merge branch 'add-public-routes-feature' into 'master'
Add public routes feature

See merge request allianceauth/allianceauth!1514
2023-08-01 10:20:14 +00:00
Erik Kalkoken
7cb7e2c77b Add public routes feature 2023-08-01 10:20:13 +00:00
Ariel Rin
5d6a4ab1a9 Merge branch 'feature-show-running-tasks' into 'master'
Show running tasks on dashboard

See merge request allianceauth/allianceauth!1515
2023-08-01 10:15:43 +00:00
Erik Kalkoken
1122d617bd Show running tasks on dashboard 2023-08-01 10:15:42 +00:00
Ariel Rin
ef33501e45 Merge branch 'proper-favicon-support' into 'master'
Proper favicon support

See merge request allianceauth/allianceauth!1520
2023-08-01 10:14:21 +00:00
Ariel Rin
08fd86db8f Merge branch 'migrate-pep-621' into 'master'
Migrate to PEP 621

See merge request allianceauth/allianceauth!1513
2023-07-25 09:32:29 +00:00
Erik Kalkoken
c4193c15fc Migrate to PEP 621 2023-07-25 09:32:28 +00:00
Ariel Rin
903074080e Merge branch 'unknown_discord_group_patch' into 'master'
Discord: Don't fail on unknown groups, simply remove them.

See merge request allianceauth/allianceauth!1504
2023-07-25 09:27:19 +00:00
Ariel Rin
3046a26a02 Merge branch 'AA-Timer-Absolute' into 'master'
Adding Absolute Timers to base timerboard

See merge request allianceauth/allianceauth!1518
2023-07-25 09:26:10 +00:00
Hamish W
951c4135c2 Adding Absolute Timers to base timerboard 2023-07-25 09:26:10 +00:00
Ariel Rin
b256a0c5e1 Merge branch 'next-params' into 'master'
Encode Next Param for Login Redirection

See merge request allianceauth/allianceauth!1519
2023-07-25 09:02:31 +00:00
Ariel Rin
212b9b0f60 Merge branch 'stringify-crontab-arguments' into 'master'
[FIX] `crontab` arguments are of type `string`, not `int`

See merge request allianceauth/allianceauth!1517
2023-07-25 08:55:25 +00:00
Peter Pfeufer
fc29d7e80d [ADD] All modern favicon versions generated by realfavicongenerator.net 2023-07-19 12:10:02 +02:00
Peter Pfeufer
ec536c66a0 [ADD] Favicon redirect to Nginx docs 2023-07-19 11:40:45 +02:00
Peter Pfeufer
749ece45e2 [ADD] Favicon redirect to Apache2 docs 2023-07-19 11:39:04 +02:00
Peter Pfeufer
b04c8873d0 [ADD] Directive for default favicon 2023-07-19 11:37:07 +02:00
Aaron Kable
9a77175bf3 Allow get params from next at login 2023-07-17 10:25:36 +08:00
Peter Pfeufer
5d4c7b9030 [FIX] crontab arguments here as well 2023-07-14 19:22:29 +02:00
Aaron Kable
5f80259d57 fix test 2023-07-13 20:28:35 +08:00
Peter Pfeufer
dcd6bd1b36 [FIX] crontab arguments are of type string, not int 2023-07-12 13:11:18 +02:00
Ariel Rin
6f4dffe930 Version Bump 3.5.1 2023-07-11 22:38:26 +10:00
Ariel Rin
56d70e6c74 Add pkg-config to dockerfile 2023-07-11 22:36:15 +10:00
Ariel Rin
5e14ea4573 Version Bump 3.5.0 2023-07-11 13:01:50 +10:00
Ariel Rin
c743eca0f7 Merge branch 'fix-use-of-deprecated-function-calls' into 'master'
[FIX] Use of deprecated `logger.warn()` function calls

See merge request allianceauth/allianceauth!1516
2023-07-11 02:36:59 +00:00
Ariel Rin
2002f24178 Merge branch 'limit-django-registration' into 'master'
[COMPATIBILITY] Limit `django-registration` to <3.4

See merge request allianceauth/allianceauth!1512
2023-07-07 23:57:30 +00:00
Ariel Rin
6412aedf53 Merge branch 'add-docs-for-external-link' into 'master'
Add customization example to docs

See merge request allianceauth/allianceauth!1511
2023-07-07 23:56:07 +00:00
Erik Kalkoken
939df08b95 Add customization example to docs 2023-07-07 23:56:07 +00:00
Ariel Rin
d8506aa753 Merge branch 'pkg-config' into 'master'
add pkg-config to our system package dependencies, for mysqlclient 2.2.0

Closes #1376

See merge request allianceauth/allianceauth!1509
2023-07-07 23:54:41 +00:00
Ariel Rin
3f2cdac658 Merge branch 'devdocs-1' into 'master'
Add pkg-config install to dev setup and expand python downgrade note.

See merge request allianceauth/allianceauth!1510
2023-07-07 23:54:39 +00:00
Peter Pfeufer
d57ab01ff3 [FIX] Use of deprecated logger.warn() function calls 2023-07-07 17:51:55 +02:00
Peter Pfeufer
91b62bbe9d [COMPATIBILITY] Limit django-registration to <3.4 2023-07-04 12:51:12 +02:00
Max Tsero
557a52e3c8 Add pkg-config install to dev setup and expand python downgrade note. 2023-07-02 10:39:23 +00:00
Ariel Rin
f8fefd92a5 add pkg-config to our system package dependencies, for mysqlclient 2.2.0 2023-06-27 11:08:59 +10:00
Ariel Rin
f2c43ee921 Merge branch 'add-docs-app-unintall' into 'master'
Improve documentation for app removal

See merge request allianceauth/allianceauth!1508
2023-06-20 14:34:32 +00:00
Erik Kalkoken
99945b0146 Improve documentation for app removal 2023-06-20 14:34:32 +00:00
Ariel Rin
abb9dc4db6 Merge branch 'master' into 'master'
Add utf8mb4 unicode option to mysql config in local.py

See merge request allianceauth/allianceauth!1503
2023-06-03 07:04:52 +00:00
Valiantiam
eba5b80cde Add utf8mb4 unicode option to mysql config in local.py 2023-06-03 07:04:52 +00:00
Ariel Rin
5b39c887a5 Merge branch 'master' into 'master'
Add Grafana datasoure and dashboard provisioning

See merge request allianceauth/allianceauth!1501
2023-06-03 05:06:23 +00:00
Ariel Rin
183363e789 Merge branch 'add-ukrainian-to-userprofile-language-selection' into 'master'
[ADDED] Ukrainian to `UserProfile.LANGUAGE_CHOICES`

See merge request allianceauth/allianceauth!1505
2023-06-03 05:04:34 +00:00
Ariel Rin
d8704f4d8f Merge branch 'add-ipv6-to-nginx-config' into 'master'
[ADDED] IPv6 to Nginx config

See merge request allianceauth/allianceauth!1506
2023-06-03 05:03:17 +00:00
Peter Pfeufer
165ee44a63 [ADDED] IPv6 to Nginx config
IPv6 is almost 25 years old, time to add it to our config …
2023-05-31 09:29:04 +02:00
Peter Pfeufer
e8f508cecb [CHANGE] Switched to more modern models.TextChoices class for languages 2023-05-28 18:31:50 +02:00
Peter Pfeufer
3044f18900 [ADDED] Ukrainian to UserProfile.LANGUAGE_CHOICES 2023-05-28 17:38:51 +02:00
Aaron Kable
1cae20fe5f Dont fail on unknown groups, simply remove them. 2023-05-19 05:00:39 +08:00
MillerUk
79637020f3 add grafana datasoure and dashboard provisioning 2023-05-16 22:14:11 +00:00
MillerUk
2d34422e2d add grafana datasoure and dashboard provisioning 2023-04-30 20:32:40 +00:00
Ariel Rin
6b932b1188 Version Bump 3.4.0 2023-04-25 20:57:26 +10:00
Ariel Rin
f62153c746 Bump grafana minor for new installs 2023-04-25 20:38:48 +10:00
Ariel Rin
88216c3f81 Merge branch 'improve-dependency-bounds' into 'master'
Reduce upper bound version constraints

See merge request allianceauth/allianceauth!1498
2023-04-25 10:07:06 +00:00
Erik Kalkoken
dc983c31e3 Reduce upper bound version constraints 2023-04-25 10:07:06 +00:00
Ariel Rin
4204c44bde Merge branch 'transifex' into 'master'
Update from Transifex

See merge request allianceauth/allianceauth!1497
2023-04-25 10:05:38 +00:00
Ariel Rin
8da0122d17 Update from Transifex 2023-04-25 10:05:38 +00:00
Ariel Rin
c9fcf6e6bf Merge branch 'dev-team-update' into 'master'
[Change] Dev Team updated in readme

See merge request allianceauth/allianceauth!1499
2023-04-25 10:05:23 +00:00
Peter Pfeufer
36866cc59b [ADDED] snipere4agle1 to the list of active developers 2023-04-24 09:56:40 +02:00
Peter Pfeufer
298bdd98ed [Change] Dev Team updated in readme 2023-04-24 09:50:47 +02:00
Ariel Rin
819018748d Merge branch 'fix-dev-docs-mysql' into 'master'
Fix mysql Django config for developers

See merge request allianceauth/allianceauth!1483
2023-04-12 03:40:50 +00:00
Erik Kalkoken
32e8e0fdd0 Fix mysql Django config for developers 2023-04-12 03:40:50 +00:00
Ariel Rin
7625060a12 Merge branch 'improve-installation-docs' into 'master'
Improve installation guide database section for Ubuntu

See merge request allianceauth/allianceauth!1494
2023-04-12 01:52:54 +00:00
Erik Kalkoken
672cb13bfe Improve installation guide database section for Ubuntu 2023-04-12 01:52:54 +00:00
Ariel Rin
7170f75b89 Merge branch 'add-docs-copy-button' into 'master'
Add copy button to  bash snippets in docs

See merge request allianceauth/allianceauth!1493
2023-04-12 01:47:43 +00:00
Erik Kalkoken
8f60c7a00a Add copy button to bash snippets in docs 2023-04-12 01:47:43 +00:00
Ariel Rin
34ae6e402c Merge branch 'tsTests' into 'master'
Fix TS Tests when testing against a real MySQL backend

See merge request allianceauth/allianceauth!1495
2023-04-12 01:42:48 +00:00
Aaron Kable
0905e48994 Merge remote-tracking branch 'origin/master' into tsTests 2023-04-10 19:49:33 +08:00
Aaron Kable
02fcf7d500 fix TS Tests with mySql 2023-04-10 19:45:28 +08:00
Ariel Rin
8d8da50946 Merge branch '1481-alt' into 'master'
!1481 - Alternate

See merge request allianceauth/allianceauth!1489
2023-04-04 01:47:27 +00:00
Ariel Rin
c1499d173f !1481 - Alternate 2023-04-04 01:47:26 +00:00
Ariel Rin
b149baa4e5 Merge branch 'combine-imports' into 'master'
Combining imports

See merge request allianceauth/allianceauth!1478
2023-02-13 03:21:24 +00:00
Ariel Rin
4807c69b5e Merge branch 'isort' into 'master'
Standardise isort

See merge request allianceauth/allianceauth!1485
2023-02-13 03:11:32 +00:00
Ariel Rin
ebefa0e307 Standardise isort 2023-02-13 03:11:32 +00:00
Ariel Rin
468e7433f9 Merge branch 'py3.11' into 'master'
Add Python 3.11 Support

See merge request allianceauth/allianceauth!1487
2023-02-13 03:06:03 +00:00
Ariel Rin
3ca313f907 Add Python 3.11 Support 2023-02-13 03:06:03 +00:00
Ariel Rin
820065fc04 Merge branch 'update-install-docu' into 'master'
Improve installation guide

See merge request allianceauth/allianceauth!1488
2023-02-13 03:05:41 +00:00
Erik Kalkoken
3eddeefe28 Improve installation guide 2023-02-13 03:05:41 +00:00
Ariel Rin
82d7d7e3bf Merge branch 'arielcode' into 'master'
Extra < in bundle

See merge request allianceauth/allianceauth!1486
2023-02-02 03:27:34 +00:00
Ariel Rin
93194b4f2d pesky < 2023-01-25 16:17:29 +10:00
Ariel Rin
fa335253d3 Merge branch 'pypy' into 'master'
Add pypy testing

See merge request allianceauth/allianceauth!1474
2023-01-25 05:00:16 +00:00
Ariel Rin
d1af9416b3 Add pypy testing 2023-01-25 05:00:16 +00:00
Ariel Rin
f4ac2ea400 Merge branch 'faster-commands' into 'master'
Faster management commands

See merge request allianceauth/allianceauth!1484
2023-01-25 03:25:47 +00:00
Erik Kalkoken
31c1f8bb7d Faster management commands 2023-01-25 03:25:47 +00:00
Ariel Rin
57f7178f1e Merge branch 'docker_docs' into 'master'
Update Docker Docs and fix custom.dockerfile

See merge request allianceauth/allianceauth!1477
2022-12-31 09:37:54 +00:00
Ariel Rin
17d4a4c415 Merge branch 'change-packaging-dependency' into 'master'
Don't limit `packaging` to versions below 22.0

See merge request allianceauth/allianceauth!1479
2022-12-20 10:01:50 +00:00
Peter Pfeufer
18ce433fa0 Don't limit packaging to versions below 22.0 2022-12-20 10:01:50 +00:00
Ariel Rin
1eadb1d934 Merge branch 'fix-tox-4-issue' into 'master'
Adopt docs section to work with tox 4

See merge request allianceauth/allianceauth!1480
2022-12-20 08:38:59 +00:00
Erik Kalkoken
59a8f8a967 Adopt docs section to work with tox 4 2022-12-20 08:38:59 +00:00
Peter Pfeufer
2dc07b5519 Combining imports 2022-12-09 23:48:17 +01:00
Aaron Kable
3454520dfe update docker docs and fix custom.dockerfile 2022-11-24 21:56:33 +08:00
Ariel Rin
7a195d4158 Merge branch 'docs' into 'master'
Tuning Docs - Redis Compression

See merge request allianceauth/allianceauth!1475
2022-11-03 10:33:25 +00:00
Ariel Rin
b73072dec0 Tuning Docs - Redis Compression 2022-11-03 10:33:24 +00:00
Ariel Rin
1ca5e38bd9 Merge branch 'fix-docker-tag' into 'master'
fix missing v in tag

See merge request allianceauth/allianceauth!1476
2022-11-03 10:32:29 +00:00
Matteo Ghia
ecb737c6a5 fix missing v in tag 2022-11-01 13:45:44 +01:00
Ariel Rin
7063f53cdf Merge branch 'coverage' into 'master'
Adding Coverage % to MRs

See merge request allianceauth/allianceauth!1473
2022-10-25 10:10:33 +00:00
Ariel Rin
017424b9d4 Adding Coverage % to MRs 2022-10-25 10:10:33 +00:00
Ariel Rin
f6c26cf2ec Merge branch 'py3.11' into 'master'
Python 3.11 Stable Tests

See merge request allianceauth/allianceauth!1471
2022-10-25 02:51:12 +00:00
Ariel Rin
9a422bd4ca Python 3.11 Stable Tests 2022-10-25 02:51:12 +00:00
Ariel Rin
47fec23f2e cap django for docs 2022-10-23 16:42:16 +10:00
165 changed files with 5132 additions and 1325 deletions

4
.gitignore vendored
View File

@@ -69,11 +69,7 @@ celerybeat-schedule
#gitlab configs
.gitlab/
#transifex
.tx/
#other
.flake8
.pylintrc
Makefile
.isort.cfg

View File

@@ -25,7 +25,7 @@ before_script:
pre-commit-check:
<<: *only-default
stage: pre-commit
image: python:3.8-bullseye
image: python:3.10-bullseye
variables:
PRE_COMMIT_HOME: ${CI_PROJECT_DIR}/.cache/pre-commit
cache:
@@ -89,7 +89,7 @@ test-3.10-core:
test-3.11-core:
<<: *only-default
image: python:3.11-rc-bullseye
image: python:3.11-bullseye
script:
- tox -e py311-core
artifacts:
@@ -98,6 +98,18 @@ test-3.11-core:
coverage_report:
coverage_format: cobertura
path: coverage.xml
test-pvpy-core:
<<: *only-default
image: pypy:3.9-bullseye
script:
- tox -e pypy-all
artifacts:
when: always
reports:
coverage_report:
coverage_format: cobertura
path: coverage.xml
allow_failure: true
test-3.8-all:
@@ -138,7 +150,7 @@ test-3.10-all:
test-3.11-all:
<<: *only-default
image: python:3.11-rc-bullseye
image: python:3.11-bullseye
script:
- tox -e py311-all
artifacts:
@@ -147,6 +159,19 @@ test-3.11-all:
coverage_report:
coverage_format: cobertura
path: coverage.xml
coverage: '/(?i)total.*? (100(?:\.0+)?\%|[1-9]?\d(?:\.\d+)?\%)$/'
test-pvpy-all:
<<: *only-default
image: pypy:3.9-bullseye
script:
- tox -e pypy-all
artifacts:
when: always
reports:
coverage_report:
coverage_format: cobertura
path: coverage.xml
allow_failure: true
build-test:

View File

@@ -5,14 +5,35 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.3.0
rev: v4.4.0
hooks:
- id: check-case-conflict
- id: check-json
- id: check-xml
# Identify invalid files
- id: check-ast
- id: check-yaml
- id: check-json
- id: check-toml
- id: check-xml
# git checks
- id: check-merge-conflict
- id: check-added-large-files
args: [ --maxkb=1000 ]
- id: detect-private-key
- id: check-case-conflict
# Python checks
# - 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
args: [ --fix=lf ]
- id: trailing-whitespace
args: [ --markdown-linebreak-ext=md ]
exclude: |
(?x)(
\.min\.css|
@@ -21,6 +42,7 @@ repos:
\.mo|
swagger\.json
)
- id: check-executables-have-shebangs
- id: end-of-file-fixer
exclude: |
(?x)(
@@ -30,13 +52,9 @@ repos:
\.mo|
swagger\.json
)
- id: mixed-line-ending
args: [ '--fix=lf' ]
- id: fix-encoding-pragma
args: [ '--remove' ]
- repo: https://github.com/editorconfig-checker/editorconfig-checker.python
rev: 2.4.0
rev: 2.7.2
hooks:
- id: editorconfig-checker
exclude: |
@@ -48,13 +66,14 @@ repos:
swagger\.json
)
- repo: https://github.com/adamchainz/django-upgrade
rev: 1.14.0
hooks:
- id: django-upgrade
args: [ --target-version=4.0 ]
- repo: https://github.com/asottile/pyupgrade
rev: v2.34.0
rev: v3.10.1
hooks:
- id: pyupgrade
args: [ --py38-plus ]
- repo: https://github.com/asottile/setup-cfg-fmt
rev: v1.20.1
hooks:
- id: setup-cfg-fmt

10
.tx/config Normal file
View File

@@ -0,0 +1,10 @@
[main]
host = https://www.transifex.com
lang_map = zh-Hans: zh_Hans
[o:alliance-auth:p:alliance-auth:r:django-po]
file_filter = allianceauth/locale/<lang>/LC_MESSAGES/django.po
source_file = allianceauth/locale/en/LC_MESSAGES/django.po
source_lang = en
type = PO
minimum_perc = 0

View File

@@ -0,0 +1,10 @@
[main]
host = https://www.transifex.com
lang_map = zh-Hans:zh_Hans
[alliance-auth.django-po]
file_filter = allianceauth/locale/<lang>/LC_MESSAGES/django.po
minimum_perc = 0
source_file = allianceauth/locale/en/LC_MESSAGES/django.po
source_lang = en
type = PO

View File

@@ -1,7 +0,0 @@
include LICENSE
include README.md
include MANIFEST.in
graft allianceauth
global-exclude __pycache__
global-exclude *.py[co]

6
README.md Executable file → Normal file
View File

@@ -36,7 +36,7 @@ Main features:
- Can be easily extended with additional services and apps. Many are provided by the community and can be found here: [Community Creations](https://gitlab.com/allianceauth/community-creations)
- English :flag_gb:, Chinese :flag_cn:, German :flag_de:, Spanish :flag_es:, Korean :flag_kr: and Russian :flag_ru: localization
- English :flag_gb:, Chinese :flag_cn:, German :flag_de:, Spanish :flag_es:, Korean :flag_kr:, Russian :flag_ru:, Italian :flag_it:, French :flag_fr:, Japanese :flag_jp: and Ukrainian :flag_ua: Localization
For further details about AA - including an installation guide and a full list of included services and plugin apps - please see the [official documentation](http://allianceauth.rtfd.io).
@@ -56,13 +56,15 @@ Here is an example of the Alliance Auth web site with some plug-ins apps and ser
- [Aaron Kable](https://gitlab.com/aaronkable/)
- [Ariel Rin](https://gitlab.com/soratidus999/)
- [Basraah](https://gitlab.com/basraah/)
- [Col Crunch](https://gitlab.com/colcrunch/)
- [Erik Kalkoken](https://gitlab.com/ErikKalkoken/)
- [Rounon Dax](https://gitlab.com/ppfeufer)
- [snipereagle1](https://gitlab.com/mckernanin)
### Former Developers
- [Adarnof](https://gitlab.com/adarnof/)
- [Basraah](https://gitlab.com/basraah/)
### Beta Testers / Bug Fixers

View File

@@ -1,7 +1,11 @@
"""An auth system for EVE Online to help in-game organizations
manage online service access.
"""
# This will make sure the app is always imported when
# Django starts so that shared_task will use this app.
__version__ = '3.3.0'
__version__ = '3.7.0'
__title__ = 'Alliance Auth'
__url__ = 'https://gitlab.com/allianceauth/allianceauth'
NAME = f'{__title__} v{__version__}'

View File

@@ -65,7 +65,7 @@ class StateBackend(ModelBackend):
# we've seen this character owner before. Re-attach to their old user account
user = records[0].user
if user.profile.main_character:
if ownership.user.profile.main_character.character_id != token.character_id:
if user.profile.main_character.character_id != token.character_id:
## this is an alt, enforce main only due to trust issues in SSO.
if request:
messages.error("Unable to authenticate with this Character, Please log in with the main character associated with this account. Then add this character from the dashboard.")

View File

@@ -0,0 +1,48 @@
"""API for interacting with celery workers."""
import itertools
import logging
from typing import Optional
from amqp.exceptions import ChannelError
from celery import current_app
from django.conf import settings
logger = logging.getLogger(__name__)
def active_tasks_count() -> Optional[int]:
"""Return count of currently active tasks
or None if celery workers are not online.
"""
inspect = current_app.control.inspect()
return _tasks_count(inspect.active())
def _tasks_count(data: dict) -> Optional[int]:
"""Return count of tasks in data from celery inspect API."""
try:
tasks = itertools.chain(*data.values())
except AttributeError:
return None
return len(list(tasks))
def queued_tasks_count() -> Optional[int]:
"""Return count of queued tasks. Return None if there was an error."""
try:
with current_app.connection_or_acquire() as conn:
result = conn.default_channel.queue_declare(
queue=getattr(settings, "CELERY_DEFAULT_QUEUE", "celery"), passive=True
)
return result.message_count
except ChannelError:
# Queue doesn't exist, probably empty
return 0
except Exception:
logger.exception("Failed to get celery queue length")
return None

View File

@@ -1,18 +1,28 @@
from django.conf.urls import include
from django.contrib.auth.decorators import user_passes_test
from django.core.exceptions import PermissionDenied
from functools import wraps
from django.shortcuts import redirect
from typing import Callable, Iterable, Optional
from django.urls import include
from django.contrib import messages
from django.contrib.auth.decorators import login_required, user_passes_test
from django.core.exceptions import PermissionDenied
from django.shortcuts import redirect
from django.utils.translation import gettext_lazy as _
from django.contrib.auth.decorators import login_required
def user_has_main_character(user):
return bool(user.profile.main_character)
def decorate_url_patterns(urls, decorator):
def decorate_url_patterns(
urls, decorator: Callable, excluded_views: Optional[Iterable] = None
):
"""Decorate views given in url patterns except when they are explicitly excluded.
Args:
- urls: Django URL patterns
- decorator: Decorator to be added to each view
- exclude_views: Optional iterable of view names to be excluded
"""
url_list, app_name, namespace = include(urls)
def process_patterns(url_patterns):
@@ -22,6 +32,8 @@ def decorate_url_patterns(urls, decorator):
process_patterns(pattern.url_patterns)
else:
# this is a pattern
if excluded_views and pattern.lookup_str in excluded_views:
return
pattern.callback = decorator(pattern.callback)
process_patterns(url_list)

View File

@@ -1,8 +1,5 @@
from django.conf.urls import include
from allianceauth.authentication import views
from django.urls import re_path
from django.urls import path
from django.urls import include, re_path, path
urlpatterns = [
path('activate/complete/', views.activation_complete, name='registration_activation_complete'),

0
allianceauth/authentication/managers.py Executable file → Normal file
View File

View File

@@ -0,0 +1,34 @@
# Generated by Django 4.0.10 on 2023-05-28 15:36
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("authentication", "0020_userprofile_language_userprofile_night_mode"),
]
operations = [
migrations.AlterField(
model_name="userprofile",
name="language",
field=models.CharField(
blank=True,
choices=[
("en", "English"),
("de", "German"),
("es", "Spanish"),
("zh-hans", "Chinese Simplified"),
("ru", "Russian"),
("ko", "Korean"),
("fr", "French"),
("ja", "Japanese"),
("it", "Italian"),
("uk", "Ukrainian"),
],
default="",
max_length=10,
verbose_name="Language",
),
),
]

29
allianceauth/authentication/models.py Executable file → Normal file
View File

@@ -63,6 +63,22 @@ class UserProfile(models.Model):
class Meta:
default_permissions = ('change',)
class Language(models.TextChoices):
"""
Choices for UserProfile.language
"""
ENGLISH = 'en', _('English')
GERMAN = 'de', _('German')
SPANISH = 'es', _('Spanish')
CHINESE = 'zh-hans', _('Chinese Simplified')
RUSSIAN = 'ru', _('Russian')
KOREAN = 'ko', _('Korean')
FRENCH = 'fr', _('French')
JAPANESE = 'ja', _('Japanese')
ITALIAN = 'it', _('Italian')
UKRAINIAN = 'uk', _('Ukrainian')
user = models.OneToOneField(
User,
related_name='profile',
@@ -76,20 +92,9 @@ class UserProfile(models.Model):
State,
on_delete=models.SET_DEFAULT,
default=get_guest_state_pk)
LANGUAGE_CHOICES = [
('en', _('English')),
('de', _('German')),
('es', _('Spanish')),
('zh-hans', _('Chinese Simplified')),
('ru', _('Russian')),
('ko', _('Korean')),
('fr', _('French')),
('ja', _('Japanese')),
('it', _('Italian')),
]
language = models.CharField(
_("Language"), max_length=10,
choices=LANGUAGE_CHOICES,
choices=Language.choices,
blank=True,
default='')
night_mode = models.BooleanField(

View File

@@ -1,29 +1,34 @@
from collections import namedtuple
"""Counters for Task Statistics."""
import datetime as dt
from typing import NamedTuple, Optional
from .event_series import EventSeries
"""Global series for counting task events."""
# Global series for counting task events.
succeeded_tasks = EventSeries("SUCCEEDED_TASKS")
retried_tasks = EventSeries("RETRIED_TASKS")
failed_tasks = EventSeries("FAILED_TASKS")
_TaskCounts = namedtuple(
"_TaskCounts", ["succeeded", "retried", "failed", "total", "earliest_task", "hours"]
)
class _TaskCounts(NamedTuple):
succeeded: int
retried: int
failed: int
total: int
earliest_task: Optional[dt.datetime]
hours: int
def dashboard_results(hours: int) -> _TaskCounts:
"""Counts of all task events within the given timeframe."""
"""Counts of all task events within the given time frame."""
def earliest_if_exists(events: EventSeries, earliest: dt.datetime) -> list:
my_earliest = events.first_event(earliest=earliest)
return [my_earliest] if my_earliest else []
earliest = dt.datetime.utcnow() - dt.timedelta(hours=hours)
earliest_events = list()
earliest_events = []
succeeded_count = succeeded_tasks.count(earliest=earliest)
earliest_events += earliest_if_exists(succeeded_tasks, earliest)
retried_count = retried_tasks.count(earliest=earliest)

View File

@@ -1,61 +1,31 @@
"""Event series for Task Statistics."""
import datetime as dt
import logging
from typing import List, Optional
from pytz import utc
from redis import Redis, RedisError
from redis import Redis
from allianceauth.utils.cache import get_redis_client
from .helpers import get_redis_client_or_stub
logger = logging.getLogger(__name__)
class _RedisStub:
"""Stub of a Redis client.
It's purpose is to prevent EventSeries objects from trying to access Redis
when it is not available. e.g. when the Sphinx docs are rendered by readthedocs.org.
"""
def delete(self, *args, **kwargs):
pass
def incr(self, *args, **kwargs):
return 0
def zadd(self, *args, **kwargs):
pass
def zcount(self, *args, **kwargs):
pass
def zrangebyscore(self, *args, **kwargs):
pass
class EventSeries:
"""API for recording and analyzing a series of events."""
_ROOT_KEY = "ALLIANCEAUTH_EVENT_SERIES"
def __init__(self, key_id: str, redis: Redis = None) -> None:
self._redis = get_redis_client() if not redis else redis
try:
if not self._redis.ping():
raise RuntimeError()
except (AttributeError, RedisError, RuntimeError):
logger.exception(
"Failed to establish a connection with Redis. "
"This EventSeries object is disabled.",
)
self._redis = _RedisStub()
def __init__(self, key_id: str, redis: Optional[Redis] = None) -> None:
self._redis = get_redis_client_or_stub() if not redis else redis
self._key_id = str(key_id)
self.clear()
@property
def is_disabled(self):
"""True when this object is disabled, e.g. Redis was not available at startup."""
return isinstance(self._redis, _RedisStub)
return hasattr(self._redis, "IS_STUB")
@property
def _key_counter(self):
@@ -73,8 +43,8 @@ class EventSeries:
"""
if not event_time:
event_time = dt.datetime.utcnow()
id = self._redis.incr(self._key_counter)
self._redis.zadd(self._key_sorted_set, {id: event_time.timestamp()})
my_id = self._redis.incr(self._key_counter)
self._redis.zadd(self._key_sorted_set, {my_id: event_time.timestamp()})
def all(self) -> List[dt.datetime]:
"""List of all known events."""
@@ -95,15 +65,15 @@ class EventSeries:
self._redis.delete(self._key_counter)
def count(self, earliest: dt.datetime = None, latest: dt.datetime = None) -> int:
"""Count of events, can be restricted to given timeframe.
"""Count of events, can be restricted to given time frame.
Args:
- earliest: Date of first events to count(inclusive), or -infinite if not specified
- latest: Date of last events to count(inclusive), or +infinite if not specified
"""
min = "-inf" if not earliest else earliest.timestamp()
max = "+inf" if not latest else latest.timestamp()
return self._redis.zcount(self._key_sorted_set, min=min, max=max)
minimum = "-inf" if not earliest else earliest.timestamp()
maximum = "+inf" if not latest else latest.timestamp()
return self._redis.zcount(self._key_sorted_set, min=minimum, max=maximum)
def first_event(self, earliest: dt.datetime = None) -> Optional[dt.datetime]:
"""Date/Time of first event. Returns `None` if series has no events.
@@ -111,10 +81,10 @@ class EventSeries:
Args:
- earliest: Date of first events to count(inclusive), or any if not specified
"""
min = "-inf" if not earliest else earliest.timestamp()
minimum = "-inf" if not earliest else earliest.timestamp()
event = self._redis.zrangebyscore(
self._key_sorted_set,
min,
minimum,
"+inf",
withscores=True,
start=0,

View File

@@ -0,0 +1,49 @@
"""Helpers for Task Statistics."""
import logging
from redis import Redis, RedisError
from allianceauth.utils.cache import get_redis_client
logger = logging.getLogger(__name__)
class _RedisStub:
"""Stub of a Redis client.
It's purpose is to prevent EventSeries objects from trying to access Redis
when it is not available. e.g. when the Sphinx docs are rendered by readthedocs.org.
"""
IS_STUB = True
def delete(self, *args, **kwargs):
pass
def incr(self, *args, **kwargs):
return 0
def zadd(self, *args, **kwargs):
pass
def zcount(self, *args, **kwargs):
pass
def zrangebyscore(self, *args, **kwargs):
pass
def get_redis_client_or_stub() -> Redis:
"""Return AA's default cache client or a stub if Redis is not available."""
redis = get_redis_client()
try:
if not redis.ping():
raise RuntimeError()
except (AttributeError, RedisError, RuntimeError):
logger.exception(
"Failed to establish a connection with Redis. "
"This EventSeries object is disabled.",
)
return _RedisStub()
return redis

View File

@@ -1,9 +1,7 @@
"""Signals for Task Statistics."""
from celery.signals import (
task_failure,
task_internal_error,
task_retry,
task_success,
worker_ready
task_failure, task_internal_error, task_retry, task_success, worker_ready,
)
from django.conf import settings
@@ -19,6 +17,7 @@ def reset_counters():
def is_enabled() -> bool:
"""Return True if task statistics are enabled, else return False."""
return not bool(
getattr(settings, "ALLIANCEAUTH_DASHBOARD_TASK_STATISTICS_DISABLED", False)
)

View File

@@ -4,29 +4,30 @@ from django.test import TestCase
from django.utils.timezone import now
from allianceauth.authentication.task_statistics.counters import (
dashboard_results,
succeeded_tasks,
retried_tasks,
failed_tasks,
dashboard_results, failed_tasks, retried_tasks, succeeded_tasks,
)
class TestDashboardResults(TestCase):
def test_should_return_counts_for_given_timeframe_only(self):
def test_should_return_counts_for_given_time_frame_only(self):
# given
earliest_task = now() - dt.timedelta(minutes=15)
succeeded_tasks.clear()
succeeded_tasks.add(now() - dt.timedelta(hours=1, seconds=1))
succeeded_tasks.add(earliest_task)
succeeded_tasks.add()
succeeded_tasks.add()
retried_tasks.clear()
retried_tasks.add(now() - dt.timedelta(hours=1, seconds=1))
retried_tasks.add(now() - dt.timedelta(seconds=30))
retried_tasks.add()
failed_tasks.clear()
failed_tasks.add(now() - dt.timedelta(hours=1, seconds=1))
failed_tasks.add()
# when
results = dashboard_results(hours=1)
# then

View File

@@ -1,48 +1,19 @@
import datetime as dt
from unittest.mock import patch
from pytz import utc
from redis import RedisError
from django.test import TestCase
from django.utils.timezone import now
from allianceauth.authentication.task_statistics.event_series import (
EventSeries,
_RedisStub,
)
from allianceauth.authentication.task_statistics.helpers import _RedisStub
MODULE_PATH = "allianceauth.authentication.task_statistics.event_series"
class TestEventSeries(TestCase):
def test_should_abort_without_redis_client(self):
# when
with patch(MODULE_PATH + ".get_redis_client") as mock:
mock.return_value = None
events = EventSeries("dummy")
# then
self.assertTrue(events._redis, _RedisStub)
self.assertTrue(events.is_disabled)
def test_should_disable_itself_if_redis_not_available_1(self):
# when
with patch(MODULE_PATH + ".get_redis_client") as mock_get_master_client:
mock_get_master_client.return_value.ping.side_effect = RedisError
events = EventSeries("dummy")
# then
self.assertIsInstance(events._redis, _RedisStub)
self.assertTrue(events.is_disabled)
def test_should_disable_itself_if_redis_not_available_2(self):
# when
with patch(MODULE_PATH + ".get_redis_client") as mock_get_master_client:
mock_get_master_client.return_value.ping.return_value = False
events = EventSeries("dummy")
# then
self.assertIsInstance(events._redis, _RedisStub)
self.assertTrue(events.is_disabled)
def test_should_add_event(self):
# given
events = EventSeries("dummy")
@@ -166,3 +137,15 @@ class TestEventSeries(TestCase):
results = events.all()
# then
self.assertEqual(len(results), 2)
def test_should_not_report_as_disabled_when_initialized_normally(self):
# given
events = EventSeries("dummy")
# when/then
self.assertFalse(events.is_disabled)
def test_should_report_as_disabled_when_initialized_with_redis_stub(self):
# given
events = EventSeries("dummy", redis=_RedisStub())
# when/then
self.assertTrue(events.is_disabled)

View File

@@ -0,0 +1,28 @@
from unittest import TestCase
from unittest.mock import patch
from redis import RedisError
from allianceauth.authentication.task_statistics.helpers import (
_RedisStub, get_redis_client_or_stub,
)
MODULE_PATH = "allianceauth.authentication.task_statistics.helpers"
class TestGetRedisClient(TestCase):
def test_should_return_mock_if_redis_not_available_1(self):
# when
with patch(MODULE_PATH + ".get_redis_client") as mock_get_master_client:
mock_get_master_client.return_value.ping.side_effect = RedisError
result = get_redis_client_or_stub()
# then
self.assertIsInstance(result, _RedisStub)
def test_should_return_mock_if_redis_not_available_2(self):
# when
with patch(MODULE_PATH + ".get_redis_client") as mock_get_master_client:
mock_get_master_client.return_value.ping.return_value = False
result = get_redis_client_or_stub()
# then
self.assertIsInstance(result, _RedisStub)

View File

@@ -17,16 +17,17 @@ from allianceauth.eveonline.tasks import update_character
@override_settings(
CELERY_ALWAYS_EAGER=True,ALLIANCEAUTH_DASHBOARD_TASK_STATISTICS_DISABLED=False
CELERY_ALWAYS_EAGER=True, ALLIANCEAUTH_DASHBOARD_TASK_STATISTICS_DISABLED=False
)
class TestTaskSignals(TestCase):
fixtures = ["disable_analytics"]
def test_should_record_successful_task(self):
# given
def setUp(self) -> None:
succeeded_tasks.clear()
retried_tasks.clear()
failed_tasks.clear()
def test_should_record_successful_task(self):
# when
with patch(
"allianceauth.eveonline.tasks.EveCharacter.objects.update_character"
@@ -39,10 +40,6 @@ class TestTaskSignals(TestCase):
self.assertEqual(failed_tasks.count(), 0)
def test_should_record_retried_task(self):
# given
succeeded_tasks.clear()
retried_tasks.clear()
failed_tasks.clear()
# when
with patch(
"allianceauth.eveonline.tasks.EveCharacter.objects.update_character"
@@ -55,10 +52,6 @@ class TestTaskSignals(TestCase):
self.assertEqual(retried_tasks.count(), 1)
def test_should_record_failed_task(self):
# given
succeeded_tasks.clear()
retried_tasks.clear()
failed_tasks.clear()
# when
with patch(
"allianceauth.eveonline.tasks.EveCharacter.objects.update_character"

View File

@@ -5,7 +5,7 @@
<select onchange="this.form.submit()" class="form-control" id="lang-select" name="language">
{% get_language_info_list for LANGUAGES as languages %}
{% for language in languages %}
<option value="{{ language.code }}"{% if language.code == LANGUAGE_CODE %} selected="selected"{% endif %}>
<option lang="{{ language.code }}" value="{{ language.code }}"{% if language.code == LANGUAGE_CODE %} selected="selected"{% endif %}>
{{ language.name_local|capfirst }} ({{ language.code }})
</option>
{% endfor %}

View File

@@ -6,7 +6,7 @@
{% block page_title %}{% translate "Login" %}{% endblock %}
{% block middle_box_content %}
<a href="{% url 'auth_sso_login' %}{% if request.GET.next %}?next={{request.GET.next}}{%endif%}">
<a href="{% url 'auth_sso_login' %}{% if request.GET.next %}?next={{request.GET.next | urlencode}}{%endif%}">
<img class="img-responsive center-block" src="{% static 'allianceauth/authentication/img/sso/EVE_SSO_Login_Buttons_Large_Black.png' %}" alt="{% translate 'Login with Eve SSO' %}">
</a>
{% endblock %}

View File

@@ -0,0 +1,85 @@
from unittest.mock import patch
from amqp.exceptions import ChannelError
from django.test import TestCase
from allianceauth.authentication.core.celery_workers import (
active_tasks_count, queued_tasks_count,
)
MODULE_PATH = "allianceauth.authentication.core.celery_workers"
@patch(MODULE_PATH + ".current_app")
class TestActiveTasksCount(TestCase):
def test_should_return_correct_count_when_no_active_tasks(self, mock_current_app):
# given
mock_current_app.control.inspect.return_value.active.return_value = {
"queue": []
}
# when
result = active_tasks_count()
# then
self.assertEqual(result, 0)
def test_should_return_correct_task_count_for_active_tasks(self, mock_current_app):
# given
mock_current_app.control.inspect.return_value.active.return_value = {
"queue": [1, 2, 3]
}
# when
result = active_tasks_count()
# then
self.assertEqual(result, 3)
def test_should_return_correct_task_count_for_multiple_queues(
self, mock_current_app
):
# given
mock_current_app.control.inspect.return_value.active.return_value = {
"queue_1": [1, 2],
"queue_2": [3, 4],
}
# when
result = active_tasks_count()
# then
self.assertEqual(result, 4)
def test_should_return_none_when_celery_not_available(self, mock_current_app):
# given
mock_current_app.control.inspect.return_value.active.return_value = None
# when
result = active_tasks_count()
# then
self.assertIsNone(result)
@patch(MODULE_PATH + ".current_app")
class TestQueuedTasksCount(TestCase):
def test_should_return_queue_length_when_queue_exists(self, mock_current_app):
# given
mock_conn = (
mock_current_app.connection_or_acquire.return_value.__enter__.return_value
)
mock_conn.default_channel.queue_declare.return_value.message_count = 7
# when
result = queued_tasks_count()
# then
self.assertEqual(result, 7)
def test_should_return_0_when_queue_does_not_exists(self, mock_current_app):
# given
mock_current_app.connection_or_acquire.side_effect = ChannelError
# when
result = queued_tasks_count()
# then
self.assertEqual(result, 0)
def test_should_return_None_on_other_errors(self, mock_current_app):
# given
mock_current_app.connection_or_acquire.side_effect = RuntimeError
# when
result = queued_tasks_count()
# then
self.assertIsNone(result)

View File

@@ -4,16 +4,16 @@ from urllib import parse
from django.conf import settings
from django.contrib.auth.models import AnonymousUser
from django.http.response import HttpResponse
from django.shortcuts import reverse
from django.test import TestCase
from django.test.client import RequestFactory
from django.urls import reverse, URLPattern
from allianceauth.eveonline.models import EveCharacter
from allianceauth.tests.auth_utils import AuthUtils
from ..decorators import main_character_required
from ..models import CharacterOwnership
from ..decorators import decorate_url_patterns, main_character_required
from ..models import CharacterOwnership
MODULE_PATH = 'allianceauth.authentication'
@@ -66,3 +66,33 @@ class DecoratorTestCase(TestCase):
setattr(self.request, 'user', self.main_user)
response = self.dummy_view(self.request)
self.assertEqual(response.status_code, 200)
class TestDecorateUrlPatterns(TestCase):
def test_should_add_decorator_by_default(self):
# given
decorator = mock.MagicMock(name="decorator")
view = mock.MagicMock(name="view")
path = mock.MagicMock(spec=URLPattern, name="path")
path.callback = view
path.lookup_str = "my_lookup_str"
urls = [path]
urlconf_module = urls
# when
decorate_url_patterns(urlconf_module, decorator)
# then
self.assertEqual(path.callback, decorator(view))
def test_should_not_add_decorator_when_excluded(self):
# given
decorator = mock.MagicMock(name="decorator")
view = mock.MagicMock(name="view")
path = mock.MagicMock(spec=URLPattern, name="path")
path.callback = view
path.lookup_str = "my_lookup_str"
urls = [path]
urlconf_module = urls
# when
decorate_url_patterns(urlconf_module, decorator, excluded_views=["my_lookup_str"])
# then
self.assertEqual(path.callback, view)

View File

@@ -9,12 +9,8 @@ from django.core.cache import cache
from django.test import TestCase
from allianceauth.templatetags.admin_status import (
status_overview,
_fetch_list_from_gitlab,
_current_notifications,
_current_version_summary,
_fetch_notification_issues_from_gitlab,
_latests_versions
_current_notifications, _current_version_summary, _fetch_list_from_gitlab,
_fetch_notification_issues_from_gitlab, _latests_versions, status_overview,
)
MODULE_PATH = 'allianceauth.templatetags'
@@ -56,14 +52,10 @@ TEST_VERSION = '2.6.5'
class TestStatusOverviewTag(TestCase):
@patch(MODULE_PATH + '.admin_status.__version__', TEST_VERSION)
@patch(MODULE_PATH + '.admin_status._fetch_celery_queue_length')
@patch(MODULE_PATH + '.admin_status._current_version_summary')
@patch(MODULE_PATH + '.admin_status._current_notifications')
def test_status_overview(
self,
mock_current_notifications,
mock_current_version_info,
mock_fetch_celery_queue_length
self, mock_current_notifications, mock_current_version_info
):
# given
notifications = {
@@ -82,7 +74,6 @@ class TestStatusOverviewTag(TestCase):
'latest_beta_version': '2.4.4a1',
}
mock_current_version_info.return_value = version_info
mock_fetch_celery_queue_length.return_value = 3
# when
result = status_overview()
# then
@@ -96,7 +87,6 @@ class TestStatusOverviewTag(TestCase):
self.assertEqual(result["latest_minor_version"], '2.4.0')
self.assertEqual(result["latest_patch_version"], '2.4.5')
self.assertEqual(result["latest_beta_version"], '2.4.4a1')
self.assertEqual(result["task_queue_length"], 3)
class TestNotifications(TestCase):

View File

@@ -0,0 +1,39 @@
import json
from unittest.mock import patch
from django.test import RequestFactory, TestCase
from allianceauth.authentication.views import task_counts
from allianceauth.tests.auth_utils import AuthUtils
MODULE_PATH = "allianceauth.authentication.views"
def jsonresponse_to_dict(response) -> dict:
return json.loads(response.content)
@patch(MODULE_PATH + ".queued_tasks_count")
@patch(MODULE_PATH + ".active_tasks_count")
class TestRunningTasksCount(TestCase):
@classmethod
def setUpClass(cls) -> None:
super().setUpClass()
cls.factory = RequestFactory()
cls.user = AuthUtils.create_user("bruce_wayne")
def test_should_return_data(
self, mock_active_tasks_count, mock_queued_tasks_count
):
# given
mock_active_tasks_count.return_value = 2
mock_queued_tasks_count.return_value = 3
request = self.factory.get("/")
request.user = self.user
# when
response = task_counts(request)
# then
self.assertEqual(response.status_code, 200)
self.assertDictEqual(
jsonresponse_to_dict(response), {"tasks_running": 2, "tasks_queued": 3}
)

View File

@@ -38,4 +38,5 @@ urlpatterns = [
name='token_refresh'
),
path('dashboard/', views.dashboard, name='dashboard'),
path('task-counts/', views.task_counts, name='task_counts'),
]

View File

@@ -1,31 +1,31 @@
import logging
from django_registration.backends.activation.views import (
REGISTRATION_SALT, ActivationView as BaseActivationView,
RegistrationView as BaseRegistrationView,
)
from django_registration.signals import user_registered
from django.conf import settings
from django.contrib import messages
from django.contrib.auth import login, authenticate
from django.contrib.auth import authenticate, login
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from django.core import signing
from django.core.mail import EmailMultiAlternatives
from django.http import JsonResponse
from django.shortcuts import redirect, render
from django.template.loader import render_to_string
from django.urls import reverse, reverse_lazy
from django.utils.translation import gettext_lazy as _
from allianceauth.eveonline.models import EveCharacter
from esi.decorators import token_required
from esi.models import Token
from django_registration.backends.activation.views import (
RegistrationView as BaseRegistrationView,
ActivationView as BaseActivationView,
REGISTRATION_SALT
)
from django_registration.signals import user_registered
from allianceauth.eveonline.models import EveCharacter
from .models import CharacterOwnership
from .core.celery_workers import active_tasks_count, queued_tasks_count
from .forms import RegistrationForm
from .models import CharacterOwnership
if 'allianceauth.eveonline.autogroups' in settings.INSTALLED_APPS:
_has_auto_groups = True
@@ -61,6 +61,7 @@ def dashboard(request):
}
return render(request, 'authentication/dashboard.html', context)
@login_required
def token_management(request):
tokens = request.user.token_set.all()
@@ -70,6 +71,7 @@ def token_management(request):
}
return render(request, 'authentication/tokens.html', context)
@login_required
def token_delete(request, token_id=None):
try:
@@ -83,6 +85,7 @@ def token_delete(request, token_id=None):
messages.warning(request, "Token does not exist")
return redirect('authentication:token_management')
@login_required
def token_refresh(request, token_id=None):
try:
@@ -127,7 +130,7 @@ def main_character_change(request, token):
def add_character(request, token):
if CharacterOwnership.objects.filter(character__character_id=token.character_id).filter(
owner_hash=token.character_owner_hash).filter(user=request.user).exists():
messages.success(request, _('Added %(name)s to your account.'% ({'name': token.character_name})))
messages.success(request, _('Added %(name)s to your account.' % ({'name': token.character_name})))
else:
messages.error(request, _('Failed to add %(name)s to your account: they already have an account.' % ({'name': token.character_name})))
return redirect('authentication:dashboard')
@@ -268,8 +271,11 @@ class ActivationView(BaseActivationView):
def validate_key(self, activation_key):
try:
dump = signing.loads(activation_key, salt=REGISTRATION_SALT,
max_age=settings.ACCOUNT_ACTIVATION_DAYS * 86400)
dump = signing.loads(
activation_key,
salt=REGISTRATION_SALT,
max_age=settings.ACCOUNT_ACTIVATION_DAYS * 86400
)
return dump
except signing.BadSignature:
return None
@@ -299,3 +305,12 @@ def activation_complete(request):
def registration_closed(request):
messages.error(request, _('Registration of new accounts is not allowed at this time.'))
return redirect('authentication:login')
def task_counts(request) -> JsonResponse:
"""Return task counts as JSON for an AJAX call."""
data = {
"tasks_running": active_tasks_count(),
"tasks_queued": queued_tasks_count()
}
return JsonResponse(data)

View File

@@ -14,6 +14,7 @@ def sync_user_groups(modeladmin, request, queryset):
agc.update_all_states_group_membership()
@admin.register(AutogroupsConfig)
class AutogroupsConfigAdmin(admin.ModelAdmin):
formfield_overrides = {
models.CharField: {'strip': False}
@@ -36,6 +37,5 @@ class AutogroupsConfigAdmin(admin.ModelAdmin):
return actions
admin.site.register(AutogroupsConfig, AutogroupsConfigAdmin)
admin.site.register(ManagedCorpGroup)
admin.site.register(ManagedAllianceGroup)

View File

@@ -8,6 +8,7 @@ from django.conf import settings
from esi.clients import esi_client_factory
from allianceauth import __version__
from allianceauth.utils.django import StartupCommand
SWAGGER_SPEC_PATH = os.path.join(os.path.dirname(
@@ -175,15 +176,16 @@ class EveProvider:
class EveSwaggerProvider(EveProvider):
def __init__(self, token=None, adapter=None):
if settings.DEBUG:
if settings.DEBUG or StartupCommand().is_management_command:
self._client = None
logger.info(
'DEBUG mode detected: ESI client will be loaded on-demand.'
)
logger.info('ESI client will be loaded on-demand')
else:
logger.info('Loading ESI client')
try:
self._client = esi_client_factory(
token=token, spec_file=SWAGGER_SPEC_PATH, app_info_text=("allianceauth v" + __version__)
token=token,
spec_file=SWAGGER_SPEC_PATH,
app_info_text=f"allianceauth v{__version__}"
)
except (HTTPError, RefResolutionError):
logger.exception(

0
allianceauth/eveonline/views.py Executable file → Normal file
View File

0
allianceauth/groupmanagement/views.py Executable file → Normal file
View File

2
allianceauth/hrapplications/admin.py Executable file → Normal file
View File

@@ -10,6 +10,7 @@ class ChoiceInline(admin.TabularInline):
verbose_name_plural = 'Choices (optional)'
verbose_name= 'Choice'
@admin.register(ApplicationQuestion)
class QuestionAdmin(admin.ModelAdmin):
fieldsets = [
(None, {'fields': ['title', 'help_text', 'multi_select']}),
@@ -18,6 +19,5 @@ class QuestionAdmin(admin.ModelAdmin):
admin.site.register(Application)
admin.site.register(ApplicationComment)
admin.site.register(ApplicationQuestion, QuestionAdmin)
admin.site.register(ApplicationForm)
admin.site.register(ApplicationResponse)

0
allianceauth/hrapplications/forms.py Executable file → Normal file
View File

0
allianceauth/hrapplications/models.py Executable file → Normal file
View File

18
allianceauth/hrapplications/views.py Executable file → Normal file
View File

@@ -57,7 +57,7 @@ def hr_application_create_view(request, form_id=None):
app_form = get_object_or_404(ApplicationForm, id=form_id)
if request.method == "POST":
if Application.objects.filter(user=request.user).filter(form=app_form).exists():
logger.warn(f"User {request.user} attempting to duplicate application to {app_form.corp}")
logger.warning(f"User {request.user} attempting to duplicate application to {app_form.corp}")
else:
application = Application(user=request.user, form=app_form)
application.save()
@@ -92,7 +92,7 @@ def hr_application_personal_view(request, app_id):
}
return render(request, 'hrapplications/view.html', context=context)
else:
logger.warn(f"User {request.user} not authorized to view {app}")
logger.warning(f"User {request.user} not authorized to view {app}")
return redirect('hrapplications:personal_view')
@@ -105,9 +105,9 @@ def hr_application_personal_removal(request, app_id):
logger.info(f"User {request.user} deleting {app}")
app.delete()
else:
logger.warn(f"User {request.user} attempting to delete reviewed app {app}")
logger.warning(f"User {request.user} attempting to delete reviewed app {app}")
else:
logger.warn(f"User {request.user} not authorized to delete {app}")
logger.warning(f"User {request.user} not authorized to delete {app}")
return redirect('hrapplications:index')
@@ -132,7 +132,7 @@ def hr_application_view(request, app_id):
logger.info(f"Saved comment by user {request.user} to {app}")
return redirect('hrapplications:view', app_id)
else:
logger.warn("User %s does not have permission to add ApplicationComments" % request.user)
logger.warning("User %s does not have permission to add ApplicationComments" % request.user)
return redirect('hrapplications:view', app_id)
else:
logger.debug("Returning blank HRApplication comment form.")
@@ -171,7 +171,7 @@ def hr_application_approve(request, app_id):
app.save()
notify(app.user, "Application Accepted", message="Your application to %s has been approved." % app.form.corp, level="success")
else:
logger.warn(f"User {request.user} not authorized to approve {app}")
logger.warning(f"User {request.user} not authorized to approve {app}")
return redirect('hrapplications:index')
@@ -187,7 +187,7 @@ def hr_application_reject(request, app_id):
app.save()
notify(app.user, "Application Rejected", message="Your application to %s has been rejected." % app.form.corp, level="danger")
else:
logger.warn(f"User {request.user} not authorized to reject {app}")
logger.warning(f"User {request.user} not authorized to reject {app}")
return redirect('hrapplications:index')
@@ -208,7 +208,7 @@ def hr_application_search(request):
app_list = app_list.filter(
form__corp__corporation_id=request.user.profile.main_character.corporation_id)
except AttributeError:
logger.warn(
logger.warning(
"User %s missing main character model: unable to filter applications to search" % request.user)
applications = app_list.filter(
@@ -246,6 +246,6 @@ def hr_application_mark_in_progress(request, app_id):
app.save()
notify(app.user, "Application In Progress", message=f"Your application to {app.form.corp} is being reviewed by {app.reviewer_str}")
else:
logger.warn(
logger.warning(
f"User {request.user} unable to mark {app} in progress: already being reviewed by {app.reviewer}")
return redirect("hrapplications:view", app_id)

View File

@@ -6,17 +6,17 @@
# Translators:
# Erik Kalkoken <erik.kalkoken@gmail.com>, 2020
# Joel Falknau <ozirascal@gmail.com>, 2021
# Peter Pfeufer <rounon.dax@terra-nanotech.de>, 2022
# Peter Pfeufer, 2022
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-09-14 23:17+1000\n"
"POT-Creation-Date: 2022-10-09 18:20+1000\n"
"PO-Revision-Date: 2020-02-18 03:14+0000\n"
"Last-Translator: Peter Pfeufer <rounon.dax@terra-nanotech.de>, 2022\n"
"Language-Team: German (https://www.transifex.com/alliance-auth/teams/107430/de/)\n"
"Last-Translator: Peter Pfeufer, 2022\n"
"Language-Team: German (https://app.transifex.com/alliance-auth/teams/107430/de/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -47,47 +47,38 @@ msgstr ""
"Du kannst diese eingeschränkten Gruppen nicht hinzufügen oder entfernen: %s"
#: allianceauth/authentication/models.py:80
#: allianceauth/project_template/project_name/settings/base.py:89
msgid "English"
msgstr "Englisch"
#: allianceauth/authentication/models.py:81
#: allianceauth/project_template/project_name/settings/base.py:90
msgid "German"
msgstr "Deutsch"
#: allianceauth/authentication/models.py:82
#: allianceauth/project_template/project_name/settings/base.py:91
msgid "Spanish"
msgstr "Spanisch"
#: allianceauth/authentication/models.py:83
#: allianceauth/project_template/project_name/settings/base.py:92
msgid "Chinese Simplified"
msgstr "Chinesisch vereinfacht"
#: allianceauth/authentication/models.py:84
#: allianceauth/project_template/project_name/settings/base.py:93
msgid "Russian"
msgstr "Russisch"
#: allianceauth/authentication/models.py:85
#: allianceauth/project_template/project_name/settings/base.py:94
msgid "Korean"
msgstr "Koreanisch"
#: allianceauth/authentication/models.py:86
#: allianceauth/project_template/project_name/settings/base.py:95
msgid "French"
msgstr "Französisch"
#: allianceauth/authentication/models.py:87
#: allianceauth/project_template/project_name/settings/base.py:96
msgid "Japanese"
msgstr "Japanisch"
#: allianceauth/authentication/models.py:88
#: allianceauth/project_template/project_name/settings/base.py:97
msgid "Italian"
msgstr "Italienisch"

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-09-14 23:17+1000\n"
"POT-Creation-Date: 2022-10-09 18:20+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"
@@ -40,47 +40,38 @@ msgid "You are not allowed to add or remove these restricted groups: %s"
msgstr ""
#: allianceauth/authentication/models.py:80
#: allianceauth/project_template/project_name/settings/base.py:89
msgid "English"
msgstr ""
#: allianceauth/authentication/models.py:81
#: allianceauth/project_template/project_name/settings/base.py:90
msgid "German"
msgstr ""
#: allianceauth/authentication/models.py:82
#: allianceauth/project_template/project_name/settings/base.py:91
msgid "Spanish"
msgstr ""
#: allianceauth/authentication/models.py:83
#: allianceauth/project_template/project_name/settings/base.py:92
msgid "Chinese Simplified"
msgstr ""
#: allianceauth/authentication/models.py:84
#: allianceauth/project_template/project_name/settings/base.py:93
msgid "Russian"
msgstr ""
#: allianceauth/authentication/models.py:85
#: allianceauth/project_template/project_name/settings/base.py:94
msgid "Korean"
msgstr ""
#: allianceauth/authentication/models.py:86
#: allianceauth/project_template/project_name/settings/base.py:95
msgid "French"
msgstr ""
#: allianceauth/authentication/models.py:87
#: allianceauth/project_template/project_name/settings/base.py:96
msgid "Japanese"
msgstr ""
#: allianceauth/authentication/models.py:88
#: allianceauth/project_template/project_name/settings/base.py:97
msgid "Italian"
msgstr ""

View File

@@ -6,16 +6,19 @@
# Translators:
# frank1210 <francolopez_16@hotmail.com>, 2021
# Joel Falknau <ozirascal@gmail.com>, 2021
# Young Anexo, 2023
# Fegpawn Kaundur, 2023
# trenus, 2023
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-09-14 23:17+1000\n"
"POT-Creation-Date: 2022-10-09 18:20+1000\n"
"PO-Revision-Date: 2020-02-18 03:14+0000\n"
"Last-Translator: Joel Falknau <ozirascal@gmail.com>, 2021\n"
"Language-Team: Spanish (https://www.transifex.com/alliance-auth/teams/107430/es/)\n"
"Last-Translator: trenus, 2023\n"
"Language-Team: Spanish (https://app.transifex.com/alliance-auth/teams/107430/es/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -24,16 +27,17 @@ msgstr ""
#: allianceauth/analytics/models.py:29
msgid "Google Analytics Universal"
msgstr ""
msgstr "Google Analytics Universal"
#: allianceauth/analytics/models.py:30
msgid "Google Analytics V4"
msgstr ""
msgstr "Google Analytics V4"
#: allianceauth/authentication/decorators.py:37
msgid "A main character is required to perform that action. Add one below."
msgstr ""
"Un personaje principal es requerido para completar esta accion. Agregue uno"
"Se necesita un personaje principal para realizar esa acción. Añade uno a "
"continuación."
#: allianceauth/authentication/forms.py:12
msgid "Email"
@@ -42,77 +46,68 @@ msgstr "E-mail"
#: allianceauth/authentication/forms.py:62
#, python-format
msgid "You are not allowed to add or remove these restricted groups: %s"
msgstr ""
msgstr "No puedes añadir o eliminar estos grupos restringidos: %s"
#: allianceauth/authentication/models.py:80
#: allianceauth/project_template/project_name/settings/base.py:89
msgid "English"
msgstr "Ingles"
msgstr "Inglés"
#: allianceauth/authentication/models.py:81
#: allianceauth/project_template/project_name/settings/base.py:90
msgid "German"
msgstr "Aleman"
msgstr "Alemán"
#: allianceauth/authentication/models.py:82
#: allianceauth/project_template/project_name/settings/base.py:91
msgid "Spanish"
msgstr "Español"
#: allianceauth/authentication/models.py:83
#: allianceauth/project_template/project_name/settings/base.py:92
msgid "Chinese Simplified"
msgstr ""
msgstr "Chino Simplificado"
#: allianceauth/authentication/models.py:84
#: allianceauth/project_template/project_name/settings/base.py:93
msgid "Russian"
msgstr "Ruso"
#: allianceauth/authentication/models.py:85
#: allianceauth/project_template/project_name/settings/base.py:94
msgid "Korean"
msgstr ""
msgstr "Coreano"
#: allianceauth/authentication/models.py:86
#: allianceauth/project_template/project_name/settings/base.py:95
msgid "French"
msgstr ""
msgstr "Francés"
#: allianceauth/authentication/models.py:87
#: allianceauth/project_template/project_name/settings/base.py:96
msgid "Japanese"
msgstr ""
msgstr "Japonés"
#: allianceauth/authentication/models.py:88
#: allianceauth/project_template/project_name/settings/base.py:97
msgid "Italian"
msgstr ""
msgstr "Italiano"
#: allianceauth/authentication/models.py:91
msgid "Language"
msgstr ""
msgstr "Idioma"
#: allianceauth/authentication/models.py:96
#: allianceauth/templates/allianceauth/night-toggle.html:6
msgid "Night Mode"
msgstr ""
msgstr "Modo Nocturno"
#: allianceauth/authentication/models.py:110
#, python-format
msgid "State changed to: %s"
msgstr ""
msgstr "Estado cambiado a: %s"
#: allianceauth/authentication/models.py:111
#, python-format
msgid "Your user's state is now: %(state)s"
msgstr ""
msgstr "El estado de su usuario es ahora: %(state)s"
#: allianceauth/authentication/templates/authentication/dashboard.html:4
#: allianceauth/authentication/templates/authentication/dashboard.html:7
#: allianceauth/templates/allianceauth/side-menu.html:10
msgid "Dashboard"
msgstr "Pagina Principal"
msgstr "Página principal"
#: allianceauth/authentication/templates/authentication/dashboard.html:17
#, python-format
@@ -121,6 +116,8 @@ msgid ""
" Main Character (State: %(state)s)\n"
" "
msgstr ""
"\n"
"Personaje Principal (estado: %(state)s)"
#: allianceauth/authentication/templates/authentication/dashboard.html:101
msgid "No main character set."
@@ -136,7 +133,7 @@ msgstr "Cambiar Personaje Principal"
#: allianceauth/authentication/templates/authentication/dashboard.html:125
msgid "Group Memberships"
msgstr ""
msgstr "Membresia de Grupos"
#: allianceauth/authentication/templates/authentication/dashboard.html:145
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticscorpview.html:21
@@ -172,23 +169,25 @@ msgstr "Ingresar"
#: allianceauth/authentication/templates/public/login.html:10
msgid "Login with Eve SSO"
msgstr ""
msgstr "Iniciar Sesión con Eve SSO"
#: allianceauth/authentication/templates/public/middle_box.html:24
msgid "For information on SSO, ESI and security read the CCP Dev Blog"
msgstr ""
"Para más información sobre SSO, ESI y seguridad, lea el blog de desarrollo "
"de CCP."
#: allianceauth/authentication/templates/public/middle_box.html:26
msgid "Introducing ESI - A New API For Eve Online"
msgstr ""
msgstr "Presentación de ESI - Una nueva API para Eve Online"
#: allianceauth/authentication/templates/public/middle_box.html:32
msgid "Manage ESI Applications"
msgstr ""
msgstr "Gestionar aplicaciones ESI"
#: allianceauth/authentication/templates/public/register.html:6
msgid "Registration"
msgstr ""
msgstr "Registro"
#: allianceauth/authentication/templates/public/register.html:21
msgid "Register"
@@ -204,6 +203,8 @@ msgid ""
"Cannot change main character to %(char)s: character owned by a different "
"account."
msgstr ""
"No se puede cambiar de personaje principal a %(char)s: personaje "
"perteneciente a otra cuenta."
#: allianceauth/authentication/views.py:83
#, python-format
@@ -245,7 +246,7 @@ msgstr ""
#: allianceauth/authentication/views.py:262
msgid "Registration of new accounts is not allowed at this time."
msgstr ""
msgstr "En este momento no se permite el registro de nuevas cuentas."
#: allianceauth/corputils/auth_hooks.py:11
msgid "Corporation Stats"
@@ -495,9 +496,9 @@ msgstr "Mes Siguiente"
#, python-format
msgid "%(user)s has collected one link this month."
msgid_plural "%(user)s has collected %(links)s links this month."
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
msgstr[0] "%(user)s ha recopilado un enlace este mes."
msgstr[1] " %(user)s ha recopilado %(links)s enlaces este mes."
msgstr[2] "%(user)s ha recopilado %(links)s enlaces este mes."
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkpersonalmonthlystatisticsview.html:26
msgid "Times used"
@@ -507,9 +508,9 @@ msgstr "Utilizado"
#, python-format
msgid "%(user)s has created one link this month."
msgid_plural "%(user)s has created %(links)s links this month."
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
msgstr[0] "%(user)s ha creado un enlace este mes."
msgstr[1] "%(user)s ha creado %(links)s enlaces este mes."
msgstr[2] "%(user)s ha creado %(links)s enlaces este mes."
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkpersonalmonthlystatisticsview.html:46
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:25
@@ -607,11 +608,11 @@ msgstr "No hay fatlinks creados recientemente"
#: allianceauth/fleetactivitytracking/views.py:218
msgid "Character does not exist"
msgstr ""
msgstr "Personaje no existe"
#: allianceauth/fleetactivitytracking/views.py:221
msgid "User does not exist"
msgstr ""
msgstr "Usuario no existe"
#: allianceauth/fleetactivitytracking/views.py:299
msgid "Fleet participation registered."
@@ -627,6 +628,8 @@ msgid ""
"Cannot register the fleet participation for {character.character_name}. The "
"character needs to be online."
msgstr ""
"No se puede registrar la participación en la flota para "
"{character.character_name}. El personaje debe estar en línea."
#: allianceauth/groupmanagement/auth_hooks.py:17
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:13
@@ -635,15 +638,15 @@ msgstr "Manejo de Grupo"
#: allianceauth/groupmanagement/forms.py:15
msgid "This name has been reserved and can not be used for groups."
msgstr ""
msgstr "Este nombre ha sido reservado y no puede utilizarse para grupos."
#: allianceauth/groupmanagement/forms.py:25
msgid "(auto)"
msgstr ""
msgstr "(auto)"
#: allianceauth/groupmanagement/forms.py:34
msgid "There already exists a group with that name."
msgstr ""
msgstr "Ya existe un grupo con ese nombre."
#: allianceauth/groupmanagement/models.py:105
msgid ""
@@ -651,16 +654,24 @@ msgid ""
"group.<br>Used for groups such as Members, Corp_*, Alliance_* "
"etc.<br><b>Overrides Hidden and Open options when selected.</b>"
msgstr ""
"Grupo interno, los usuarios no pueden ver, unirse o solicitar unirse a este "
"grupo.<br>Se utiliza para grupos como Miembros, Corp_*, Alliance_*, "
"etc.<br><b>Anula las opciones Oculto y Abierto cuando se selecciona.</b>"
#: allianceauth/groupmanagement/models.py:113
msgid "Group is hidden from users but can still join with the correct link."
msgstr ""
"El grupo está oculto para los usuarios, pero aún pueden unirse con el enlace"
" correcto."
#: allianceauth/groupmanagement/models.py:119
msgid ""
"Group is open and users will be automatically added upon request.<br>If the "
"group is not open users will need their request manually approved."
msgstr ""
"El grupo está abierto y los usuarios se añadirán automáticamente cuando lo "
"soliciten.<br>Si el grupo no está abierto, los usuarios necesitarán que su "
"solicitud sea aprobada manualmente."
#: allianceauth/groupmanagement/models.py:126
msgid ""
@@ -669,12 +680,18 @@ msgid ""
"remove users from this group automatically when they are no longer "
"authenticated."
msgstr ""
"El grupo es público. Cualquier usuario registrado puede unirse a este grupo,"
" con visibilidad basada en las otras opciones establecidas para este "
"grupo.<br>Auth no eliminará automáticamente a los usuarios de este grupo "
"cuando ya no estén autenticados."
#: allianceauth/groupmanagement/models.py:135
msgid ""
"Group is restricted. This means that adding or removing users for this group"
" requires a superuser admin."
msgstr ""
"El grupo está restringido. Esto significa que para añadir o eliminar "
"usuarios de este grupo se requiere un superusuario administrador."
#: allianceauth/groupmanagement/models.py:144
msgid ""
@@ -682,6 +699,9 @@ msgid ""
"<code>auth.group_management</code> permission to allow a user to manage all "
"groups.<br>"
msgstr ""
"Los líderes de grupo pueden procesar solicitudes para este grupo. Utilice el"
" permiso <code>auth.group_management</code> para permitir que un usuario "
"gestione todos los grupos.<br>"
#: allianceauth/groupmanagement/models.py:154
msgid ""
@@ -689,49 +709,56 @@ msgid ""
"<code>auth.group_management</code> permission to allow a user to manage all "
"groups.<br>"
msgstr ""
"Los miembros de los grupos líderes pueden procesar solicitudes para este "
"grupo. Utilice el <code>permiso auth.group_management</code> para permitir "
"que un usuario gestione todos los grupos.<br>"
#: allianceauth/groupmanagement/models.py:163
msgid ""
"States listed here will have the ability to join this group provided they "
"have the proper permissions.<br>"
msgstr ""
"Los estados que figuren en esta lista podrán unirse a este grupo siempre que"
" dispongan de los permisos adecuados.<br>"
#: allianceauth/groupmanagement/models.py:171
msgid ""
"Short description <i>(max. 512 characters)</i> of the group shown to users."
msgstr ""
"Breve descripción <i>(máx. 512 caracteres)</i> del grupo que se muestra a "
"los usuarios."
#: allianceauth/groupmanagement/models.py:178
msgid "Can request non-public groups"
msgstr ""
msgstr "Se pueden solicitar grupos no públicos"
#: allianceauth/groupmanagement/models.py:209
msgid "name"
msgstr ""
msgstr "nombre"
#: allianceauth/groupmanagement/models.py:212
msgid "Name that can not be used for groups."
msgstr ""
msgstr "Nombre que no se puede utilizar para los grupos."
#: allianceauth/groupmanagement/models.py:215
msgid "reason"
msgstr ""
msgstr "razón"
#: allianceauth/groupmanagement/models.py:215
msgid "Reason why this name is reserved."
msgstr ""
msgstr "Razón por la que este nombre está reservado."
#: allianceauth/groupmanagement/models.py:218
msgid "created by"
msgstr ""
msgstr "creado por"
#: allianceauth/groupmanagement/models.py:223
msgid "created at"
msgstr ""
msgstr "creado en"
#: allianceauth/groupmanagement/models.py:223
msgid "Date when this entry was created"
msgstr ""
msgstr "Fecha de creación de esta entrada"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:4
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:13
@@ -773,11 +800,11 @@ msgstr "Actor"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:48
msgid "Removed"
msgstr ""
msgstr "Eliminado"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:60
msgid "All times displayed are EVE/UTC."
msgstr ""
msgstr "Todas las horas indicadas son EVE/UTC."
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:67
msgid "No entries found for this group."
@@ -792,18 +819,18 @@ msgstr "Miembros del Grupo"
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:113
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:21
msgid "Organization"
msgstr ""
msgstr "Organización"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:49
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:75
msgid "Group leader"
msgstr ""
msgstr "Líder de grupo"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:60
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:82
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:139
msgid "(unknown)"
msgstr ""
msgstr "(desconocido)"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:65
msgid "Remove from group"
@@ -865,7 +892,7 @@ msgstr "Auditar Miembros"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:63
msgid "Copy Direct Join Link"
msgstr ""
msgstr "Copiar enlace directo"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:74
msgid "No groups to list."
@@ -911,11 +938,11 @@ msgstr "Manejo de Grupos"
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:24
msgid "Join Requests"
msgstr ""
msgstr "Solicitudes de ingreso"
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:35
msgid "Leave Requests"
msgstr ""
msgstr "Abandonar solicitudes"
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:57
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:114
@@ -1001,6 +1028,8 @@ msgid ""
"An unhandled error occurred while processing the application from "
"%(mainchar)s to leave %(group)s."
msgstr ""
"Se ha producido un error al procesar la solicitud de %(mainchar)s para "
"abandonar %(group)s."
#: allianceauth/groupmanagement/views.py:292
#, python-format
@@ -1015,11 +1044,11 @@ msgstr "No puedes unirte a ese grupo"
#: allianceauth/groupmanagement/views.py:341
msgid "You are already a member of that group."
msgstr ""
msgstr "Ya eres miembro de ese grupo."
#: allianceauth/groupmanagement/views.py:358
msgid "You already have a pending application for that group."
msgstr ""
msgstr "Ya tiene una solicitud pendiente para ese grupo."
#: allianceauth/groupmanagement/views.py:367
#, python-format
@@ -1036,7 +1065,7 @@ msgstr "No eres miembro de ese grupo"
#: allianceauth/groupmanagement/views.py:393
msgid "You already have a pending leave request for that group."
msgstr ""
msgstr "Ya tiene una solicitud de baja pendiente para ese grupo."
#: allianceauth/groupmanagement/views.py:409
#, python-format
@@ -1220,19 +1249,19 @@ msgstr "Agregar comentario"
#: allianceauth/notifications/models.py:21
msgid "danger"
msgstr ""
msgstr "peligro"
#: allianceauth/notifications/models.py:22
msgid "warning"
msgstr ""
msgstr "advertencia"
#: allianceauth/notifications/models.py:23
msgid "info"
msgstr ""
msgstr "info"
#: allianceauth/notifications/models.py:24
msgid "success"
msgstr ""
msgstr "éxito"
#: allianceauth/notifications/templates/notifications/list.html:4
#: allianceauth/notifications/templates/notifications/list.html:7
@@ -1266,7 +1295,7 @@ msgstr "Titulo"
#: allianceauth/notifications/templates/notifications/list_partial.html:28
msgid "No notifications."
msgstr ""
msgstr "No hay notificaciones."
#: allianceauth/notifications/templates/notifications/view.html:4
#: allianceauth/notifications/templates/notifications/view.html:8
@@ -1314,7 +1343,7 @@ msgstr "Nombre de la operacion"
#: allianceauth/optimer/form.py:16
msgid "Operation Type"
msgstr ""
msgstr "Tipo de operación"
#: allianceauth/optimer/form.py:17
#: allianceauth/srp/templates/srp/management.html:38
@@ -1328,7 +1357,7 @@ msgstr "Informacion Adicional"
#: allianceauth/optimer/form.py:23
msgid "(Optional) Describe the operation with a couple of short words."
msgstr ""
msgstr "(Opcional) Describa la operación con un par de palabras breves."
#: allianceauth/optimer/templates/optimer/add.html:6
#: allianceauth/optimer/templates/optimer/management.html:13
@@ -1365,7 +1394,7 @@ msgstr "Tipo en EVE actual:"
#: allianceauth/optimer/templates/optimer/management.html:26
msgid "Next Fleet Operations"
msgstr ""
msgstr "Próximas operaciones de flota"
#: allianceauth/optimer/templates/optimer/management.html:30
#: allianceauth/timerboard/templates/timerboard/view.html:362
@@ -1374,7 +1403,7 @@ msgstr "No hay proximos timers."
#: allianceauth/optimer/templates/optimer/management.html:33
msgid "Past Fleet Operations"
msgstr ""
msgstr "Operaciones de flota pasadas"
#: allianceauth/optimer/templates/optimer/management.html:37
#: allianceauth/timerboard/templates/timerboard/view.html:535
@@ -1413,7 +1442,7 @@ msgstr "Auditar Permisos"
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:20
msgid "User / Character"
msgstr ""
msgstr "Usuario / Personaje"
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:4
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:8
@@ -1458,16 +1487,16 @@ msgstr "Estados"
#: allianceauth/services/abstract.py:72
msgid "That service account already exists"
msgstr ""
msgstr "Esa cuenta de servicio ya existe"
#: allianceauth/services/abstract.py:103
#, python-brace-format
msgid "Successfully set your {self.service_name} password"
msgstr ""
msgstr "Ha establecido correctamente su contraseña {self.service_name}."
#: allianceauth/services/auth_hooks.py:12
msgid "Services"
msgstr ""
msgstr "Servicios"
#: allianceauth/services/forms.py:6
msgid "Name of Fleet:"
@@ -1531,29 +1560,31 @@ msgstr "La contraseña tiene que tener 8 caracteres de largo minimo"
#: allianceauth/services/modules/discord/models.py:187
msgid "Discord Account Disabled"
msgstr ""
msgstr "Cuenta de Discord desactivada"
#: allianceauth/services/modules/discord/models.py:189
msgid ""
"Your Discord account was disabled automatically by Auth. If you think this "
"was a mistake, please contact an admin."
msgstr ""
"Tu cuenta de Discord ha sido desactivada automáticamente por Auth. Si crees "
"que se trata de un error, ponte en contacto con un administrador."
#: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:5
msgid "Discord"
msgstr ""
msgstr "Discord"
#: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:18
msgid "Join the Discord server"
msgstr ""
msgstr "Unirse al servidor Discord"
#: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:22
msgid "Leave- and rejoin the Discord Server (Reset)"
msgstr ""
msgstr "Salir y volver al servidor Discord (Reiniciar)"
#: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:25
msgid "Leave the Discord server"
msgstr ""
msgstr "Abandonar el servidor de Discord"
#: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:32
msgid "Link Discord Server"
@@ -1561,68 +1592,74 @@ msgstr "Enlace a servidor de Discord"
#: allianceauth/services/modules/discord/views.py:30
msgid "Deactivated Discord account."
msgstr ""
msgstr "Cuenta de Discord desactivada."
#: allianceauth/services/modules/discord/views.py:36
#: allianceauth/services/modules/discord/views.py:59
msgid "An error occurred while processing your Discord account."
msgstr ""
msgstr "Se ha producido un error al procesar tu cuenta de Discord."
#: allianceauth/services/modules/discord/views.py:102
msgid "Your Discord account has been successfully activated."
msgstr ""
msgstr "Tu cuenta de Discord se ha activado correctamente."
#: allianceauth/services/modules/discord/views.py:108
msgid ""
"An error occurred while trying to activate your Discord account. Please try "
"again."
msgstr ""
"Se ha producido un error al intentar activar tu cuenta de Discord. Inténtalo"
" de nuevo."
#: allianceauth/services/modules/discourse/views.py:29
msgid "You are not authorized to access Discourse."
msgstr ""
msgstr "No estás autorizado a acceder a Discourse."
#: allianceauth/services/modules/discourse/views.py:34
msgid "You must have a main character set to access Discourse."
msgstr ""
msgstr "Para acceder a Discourse es necesario tener un personaje principal."
#: allianceauth/services/modules/discourse/views.py:44
msgid ""
"No SSO payload or signature. Please contact support if this problem "
"persists."
msgstr ""
"No existe contenido ni firma SSO. Póngase en contacto con el servicio de "
"asistencia si este problema persiste."
#: allianceauth/services/modules/discourse/views.py:54
#: allianceauth/services/modules/discourse/views.py:62
msgid "Invalid payload. Please contact support if this problem persists."
msgstr ""
"Contenido no válido. Póngase en contacto con el servicio de asistencia si "
"este problema persiste."
#: allianceauth/services/modules/ips4/views.py:31
msgid "Activated IPSuite4 account."
msgstr ""
msgstr "Cuenta IPSuite4 activada."
#: allianceauth/services/modules/ips4/views.py:39
#: allianceauth/services/modules/ips4/views.py:60
#: allianceauth/services/modules/ips4/views.py:81
#: allianceauth/services/modules/ips4/views.py:101
msgid "An error occurred while processing your IPSuite4 account."
msgstr ""
msgstr "Se ha producido un error al procesar su cuenta IPSuite4."
#: allianceauth/services/modules/ips4/views.py:52
msgid "Reset IPSuite4 password."
msgstr ""
msgstr "Restablecer la contraseña de IPSuite4."
#: allianceauth/services/modules/ips4/views.py:78
msgid "Set IPSuite4 password."
msgstr ""
msgstr "Establecer contraseña de IPSuite4."
#: allianceauth/services/modules/ips4/views.py:98
msgid "Deactivated IPSuite4 account."
msgstr ""
msgstr "Cuenta IPSuite4 desactivada."
#: allianceauth/services/modules/openfire/auth_hooks.py:26
msgid "Jabber"
msgstr ""
msgstr "Jabber"
#: allianceauth/services/modules/openfire/auth_hooks.py:79
#: allianceauth/services/modules/openfire/templates/services/openfire/broadcast.html:5
@@ -1632,7 +1669,7 @@ msgstr "Anuncio por Jabber"
#: allianceauth/services/modules/openfire/auth_hooks.py:94
msgid "Fleet Broadcast Formatter"
msgstr ""
msgstr "Formateador de difusión de flota"
#: allianceauth/services/modules/openfire/forms.py:7
msgid "Message"
@@ -1648,73 +1685,73 @@ msgstr "Anuncio"
#: allianceauth/services/modules/openfire/views.py:35
msgid "Activated jabber account."
msgstr ""
msgstr "Cuenta jabber activada."
#: allianceauth/services/modules/openfire/views.py:43
#: allianceauth/services/modules/openfire/views.py:56
#: allianceauth/services/modules/openfire/views.py:76
#: allianceauth/services/modules/openfire/views.py:147
msgid "An error occurred while processing your jabber account."
msgstr ""
msgstr "Se ha producido un error al procesar su cuenta jabber."
#: allianceauth/services/modules/openfire/views.py:69
msgid "Reset jabber password."
msgstr ""
msgstr "Restablecer contraseña jabber."
#: allianceauth/services/modules/openfire/views.py:115
#, python-format
msgid "Sent jabber broadcast to %s"
msgstr ""
msgstr "Enviar difusión jabber a %s"
#: allianceauth/services/modules/openfire/views.py:144
msgid "Set jabber password."
msgstr ""
msgstr "Establecer contraseña jabber."
#: allianceauth/services/modules/phpbb3/views.py:34
msgid "Activated forum account."
msgstr ""
msgstr "Cuenta del foro activada."
#: allianceauth/services/modules/phpbb3/views.py:42
#: allianceauth/services/modules/phpbb3/views.py:56
#: allianceauth/services/modules/phpbb3/views.py:78
#: allianceauth/services/modules/phpbb3/views.py:101
msgid "An error occurred while processing your forum account."
msgstr ""
msgstr "Se ha producido un error al procesar su cuenta del foro."
#: allianceauth/services/modules/phpbb3/views.py:53
msgid "Deactivated forum account."
msgstr ""
msgstr "Cuenta del foro desactivada."
#: allianceauth/services/modules/phpbb3/views.py:70
msgid "Reset forum password."
msgstr ""
msgstr "Restablecer contraseña del foro."
#: allianceauth/services/modules/phpbb3/views.py:98
msgid "Set forum password."
msgstr ""
msgstr "Establecer contraseña del foro."
#: allianceauth/services/modules/smf/views.py:52
msgid "Activated SMF account."
msgstr ""
msgstr "Cuenta SMF activada."
#: allianceauth/services/modules/smf/views.py:65
#: allianceauth/services/modules/smf/views.py:81
#: allianceauth/services/modules/smf/views.py:102
#: allianceauth/services/modules/smf/views.py:124
msgid "An error occurred while processing your SMF account."
msgstr ""
msgstr "Se ha producido un error al procesar tu cuenta SMF."
#: allianceauth/services/modules/smf/views.py:78
msgid "Deactivated SMF account."
msgstr ""
msgstr "Cuenta SMF desactivada."
#: allianceauth/services/modules/smf/views.py:95
msgid "Reset SMF password."
msgstr ""
msgstr "Restablecer contraseña de SMF."
#: allianceauth/services/modules/smf/views.py:121
msgid "Set SMF password."
msgstr ""
msgstr "Establecer contraseña de SMF."
#: allianceauth/services/modules/teamspeak3/forms.py:14
#, python-format
@@ -1723,7 +1760,7 @@ msgstr "No fue posible localizar tu usuario %s en el servidor"
#: allianceauth/services/modules/teamspeak3/templates/admin/teamspeak3/authts/change_list.html:8
msgid "Update TS3 groups"
msgstr ""
msgstr "Actualizar los grupos de TS3"
#: allianceauth/services/modules/teamspeak3/templates/services/teamspeak3/teamspeakjoin.html:5
msgid "Verify Teamspeak"
@@ -1745,44 +1782,44 @@ msgstr "Continuar"
#: allianceauth/services/modules/teamspeak3/views.py:35
msgid "Activated TeamSpeak3 account."
msgstr ""
msgstr "Cuenta de TeamSpeak3 activada."
#: allianceauth/services/modules/teamspeak3/views.py:38
#: allianceauth/services/modules/teamspeak3/views.py:74
#: allianceauth/services/modules/teamspeak3/views.py:100
msgid "An error occurred while processing your TeamSpeak3 account."
msgstr ""
msgstr "Se ha producido un error al procesar tu cuenta de TeamSpeak3."
#: allianceauth/services/modules/teamspeak3/views.py:71
msgid "Deactivated TeamSpeak3 account."
msgstr ""
msgstr "Cuenta de TeamSpeak3 desactivada."
#: allianceauth/services/modules/teamspeak3/views.py:97
msgid "Reset TeamSpeak3 permission key."
msgstr ""
msgstr "Restablecer la clave de permiso de TeamSpeak3."
#: allianceauth/services/modules/xenforo/views.py:30
msgid "Activated XenForo account."
msgstr ""
msgstr "Cuenta de XenForo activada."
#: allianceauth/services/modules/xenforo/views.py:40
#: allianceauth/services/modules/xenforo/views.py:52
#: allianceauth/services/modules/xenforo/views.py:73
#: allianceauth/services/modules/xenforo/views.py:94
msgid "An error occurred while processing your XenForo account."
msgstr ""
msgstr "Se ha producido un error al procesar tu cuenta de XenForo."
#: allianceauth/services/modules/xenforo/views.py:50
msgid "Deactivated XenForo account."
msgstr ""
msgstr "Cuenta de XenForo desactivada."
#: allianceauth/services/modules/xenforo/views.py:65
msgid "Reset XenForo account password."
msgstr ""
msgstr "Restablecer la contraseña de la cuenta de XenForo."
#: allianceauth/services/modules/xenforo/views.py:91
msgid "Changed XenForo password."
msgstr ""
msgstr "Contraseña de XenForo cambiada."
#: allianceauth/services/templates/services/fleetformattertool.html:5
msgid "Fleet Formatter Tool"
@@ -1807,6 +1844,8 @@ msgstr "Eliminar tu cuenta en %(service_name)s ?"
msgid ""
"Are you sure you want to delete your %(service_name)s account %(object)s?"
msgstr ""
"¿Estás seguro de que quieres eliminar tu cuenta de %(service_name)s "
"%(object)s?"
#: allianceauth/services/templates/services/service_credentials.html:4
#: allianceauth/services/templates/services/service_credentials.html:8
@@ -1860,15 +1899,16 @@ msgstr "Doctrina"
#: allianceauth/srp/form.py:16
msgid "Killboard Link (zkillboard.com or kb.evetools.org)"
msgstr ""
msgstr "Enlace Killboard (zkillboard.com o kb.evetools.org)"
#: allianceauth/srp/form.py:34
msgid "Invalid Link. Please use zkillboard.com or kb.evetools.org"
msgstr ""
msgstr "Enlace no válido. Por favor, utilice zkillboard.com o kb.evetools.org"
#: allianceauth/srp/form.py:46
msgid "Invalid Link. Please post a direct link to a killmail."
msgstr ""
"Enlace no válido. Por favor, proporcione un enlace directo a un killmail."
#: allianceauth/srp/form.py:53
msgid "After Action Report Link"
@@ -1889,7 +1929,7 @@ msgstr "Entregar este enlace a los miembros"
#: allianceauth/srp/templates/srp/data.html:5
msgid "Srp Fleet Data"
msgstr ""
msgstr "Informacion de SRP de la flota"
#: allianceauth/srp/templates/srp/data.html:50
msgid "SRP Fleet Data"
@@ -1942,6 +1982,8 @@ msgstr "Costo del SRP"
#: allianceauth/srp/templates/srp/data.html:95
msgid "Click value to edit Enter to save & next ESC to cancel"
msgstr ""
"Haz clic en el valor para editar. Presiona Enter para guardar y continuar, o"
" ESC para cancelar"
#: allianceauth/srp/templates/srp/data.html:98
msgid "Post Time"
@@ -2063,7 +2105,7 @@ msgstr "Imposible localizar el SRP con el codigo %(srpfleetid)s"
#: allianceauth/srp/views.py:179
msgid "This kill mail has already been posted."
msgstr ""
msgstr "Este correo mortal ya ha sido publicado."
#: allianceauth/srp/views.py:200
msgid ""
@@ -2132,11 +2174,11 @@ msgstr "Cerrado"
#: allianceauth/templates/allianceauth/admin-status/overview.html:28
msgid "Powered by GitLab"
msgstr ""
msgstr "Desarrollado por GitLab"
#: allianceauth/templates/allianceauth/admin-status/overview.html:35
msgid "Support Discord"
msgstr ""
msgstr "Soporte Discord"
#: allianceauth/templates/allianceauth/admin-status/overview.html:43
msgid "Software Version"
@@ -2148,7 +2190,7 @@ msgstr "Actual"
#: allianceauth/templates/allianceauth/admin-status/overview.html:53
msgid "Latest Stable"
msgstr ""
msgstr "Último Estable"
#: allianceauth/templates/allianceauth/admin-status/overview.html:59
msgid "Update available"
@@ -2156,11 +2198,11 @@ msgstr "Actualizacion Disponible"
#: allianceauth/templates/allianceauth/admin-status/overview.html:64
msgid "Latest Pre-Release"
msgstr ""
msgstr "Último Pre-Lanzamiento"
#: allianceauth/templates/allianceauth/admin-status/overview.html:70
msgid "Pre-Release available"
msgstr ""
msgstr "Pre-Lanzamiento disponible"
#: allianceauth/templates/allianceauth/admin-status/overview.html:78
msgid "Task Queue"
@@ -2173,6 +2215,8 @@ msgid ""
" Status of %(total)s processed tasks • last %(latest)s\n"
" "
msgstr ""
"\n"
"Estado de %(total)s tareas procesadas • últimos %(latest)s"
#: allianceauth/templates/allianceauth/admin-status/overview.html:95
#, python-format
@@ -2181,6 +2225,8 @@ msgid ""
" %(queue_length)s queued tasks\n"
" "
msgstr ""
"\n"
"%(queue_length)s tareas en cola"
#: allianceauth/templates/allianceauth/top-menu-admin.html:9
msgid "Admin"
@@ -2188,16 +2234,16 @@ msgstr "Administrador"
#: allianceauth/templates/allianceauth/top-menu-admin.html:19
msgid "AA Documentation"
msgstr ""
msgstr "Documentación AA"
#: allianceauth/templates/allianceauth/top-menu-admin.html:26
msgid "AA Support Discord"
msgstr ""
msgstr "Soporte Discord AA"
#: allianceauth/templates/allianceauth/top-menu-user-dropdown.html:10
#: allianceauth/templates/allianceauth/top-menu-user-dropdown.html:14
msgid "User Menu"
msgstr ""
msgstr "Menú de usuario"
#: allianceauth/templates/allianceauth/top-menu-user-dropdown.html:56
msgid "Logout"
@@ -2245,7 +2291,7 @@ msgstr "Tipo de Estructura"
#: allianceauth/timerboard/form.py:62
msgid "Timer Type"
msgstr ""
msgstr "Tipo de temporizador"
#: allianceauth/timerboard/form.py:63
#: allianceauth/timerboard/templates/timerboard/view.html:32
@@ -2276,15 +2322,15 @@ msgstr "Restringido a Corp"
#: allianceauth/timerboard/models.py:14
msgid "Not Specified"
msgstr ""
msgstr "Sin especificación"
#: allianceauth/timerboard/models.py:15
msgid "Shield"
msgstr ""
msgstr "Escudo"
#: allianceauth/timerboard/models.py:16
msgid "Armor"
msgstr ""
msgstr "Armadura"
#: allianceauth/timerboard/models.py:17
msgid "Hull"
@@ -2292,15 +2338,15 @@ msgstr "Tipo"
#: allianceauth/timerboard/models.py:18
msgid "Final"
msgstr ""
msgstr "Final"
#: allianceauth/timerboard/models.py:19
msgid "Anchoring"
msgstr ""
msgstr "Anclando"
#: allianceauth/timerboard/models.py:20
msgid "Unanchoring"
msgstr ""
msgstr "Desanclando"
#: allianceauth/timerboard/templates/timerboard/timer_confirm_delete.html:11
msgid "Delete Timer"

View File

@@ -10,16 +10,18 @@
# Idea ., 2021
# Mickael PATTE, 2021
# Geoffrey Fabbro, 2021
# Mohssine Daghghar, 2023
# Ludovick Fortin, 2023
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-09-14 23:17+1000\n"
"POT-Creation-Date: 2022-10-09 18:20+1000\n"
"PO-Revision-Date: 2020-02-18 03:14+0000\n"
"Last-Translator: Geoffrey Fabbro, 2021\n"
"Language-Team: French (France) (https://www.transifex.com/alliance-auth/teams/107430/fr_FR/)\n"
"Last-Translator: Ludovick Fortin, 2023\n"
"Language-Team: French (France) (https://app.transifex.com/alliance-auth/teams/107430/fr_FR/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -28,7 +30,7 @@ msgstr ""
#: allianceauth/analytics/models.py:29
msgid "Google Analytics Universal"
msgstr ""
msgstr "Google Analytique Universelle"
#: allianceauth/analytics/models.py:30
msgid "Google Analytics V4"
@@ -48,55 +50,48 @@ msgstr "Email"
#, python-format
msgid "You are not allowed to add or remove these restricted groups: %s"
msgstr ""
"Vous n'avez pas lautorisation d'ajouter ou d'enlever ces groupes "
"restreints: %s"
#: allianceauth/authentication/models.py:80
#: allianceauth/project_template/project_name/settings/base.py:89
msgid "English"
msgstr "Anglais"
#: allianceauth/authentication/models.py:81
#: allianceauth/project_template/project_name/settings/base.py:90
msgid "German"
msgstr "Allemand"
#: allianceauth/authentication/models.py:82
#: allianceauth/project_template/project_name/settings/base.py:91
msgid "Spanish"
msgstr "Espagnol"
#: allianceauth/authentication/models.py:83
#: allianceauth/project_template/project_name/settings/base.py:92
msgid "Chinese Simplified"
msgstr "Chinois simplifié"
#: allianceauth/authentication/models.py:84
#: allianceauth/project_template/project_name/settings/base.py:93
msgid "Russian"
msgstr "Russe"
#: allianceauth/authentication/models.py:85
#: allianceauth/project_template/project_name/settings/base.py:94
msgid "Korean"
msgstr "Coréen"
#: allianceauth/authentication/models.py:86
#: allianceauth/project_template/project_name/settings/base.py:95
msgid "French"
msgstr "Français"
#: allianceauth/authentication/models.py:87
#: allianceauth/project_template/project_name/settings/base.py:96
msgid "Japanese"
msgstr "Japonais"
#: allianceauth/authentication/models.py:88
#: allianceauth/project_template/project_name/settings/base.py:97
msgid "Italian"
msgstr "Italien"
#: allianceauth/authentication/models.py:91
msgid "Language"
msgstr ""
msgstr "Langue"
#: allianceauth/authentication/models.py:96
#: allianceauth/templates/allianceauth/night-toggle.html:6
@@ -179,19 +174,21 @@ msgstr "Connexion"
#: allianceauth/authentication/templates/public/login.html:10
msgid "Login with Eve SSO"
msgstr ""
msgstr "Connexion avec Eve SSO"
#: allianceauth/authentication/templates/public/middle_box.html:24
msgid "For information on SSO, ESI and security read the CCP Dev Blog"
msgstr ""
"Pour de l'information sur le SSO, le ESI et la sécurité, lisez le blog de "
"développeur CCP"
#: allianceauth/authentication/templates/public/middle_box.html:26
msgid "Introducing ESI - A New API For Eve Online"
msgstr ""
msgstr "Présentation d'ESI, une nouvelle API pour Eve Online."
#: allianceauth/authentication/templates/public/middle_box.html:32
msgid "Manage ESI Applications"
msgstr ""
msgstr "Gestion des Application ESI"
#: allianceauth/authentication/templates/public/register.html:6
msgid "Registration"
@@ -614,11 +611,11 @@ msgstr "Aucun lien FAT enregistré"
#: allianceauth/fleetactivitytracking/views.py:218
msgid "Character does not exist"
msgstr ""
msgstr "Le personnage n'existe pas"
#: allianceauth/fleetactivitytracking/views.py:221
msgid "User does not exist"
msgstr ""
msgstr "L'utilisateur n'existe pas"
#: allianceauth/fleetactivitytracking/views.py:299
msgid "Fleet participation registered."
@@ -634,6 +631,8 @@ msgid ""
"Cannot register the fleet participation for {character.character_name}. The "
"character needs to be online."
msgstr ""
"Impossible d'enregistrer la participation pour {character.character_name}. "
"Le personnage doit être en ligne."
#: allianceauth/groupmanagement/auth_hooks.py:17
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:13
@@ -642,15 +641,15 @@ msgstr "Gestion de groupe"
#: allianceauth/groupmanagement/forms.py:15
msgid "This name has been reserved and can not be used for groups."
msgstr ""
msgstr "Ce nom a été réserver et il ne peut être utilisé pour les groupes."
#: allianceauth/groupmanagement/forms.py:25
msgid "(auto)"
msgstr ""
msgstr "(automatique)"
#: allianceauth/groupmanagement/forms.py:34
msgid "There already exists a group with that name."
msgstr ""
msgstr "Il existe déjà un groupe portant ce nom."
#: allianceauth/groupmanagement/models.py:105
msgid ""
@@ -658,16 +657,25 @@ msgid ""
"group.<br>Used for groups such as Members, Corp_*, Alliance_* "
"etc.<br><b>Overrides Hidden and Open options when selected.</b>"
msgstr ""
"Groupe interne, les utilisateurs ne peuvent pas voir, rejoindre ou demander "
"de rejoindre ce groupe.<br> Utilisé pour les groupes comme, Membres, "
"Corporations _*, Alliance etc.<br><b> Annule les options masquer et exposer "
"quand sélectionner."
#: allianceauth/groupmanagement/models.py:113
msgid "Group is hidden from users but can still join with the correct link."
msgstr ""
"Le groupe est caché aux utilisateurs, mais ils peuvent toujours rejoindre "
"avec le bon lien."
#: allianceauth/groupmanagement/models.py:119
msgid ""
"Group is open and users will be automatically added upon request.<br>If the "
"group is not open users will need their request manually approved."
msgstr ""
"Le groupe est ouvert, et les utilisateurs seront automatiquement ajoutés sur"
" demande. <br> Si le groupe nest pas ouvert, les utilisateurs auront besoin"
" que leurs demandes soit approuvées manuellement."
#: allianceauth/groupmanagement/models.py:126
msgid ""
@@ -676,12 +684,18 @@ msgid ""
"remove users from this group automatically when they are no longer "
"authenticated."
msgstr ""
"Le groupe est public. Tout utilisateur enregistré peut rejoindre ce groupe, "
"avec une visibilité basée sur les autres options définies pour ce "
"groupe.<br> L' Auth ne supprimera pas automatiquement les utilisateurs de ce"
" groupe lorsquils ne seront plus authentifiés."
#: allianceauth/groupmanagement/models.py:135
msgid ""
"Group is restricted. This means that adding or removing users for this group"
" requires a superuser admin."
msgstr ""
"Le groupe est restreint. Cela signifie que lajout ou la suppression "
"dutilisateurs pour ce groupe nécessite un administrateur superutilisateur."
#: allianceauth/groupmanagement/models.py:144
msgid ""
@@ -707,38 +721,40 @@ msgstr ""
msgid ""
"Short description <i>(max. 512 characters)</i> of the group shown to users."
msgstr ""
"Brève description <i> (512 caractères maximum) </i> du groupe présenté aux "
"utilisateurs."
#: allianceauth/groupmanagement/models.py:178
msgid "Can request non-public groups"
msgstr ""
msgstr "Peut demander des groupes non publics"
#: allianceauth/groupmanagement/models.py:209
msgid "name"
msgstr ""
msgstr "Nom"
#: allianceauth/groupmanagement/models.py:212
msgid "Name that can not be used for groups."
msgstr ""
msgstr "Nom qui ne peut pas être utilisé pour les groupes."
#: allianceauth/groupmanagement/models.py:215
msgid "reason"
msgstr ""
msgstr "raison"
#: allianceauth/groupmanagement/models.py:215
msgid "Reason why this name is reserved."
msgstr ""
msgstr "Raison pour laquelle ce nom est réservé."
#: allianceauth/groupmanagement/models.py:218
msgid "created by"
msgstr ""
msgstr "créé par"
#: allianceauth/groupmanagement/models.py:223
msgid "created at"
msgstr ""
msgstr "créé à"
#: allianceauth/groupmanagement/models.py:223
msgid "Date when this entry was created"
msgstr ""
msgstr "Date de création de cette entrée"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:4
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:13
@@ -868,7 +884,7 @@ msgstr "Voir les membres"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:59
msgid "Audit Members"
msgstr ""
msgstr "Membres de l'audit"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:63
msgid "Copy Direct Join Link"
@@ -1274,7 +1290,7 @@ msgstr "Titre"
#: allianceauth/notifications/templates/notifications/list_partial.html:28
msgid "No notifications."
msgstr ""
msgstr "Aucune notification."
#: allianceauth/notifications/templates/notifications/view.html:4
#: allianceauth/notifications/templates/notifications/view.html:8
@@ -1322,7 +1338,7 @@ msgstr "Nom de l'opération"
#: allianceauth/optimer/form.py:16
msgid "Operation Type"
msgstr ""
msgstr "Type d'opération"
#: allianceauth/optimer/form.py:17
#: allianceauth/srp/templates/srp/management.html:38
@@ -1336,7 +1352,7 @@ msgstr "Information additionnelle"
#: allianceauth/optimer/form.py:23
msgid "(Optional) Describe the operation with a couple of short words."
msgstr ""
msgstr "(Facultatif) Décrivez l'opération en quelques mots."
#: allianceauth/optimer/templates/optimer/add.html:6
#: allianceauth/optimer/templates/optimer/management.html:13
@@ -1373,7 +1389,7 @@ msgstr "Heure d'Eve actuelle:"
#: allianceauth/optimer/templates/optimer/management.html:26
msgid "Next Fleet Operations"
msgstr ""
msgstr "Prochaines opérations de la flotte"
#: allianceauth/optimer/templates/optimer/management.html:30
#: allianceauth/timerboard/templates/timerboard/view.html:362
@@ -1382,7 +1398,7 @@ msgstr "Aucun minuteur à venir."
#: allianceauth/optimer/templates/optimer/management.html:33
msgid "Past Fleet Operations"
msgstr ""
msgstr "Opérations passées de la flotte"
#: allianceauth/optimer/templates/optimer/management.html:37
#: allianceauth/timerboard/templates/timerboard/view.html:535
@@ -1830,7 +1846,7 @@ msgstr ""
#: allianceauth/services/templates/services/service_credentials.html:8
#, python-format
msgid "%(service_name)s Credentials"
msgstr ""
msgstr "%(service_name)sInformations d'identification"
#: allianceauth/services/templates/services/service_password.html:5
#, python-format
@@ -1890,7 +1906,7 @@ msgstr "Lien non valide. Veuillez poster un lien direct vers un Killmail."
#: allianceauth/srp/form.py:53
msgid "After Action Report Link"
msgstr ""
msgstr "Lien vers le rapport après action"
#: allianceauth/srp/templates/srp/add.html:5
msgid "SRP Fleet Create"
@@ -1907,7 +1923,7 @@ msgstr "Donner ce lien aux membres de la flotte"
#: allianceauth/srp/templates/srp/data.html:5
msgid "Srp Fleet Data"
msgstr ""
msgstr "Données de flotte SRP"
#: allianceauth/srp/templates/srp/data.html:50
msgid "SRP Fleet Data"
@@ -1965,7 +1981,7 @@ msgstr ""
#: allianceauth/srp/templates/srp/data.html:98
msgid "Post Time"
msgstr ""
msgstr "Heure de publication"
#: allianceauth/srp/templates/srp/data.html:175
msgid "No SRP requests for this fleet."
@@ -2069,17 +2085,17 @@ msgstr "Flotte SRP %(fleetname)sActive."
#: allianceauth/srp/views.py:140
#, python-format
msgid "Marked SRP fleet %(fleetname)s as completed."
msgstr ""
msgstr "Flotte SRP marquée %(fleetname)s comme terminée."
#: allianceauth/srp/views.py:153
#, python-format
msgid "Marked SRP fleet %(fleetname)s as incomplete."
msgstr ""
msgstr "Flotte SRP %(fleetname)smarquée comme incomplète."
#: allianceauth/srp/views.py:165
#, python-format
msgid "Unable to locate SRP code with ID %(srpfleetid)s"
msgstr ""
msgstr "Impossible de localiser le code SRP avec l'ID %(srpfleetid)s"
#: allianceauth/srp/views.py:179
msgid "This kill mail has already been posted."
@@ -2096,7 +2112,7 @@ msgstr ""
#: allianceauth/srp/views.py:212
#, python-format
msgid "Submitted SRP request for your %(ship)s."
msgstr ""
msgstr "Demande SRP soumise pour votre. %(ship)s"
#: allianceauth/srp/views.py:216
#, python-format
@@ -2104,6 +2120,8 @@ msgid ""
"Character %(charid)s does not belong to your Auth account. Please add the "
"API key for this character and try again"
msgstr ""
"Le personnage%(charid)s n'appartient pas à votre compte Auth. Ajoutez la clé"
" API pour ce personnage et réessayez"
#: allianceauth/srp/views.py:236 allianceauth/srp/views.py:262
#: allianceauth/srp/views.py:300
@@ -2131,17 +2149,17 @@ msgstr "Impossible à trouver, veuillez sélectionner une autre requête SRP"
#: allianceauth/srp/views.py:323
#, python-format
msgid "Rejected %(numrequests)s SRP requests."
msgstr ""
msgstr "Requêtes %(numrequests)s SRP rejetées."
#: allianceauth/srp/views.py:336
#, python-format
msgid "Unable to locate SRP request with ID %(requestid)s"
msgstr ""
msgstr "Impossible de localiser la demande SRP avec l'ID %(requestid)s"
#: allianceauth/srp/views.py:360
#, python-format
msgid "Saved changes to SRP fleet %(fleetname)s"
msgstr ""
msgstr "Modifications enregistrées de la flotte SRP%(fleetname)s"
#: allianceauth/templates/allianceauth/admin-status/overview.html:8
msgid "Alliance Auth Notifications"
@@ -2194,6 +2212,9 @@ msgid ""
" Status of %(total)s processed tasks • last %(latest)s\n"
" "
msgstr ""
"\n"
"État des tâches %(total)s traitées • dernier %(latest)s\n"
" "
#: allianceauth/templates/allianceauth/admin-status/overview.html:95
#, python-format
@@ -2202,6 +2223,9 @@ msgid ""
" %(queue_length)s queued tasks\n"
" "
msgstr ""
"\n"
" %(queue_length)stâches en file d'attente\n"
" "
#: allianceauth/templates/allianceauth/top-menu-admin.html:9
msgid "Admin"

View File

@@ -5,17 +5,17 @@
#
# Translators:
# Alessandro Cresti, 2021
# Linus Hope, 2021
# Linus Hope, 2023
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-09-14 23:17+1000\n"
"POT-Creation-Date: 2022-10-09 18:20+1000\n"
"PO-Revision-Date: 2020-02-18 03:14+0000\n"
"Last-Translator: Linus Hope, 2021\n"
"Language-Team: Italian (Italy) (https://www.transifex.com/alliance-auth/teams/107430/it_IT/)\n"
"Last-Translator: Linus Hope, 2023\n"
"Language-Team: Italian (Italy) (https://app.transifex.com/alliance-auth/teams/107430/it_IT/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -24,11 +24,11 @@ msgstr ""
#: allianceauth/analytics/models.py:29
msgid "Google Analytics Universal"
msgstr ""
msgstr "Google Analytics Universal"
#: allianceauth/analytics/models.py:30
msgid "Google Analytics V4"
msgstr ""
msgstr "Google Analytics V4"
#: allianceauth/authentication/decorators.py:37
msgid "A main character is required to perform that action. Add one below."
@@ -38,76 +38,67 @@ msgstr ""
#: allianceauth/authentication/forms.py:12
msgid "Email"
msgstr ""
msgstr "Indirizzo di posta elettronica"
#: allianceauth/authentication/forms.py:62
#, python-format
msgid "You are not allowed to add or remove these restricted groups: %s"
msgstr ""
msgstr "Non ti è consentito aggiungere o rimuovere questi gruppi limitati:%s"
#: allianceauth/authentication/models.py:80
#: allianceauth/project_template/project_name/settings/base.py:89
msgid "English"
msgstr ""
msgstr "Inglese"
#: allianceauth/authentication/models.py:81
#: allianceauth/project_template/project_name/settings/base.py:90
msgid "German"
msgstr ""
msgstr "Tedesco"
#: allianceauth/authentication/models.py:82
#: allianceauth/project_template/project_name/settings/base.py:91
msgid "Spanish"
msgstr ""
msgstr "Spagnolo"
#: allianceauth/authentication/models.py:83
#: allianceauth/project_template/project_name/settings/base.py:92
msgid "Chinese Simplified"
msgstr ""
msgstr "Cinese semplificato"
#: allianceauth/authentication/models.py:84
#: allianceauth/project_template/project_name/settings/base.py:93
msgid "Russian"
msgstr ""
msgstr "Russo"
#: allianceauth/authentication/models.py:85
#: allianceauth/project_template/project_name/settings/base.py:94
msgid "Korean"
msgstr ""
msgstr "Coreano"
#: allianceauth/authentication/models.py:86
#: allianceauth/project_template/project_name/settings/base.py:95
msgid "French"
msgstr ""
msgstr "Francese"
#: allianceauth/authentication/models.py:87
#: allianceauth/project_template/project_name/settings/base.py:96
msgid "Japanese"
msgstr ""
msgstr "Giapponese"
#: allianceauth/authentication/models.py:88
#: allianceauth/project_template/project_name/settings/base.py:97
msgid "Italian"
msgstr ""
msgstr "Italiano"
#: allianceauth/authentication/models.py:91
msgid "Language"
msgstr ""
msgstr "Lingua"
#: allianceauth/authentication/models.py:96
#: allianceauth/templates/allianceauth/night-toggle.html:6
msgid "Night Mode"
msgstr ""
msgstr "Modalità scura"
#: allianceauth/authentication/models.py:110
#, python-format
msgid "State changed to: %s"
msgstr ""
msgstr "Stato modificato a: %s"
#: allianceauth/authentication/models.py:111
#, python-format
msgid "Your user's state is now: %(state)s"
msgstr ""
msgstr "Il tuo stato utente è ora: %(state)s"
#: allianceauth/authentication/templates/authentication/dashboard.html:4
#: allianceauth/authentication/templates/authentication/dashboard.html:7
@@ -172,23 +163,25 @@ msgstr "Alleanza"
#: allianceauth/authentication/templates/public/login.html:6
#: allianceauth/templates/allianceauth/top-menu-user-dropdown.html:58
msgid "Login"
msgstr ""
msgstr "Accedi"
#: allianceauth/authentication/templates/public/login.html:10
msgid "Login with Eve SSO"
msgstr ""
msgstr "Accedi con EVE SSO"
#: allianceauth/authentication/templates/public/middle_box.html:24
msgid "For information on SSO, ESI and security read the CCP Dev Blog"
msgstr ""
"Per ulteriori informazioni riguardo a SSO, ESI e sicurezza consulta il CCP "
"Dev Blog"
#: allianceauth/authentication/templates/public/middle_box.html:26
msgid "Introducing ESI - A New API For Eve Online"
msgstr ""
msgstr "Introducendo ESI - Una nuova API per Eve Online"
#: allianceauth/authentication/templates/public/middle_box.html:32
msgid "Manage ESI Applications"
msgstr ""
msgstr "Gestisci applicazioni ESI"
#: allianceauth/authentication/templates/public/register.html:6
msgid "Registration"
@@ -230,7 +223,7 @@ msgstr ""
#: allianceauth/authentication/views.py:133
msgid "Unable to authenticate as the selected character."
msgstr ""
msgstr "Impossibile autenticarsi con il personaggio selezioanto."
#: allianceauth/authentication/views.py:197
msgid "Registration token has expired."
@@ -322,7 +315,7 @@ msgstr "Corporazione"
#: allianceauth/corputils/templates/corputils/corpstats.html:167
#: allianceauth/corputils/templates/corputils/search.html:27
msgid "Killboard"
msgstr ""
msgstr "Killboard"
#: allianceauth/corputils/templates/corputils/corpstats.html:114
#: allianceauth/corputils/templates/corputils/search.html:16
@@ -350,11 +343,11 @@ msgstr "Cerca risultati"
#: allianceauth/corputils/templates/corputils/search.html:15
msgid "zKillboard"
msgstr ""
msgstr "zKillboard"
#: allianceauth/corputils/views.py:54
msgid "Selected corp already has a statistics module."
msgstr ""
msgstr "La corporazione selezionata dispone già di un modulo statistiche."
#: allianceauth/corputils/views.py:56
msgid "Failed to gather corporation statistics with selected token."
@@ -410,7 +403,7 @@ msgstr "Crea Fatlink"
#: allianceauth/optimer/templates/optimer/add.html:13
#: allianceauth/optimer/templates/optimer/add.html:22
msgid "Create Fleet Operation"
msgstr ""
msgstr "Crea Fleet Operation"
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkformatter.html:13
msgid "Bad request!"
@@ -508,7 +501,7 @@ msgstr[2] "%(user)s ha ottenuto %(links)s links questo mese."
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkpersonalmonthlystatisticsview.html:26
msgid "Times used"
msgstr ""
msgstr "Numero di volte utilizzato"
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkpersonalmonthlystatisticsview.html:37
#, python-format
@@ -565,7 +558,7 @@ msgstr "Mese"
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticscorpview.html:22
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticsview.html:23
msgid "Fats"
msgstr ""
msgstr "Fats"
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticscorpview.html:4
msgid "Fatlink Corp Statistics"
@@ -614,11 +607,11 @@ msgstr "Nessun fatlink documentato."
#: allianceauth/fleetactivitytracking/views.py:218
msgid "Character does not exist"
msgstr ""
msgstr "Il personaggio non esiste"
#: allianceauth/fleetactivitytracking/views.py:221
msgid "User does not exist"
msgstr ""
msgstr "L'utente non esiste"
#: allianceauth/fleetactivitytracking/views.py:299
msgid "Fleet participation registered."
@@ -634,23 +627,25 @@ msgid ""
"Cannot register the fleet participation for {character.character_name}. The "
"character needs to be online."
msgstr ""
"Impossibile registrare la partecipazione alla flotta per "
"{character.character_name}. Il personaggio deve essere online."
#: allianceauth/groupmanagement/auth_hooks.py:17
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:13
msgid "Group Management"
msgstr ""
msgstr "Gestione gruppi"
#: allianceauth/groupmanagement/forms.py:15
msgid "This name has been reserved and can not be used for groups."
msgstr ""
msgstr "Questo nome è riservato e non può essere utilizzato per gruppi."
#: allianceauth/groupmanagement/forms.py:25
msgid "(auto)"
msgstr ""
msgstr "(auto)"
#: allianceauth/groupmanagement/forms.py:34
msgid "There already exists a group with that name."
msgstr ""
msgstr "Esiste già un gruppo con quel nome."
#: allianceauth/groupmanagement/models.py:105
msgid ""
@@ -658,16 +653,25 @@ msgid ""
"group.<br>Used for groups such as Members, Corp_*, Alliance_* "
"etc.<br><b>Overrides Hidden and Open options when selected.</b>"
msgstr ""
"Gruppo interno, gli utenti non possono vedere, unirsi o fare richiesta di "
"adesione a questo gruppo. <br>Utilizzato per gruppi come Membri, Corpazioni,"
" Alleanze, etc. <br><b>Sovrascrive opzioni nascoste e aperte quando "
"seleazionato."
#: allianceauth/groupmanagement/models.py:113
msgid "Group is hidden from users but can still join with the correct link."
msgstr ""
"Il gruppo è nascosto agli utenti ma questi vi possono aderire utilizzando il"
" link corretto. "
#: allianceauth/groupmanagement/models.py:119
msgid ""
"Group is open and users will be automatically added upon request.<br>If the "
"group is not open users will need their request manually approved."
msgstr ""
"Il gruppo è aperto e gli utenti saranno automaticamente aggiunti a seguito "
"richiesta. <br>Se il gruppo non è aperto gli utenti dovranno necessitare di "
"approvazione manuale."
#: allianceauth/groupmanagement/models.py:126
msgid ""

File diff suppressed because it is too large Load Diff

View File

@@ -17,10 +17,10 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-09-14 23:17+1000\n"
"POT-Creation-Date: 2022-10-09 18:20+1000\n"
"PO-Revision-Date: 2020-02-18 03:14+0000\n"
"Last-Translator: jackfrost, 2022\n"
"Language-Team: Korean (Korea) (https://www.transifex.com/alliance-auth/teams/107430/ko_KR/)\n"
"Language-Team: Korean (Korea) (https://app.transifex.com/alliance-auth/teams/107430/ko_KR/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -49,47 +49,38 @@ msgid "You are not allowed to add or remove these restricted groups: %s"
msgstr ""
#: allianceauth/authentication/models.py:80
#: allianceauth/project_template/project_name/settings/base.py:89
msgid "English"
msgstr "영어"
#: allianceauth/authentication/models.py:81
#: allianceauth/project_template/project_name/settings/base.py:90
msgid "German"
msgstr "독일어"
#: allianceauth/authentication/models.py:82
#: allianceauth/project_template/project_name/settings/base.py:91
msgid "Spanish"
msgstr "스페인어"
#: allianceauth/authentication/models.py:83
#: allianceauth/project_template/project_name/settings/base.py:92
msgid "Chinese Simplified"
msgstr "간체자"
#: allianceauth/authentication/models.py:84
#: allianceauth/project_template/project_name/settings/base.py:93
msgid "Russian"
msgstr "러시아어"
#: allianceauth/authentication/models.py:85
#: allianceauth/project_template/project_name/settings/base.py:94
msgid "Korean"
msgstr "한국어"
#: allianceauth/authentication/models.py:86
#: allianceauth/project_template/project_name/settings/base.py:95
msgid "French"
msgstr "프랑스어"
#: allianceauth/authentication/models.py:87
#: allianceauth/project_template/project_name/settings/base.py:96
msgid "Japanese"
msgstr "일본어"
#: allianceauth/authentication/models.py:88
#: allianceauth/project_template/project_name/settings/base.py:97
msgid "Italian"
msgstr "이탈리아어"

View File

@@ -7,16 +7,17 @@
# Alexander Gess <de.alex.gess@gmail.com>, 2020
# Yuriy K <thedjcooltv@gmail.com>, 2020
# Андрей Зубков <and.vareba81@gmail.com>, 2020
# Filipp Chertiev <f@fzfx.ru>, 2023
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-09-14 23:17+1000\n"
"POT-Creation-Date: 2022-10-09 18:20+1000\n"
"PO-Revision-Date: 2020-02-18 03:14+0000\n"
"Last-Translator: Андрей Зубков <and.vareba81@gmail.com>, 2020\n"
"Language-Team: Russian (https://www.transifex.com/alliance-auth/teams/107430/ru/)\n"
"Last-Translator: Filipp Chertiev <f@fzfx.ru>, 2023\n"
"Language-Team: Russian (https://app.transifex.com/alliance-auth/teams/107430/ru/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -25,15 +26,16 @@ msgstr ""
#: allianceauth/analytics/models.py:29
msgid "Google Analytics Universal"
msgstr ""
msgstr "Google Analytics Universal"
#: allianceauth/analytics/models.py:30
msgid "Google Analytics V4"
msgstr ""
msgstr "Google Analytics V4"
#: allianceauth/authentication/decorators.py:37
msgid "A main character is required to perform that action. Add one below."
msgstr "Необходимо указать основного персонажа. Добавим?"
msgstr ""
"Для продолжения следует указать основного персонажа. Выберите его ниже."
#: allianceauth/authentication/forms.py:12
msgid "Email"
@@ -42,61 +44,52 @@ msgstr "Email"
#: allianceauth/authentication/forms.py:62
#, python-format
msgid "You are not allowed to add or remove these restricted groups: %s"
msgstr ""
msgstr "Вам не разрешено добавлять или удалять эти ограниченные группы: %s"
#: allianceauth/authentication/models.py:80
#: allianceauth/project_template/project_name/settings/base.py:89
msgid "English"
msgstr ""
msgstr "Английский"
#: allianceauth/authentication/models.py:81
#: allianceauth/project_template/project_name/settings/base.py:90
msgid "German"
msgstr ""
msgstr "Немецкий"
#: allianceauth/authentication/models.py:82
#: allianceauth/project_template/project_name/settings/base.py:91
msgid "Spanish"
msgstr ""
msgstr "Испанский"
#: allianceauth/authentication/models.py:83
#: allianceauth/project_template/project_name/settings/base.py:92
msgid "Chinese Simplified"
msgstr ""
msgstr "Китайский упрощённый"
#: allianceauth/authentication/models.py:84
#: allianceauth/project_template/project_name/settings/base.py:93
msgid "Russian"
msgstr ""
msgstr "Русский"
#: allianceauth/authentication/models.py:85
#: allianceauth/project_template/project_name/settings/base.py:94
msgid "Korean"
msgstr ""
msgstr "Корейский"
#: allianceauth/authentication/models.py:86
#: allianceauth/project_template/project_name/settings/base.py:95
msgid "French"
msgstr ""
msgstr "Французский"
#: allianceauth/authentication/models.py:87
#: allianceauth/project_template/project_name/settings/base.py:96
msgid "Japanese"
msgstr ""
msgstr "Японский"
#: allianceauth/authentication/models.py:88
#: allianceauth/project_template/project_name/settings/base.py:97
msgid "Italian"
msgstr ""
msgstr "Итальянский"
#: allianceauth/authentication/models.py:91
msgid "Language"
msgstr ""
msgstr "Язык"
#: allianceauth/authentication/models.py:96
#: allianceauth/templates/allianceauth/night-toggle.html:6
msgid "Night Mode"
msgstr ""
msgstr "Ночной режим"
#: allianceauth/authentication/models.py:110
#, python-format
@@ -122,7 +115,7 @@ msgid ""
" "
msgstr ""
"\n"
" Основной персонаж (статус: %(state)s)\n"
" Основной персонаж (статус: %(state)s)\n"
" "
#: allianceauth/authentication/templates/authentication/dashboard.html:101
@@ -175,23 +168,24 @@ msgstr "Вход"
#: allianceauth/authentication/templates/public/login.html:10
msgid "Login with Eve SSO"
msgstr ""
msgstr "Зайти с помощью EVE SSO"
#: allianceauth/authentication/templates/public/middle_box.html:24
msgid "For information on SSO, ESI and security read the CCP Dev Blog"
msgstr ""
"Информацию по SSO, ESI и вопросам безопасности читайте в блоге CCP Dev"
#: allianceauth/authentication/templates/public/middle_box.html:26
msgid "Introducing ESI - A New API For Eve Online"
msgstr ""
msgstr "Введение в ESI — новое API для EVE Online"
#: allianceauth/authentication/templates/public/middle_box.html:32
msgid "Manage ESI Applications"
msgstr ""
msgstr "Управление приложениями ESI"
#: allianceauth/authentication/templates/public/register.html:6
msgid "Registration"
msgstr ""
msgstr "Регистрация"
#: allianceauth/authentication/templates/public/register.html:21
msgid "Register"
@@ -314,7 +308,7 @@ msgstr "Корпорация"
#: allianceauth/corputils/templates/corputils/corpstats.html:167
#: allianceauth/corputils/templates/corputils/search.html:27
msgid "Killboard"
msgstr "zKillBoard"
msgstr "Killboard"
#: allianceauth/corputils/templates/corputils/corpstats.html:114
#: allianceauth/corputils/templates/corputils/search.html:16
@@ -342,7 +336,7 @@ msgstr "Результаты поиска:"
#: allianceauth/corputils/templates/corputils/search.html:15
msgid "zKillboard"
msgstr "zKillBoard"
msgstr "zKillboard"
#: allianceauth/corputils/views.py:54
msgid "Selected corp already has a statistics module."
@@ -607,11 +601,11 @@ msgstr "Нет закрепленных ФлАк ссылок в записи"
#: allianceauth/fleetactivitytracking/views.py:218
msgid "Character does not exist"
msgstr ""
msgstr "Персонаж не существует"
#: allianceauth/fleetactivitytracking/views.py:221
msgid "User does not exist"
msgstr ""
msgstr "Пользователь не существует"
#: allianceauth/fleetactivitytracking/views.py:299
msgid "Fleet participation registered."
@@ -627,6 +621,8 @@ msgid ""
"Cannot register the fleet participation for {character.character_name}. The "
"character needs to be online."
msgstr ""
"Не могу зарегистрировать ФлАк для {character.character_name}. Персонаж "
"должен быть онлайн."
#: allianceauth/groupmanagement/auth_hooks.py:17
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:13
@@ -636,14 +632,15 @@ msgstr "Управление Группой"
#: allianceauth/groupmanagement/forms.py:15
msgid "This name has been reserved and can not be used for groups."
msgstr ""
"Это имя является зарезервированным и не может быть использовано для групп."
#: allianceauth/groupmanagement/forms.py:25
msgid "(auto)"
msgstr ""
msgstr "(авто)"
#: allianceauth/groupmanagement/forms.py:34
msgid "There already exists a group with that name."
msgstr ""
msgstr "Группа с таким именем уже существует."
#: allianceauth/groupmanagement/models.py:105
msgid ""
@@ -651,16 +648,25 @@ msgid ""
"group.<br>Used for groups such as Members, Corp_*, Alliance_* "
"etc.<br><b>Overrides Hidden and Open options when selected.</b>"
msgstr ""
"Внутренняя группа, пользователи не могут видеть эту группу, присоединяться к"
" ней или подавать запрос на присоединение.<br>Используется таких групп как "
"Members, Corp_*, Alliance_* и т. п.<br><b>Будучи выбранной, отменяет "
"настройки \"Скрытая\" и \"Открытая\".</b>"
#: allianceauth/groupmanagement/models.py:113
msgid "Group is hidden from users but can still join with the correct link."
msgstr ""
"Группы скрыты от пользователей, но к ним всё ещё можно присоединиться с "
"помощью корректной ссылки."
#: allianceauth/groupmanagement/models.py:119
msgid ""
"Group is open and users will be automatically added upon request.<br>If the "
"group is not open users will need their request manually approved."
msgstr ""
"Группа является открытой, пользователи будут автоматически добавлены в неё "
"при отправке запроса.<br>Если группа не является открытой, запросы от "
"пользователей будут требовать ручного подтверждения."
#: allianceauth/groupmanagement/models.py:126
msgid ""
@@ -669,12 +675,18 @@ msgid ""
"remove users from this group automatically when they are no longer "
"authenticated."
msgstr ""
"Группа является публичной. Любые зарегистрированные пользователи могут "
"присоединиться к этой группе, настройки видимости будут основаны на других "
"настройках данной группы.<br>Auth не будет удалять пользователей из этой "
"группы автоматически при окончании срока их аутентификации."
#: allianceauth/groupmanagement/models.py:135
msgid ""
"Group is restricted. This means that adding or removing users for this group"
" requires a superuser admin."
msgstr ""
"Группа является ограниченной. Это значит что добавление пользователей в эту "
"группу или удаление из неё требует прав superuser admin."
#: allianceauth/groupmanagement/models.py:144
msgid ""
@@ -682,6 +694,9 @@ msgid ""
"<code>auth.group_management</code> permission to allow a user to manage all "
"groups.<br>"
msgstr ""
"Лидеры группы могут обрабатывать запросы, относящиеся к этой группе. "
"Используйте разрешение <code>auth.group_management</code>, чтобы позволить "
"пользователю управлять всеми группами.<br>"
#: allianceauth/groupmanagement/models.py:154
msgid ""
@@ -689,49 +704,56 @@ msgid ""
"<code>auth.group_management</code> permission to allow a user to manage all "
"groups.<br>"
msgstr ""
"Члены групп лидеров могут обрабатывать запросы, относящиеся к этой группе. "
"Используйте разрешение <code>auth.group_management</code>, чтобы позволить "
"пользователю управлять всеми группами.<br>"
#: allianceauth/groupmanagement/models.py:163
msgid ""
"States listed here will have the ability to join this group provided they "
"have the proper permissions.<br>"
msgstr ""
"Статусы, перечисленные здесь, смогут присоединиться к группе, если у них "
"есть соответствующие разрешения.<br>"
#: allianceauth/groupmanagement/models.py:171
msgid ""
"Short description <i>(max. 512 characters)</i> of the group shown to users."
msgstr ""
"Краткое описание <i>(макс. 512 символов)</i> группы, отображаемое "
"пользователям."
#: allianceauth/groupmanagement/models.py:178
msgid "Can request non-public groups"
msgstr ""
msgstr "Можно отправлять запрос на непубличную группу."
#: allianceauth/groupmanagement/models.py:209
msgid "name"
msgstr ""
msgstr "имя"
#: allianceauth/groupmanagement/models.py:212
msgid "Name that can not be used for groups."
msgstr ""
msgstr "Имя, которое не может быть использовано для групп."
#: allianceauth/groupmanagement/models.py:215
msgid "reason"
msgstr ""
msgstr "причина"
#: allianceauth/groupmanagement/models.py:215
msgid "Reason why this name is reserved."
msgstr ""
msgstr "Причина, по которой это имя зарезервировано."
#: allianceauth/groupmanagement/models.py:218
msgid "created by"
msgstr ""
msgstr "создано кем"
#: allianceauth/groupmanagement/models.py:223
msgid "created at"
msgstr ""
msgstr "создано когда"
#: allianceauth/groupmanagement/models.py:223
msgid "Date when this entry was created"
msgstr ""
msgstr "Дата, когда данное содержимое было создано"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:4
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:13
@@ -773,11 +795,11 @@ msgstr "Исполнитель"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:48
msgid "Removed"
msgstr ""
msgstr "Удалено"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:60
msgid "All times displayed are EVE/UTC."
msgstr ""
msgstr "Все значения времени отображаются в EVE/ET/UTC."
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:67
msgid "No entries found for this group."
@@ -797,13 +819,13 @@ msgstr "Корпорация"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:49
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:75
msgid "Group leader"
msgstr ""
msgstr "Лидер группы"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:60
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:82
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:139
msgid "(unknown)"
msgstr ""
msgstr "(неизвестно)"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:65
msgid "Remove from group"
@@ -1221,19 +1243,19 @@ msgstr "Откомментировать"
#: allianceauth/notifications/models.py:21
msgid "danger"
msgstr ""
msgstr "опасн"
#: allianceauth/notifications/models.py:22
msgid "warning"
msgstr ""
msgstr "упрежд"
#: allianceauth/notifications/models.py:23
msgid "info"
msgstr ""
msgstr "инфо"
#: allianceauth/notifications/models.py:24
msgid "success"
msgstr ""
msgstr "успех"
#: allianceauth/notifications/templates/notifications/list.html:4
#: allianceauth/notifications/templates/notifications/list.html:7
@@ -1267,7 +1289,7 @@ msgstr "Заголовок"
#: allianceauth/notifications/templates/notifications/list_partial.html:28
msgid "No notifications."
msgstr ""
msgstr "Нет уведомлений."
#: allianceauth/notifications/templates/notifications/view.html:4
#: allianceauth/notifications/templates/notifications/view.html:8
@@ -1315,7 +1337,7 @@ msgstr "Название операции"
#: allianceauth/optimer/form.py:16
msgid "Operation Type"
msgstr ""
msgstr "Тип операции"
#: allianceauth/optimer/form.py:17
#: allianceauth/srp/templates/srp/management.html:38
@@ -1329,7 +1351,7 @@ msgstr "Дополнительная информация"
#: allianceauth/optimer/form.py:23
msgid "(Optional) Describe the operation with a couple of short words."
msgstr ""
msgstr "(Опционально) Опишите операцию несколькими короткими словами."
#: allianceauth/optimer/templates/optimer/add.html:6
#: allianceauth/optimer/templates/optimer/management.html:13
@@ -1366,7 +1388,7 @@ msgstr "Текущий EVE Time:"
#: allianceauth/optimer/templates/optimer/management.html:26
msgid "Next Fleet Operations"
msgstr ""
msgstr "Грядущие Флотовые операции"
#: allianceauth/optimer/templates/optimer/management.html:30
#: allianceauth/timerboard/templates/timerboard/view.html:362
@@ -1375,7 +1397,7 @@ msgstr "Нет предстоящих таймеров"
#: allianceauth/optimer/templates/optimer/management.html:33
msgid "Past Fleet Operations"
msgstr ""
msgstr "Прошлые Флотовые операции"
#: allianceauth/optimer/templates/optimer/management.html:37
#: allianceauth/timerboard/templates/timerboard/view.html:535
@@ -1455,7 +1477,7 @@ msgstr "Пользователи"
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:41
msgid "States"
msgstr "Состояния"
msgstr "Статусы"
#: allianceauth/services/abstract.py:72
msgid "That service account already exists"
@@ -1464,7 +1486,7 @@ msgstr "Этот сервис уже активирован"
#: allianceauth/services/abstract.py:103
#, python-brace-format
msgid "Successfully set your {self.service_name} password"
msgstr ""
msgstr "Успешно установлен пароль для вашего {self.setvice_name}"
#: allianceauth/services/auth_hooks.py:12
msgid "Services"
@@ -1508,7 +1530,7 @@ msgstr "Назначение:"
#: allianceauth/services/forms.py:15
msgid "Reimbursable?*"
msgstr "Конпенсировать?"
msgstr "Компенсировать?"
#: allianceauth/services/forms.py:15 allianceauth/services/forms.py:16
msgid "Yes"
@@ -1539,10 +1561,12 @@ msgid ""
"Your Discord account was disabled automatically by Auth. If you think this "
"was a mistake, please contact an admin."
msgstr ""
"Auth автоматически отключил ваш аккаунт Discord. Если вы думаете, что это "
"произошло по ошибке, пожалуйста свяжитесь с админом."
#: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:5
msgid "Discord"
msgstr ""
msgstr "Discord"
#: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:18
msgid "Join the Discord server"
@@ -1550,7 +1574,7 @@ msgstr "Подключиться к серверу Discord"
#: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:22
msgid "Leave- and rejoin the Discord Server (Reset)"
msgstr "Переподключиться к серверу Discord. "
msgstr "Переподключиться к серверу Discord (сброс). "
#: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:25
msgid "Leave the Discord server"
@@ -1605,29 +1629,31 @@ msgstr ""
#: allianceauth/services/modules/discourse/views.py:62
msgid "Invalid payload. Please contact support if this problem persists."
msgstr ""
"Недопустимая \"полезная нагрузка\". Пожалуйста свяжитесь с поддержкой, если "
"данная проблема будет продолжаться."
#: allianceauth/services/modules/ips4/views.py:31
msgid "Activated IPSuite4 account."
msgstr ""
msgstr "Активирован аккаунт IPSuite4."
#: allianceauth/services/modules/ips4/views.py:39
#: allianceauth/services/modules/ips4/views.py:60
#: allianceauth/services/modules/ips4/views.py:81
#: allianceauth/services/modules/ips4/views.py:101
msgid "An error occurred while processing your IPSuite4 account."
msgstr ""
msgstr "Произошла ошибка при работе с вашим аккаунтом IPSuite4."
#: allianceauth/services/modules/ips4/views.py:52
msgid "Reset IPSuite4 password."
msgstr ""
msgstr "Сбросить пароль IPSuite4."
#: allianceauth/services/modules/ips4/views.py:78
msgid "Set IPSuite4 password."
msgstr ""
msgstr "Установить пароль IPSuite4."
#: allianceauth/services/modules/ips4/views.py:98
msgid "Deactivated IPSuite4 account."
msgstr ""
msgstr "Деактивированный аккаунт IPSuite4."
#: allianceauth/services/modules/openfire/auth_hooks.py:26
msgid "Jabber"
@@ -1641,7 +1667,7 @@ msgstr "Jabber Бродкаст"
#: allianceauth/services/modules/openfire/auth_hooks.py:94
msgid "Fleet Broadcast Formatter"
msgstr ""
msgstr "Флотовый Оповещатель"
#: allianceauth/services/modules/openfire/forms.py:7
msgid "Message"
@@ -1704,26 +1730,26 @@ msgstr "Установить пароль на Форум."
#: allianceauth/services/modules/smf/views.py:52
msgid "Activated SMF account."
msgstr ""
msgstr "Активированный аккаунт SMF."
#: allianceauth/services/modules/smf/views.py:65
#: allianceauth/services/modules/smf/views.py:81
#: allianceauth/services/modules/smf/views.py:102
#: allianceauth/services/modules/smf/views.py:124
msgid "An error occurred while processing your SMF account."
msgstr ""
msgstr "Произошла ошибка при работе с вашим аккаунтом SMF."
#: allianceauth/services/modules/smf/views.py:78
msgid "Deactivated SMF account."
msgstr ""
msgstr "Деактивированный аккаунт SMF."
#: allianceauth/services/modules/smf/views.py:95
msgid "Reset SMF password."
msgstr ""
msgstr "Сбросить пароль SMF."
#: allianceauth/services/modules/smf/views.py:121
msgid "Set SMF password."
msgstr ""
msgstr "Установить пароль SMF."
#: allianceauth/services/modules/teamspeak3/forms.py:14
#, python-format
@@ -1732,7 +1758,7 @@ msgstr "Не могу найти %s на сервере"
#: allianceauth/services/modules/teamspeak3/templates/admin/teamspeak3/authts/change_list.html:8
msgid "Update TS3 groups"
msgstr ""
msgstr "Обновить группы TS3"
#: allianceauth/services/modules/teamspeak3/templates/services/teamspeak3/teamspeakjoin.html:5
msgid "Verify Teamspeak"
@@ -1772,26 +1798,26 @@ msgstr "Сбросить TeamSpeak3 ключ доступа."
#: allianceauth/services/modules/xenforo/views.py:30
msgid "Activated XenForo account."
msgstr ""
msgstr "Активированный аккаунт XenForo."
#: allianceauth/services/modules/xenforo/views.py:40
#: allianceauth/services/modules/xenforo/views.py:52
#: allianceauth/services/modules/xenforo/views.py:73
#: allianceauth/services/modules/xenforo/views.py:94
msgid "An error occurred while processing your XenForo account."
msgstr ""
msgstr "Произошла ошибка при работе с вашим аккаунтом XenForo."
#: allianceauth/services/modules/xenforo/views.py:50
msgid "Deactivated XenForo account."
msgstr ""
msgstr "Деактивированный аккаунт XenForo."
#: allianceauth/services/modules/xenforo/views.py:65
msgid "Reset XenForo account password."
msgstr ""
msgstr "Сбросить пароль XenForo."
#: allianceauth/services/modules/xenforo/views.py:91
msgid "Changed XenForo password."
msgstr ""
msgstr "Изменённый пароль XenForo."
#: allianceauth/services/templates/services/fleetformattertool.html:5
msgid "Fleet Formatter Tool"
@@ -1799,7 +1825,7 @@ msgstr "ФлитФорматер"
#: allianceauth/services/templates/services/fleetformattertool.html:10
msgid "Fleet Broadcast Formatter Tool"
msgstr "Флотовый Бродкастер"
msgstr "Флотовый Оповещатель"
#: allianceauth/services/templates/services/fleetformattertool.html:23
msgid "Format"
@@ -1869,15 +1895,16 @@ msgstr "Флотовая Доктрина"
#: allianceauth/srp/form.py:16
msgid "Killboard Link (zkillboard.com or kb.evetools.org)"
msgstr ""
msgstr "Ссылка киллборды (zkillboard.com или kb.evetools.org)"
#: allianceauth/srp/form.py:34
msgid "Invalid Link. Please use zkillboard.com or kb.evetools.org"
msgstr ""
"Неверная ссылка. Пожалуйста используйте zkillboard.com или kb.evetools.org"
#: allianceauth/srp/form.py:46
msgid "Invalid Link. Please post a direct link to a killmail."
msgstr ""
msgstr "Неверная ссылка. Пожалуйста предоставьте прямую ссылку на киллмейл."
#: allianceauth/srp/form.py:53
msgid "After Action Report Link"
@@ -1898,7 +1925,7 @@ msgstr "Поделиться ссылкой с рядовыми участник
#: allianceauth/srp/templates/srp/data.html:5
msgid "Srp Fleet Data"
msgstr ""
msgstr "Данные флота по SRP"
#: allianceauth/srp/templates/srp/data.html:50
msgid "SRP Fleet Data"
@@ -1921,7 +1948,7 @@ msgstr "Суммарные потери:"
#: allianceauth/srp/templates/srp/data.html:158
#: allianceauth/srp/templates/srp/management.html:28
msgid "Total ISK Cost:"
msgstr "Оценочная стоимость (ISK):"
msgstr "Оценочная стоимость, ISK:"
#: allianceauth/srp/templates/srp/data.html:80
#: allianceauth/srp/templates/srp/data.html:166
@@ -1934,7 +1961,7 @@ msgstr "Имя Пилота"
#: allianceauth/srp/templates/srp/data.html:90
msgid "Killboard Link"
msgstr "zKillBoard ссылка"
msgstr "Killboard ссылка"
#: allianceauth/srp/templates/srp/data.html:92
msgid "Ship Type"
@@ -1942,7 +1969,7 @@ msgstr "Тип корабля"
#: allianceauth/srp/templates/srp/data.html:93
msgid "Killboard Loss Amt"
msgstr "потерь по zKillBoard на данный момент"
msgstr "Потерь по Killboard на данный момент"
#: allianceauth/srp/templates/srp/data.html:94
msgid "SRP ISK Cost"
@@ -1978,7 +2005,7 @@ msgstr "Добавить SRP флот"
#: allianceauth/srp/templates/srp/management.html:39
msgid "Fleet AAR"
msgstr "Флитовый AAR."
msgstr "Флитовый AAR"
#: allianceauth/srp/templates/srp/management.html:40
msgid "Fleet SRP Code"
@@ -2072,15 +2099,15 @@ msgstr "Не могу найти SRP код с ID %(srpfleetid)s"
#: allianceauth/srp/views.py:179
msgid "This kill mail has already been posted."
msgstr ""
msgstr "Этот киллмейл уже был предоставлен ранее."
#: allianceauth/srp/views.py:200
msgid ""
"Your SRP request Killmail link is invalid. Please make sure you are using "
"zKillboard."
msgstr ""
"Ваш SRP запрос Killmail неправильный. Пожалуйста убедитесь в правильности "
"ссылки. "
"Ссылка на киллмейл в вашем SRP запросе неправильная. Пожалуйста убедитесь в "
"правильности ссылки. "
#: allianceauth/srp/views.py:212
#, python-format
@@ -2144,11 +2171,11 @@ msgstr "Закрыт"
#: allianceauth/templates/allianceauth/admin-status/overview.html:28
msgid "Powered by GitLab"
msgstr ""
msgstr "При поддержке GitLab"
#: allianceauth/templates/allianceauth/admin-status/overview.html:35
msgid "Support Discord"
msgstr ""
msgstr "Поддержка Discord"
#: allianceauth/templates/allianceauth/admin-status/overview.html:43
msgid "Software Version"
@@ -2185,6 +2212,8 @@ msgid ""
" Status of %(total)s processed tasks • last %(latest)s\n"
" "
msgstr ""
"\n"
" Статус %(total)s обработанных задач • последние %(latest)s"
#: allianceauth/templates/allianceauth/admin-status/overview.html:95
#, python-format
@@ -2193,6 +2222,8 @@ msgid ""
" %(queue_length)s queued tasks\n"
" "
msgstr ""
"\n"
" %(queue_length)s запланированных задач"
#: allianceauth/templates/allianceauth/top-menu-admin.html:9
msgid "Admin"
@@ -2200,16 +2231,16 @@ msgstr "Администратор"
#: allianceauth/templates/allianceauth/top-menu-admin.html:19
msgid "AA Documentation"
msgstr ""
msgstr "Документация AA"
#: allianceauth/templates/allianceauth/top-menu-admin.html:26
msgid "AA Support Discord"
msgstr ""
msgstr "Discord поддержки AA"
#: allianceauth/templates/allianceauth/top-menu-user-dropdown.html:10
#: allianceauth/templates/allianceauth/top-menu-user-dropdown.html:14
msgid "User Menu"
msgstr ""
msgstr "Меню пользователя"
#: allianceauth/templates/allianceauth/top-menu-user-dropdown.html:56
msgid "Logout"
@@ -2257,7 +2288,7 @@ msgstr "Тип структуры"
#: allianceauth/timerboard/form.py:62
msgid "Timer Type"
msgstr ""
msgstr "Тип таймера"
#: allianceauth/timerboard/form.py:63
#: allianceauth/timerboard/templates/timerboard/view.html:32
@@ -2288,31 +2319,31 @@ msgstr "Корпорация зарегистрированна"
#: allianceauth/timerboard/models.py:14
msgid "Not Specified"
msgstr ""
msgstr "Не указано"
#: allianceauth/timerboard/models.py:15
msgid "Shield"
msgstr ""
msgstr "Щит"
#: allianceauth/timerboard/models.py:16
msgid "Armor"
msgstr ""
msgstr "Броня"
#: allianceauth/timerboard/models.py:17
msgid "Hull"
msgstr ""
msgstr "Структура"
#: allianceauth/timerboard/models.py:18
msgid "Final"
msgstr ""
msgstr "Финальный"
#: allianceauth/timerboard/models.py:19
msgid "Anchoring"
msgstr ""
msgstr "Постановка на якорь"
#: allianceauth/timerboard/models.py:20
msgid "Unanchoring"
msgstr ""
msgstr "Снятие с якоря"
#: allianceauth/timerboard/templates/timerboard/timer_confirm_delete.html:11
msgid "Delete Timer"
@@ -2372,4 +2403,4 @@ msgstr "Добавлен таймер в %(system)s на %(time)s."
#: allianceauth/timerboard/views.py:82
msgid "Saved changes to the timer."
msgstr "Изменения сохранены"
msgstr "Изменения таймера сохранены."

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -13,10 +13,10 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-09-14 23:17+1000\n"
"POT-Creation-Date: 2022-10-09 18:20+1000\n"
"PO-Revision-Date: 2020-02-18 03:14+0000\n"
"Last-Translator: Aaron BuBu <351793078@qq.com>, 2020\n"
"Language-Team: Chinese Simplified (https://www.transifex.com/alliance-auth/teams/107430/zh-Hans/)\n"
"Language-Team: Chinese Simplified (https://app.transifex.com/alliance-auth/teams/107430/zh-Hans/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -45,47 +45,38 @@ msgid "You are not allowed to add or remove these restricted groups: %s"
msgstr ""
#: allianceauth/authentication/models.py:80
#: allianceauth/project_template/project_name/settings/base.py:89
msgid "English"
msgstr ""
#: allianceauth/authentication/models.py:81
#: allianceauth/project_template/project_name/settings/base.py:90
msgid "German"
msgstr ""
#: allianceauth/authentication/models.py:82
#: allianceauth/project_template/project_name/settings/base.py:91
msgid "Spanish"
msgstr ""
#: allianceauth/authentication/models.py:83
#: allianceauth/project_template/project_name/settings/base.py:92
msgid "Chinese Simplified"
msgstr ""
#: allianceauth/authentication/models.py:84
#: allianceauth/project_template/project_name/settings/base.py:93
msgid "Russian"
msgstr ""
#: allianceauth/authentication/models.py:85
#: allianceauth/project_template/project_name/settings/base.py:94
msgid "Korean"
msgstr ""
#: allianceauth/authentication/models.py:86
#: allianceauth/project_template/project_name/settings/base.py:95
msgid "French"
msgstr ""
#: allianceauth/authentication/models.py:87
#: allianceauth/project_template/project_name/settings/base.py:96
msgid "Japanese"
msgstr ""
#: allianceauth/authentication/models.py:88
#: allianceauth/project_template/project_name/settings/base.py:97
msgid "Italian"
msgstr ""

View File

@@ -1,3 +1 @@
from .core import notify # noqa: F401
default_app_config = 'allianceauth.notifications.apps.NotificationsConfig'

View File

@@ -15,18 +15,22 @@ class NotificationAdmin(admin.ModelAdmin):
ordering = ("-timestamp", )
search_fields = ["user__username", "user__profile__main_character__character_name"]
@admin.display(
ordering="user__profile__main_character__character_name"
)
def _main(self, obj):
try:
return obj.user.profile.main_character
except AttributeError:
return obj.user
_main.admin_order_field = "user__profile__main_character__character_name"
@admin.display(
ordering="user__profile__state__name"
)
def _state(self, obj):
return obj.user.profile.state
_state.admin_order_field = "user__profile__state__name"
def has_change_permission(self, request, obj=None):
return False

View File

@@ -44,7 +44,7 @@ def notification_view(request, notif_id):
notif.mark_viewed()
return render(request, 'notifications/view.html', context)
else:
logger.warn(
logger.warning(
"User %s not authorized to view notif_id %s belonging to user %s",
request.user,
notif_id, notif.user

View File

@@ -13,6 +13,10 @@ app = Celery('{{ project_name }}')
# the configuration object to child processes.
app.config_from_object('django.conf:settings')
# Automatically try to establish the connection to the AMQP broker on
# Celery startup if it is unavailable.
app.conf.broker_connection_retry_on_startup = True
# setup priorities ( 0 Highest, 9 Lowest )
app.conf.broker_transport_options = {
'priority_steps': list(range(10)), # setup que to have 10 steps

View File

@@ -41,23 +41,23 @@ CELERYBEAT_SCHEDULER = "django_celery_beat.schedulers.DatabaseScheduler"
CELERYBEAT_SCHEDULE = {
'esi_cleanup_callbackredirect': {
'task': 'esi.tasks.cleanup_callbackredirect',
'schedule': crontab(minute=0, hour='*/4'),
'schedule': crontab(minute='0', hour='*/4'),
},
'esi_cleanup_token': {
'task': 'esi.tasks.cleanup_token',
'schedule': crontab(minute=0, hour=0),
'schedule': crontab(minute='0', hour='0'),
},
'run_model_update': {
'task': 'allianceauth.eveonline.tasks.run_model_update',
'schedule': crontab(minute=0, hour="*/6"),
'schedule': crontab(minute='0', hour="*/6"),
},
'check_all_character_ownership': {
'task': 'allianceauth.authentication.tasks.check_all_character_ownership',
'schedule': crontab(minute=0, hour='*/4'),
'schedule': crontab(minute='0', hour='*/4'),
},
'analytics_daily_stats': {
'task': 'allianceauth.analytics.tasks.analytics_daily_stats',
'schedule': crontab(minute=0, hour=2),
'schedule': crontab(minute='0', hour='2'),
}
}
@@ -94,6 +94,7 @@ LANGUAGES = (
("fr", "French"),
("ja", "Japanese"),
("it", "Italian"),
("uk", "Ukrainian"),
)
TEMPLATES = [

View File

@@ -32,6 +32,13 @@ INSTALLED_APPS += [
# To change the logging level for extensions, uncomment the following line.
# LOGGING['handlers']['extension_file']['level'] = 'DEBUG'
# By default, apps are prevented from having public views for security reasons.
# To allow specific apps to have public views, add them to APPS_WITH_PUBLIC_VIEWS
# » The format is the same as in INSTALLED_APPS
# » The app developer must also explicitly allow public views for their app
APPS_WITH_PUBLIC_VIEWS = [
]
# Enter credentials to use MySQL/MariaDB. Comment out to use sqlite3
DATABASES['default'] = {

View File

@@ -1,9 +1,8 @@
from django.conf.urls import include
from allianceauth import urls
from django.urls import re_path
from django.urls import include, path
urlpatterns = [
re_path(r'', include(urls)),
path('', include(urls)),
]
handler500 = 'allianceauth.views.Generic500Redirect'

View File

@@ -66,6 +66,8 @@ class NameFormatConfigAdmin(admin.ModelAdmin):
form = NameFormatConfigForm
list_display = ('service_name', 'get_state_display_string')
@admin.display(
description='States'
)
def get_state_display_string(self, obj):
return ', '.join([state.name for state in obj.states.all()])
get_state_display_string.short_description = 'States'

View File

@@ -1,15 +1,17 @@
from django.conf.urls import include
from django.urls import re_path
from string import Formatter
from typing import Iterable, Optional
from django.conf import settings
from django.core.exceptions import ObjectDoesNotExist
from django.template.loader import render_to_string
from django.urls import include, re_path
from django.utils.functional import cached_property
from django.conf import settings
from string import Formatter
from allianceauth.hooks import get_hooks
from .models import NameFormatConfig
def get_extension_logger(name):
"""
Takes the name of a plugin/extension and generates a child logger of the extensions logger
@@ -156,8 +158,32 @@ class MenuItemHook:
class UrlHook:
def __init__(self, urls, namespace, base_url):
"""A hook for registering the URLs of a Django app.
Args:
- urls: The urls module to include
- namespace: The URL namespace to apply. This is usually just the app name.
- base_url: The URL prefix to match against in regex form.
Example ``r'^app_name/'``.
This prefix will be applied in front of all URL patterns included.
It is possible to use the same prefix as existing apps (or no prefix at all),
but standard URL resolution ordering applies
(hook URLs are the last ones registered).
- excluded_views: Optional list of views to be excluded
from auto-decorating them with the
default ``main_character_required`` decorator, e.g. to make them public.
Views must be specified by their qualified name,
e.g. ``["example.views.my_public_view"]``
"""
def __init__(
self,
urls,
namespace: str,
base_url: str,
excluded_views : Optional[Iterable[str]] = None
):
self.include_pattern = re_path(base_url, include(urls, namespace=namespace))
self.excluded_views = set(excluded_views or [])
class NameFormatter:

View File

@@ -6,6 +6,7 @@ from ...admin import ServicesUserAdmin
from . import __title__
from .models import DiscordUser
from .utils import LoggerAddTag
from .auth_hooks import DiscordService
logger = LoggerAddTag(logging.getLogger(__name__), __title__)
@@ -27,6 +28,6 @@ class DiscordUserAdmin(ServicesUserAdmin):
@admin.display(description='Discord Username', ordering='username')
def _username(self, obj):
if obj.username and obj.discriminator:
return f'{obj.username}#{obj.discriminator}'
return ''
return DiscordService.get_discord_username(
username=obj.username, discriminator=obj.discriminator
)

View File

@@ -30,6 +30,29 @@ class DiscordService(ServicesHook):
self.access_perm = 'discord.access_discord'
self.name_format = '{character_name}'
@staticmethod
def get_discord_username(username:str, discriminator:str) -> str:
"""
Determine the Discord username (Old and new format)
:param username:
:type username:
:param discriminator:
:type discriminator:
:return:
:rtype:
"""
if username and discriminator:
discord_username = f'{username}#{discriminator}'
# New Discord user name format
if discriminator == '0':
discord_username = f'@{username}'
else:
discord_username = ''
return discord_username
def delete_user(self, user: User, notify_user: bool = False) -> None:
if self.user_has_account(user):
logger.debug('Deleting user %s %s account', user, self.name)
@@ -43,10 +66,19 @@ class DiscordService(ServicesHook):
user_has_account = True
username = request.user.discord.username
discriminator = request.user.discord.discriminator
if username and discriminator:
discord_username = f'{username}#{discriminator}'
else:
discord_username = ''
discord_username = self.get_discord_username(
username=username, discriminator=discriminator
)
# if username and discriminator:
# discord_username = f'{username}#{discriminator}'
#
# # New Discord user name format
# if discriminator == '0':
# discord_username = f'@{username}'
# else:
# discord_username = ''
else:
discord_username = ''
user_has_account = False

View File

@@ -588,16 +588,17 @@ class DiscordClient:
return None # User is no longer a member
guild_roles = RolesSet(self.guild_roles(guild_id=guild_id))
logger.debug('Current guild roles: %s', guild_roles.ids())
_roles = set(member_info.roles)
if not guild_roles.has_roles(member_info.roles):
guild_roles = RolesSet(
self.guild_roles(guild_id=guild_id, use_cache=False)
)
if not guild_roles.has_roles(member_info.roles):
role_ids = set(member_info.roles).difference(guild_roles.ids())
raise RuntimeError(
f'Discord user {user_id} has unknown roles: {role_ids}'
)
return guild_roles.subset(member_info.roles)
logger.warning(f'Discord user {user_id} has unknown roles: {role_ids}')
for _r in role_ids:
_roles.remove(_r)
return guild_roles.subset(_roles)
@classmethod
def _is_member_unknown_error(cls, r: requests.Response) -> bool:

View File

@@ -899,8 +899,8 @@ class TestGuildMemberRoles(NoSocketsTestCase):
mock_guild_roles.return_value = {role_a, role_b}
client = DiscordClientStub(TEST_BOT_TOKEN, mock_redis)
# when/then
with self.assertRaises(RuntimeError):
client.guild_member_roles(TEST_GUILD_ID, TEST_USER_ID)
roles = client.guild_member_roles(TEST_GUILD_ID, TEST_USER_ID)
self.assertEqual(roles, RolesSet([role_a]))
# TODO: Re-enable after adding Discord general error handling
# def test_should_raise_exception_if_member_info_is_invalid(

View File

View File

@@ -150,3 +150,23 @@ class TestDiscordService(NoSocketsTestCase):
self.assertTemplateUsed(service.service_ctrl_template)
self.assertIn('/discord/reset/', response)
self.assertIn('/discord/deactivate/', response)
def test_new_discord_username_format(self):
"""
Test if we get Discord's new username format
:return:
:rtype:
"""
# given
username = 'william_riker'
discriminator = '0' # Seems to be returned as 0 for Discord's new username format
# when
discord_username = DiscordService.get_discord_username(
username=username, discriminator=discriminator
)
# then
expected_username = '@william_riker'
self.assertEqual(first=discord_username, second=expected_username)

View File

@@ -1,5 +1,4 @@
from django.conf.urls import include
from django.urls import path
from django.urls import include, path
from . import views

View File

@@ -49,7 +49,7 @@ class DiscourseTasks:
DiscourseManager.update_groups(user)
except Exception as e:
logger.exception(e)
logger.warn("Discourse group sync failed for %s, retrying in 10 mins" % user)
logger.warning("Discourse group sync failed for %s, retrying in 10 mins" % user)
raise self.retry(countdown=60 * 10)
logger.debug("Updated user %s discourse groups." % user)

View File

@@ -1,5 +1,4 @@
from django.conf.urls import include
from django.urls import path
from django.urls import include, path
app_name = 'example'

View File

@@ -2,8 +2,7 @@ from django.contrib import admin
from .models import Ips4User
@admin.register(Ips4User)
class Ips4UserAdmin(admin.ModelAdmin):
list_display = ('user', 'username', 'id')
search_fields = ('user__username', 'username', 'id')
admin.site.register(Ips4User, Ips4UserAdmin)

View File

@@ -1,5 +1,4 @@
from django.conf.urls import include
from django.urls import path
from django.urls import include, path
from . import views

View File

@@ -1,13 +1,16 @@
<tr>
<td class="text-center">{{ service_name }}</td>
<td class="text-center">{{ username }}</td>
<td class="text-center"><a href="mumble://{{ service_url }}">{{ service_url }}</a></td>
<td class="text-center">
{% if username == "" %}
<td class="text-center">{{ service_url }}</td>
<td class="text-center">
<a href="{% url 'mumble:activate' %}" title="Activate" class="btn btn-warning">
<span class="glyphicon glyphicon-ok"></span>
</a>
</td>
{% else %}
<td class="text-center"><a href="mumble://{{ connect_url }}">{{ service_url }}</a></td>
<td class="text-center">
<a href="{% url 'mumble:set_password' %}" title="Set Password" class="btn btn-warning">
<span class="glyphicon glyphicon-pencil"></span>
</a>
@@ -17,9 +20,9 @@
<a href="{% url 'mumble:deactivate' %}" title="Deactivate" class="btn btn-danger">
<span class="glyphicon glyphicon-remove"></span>
</a>
<a href="mumble://{{ connect_url }}" class="btn btn-success" title="Connect">
<a href="mumble://{{ connect_url }}" class="btn btn-success" title="Connect">
<span class="glyphicon glyphicon-arrow-right"></span>
</a>
</td>
{% endif %}
</td>
</tr>

View File

@@ -1,5 +1,4 @@
from django.conf.urls import include
from django.urls import path
from django.urls import include, path
from . import views

0
allianceauth/services/modules/openfire/manager.py Executable file → Normal file
View File

View File

@@ -1,5 +1,4 @@
from django.conf.urls import include
from django.urls import path
from django.urls import include, path
from . import views

2
allianceauth/services/modules/phpbb3/manager.py Executable file → Normal file
View File

@@ -176,7 +176,7 @@ class Phpbb3Manager:
logger.debug(f"Proceeding to add phpbb user {username_clean} and pwhash starting with {pwhash[0:5]}")
# check if the username was simply revoked
if Phpbb3Manager.check_user(username_clean):
logger.warn("Unable to add phpbb user with username %s - already exists. Updating user instead." % username)
logger.warning("Unable to add phpbb user with username %s - already exists. Updating user instead." % username)
Phpbb3Manager.__update_user_info(username_clean, email, pwhash)
else:
try:

View File

@@ -1,5 +1,4 @@
from django.conf.urls import include
from django.urls import path
from django.urls import include, path
from . import views

View File

@@ -1,5 +1,4 @@
from django.conf.urls import include
from django.urls import path
from django.urls import include, path
from . import views

View File

@@ -36,10 +36,12 @@ class AuthTSgroupAdmin(admin.ModelAdmin):
kwargs['queryset'] = TSgroup.objects.exclude(ts_group_name__in=ReservedGroupName.objects.values_list('name', flat=True))
return super().formfield_for_manytomany(db_field, request, **kwargs)
@admin.display(
description='ts groups'
)
def _ts_group(self, obj):
return [x for x in obj.ts_group.all().order_by('ts_group_id')]
_ts_group.short_description = 'ts groups'
# _ts_group.admin_order_field = 'profile__state'

0
allianceauth/services/modules/teamspeak3/manager.py Executable file → Normal file
View File

View File

@@ -457,7 +457,7 @@ class Teamspeak3AdminTestCase(TestCase):
cls.site = AdminSite()
cls.admin = AuthTSgroupAdmin(AuthTS, cls.site)
cls.group = Group.objects.create(name='test')
cls.ts_group = TSgroup.objects.create(ts_group_name='test')
cls.ts_group = TSgroup.objects.create(ts_group_id=1, ts_group_name='test')
def test_field_queryset_no_reserved_names(self):
"""Ensure all groups are listed when no reserved names"""

View File

@@ -1,5 +1,4 @@
from django.conf.urls import include
from django.urls import path
from django.urls import include, path
from . import views

View File

0
allianceauth/services/modules/teamspeak3/util/ts3.py Executable file → Normal file
View File

View File

@@ -44,7 +44,7 @@ def activate_teamspeak3(request):
def verify_teamspeak3(request):
logger.debug("verify_teamspeak3 called by user %s" % request.user)
if not Teamspeak3Tasks.has_account(request.user):
logger.warn("Unable to validate user %s teamspeak: no teamspeak data" % request.user)
logger.warning("Unable to validate user %s teamspeak: no teamspeak data" % request.user)
return redirect("services:services")
if request.method == "POST":
form = TeamspeakJoinForm(request.POST)

View File

@@ -1,5 +1,4 @@
from django.conf.urls import include
from django.urls import path
from django.urls import include, path
from . import views

0
allianceauth/services/templates/services/services.html Executable file → Normal file
View File

View File

@@ -0,0 +1,30 @@
from unittest import TestCase
from allianceauth.services.hooks import UrlHook
from allianceauth.groupmanagement import urls
class TestUrlHook(TestCase):
def test_can_create_simple_hook(self):
# when
obj = UrlHook(urls, "groupmanagement", r"^groupmanagement/")
# then
self.assertEqual(obj.include_pattern.app_name, "groupmanagement")
self.assertFalse(obj.excluded_views)
def test_can_create_hook_with_excluded_views(self):
# when
obj = UrlHook(
urls,
"groupmanagement",
r"^groupmanagement/",
["groupmanagement.views.group_management"],
)
# then
self.assertEqual(obj.include_pattern.app_name, "groupmanagement")
self.assertIn("groupmanagement.views.group_management", obj.excluded_views)
def test_should_raise_error_when_called_with_invalid_excluded_views(self):
# when/then
with self.assertRaises(TypeError):
UrlHook(urls, "groupmanagement", r"^groupmanagement/", 99)

View File

@@ -1,4 +1,4 @@
from django.conf.urls import include
from django.urls import include
from allianceauth.hooks import get_hooks
from django.urls import path

0
allianceauth/services/views.py Executable file → Normal file
View File

Some files were not shown because too many files have changed in this diff Show More