From 200e8f2ff17d9d92adb132ed4f6974ffece130ae Mon Sep 17 00:00:00 2001 From: Ariel Rin Date: Wed, 11 Oct 2023 12:33:17 +1000 Subject: [PATCH 1/8] initial sql tuning and python version comparison --- docs/maintenance/tuning/index.md | 1 + docs/maintenance/tuning/python.md | 633 ++++++++++++++++++++++++++++++ docs/maintenance/tuning/sql.md | 196 +++++++++ 3 files changed, 830 insertions(+) create mode 100644 docs/maintenance/tuning/python.md create mode 100644 docs/maintenance/tuning/sql.md diff --git a/docs/maintenance/tuning/index.md b/docs/maintenance/tuning/index.md index 9acf1909..e01d46cc 100644 --- a/docs/maintenance/tuning/index.md +++ b/docs/maintenance/tuning/index.md @@ -14,4 +14,5 @@ The official installation guide will install a stable version of Alliance Auth t gunicorn celery redis + python ``` diff --git a/docs/maintenance/tuning/python.md b/docs/maintenance/tuning/python.md new file mode 100644 index 00000000..b0777d97 --- /dev/null +++ b/docs/maintenance/tuning/python.md @@ -0,0 +1,633 @@ +# Python + +## Version Update + +Newer versions of python can focus heavily on performance improvements, some more than others. But be aware regressions for stability or security reasons may always be the case. + +As a general rule, Python 3.9 and Python 3.11 both had a strong focus on performance improvements. Python 3.12 is looking promising but has yet to have widespread testing, adoption and deployment. A simple comparison is available at [speed.python.org](https://speed.python.org/comparison/?exe=12%2BL%2B3.11%2C12%2BL%2B3.12%2C12%2BL%2B3.10%2C12%2BL%2B3.9%2C12%2BL%2B3.8&ben=746&env=1&hor=false&bas=none&chart=normal+bars). + +[Djangobench](https://github.com/django/djangobench/tree/master) is source of synthetic benchmarks and a useful tool for running comparisons. Below are some examples to inform your investigations. + +Keep in mind while a 1.2x faster result is significant, it's only one step of the process, Celery, SQL, Redis and many other factors will influence the end result and this _python_ speed improvement will not translate 1:1 into real world performance. + +### Django 4.0.10 + +- Djangobench 0.10.0 +- Django 4.0.10 +- Python 3.8.18 vs Python 3.11.5 + +```bash +joel@METABOX:~/djangobench/django$ djangobench --vcs=none --control=. --experiment=. --control-python=/home/joel/djangobench/py38/bin/python --experiment-python=/home/joel/djangobench/py311/bin/python -r /home/joel/djangobench/results -t 500 +Running all benchmarks +Recording data to '/home/joel/djangobench/results' +Control: Django 4.0.10 (in .) +Experiment: Django 4.0.10 (in .) + +Running 'multi_value_dict' benchmark ... +Min: 0.000014 -> 0.000013: 1.0304x faster +Avg: 0.000183 -> 0.000133: 1.3698x faster +Significant (t=9.325958) +Stddev: 0.00010 -> 0.00007: 1.3791x smaller (N = 500) + +Running 'query_values' benchmark ... +Min: 0.000079 -> 0.000070: 1.1308x faster +Avg: 0.000084 -> 0.000074: 1.1267x faster +Significant (t=19.174361) +Stddev: 0.00001 -> 0.00001: 1.0255x larger (N = 500) + +Running 'query_delete' benchmark ... +Min: 0.000082 -> 0.000074: 1.1145x faster +Avg: 0.000086 -> 0.000078: 1.0987x faster +Significant (t=17.504085) +Stddev: 0.00001 -> 0.00001: 1.1888x smaller (N = 500) + +Running 'query_select_related' benchmark ... +Min: 0.016771 -> 0.013520: 1.2405x faster +Avg: 0.017897 -> 0.014149: 1.2649x faster +Significant (t=40.942990) +Stddev: 0.00190 -> 0.00077: 2.4535x smaller (N = 500) + +Running 'query_aggregate' benchmark ... +Min: 0.000092 -> 0.000083: 1.1105x faster +Avg: 0.000100 -> 0.000090: 1.1107x faster +Significant (t=9.967204) +Stddev: 0.00002 -> 0.00001: 1.5003x smaller (N = 500) + +Running 'query_raw_deferred' benchmark ... +Min: 0.004157 -> 0.003563: 1.1666x faster +Avg: 0.004626 -> 0.003809: 1.2143x faster +Significant (t=12.325104) +Stddev: 0.00121 -> 0.00086: 1.4047x smaller (N = 500) + +Running 'query_get_or_create' benchmark ... +Min: 0.000412 -> 0.000362: 1.1385x faster +Avg: 0.000458 -> 0.000407: 1.1259x faster +Significant (t=14.169322) +Stddev: 0.00006 -> 0.00005: 1.1306x smaller (N = 500) + +Running 'query_values_list' benchmark ... +Min: 0.000080 -> 0.000071: 1.1231x faster +Avg: 0.000089 -> 0.000076: 1.1706x faster +Significant (t=18.298942) +Stddev: 0.00001 -> 0.00001: 1.9398x smaller (N = 500) + +Running 'url_resolve_flat_i18n_off' benchmark ... +Min: 0.055764 -> 0.045370: 1.2291x faster +Avg: 0.057670 -> 0.047020: 1.2265x faster +Significant (t=111.187780) +Stddev: 0.00206 -> 0.00059: 3.4618x smaller (N = 500) + +Running 'qs_filter_chaining' benchmark ... +Min: 0.000236 -> 0.000196: 1.2034x faster +Avg: 0.000248 -> 0.000206: 1.2041x faster +Significant (t=44.893544) +Stddev: 0.00002 -> 0.00001: 1.0833x smaller (N = 500) + +Running 'template_render' benchmark ... +Min: 0.000933 -> 0.000712: 1.3110x faster +Avg: 0.001003 -> 0.000777: 1.2909x faster +Significant (t=8.379095) +Stddev: 0.00043 -> 0.00042: 1.0287x smaller (N = 500) + +Running 'query_get' benchmark ... +Min: 0.000259 -> 0.000230: 1.1259x faster +Avg: 0.000282 -> 0.000238: 1.1829x faster +Significant (t=42.267305) +Stddev: 0.00002 -> 0.00001: 1.7842x smaller (N = 500) + +Running 'query_none' benchmark ... +Min: 0.000053 -> 0.000045: 1.1830x faster +Avg: 0.000056 -> 0.000049: 1.1449x faster +Significant (t=16.426843) +Stddev: 0.00001 -> 0.00001: 1.1267x larger (N = 500) + +Running 'query_complex_filter' benchmark ... +Min: 0.000039 -> 0.000034: 1.1527x faster +Avg: 0.000041 -> 0.000037: 1.1091x faster +Significant (t=13.582718) +Stddev: 0.00000 -> 0.00001: 1.5373x larger (N = 500) + +Running 'query_filter' benchmark ... +Min: 0.000127 -> 0.000112: 1.1288x faster +Avg: 0.000133 -> 0.000119: 1.1228x faster +Significant (t=22.727829) +Stddev: 0.00001 -> 0.00001: 1.1771x smaller (N = 500) + +Running 'template_render_simple' benchmark ... +Min: 0.000030 -> 0.000024: 1.2405x faster +Avg: 0.000035 -> 0.000029: 1.2042x faster +Not significant +Stddev: 0.00007 -> 0.00005: 1.3190x smaller (N = 500) + +Running 'default_middleware' benchmark ... +Min: -0.000047 -> -0.000054: 0.8624x faster +Avg: 0.000017 -> 0.000017: 1.0032x faster +Not significant +Stddev: 0.00037 -> 0.00037: 1.0091x larger (N = 500) + +Running 'query_annotate' benchmark ... +Min: 0.000186 -> 0.000162: 1.1505x faster +Avg: 0.000207 -> 0.000178: 1.1660x faster +Significant (t=16.516089) +Stddev: 0.00003 -> 0.00003: 1.1403x smaller (N = 500) + +Running 'raw_sql' benchmark ... +Min: 0.000015 -> 0.000013: 1.1070x faster +Avg: 0.000017 -> 0.000014: 1.1676x faster +Significant (t=13.598519) +Stddev: 0.00000 -> 0.00000: 2.3503x smaller (N = 500) + +Running 'url_resolve_flat' benchmark ... +Min: 0.056378 -> 0.044772: 1.2592x faster +Avg: 0.058268 -> 0.046656: 1.2489x faster +Significant (t=197.176590) +Stddev: 0.00121 -> 0.00051: 2.3665x smaller (N = 500) + +Running 'l10n_render' benchmark ... +Min: 0.001097 -> 0.000727: 1.5092x faster +Avg: 0.001160 -> 0.000768: 1.5101x faster +Significant (t=36.971179) +Stddev: 0.00019 -> 0.00014: 1.2946x smaller (N = 500) + +Running 'query_count' benchmark ... +Min: 0.000083 -> 0.000073: 1.1302x faster +Avg: 0.000091 -> 0.000079: 1.1640x faster +Significant (t=15.049336) +Stddev: 0.00002 -> 0.00001: 1.6661x smaller (N = 500) + +Running 'model_delete' benchmark ... +Min: 0.000123 -> 0.000105: 1.1701x faster +Avg: 0.000135 -> 0.000119: 1.1396x faster +Significant (t=17.781816) +Stddev: 0.00001 -> 0.00002: 1.1990x larger (N = 500) + +Running 'query_iterator' benchmark ... +Min: 0.000102 -> 0.000088: 1.1605x faster +Avg: 0.000108 -> 0.000093: 1.1598x faster +Significant (t=23.872009) +Stddev: 0.00001 -> 0.00001: 1.1366x smaller (N = 500) + +Running 'template_compilation' benchmark ... +Min: 0.000155 -> 0.000129: 1.2015x faster +Avg: 0.000169 -> 0.000137: 1.2317x faster +Significant (t=6.119618) +Stddev: 0.00009 -> 0.00007: 1.4162x smaller (N = 500) + +Running 'query_all_multifield' benchmark ... +Min: 0.014582 -> 0.012509: 1.1658x faster +Avg: 0.015715 -> 0.013337: 1.1783x faster +Significant (t=19.183517) +Stddev: 0.00207 -> 0.00184: 1.1241x smaller (N = 500) + +Running 'query_prefetch_related' benchmark ... +Min: 0.014293 -> 0.012157: 1.1758x faster +Avg: 0.015467 -> 0.013276: 1.1650x faster +Significant (t=20.607411) +Stddev: 0.00176 -> 0.00160: 1.0952x smaller (N = 500) + +Running 'query_all_converters' benchmark ... +Min: 0.000536 -> 0.000464: 1.1554x faster +Avg: 0.000563 -> 0.000486: 1.1595x faster +Significant (t=38.503433) +Stddev: 0.00004 -> 0.00002: 1.6468x smaller (N = 500) + +Running 'query_distinct' benchmark ... +Min: 0.000106 -> 0.000092: 1.1583x faster +Avg: 0.000127 -> 0.000096: 1.3223x faster +Significant (t=27.798102) +Stddev: 0.00002 -> 0.00001: 3.7187x smaller (N = 500) + +Running 'query_dates' benchmark ... +Min: 0.000249 -> 0.000209: 1.1953x faster +Avg: 0.000275 -> 0.000228: 1.2056x faster +Significant (t=30.785168) +Stddev: 0.00003 -> 0.00002: 1.0854x smaller (N = 500) + +Running 'model_save_existing' benchmark ... +Min: 0.003526 -> 0.003094: 1.1397x faster +Avg: 0.003723 -> 0.003212: 1.1591x faster +Significant (t=47.274918) +Stddev: 0.00018 -> 0.00016: 1.1817x smaller (N = 500) + +Running 'query_delete_related' benchmark ... +Min: 0.000120 -> 0.000103: 1.1655x faster +Avg: 0.000132 -> 0.000111: 1.1815x faster +Significant (t=6.428771) +Stddev: 0.00005 -> 0.00004: 1.2149x smaller (N = 500) + +Running 'url_reverse' benchmark ... +Min: 0.000062 -> 0.000060: 1.0318x faster +Avg: 0.000072 -> 0.000068: 1.0622x faster +Not significant +Stddev: 0.00006 -> 0.00005: 1.0531x smaller (N = 500) + +Running 'query_latest' benchmark ... +Min: 0.000136 -> 0.000118: 1.1454x faster +Avg: 0.000155 -> 0.000129: 1.2008x faster +Significant (t=8.372115) +Stddev: 0.00007 -> 0.00001: 5.1365x smaller (N = 500) + +Running 'form_create' benchmark ... +Min: 0.000015 -> 0.000013: 1.2319x faster +Avg: 0.000019 -> 0.000015: 1.2739x faster +Significant (t=4.158080) +Stddev: 0.00002 -> 0.00001: 1.1449x smaller (N = 500) + +Running 'query_update' benchmark ... +Min: 0.000047 -> 0.000041: 1.1323x faster +Avg: 0.000052 -> 0.000044: 1.1721x faster +Significant (t=18.470635) +Stddev: 0.00001 -> 0.00000: 1.6104x smaller (N = 500) + +Running 'query_in_bulk' benchmark ... +Min: 0.000152 -> 0.000136: 1.1193x faster +Avg: 0.000173 -> 0.000147: 1.1735x faster +Significant (t=16.901845) +Stddev: 0.00003 -> 0.00001: 2.1199x smaller (N = 500) + +Running 'url_resolve_nested' benchmark ... +Min: 0.000043 -> 0.000034: 1.2871x faster +Avg: 0.000075 -> 0.000047: 1.6049x faster +Not significant +Stddev: 0.00066 -> 0.00023: 2.8387x smaller (N = 500) + +Running 'model_creation' benchmark ... +Min: 0.000077 -> 0.000066: 1.1579x faster +Avg: 0.000088 -> 0.000072: 1.2205x faster +Significant (t=10.514202) +Stddev: 0.00003 -> 0.00001: 3.1410x smaller (N = 500) + +Running 'query_order_by' benchmark ... +Min: 0.000135 -> 0.000124: 1.0945x faster +Avg: 0.000145 -> 0.000133: 1.0902x faster +Significant (t=13.574502) +Stddev: 0.00001 -> 0.00001: 1.1586x smaller (N = 500) + +Running 'startup' benchmark ... +Skipped: Django 1.9 and later has changed app loading. This benchmark needs fixing anyway. + +Running 'form_clean' benchmark ... +Min: 0.000005 -> 0.000003: 1.4696x faster +Avg: 0.000006 -> 0.000004: 1.4931x faster +Significant (t=11.263253) +Stddev: 0.00000 -> 0.00000: 2.2571x smaller (N = 500) + +Running 'locale_from_request' benchmark ... +Min: 0.000076 -> 0.000082: 1.0895x slower +Avg: 0.000083 -> 0.000090: 1.0877x slower +Not significant +Stddev: 0.00009 -> 0.00006: 1.6230x smaller (N = 500) + +Running 'query_exists' benchmark ... +Min: 0.000243 -> 0.000214: 1.1399x faster +Avg: 0.000262 -> 0.000227: 1.1571x faster +Significant (t=27.797738) +Stddev: 0.00002 -> 0.00002: 1.2601x smaller (N = 500) + +Running 'query_values_10000' benchmark ... +Min: 0.005755 -> 0.005269: 1.0923x faster +Avg: 0.006184 -> 0.005587: 1.1067x faster +Significant (t=10.895954) +Stddev: 0.00094 -> 0.00079: 1.1902x smaller (N = 500) + +Running 'query_exclude' benchmark ... +Min: 0.000159 -> 0.000141: 1.1256x faster +Avg: 0.000177 -> 0.000151: 1.1741x faster +Significant (t=23.556200) +Stddev: 0.00002 -> 0.00001: 1.8250x smaller (N = 500) + +Running 'query_raw' benchmark ... +Min: 0.005619 -> 0.004860: 1.1562x faster +Avg: 0.006181 -> 0.005041: 1.2263x faster +Significant (t=18.008590) +Stddev: 0.00121 -> 0.00074: 1.6376x smaller (N = 500) + +Running 'url_resolve' benchmark ... +Min: 0.004666 -> 0.004233: 1.1023x faster +Avg: 0.004920 -> 0.004347: 1.1318x faster +Significant (t=24.865249) +Stddev: 0.00049 -> 0.00016: 3.1507x smaller (N = 500) + +Running 'model_save_new' benchmark ... +Min: 0.003420 -> 0.003105: 1.1014x faster +Avg: 0.003610 -> 0.003217: 1.1221x faster +Significant (t=42.956103) +Stddev: 0.00017 -> 0.00011: 1.6304x smaller (N = 500) + +Running 'query_all' benchmark ... +Min: 0.008101 -> 0.007077: 1.1447x faster +Avg: 0.009006 -> 0.007936: 1.1348x faster +Significant (t=9.981534) +Stddev: 0.00171 -> 0.00168: 1.0215x smaller (N = 500) +``` + +### Django 4.2.6 + +- Djangobench 0.10.0 +- Django 4.0.10 +- Python 3.8.18 vs Python 3.11.5 + +```bash +joel@METABOX:~/djangobench/django$ djangobench --vcs=none --control=. --experiment=. --control-python=/home/joel/djangobench/py38/bin/python --experiment-python=/home/joel/djangobench/py311/bin/python -r /home/joel/djangobench/results -t 500 +Running all benchmarks +Recording data to '/home/joel/djangobench/results' +Control: Django 4.2.6 (in .) +Experiment: Django 4.2.6 (in .) + +Running 'multi_value_dict' benchmark ... +Min: -0.000004 -> 0.000013: -3.0336x slower +Avg: 0.000182 -> 0.000133: 1.3680x faster +Significant (t=9.151616) +Stddev: 0.00010 -> 0.00007: 1.3826x smaller (N = 500) + +Running 'query_values' benchmark ... +Min: 0.000082 -> 0.000072: 1.1485x faster +Avg: 0.000086 -> 0.000075: 1.1462x faster +Significant (t=30.114973) +Stddev: 0.00001 -> 0.00001: 1.0258x larger (N = 500) + +Running 'query_delete' benchmark ... +Min: 0.000080 -> 0.000071: 1.1169x faster +Avg: 0.000086 -> 0.000077: 1.1088x faster +Significant (t=13.459411) +Stddev: 0.00001 -> 0.00001: 1.0008x smaller (N = 500) + +Running 'query_select_related' benchmark ... +Min: 0.016889 -> 0.013513: 1.2498x faster +Avg: 0.018370 -> 0.013885: 1.3230x faster +Significant (t=48.921967) +Stddev: 0.00196 -> 0.00061: 3.2174x smaller (N = 500) + +Running 'query_aggregate' benchmark ... +Min: 0.000167 -> 0.000153: 1.0904x faster +Avg: 0.000182 -> 0.000165: 1.1029x faster +Significant (t=12.685517) +Stddev: 0.00002 -> 0.00002: 1.3019x smaller (N = 500) + +Running 'query_raw_deferred' benchmark ... +Min: 0.004160 -> 0.003674: 1.1323x faster +Avg: 0.004596 -> 0.003888: 1.1820x faster +Significant (t=11.504156) +Stddev: 0.00117 -> 0.00073: 1.5957x smaller (N = 500) + +Running 'query_get_or_create' benchmark ... +Min: 0.000421 -> 0.000356: 1.1823x faster +Avg: 0.000470 -> 0.000392: 1.2011x faster +Significant (t=14.613017) +Stddev: 0.00008 -> 0.00009: 1.0954x larger (N = 500) + +Running 'query_values_list' benchmark ... +Min: 0.000080 -> 0.000070: 1.1395x faster +Avg: 0.000085 -> 0.000075: 1.1202x faster +Significant (t=20.300988) +Stddev: 0.00001 -> 0.00001: 1.0537x smaller (N = 500) + +Running 'url_resolve_flat_i18n_off' benchmark ... +Min: 0.056031 -> 0.045854: 1.2219x faster +Avg: 0.057048 -> 0.048370: 1.1794x faster +Significant (t=106.668460) +Stddev: 0.00117 -> 0.00139: 1.1819x larger (N = 500) + +Running 'qs_filter_chaining' benchmark ... +Min: 0.000247 -> 0.000205: 1.2080x faster +Avg: 0.000267 -> 0.000219: 1.2211x faster +Significant (t=38.507950) +Stddev: 0.00002 -> 0.00002: 1.0252x larger (N = 500) + +Running 'template_render' benchmark ... +Min: 0.000956 -> 0.000761: 1.2550x faster +Avg: 0.001061 -> 0.000862: 1.2302x faster +Significant (t=6.128572) +Stddev: 0.00052 -> 0.00051: 1.0109x smaller (N = 500) + +Running 'query_get' benchmark ... +Min: 0.000268 -> 0.000235: 1.1388x faster +Avg: 0.000293 -> 0.000256: 1.1411x faster +Significant (t=24.002331) +Stddev: 0.00002 -> 0.00003: 1.2917x larger (N = 500) + +Running 'query_none' benchmark ... +Min: 0.000055 -> 0.000050: 1.1079x faster +Avg: 0.000061 -> 0.000055: 1.1183x faster +Significant (t=3.149707) +Stddev: 0.00003 -> 0.00004: 1.3162x larger (N = 500) + +Running 'query_complex_filter' benchmark ... +Min: 0.000040 -> 0.000034: 1.1777x faster +Avg: 0.000042 -> 0.000038: 1.1267x faster +Significant (t=15.246074) +Stddev: 0.00000 -> 0.00001: 1.5250x larger (N = 500) + +Running 'query_filter' benchmark ... +Min: 0.000131 -> 0.000116: 1.1288x faster +Avg: 0.000139 -> 0.000127: 1.0907x faster +Significant (t=14.448319) +Stddev: 0.00001 -> 0.00001: 1.2281x larger (N = 500) + +Running 'template_render_simple' benchmark ... +Min: 0.000031 -> 0.000024: 1.2650x faster +Avg: 0.000037 -> 0.000029: 1.2895x faster +Significant (t=2.094800) +Stddev: 0.00007 -> 0.00005: 1.3630x smaller (N = 500) + +Running 'default_middleware' benchmark ... +Min: -0.000037 -> -0.000060: 0.6180x faster +Avg: 0.000001 -> 0.000001: 1.0056x slower +Not significant +Stddev: 0.00002 -> 0.00002: 1.0915x smaller (N = 500) + +Running 'query_annotate' benchmark ... +Min: 0.000192 -> 0.000173: 1.1122x faster +Avg: 0.000206 -> 0.000185: 1.1134x faster +Significant (t=17.849733) +Stddev: 0.00002 -> 0.00002: 1.0456x smaller (N = 500) + +Running 'raw_sql' benchmark ... +Min: 0.000013 -> 0.000012: 1.0839x faster +Avg: 0.000015 -> 0.000014: 1.0882x faster +Significant (t=4.252084) +Stddev: 0.00001 -> 0.00000: 1.5868x smaller (N = 500) + +Running 'url_resolve_flat' benchmark ... +Min: 0.055540 -> 0.046018: 1.2069x faster +Avg: 0.058030 -> 0.048408: 1.1988x faster +Significant (t=98.852976) +Stddev: 0.00157 -> 0.00151: 1.0444x smaller (N = 500) + +Running 'l10n_render' benchmark ... +Min: 0.001604 -> 0.001253: 1.2797x faster +Avg: 0.001684 -> 0.001304: 1.2918x faster +Significant (t=37.535402) +Stddev: 0.00017 -> 0.00015: 1.1476x smaller (N = 500) + +Running 'query_count' benchmark ... +Min: 0.000176 -> 0.000165: 1.0631x faster +Avg: 0.000189 -> 0.000176: 1.0755x faster +Significant (t=12.229046) +Stddev: 0.00002 -> 0.00002: 1.0395x larger (N = 500) + +Running 'model_delete' benchmark ... +Min: 0.000122 -> 0.000104: 1.1743x faster +Avg: 0.000152 -> 0.000115: 1.3227x faster +Significant (t=19.812953) +Stddev: 0.00004 -> 0.00001: 2.6554x smaller (N = 500) + +Running 'query_iterator' benchmark ... +Min: 0.000108 -> 0.000094: 1.1518x faster +Avg: 0.000119 -> 0.000098: 1.2203x faster +Significant (t=21.984884) +Stddev: 0.00002 -> 0.00001: 2.7750x smaller (N = 500) + +Running 'template_compilation' benchmark ... +Min: 0.000164 -> 0.000148: 1.1034x faster +Avg: 0.000184 -> 0.000162: 1.1386x faster +Significant (t=4.665298) +Stddev: 0.00008 -> 0.00007: 1.2952x smaller (N = 500) + +Running 'query_all_multifield' benchmark ... +Min: 0.014802 -> 0.012188: 1.2144x faster +Avg: 0.016029 -> 0.013294: 1.2057x faster +Significant (t=21.516971) +Stddev: 0.00210 -> 0.00191: 1.0984x smaller (N = 500) + +Running 'query_prefetch_related' benchmark ... +Min: 0.013401 -> 0.011583: 1.1569x faster +Avg: 0.014822 -> 0.013366: 1.1090x faster +Significant (t=11.422100) +Stddev: 0.00170 -> 0.00229: 1.3410x larger (N = 500) + +Running 'query_all_converters' benchmark ... +Min: 0.000499 -> 0.000429: 1.1618x faster +Avg: 0.000531 -> 0.000455: 1.1670x faster +Significant (t=42.716720) +Stddev: 0.00002 -> 0.00003: 1.5394x larger (N = 500) + +Running 'query_distinct' benchmark ... +Min: 0.000108 -> 0.000095: 1.1397x faster +Avg: 0.000116 -> 0.000100: 1.1646x faster +Significant (t=25.915629) +Stddev: 0.00001 -> 0.00001: 1.1204x larger (N = 500) + +Running 'query_dates' benchmark ... +Min: 0.000333 -> 0.000290: 1.1490x faster +Avg: 0.000365 -> 0.000326: 1.1207x faster +Significant (t=18.213858) +Stddev: 0.00003 -> 0.00003: 1.0118x larger (N = 500) + +Running 'model_save_existing' benchmark ... +Min: 0.003455 -> 0.003081: 1.1215x faster +Avg: 0.003764 -> 0.003326: 1.1316x faster +Significant (t=32.229651) +Stddev: 0.00023 -> 0.00020: 1.1398x smaller (N = 500) + +Running 'query_delete_related' benchmark ... +Min: 0.000122 -> 0.000102: 1.1946x faster +Avg: 0.000131 -> 0.000113: 1.1564x faster +Significant (t=5.027485) +Stddev: 0.00005 -> 0.00006: 1.4129x larger (N = 500) + +Running 'url_reverse' benchmark ... +Min: 0.000068 -> 0.000067: 1.0193x faster +Avg: 0.000075 -> 0.000074: 1.0157x faster +Not significant +Stddev: 0.00006 -> 0.00005: 1.1543x smaller (N = 500) + +Running 'query_latest' benchmark ... +Min: 0.000147 -> 0.000138: 1.0631x faster +Avg: 0.000167 -> 0.000148: 1.1277x faster +Significant (t=11.353029) +Stddev: 0.00003 -> 0.00002: 1.6091x smaller (N = 500) + +Running 'form_create' benchmark ... +Min: 0.000016 -> 0.000013: 1.2659x faster +Avg: 0.000020 -> 0.000015: 1.2770x faster +Significant (t=3.482649) +Stddev: 0.00002 -> 0.00002: 1.0947x larger (N = 500) + +Running 'query_update' benchmark ... +Min: 0.000047 -> 0.000043: 1.0971x faster +Avg: 0.000050 -> 0.000046: 1.0691x faster +Significant (t=9.363513) +Stddev: 0.00001 -> 0.00000: 1.2636x smaller (N = 500) + +Running 'query_in_bulk' benchmark ... +Min: 0.000157 -> 0.000143: 1.0970x faster +Avg: 0.000178 -> 0.000162: 1.0981x faster +Significant (t=9.031182) +Stddev: 0.00002 -> 0.00003: 1.5173x larger (N = 500) + +Running 'url_resolve_nested' benchmark ... +Min: 0.000046 -> 0.000038: 1.2179x faster +Avg: 0.000075 -> 0.000052: 1.4505x faster +Not significant +Stddev: 0.00059 -> 0.00024: 2.4300x smaller (N = 500) + +Running 'model_creation' benchmark ... +Min: 0.000071 -> 0.000065: 1.1058x faster +Avg: 0.000079 -> 0.000073: 1.0876x faster +Significant (t=2.786580) +Stddev: 0.00003 -> 0.00004: 1.1518x larger (N = 500) + +Running 'query_order_by' benchmark ... +Min: 0.000146 -> 0.000128: 1.1407x faster +Avg: 0.000154 -> 0.000138: 1.1206x faster +Significant (t=14.021341) +Stddev: 0.00002 -> 0.00002: 1.2540x larger (N = 500) + +Running 'startup' benchmark ... +Skipped: Django 1.9 and later has changed app loading. This benchmark needs fixing anyway. + +Running 'form_clean' benchmark ... +Min: 0.000005 -> 0.000004: 1.4613x faster +Avg: 0.000006 -> 0.000004: 1.3654x faster +Significant (t=12.763128) +Stddev: 0.00000 -> 0.00000: 1.1666x larger (N = 500) + +Running 'locale_from_request' benchmark ... +Min: 0.000097 -> 0.000108: 1.1090x slower +Avg: 0.000108 -> 0.000120: 1.1178x slower +Significant (t=-3.057677) +Stddev: 0.00007 -> 0.00006: 1.1186x smaller (N = 500) + +Running 'query_exists' benchmark ... +Min: 0.000273 -> 0.000234: 1.1698x faster +Avg: 0.000290 -> 0.000248: 1.1686x faster +Significant (t=39.518859) +Stddev: 0.00002 -> 0.00002: 1.2025x smaller (N = 500) + +Running 'query_values_10000' benchmark ... +Min: 0.005601 -> 0.005298: 1.0571x faster +Avg: 0.006023 -> 0.005691: 1.0583x faster +Significant (t=6.167352) +Stddev: 0.00082 -> 0.00088: 1.0752x larger (N = 500) + +Running 'query_exclude' benchmark ... +Min: 0.000159 -> 0.000140: 1.1367x faster +Avg: 0.000165 -> 0.000149: 1.1020x faster +Significant (t=19.643154) +Stddev: 0.00001 -> 0.00001: 1.2636x larger (N = 500) + +Running 'query_raw' benchmark ... +Min: 0.005764 -> 0.004630: 1.2450x faster +Avg: 0.006169 -> 0.004881: 1.2638x faster +Significant (t=20.996453) +Stddev: 0.00109 -> 0.00083: 1.3105x smaller (N = 500) + +Running 'url_resolve' benchmark ... +Min: 0.004928 -> 0.004597: 1.0721x faster +Avg: 0.005217 -> 0.004716: 1.1063x faster +Significant (t=46.893945) +Stddev: 0.00022 -> 0.00010: 2.2192x smaller (N = 500) + +Running 'model_save_new' benchmark ... +Min: 0.003404 -> 0.003012: 1.1301x faster +Avg: 0.003494 -> 0.003105: 1.1251x faster +Significant (t=45.888484) +Stddev: 0.00014 -> 0.00013: 1.0298x smaller (N = 500) + +Running 'query_all' benchmark ... +Min: 0.007971 -> 0.007085: 1.1250x faster +Avg: 0.009091 -> 0.008147: 1.1159x faster +Significant (t=7.583074) +Stddev: 0.00183 -> 0.00210: 1.1518x larger (N = 500) +``` diff --git a/docs/maintenance/tuning/sql.md b/docs/maintenance/tuning/sql.md new file mode 100644 index 00000000..6f78ed66 --- /dev/null +++ b/docs/maintenance/tuning/sql.md @@ -0,0 +1,196 @@ +# SQL + +SQL Tuning is usually the realm of experienced Database Admins, as it can be full of missteps leading to worse performance. It is _extremely_ important that you take it slowly, make one change at a time with dedicated research and test before and after. + +Before you start down this path its best to update [MariaDB](https://mariadb.org/download/?t=repo-config) / MySQL. Performance Schemas, some default tuning and other general performance improvements are only available on new versions. You must also allow your server to run for 24 hours at least to gather accurate data. + +## MySQLTuner + +[MySQLTuner](https://github.com/major/MySQLTuner-perl) is a Perl script that will analyze inbuilt metrics and spit out recommendations. + +### [performance_schema](https://mariadb.com/kb/en/performance-schema-system-variables/#performance_schema) + +This should be ON for 24 hours before applying any recommendations, then can be turned _OFF_ to save Memory while its not needed. + +```bash +-------- Performance schema ------------------------------------------------------------------------ +[--] Performance_schema is activated. +[--] Memory used by Performance_schema: 105.7M +[--] Sys schema is installed. +# 105M could be significant depending on your hardware +``` + +## SQL Variables + +### [skip-name-resolve](https://mariadb.com/kb/en/server-system-variables/#skip_name_resolve) + +While on, SQL will perform a dns resolve for all connections, if your database is connected via IP, this will save you a handful of cpu cycles per connection. + +Note you must use 127.0.0.1 for localhost connections, and all entries in GRANT tables (permissions), must use IP addresses. + +### [table_definition_cache](https://mariadb.com/kb/en/server-system-variables/#table_definition_cache) + +Will usually need to be expanded on installs with many extensions + +Most installs should cache all their tables, but if your hit rate is still quite high, you may have a lot of rarely used tables that you don't need to waste memory caching. + +```bash +[OK] Table cache hit rate: 63% (2K hits / 4K requests). +# Only 63% of our queries are using this cache +table_definition_cache (400) > 567 or -1 (autosizing if supported) +# Here We have 567 tables, but a default cache of only 400. +``` + +```bash +[OK] Table cache hit rate: 99% (372M hits / 372M requests) +[OK] table_definition_cache (600) is greater than number of tables (567) +# Much better +``` + +### [innodb_buffer_pool_size](https://mariadb.com/kb/en/innodb-system-variables/#innodb_buffer_pool_size) + +This is in short, the amount of memory assigned to store data for faster reads. If you are memory starved you should not increase this variable regardless of the suggestions of this tool. Pushing SQL cache to pagefile will not result in faster queries. + +If you are not memory starved, you can wind this up to the amount of total data you have to store it all in memory. This would be a significant performance increase for larger installs on dedicated hardware with memory to spare. + +```bash +[!!] InnoDB buffer pool / data size: 128.0M / 651.6M +# I have 651mb of _possible_ data to cache. +# We won't and shouldn't cache it all unless we have excess memory to spare. +... +[!!] InnoDB Read buffer efficiency: 0% (-2019 hits / 0 total) +# A low ratio here would suggest more Memory can be used effectively. +# A high ratio might mean we have most of our regularly used data cached already +``` + +### [innodb_log_buffer_size](https://mariadb.com/kb/en/innodb-system-variables/#innodb_log_buffer_size) / [innodb_log_file_size](https://mariadb.com/kb/en/innodb-system-variables/#innodb_log_file_size) + +[innodb_log_file_size](https://mariadb.com/kb/en/innodb-system-variables/#innodb_log_file_size) This is your _write_ log, used to redo any commits in the event of a crash. MySQLTuner recommends this be 1/4 of your innodb_buffer_pool / read buffer. I would not lower this past the default size. + +[innodb_log_buffer_size](https://mariadb.com/kb/en/innodb-system-variables/#innodb_log_buffer_size) This is the memory buffer for the write log. Larger transactions will benefit from a larger setting. + +```bash +[!!] Ratio InnoDB log file size / InnoDB Buffer pool size (75%): 96.0M \* 1 / 128.0M should be equal to 25% +# Here our write log file is 75% of our read buffer, but 96MB is the default so we probably wont shrink it further +... +[OK] InnoDB Write Log efficiency: 99.11% (23167614 hits / 23375465 total) # Our transactions are typically not large enough to exhaust the write log buffer, +[OK] InnoDB log waits: 0.00% (0 waits / 207851 writes) +``` + +### [innodb_file_per_table](https://mariadb.com/kb/en/innodb-system-variables/#innodb_file_per_table) + +This is not for performance, but for file system utilization and ease of use. While off all tables are stored in a single monolith file, as opposed to individual files. This is deprecated and set to ON in MariaDB 11.x + +```bash +[OK] InnoDB File per table is activated +``` + +### [join_buffer_size](https://mariadb.com/kb/en/server-system-variables/#join_buffer_size) + +It is always better to optimize a table with indexes, if you have valuable performance data and analysis please reach out to either the Alliance Auth or Community dev responsible for the data that could benefit from indexes. MySQLTuner will likely recommend increasing this number for as long as there are any queries that could benefit, regardless of their resulting performance impact. + +Also keep in mind this is _per thread_, if you have a potential 200 connections, 256MB \* 200 = 50MB, scaling this setting out too far can result in more memory use than expected. + +```bash +[!!] Joins performed without indexes: 67646 +``` + +```bash +[OK] No joins without indexes +# An ideal scenario. With well designed apps this is possible with a default join buffer. +``` + +### [tmp_table_size](https://mariadb.com/kb/en/server-system-variables/#tmp_table_size) / [max_heap_table_size](https://mariadb.com/kb/en/server-system-variables/#max_heap_table_size) + +If a temporary table must be created due to a lack of other optimizations or large queries, it may only be stored in memory under this size. Any larger and it is performed on disk reducing performance. + +tmp_table_size and max_heap_table_size should be increased together. + +```bash +[!!] Temporary tables created on disk: 32% (775 on disk / 2K total) +# 32% of my temp tables are performed on disk. If you increase this size, monitor if your performance improves. +# If it does not you may have data of a certain size that is impractical to cache, and you can reclaim this memory. +``` + +```bash +[OK] Temporary tables created on disk: 0% (5K on disk / 4M total) +# Here only a miniscule amount of my temp tables are done on disk. No action required +``` + +### key_buffer_size + +Index buffer for MyISAM tables, If you use no or very little data in MyISAM tables. You may reclaim some memory here + +In this example we still have some MyISAM tables, you may have none + +```bash +[--] General MyIsam metrics: +[--] +-- Total MyISAM Tables : 67 +[--] +-- Total MyISAM indexes : 7.1M +[--] +-- KB Size :8.0M +[--] +-- KB Used Size :1.5M +[--] +-- KB used :18.3% +[--] +-- Read KB hit rate: 0% (0 cached / 0 reads) +[--] +-- Write KB hit rate: 0% (0 cached / 0 writes) +[!!] Key buffer used: 18.3% (1.5M used / 8.0M cache) # We have only filled 1.5M of the 8 assigned +[OK] Key buffer size / total MyISAM indexes: 8.0M/7.1M # This is the max theoretical buffer to cache all my indexes +Variables to adjust: + key_buffer_size (~ 1M) +# Tuner has seen that we barely use this buffer and it can be shrunk, if you care about its impact don't lower this below your total indexes. +``` + +### [aria_pagecache_buffer_size](https://mariadb.com/kb/en/aria-system-variables/#aria_pagecache_buffer_size) + +Index and data buffer for Aria tables, If you use no or very little data in Aria tables. You may reclaim some memory here + +```bash +-------- Aria Metrics ------------------------------------------------------------------------------ +[--] Aria Storage Engine is enabled. +[OK] Aria pagecache size / total Aria indexes: 128.0M/328.0K # i use a fraction of my aria buffer since i have no aria tables. +[OK] Aria pagecache hit rate: 99.9% (112K cached / 75 reads) # Aria is used internally for MariaDB, so you still want an incredily high ratio here. +``` + +## Swappiness + +Swappiness is not an SQL variable but part of your system kernel. Swappiness controls how much free memory a server "likes" to have at any given time, and how frequently it shifts data to swapfile in order to free up memory. Desktop operating systems will have this value set quite high, whereas servers are less aggressive with their swapfile. + +Database workloads especially benefit from having their caches stay in memory and will recommend values under 10 for a dedicated database server. 10 is a good compromise for a mixed use server with adequate memory. + +If your server is memory starved, leave swapfile aggressive to ensure it is moving memory around as needed. + +```bash +joel@METABOX:~/aa_dev$ free -m + total used free shared buff/cache available +Mem: 15998 1903 13372 2 722 13767 +Swap: 4096 1404 2691 +# Here we can see a lot of memory page (1404MB) sitting in swap while there is free memory (13372MB) available + +``` + +```bash +[root@auth ~]# free -m + total used free shared buff/cache available +Mem: 738 611 59 1 68 35 +Swap: 2047 1014 1033 +# Here we can see a memory starved server highly utilizing swap already. I wouldn't mess with it too much. (vm.swappiness is 30) +``` + +```bash +[root@mysql ~]# free -m + total used free shared buff/cache available +Mem: 738 498 95 7 145 120 +Swap: 2047 289 1758 +# Here we can see a dedicated single use Database Server, Swappiness is 10 here because we have been careful not to starve it of memory and there is low potential to impact other applications +``` + +```bash +vm.swappiness <= 10 (echo 10 > /proc/sys/vm/swappiness) or vm.swappiness=10 in /etc/sysctl.conf +``` + +## Max Asyncronous IO + +Unless you are still operating on spinning rust (Hard Disk Drives), or an IO limited VPS, you can likely increase this value. Database workloads appreciate the additional scaling. + +```bash +fs.aio-max-nr > 1M (echo 1048576 > /proc/sys/fs/aio-max-nr) or fs.aio-max-nr=1048576 in /etc/sysctl.conf +``` From ea1887b9ec6d59941ff86e2cb25d8fc2fccaab31 Mon Sep 17 00:00:00 2001 From: Ariel Rin Date: Thu, 26 Oct 2023 11:26:39 +1000 Subject: [PATCH 2/8] mild clarifications --- .../aa_core/{code-style => code-style.md} | 0 docs/maintenance/tuning/index.md | 1 + docs/maintenance/tuning/sql.md | 15 +++++++++++---- 3 files changed, 12 insertions(+), 4 deletions(-) rename docs/development/aa_core/{code-style => code-style.md} (100%) diff --git a/docs/development/aa_core/code-style b/docs/development/aa_core/code-style.md similarity index 100% rename from docs/development/aa_core/code-style rename to docs/development/aa_core/code-style.md diff --git a/docs/maintenance/tuning/index.md b/docs/maintenance/tuning/index.md index e01d46cc..44b50c1d 100644 --- a/docs/maintenance/tuning/index.md +++ b/docs/maintenance/tuning/index.md @@ -15,4 +15,5 @@ The official installation guide will install a stable version of Alliance Auth t celery redis python + sql ``` diff --git a/docs/maintenance/tuning/sql.md b/docs/maintenance/tuning/sql.md index 6f78ed66..17253608 100644 --- a/docs/maintenance/tuning/sql.md +++ b/docs/maintenance/tuning/sql.md @@ -89,7 +89,7 @@ This is not for performance, but for file system utilization and ease of use. Wh It is always better to optimize a table with indexes, if you have valuable performance data and analysis please reach out to either the Alliance Auth or Community dev responsible for the data that could benefit from indexes. MySQLTuner will likely recommend increasing this number for as long as there are any queries that could benefit, regardless of their resulting performance impact. -Also keep in mind this is _per thread_, if you have a potential 200 connections, 256MB \* 200 = 50MB, scaling this setting out too far can result in more memory use than expected. +Also keep in mind this is _per thread_, if you have a potential 200 connections, 256KB * 200 = 50MB, scaling this setting out too far can result in more memory use than expected. ```bash [!!] Joins performed without indexes: 67646 @@ -147,7 +147,7 @@ Index and data buffer for Aria tables, If you use no or very little data in Aria -------- Aria Metrics ------------------------------------------------------------------------------ [--] Aria Storage Engine is enabled. [OK] Aria pagecache size / total Aria indexes: 128.0M/328.0K # i use a fraction of my aria buffer since i have no aria tables. -[OK] Aria pagecache hit rate: 99.9% (112K cached / 75 reads) # Aria is used internally for MariaDB, so you still want an incredily high ratio here. +[OK] Aria pagecache hit rate: 99.9% (112K cached / 75 reads) # Aria is used internally for MariaDB, so you still want an incredibly high ratio here. ``` ## Swappiness @@ -164,7 +164,6 @@ joel@METABOX:~/aa_dev$ free -m Mem: 15998 1903 13372 2 722 13767 Swap: 4096 1404 2691 # Here we can see a lot of memory page (1404MB) sitting in swap while there is free memory (13372MB) available - ``` ```bash @@ -184,13 +183,21 @@ Swap: 2047 289 1758 ``` ```bash +[--] Information about kernel tuning: +... +[--] vm.swappiness = 30 +[xx] Swappiness is < 10. +... vm.swappiness <= 10 (echo 10 > /proc/sys/vm/swappiness) or vm.swappiness=10 in /etc/sysctl.conf ``` -## Max Asyncronous IO +## Max Asynchronous IO Unless you are still operating on spinning rust (Hard Disk Drives), or an IO limited VPS, you can likely increase this value. Database workloads appreciate the additional scaling. ```bash +[--] Information about kernel tuning: +[--] fs.aio-max-nr = 65536 +... fs.aio-max-nr > 1M (echo 1048576 > /proc/sys/fs/aio-max-nr) or fs.aio-max-nr=1048576 in /etc/sysctl.conf ``` From 2a9981cdb943efee200948fc513a4e8824ed3ef4 Mon Sep 17 00:00:00 2001 From: Dusty Meg Date: Wed, 8 Nov 2023 13:04:11 +0000 Subject: [PATCH 3/8] Stop renaming discord nick when setting has it disabled --- .../services/modules/discord/auth_hooks.py | 26 +++++++++++-------- .../modules/discord/tests/test_auth_hooks.py | 7 +++++ .../modules/discord/tests/test_integration.py | 2 ++ 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/allianceauth/services/modules/discord/auth_hooks.py b/allianceauth/services/modules/discord/auth_hooks.py index 2d6bd204..4f3af11f 100644 --- a/allianceauth/services/modules/discord/auth_hooks.py +++ b/allianceauth/services/modules/discord/auth_hooks.py @@ -11,6 +11,9 @@ from .models import DiscordUser from .urls import urlpatterns from .utils import LoggerAddTag from . import tasks, __title__ +from .app_settings import ( + DISCORD_SYNC_NAMES +) logger = LoggerAddTag(logging.getLogger(__name__), __title__) @@ -99,17 +102,18 @@ class DiscordService(ServicesHook): return has_perms def sync_nickname(self, user): - logger.debug('Syncing %s nickname for user %s', self.name, user) - if self.user_has_account(user): - tasks.update_nickname.apply_async( - kwargs={ - 'user_pk': user.pk, - # since the new nickname is not yet in the DB we need to - # provide it manually to the task - 'nickname': user_formatted_nick(user) - }, - priority=SINGLE_TASK_PRIORITY - ) + if DISCORD_SYNC_NAMES: + logger.debug('Syncing %s nickname for user %s', self.name, user) + if self.user_has_account(user): + tasks.update_nickname.apply_async( + kwargs={ + 'user_pk': user.pk, + # since the new nickname is not yet in the DB we need to + # provide it manually to the task + 'nickname': user_formatted_nick(user) + }, + priority=SINGLE_TASK_PRIORITY + ) def sync_nicknames_bulk(self, users: list): """Sync nickname for a list of users in bulk. diff --git a/allianceauth/services/modules/discord/tests/test_auth_hooks.py b/allianceauth/services/modules/discord/tests/test_auth_hooks.py index 61c07cbf..0ca60ce5 100644 --- a/allianceauth/services/modules/discord/tests/test_auth_hooks.py +++ b/allianceauth/services/modules/discord/tests/test_auth_hooks.py @@ -81,11 +81,18 @@ class TestDiscordService(NoSocketsTestCase): self.assertFalse(DiscordUser.objects.filter(user=self.none_member).exists()) @patch(MODULE_PATH + '.tasks.update_nickname') + @patch(MODULE_PATH + '.auth_hooks.DISCORD_SYNC_NAMES', True) def test_sync_nickname(self, mock_update_nickname): service = self.service() service.sync_nickname(self.member) self.assertTrue(mock_update_nickname.apply_async.called) + @patch(MODULE_PATH + '.tasks.update_nickname') + def test_sync_nickname_no_setting(self, mock_update_nickname): + service = self.service() + service.sync_nickname(self.member) + self.assertFalse(mock_update_nickname.apply_async.called) + @patch(MODULE_PATH + '.tasks.update_nicknames_bulk') def test_sync_nicknames_bulk(self, mock_update_nicknames_bulk): service = self.service() diff --git a/allianceauth/services/modules/discord/tests/test_integration.py b/allianceauth/services/modules/discord/tests/test_integration.py index 2d50db5e..aae213e9 100644 --- a/allianceauth/services/modules/discord/tests/test_integration.py +++ b/allianceauth/services/modules/discord/tests/test_integration.py @@ -164,6 +164,7 @@ class TestServiceFeatures(TransactionTestCase): self.discord_user = DiscordUser.objects.create(user=self.user, uid=TEST_USER_ID) self.assertTrue(DiscordUser.objects.user_has_account(self.user)) + @patch(MODULE_PATH + '.auth_hooks.DISCORD_SYNC_NAMES', True) def test_when_name_of_main_changes_then_discord_nick_is_updated( self, requests_mocker ): @@ -185,6 +186,7 @@ class TestServiceFeatures(TransactionTestCase): self.assertTrue(nick_updated) self.assertTrue(DiscordUser.objects.user_has_account(self.user)) + @patch(MODULE_PATH + '.auth_hooks.DISCORD_SYNC_NAMES', True) def test_when_name_of_main_changes_and_user_deleted_then_account_is_deleted( self, requests_mocker ): From 2477c31656e2372c08b395ca00f0ffabdd3bf8a8 Mon Sep 17 00:00:00 2001 From: Erik Kalkoken Date: Wed, 8 Nov 2023 13:04:26 +0000 Subject: [PATCH 4/8] Fix leave tab for autoleave --- allianceauth/groupmanagement/models.py | 7 +++---- .../templates/groupmanagement/index.html | 4 ++-- .../groupmanagement/tests/test_views.py | 18 ++++++++++++++++++ allianceauth/groupmanagement/views.py | 13 ++++++++----- 4 files changed, 31 insertions(+), 11 deletions(-) diff --git a/allianceauth/groupmanagement/models.py b/allianceauth/groupmanagement/models.py index 3ca6b8c6..8491f08f 100644 --- a/allianceauth/groupmanagement/models.py +++ b/allianceauth/groupmanagement/models.py @@ -1,8 +1,7 @@ from typing import Set from django.conf import settings -from django.contrib.auth.models import Group -from django.contrib.auth.models import User +from django.contrib.auth.models import Group, User from django.db import models from django.utils.timezone import now from django.utils.translation import gettext_lazy as _ @@ -14,7 +13,7 @@ from allianceauth.notifications import notify class GroupRequest(models.Model): """Request from a user for joining or leaving a group.""" - leave_request = models.BooleanField(default=0) + leave_request = models.BooleanField(default=False) user = models.ForeignKey(User, on_delete=models.CASCADE) group = models.ForeignKey(Group, on_delete=models.CASCADE) @@ -49,7 +48,7 @@ class RequestLog(models.Model): request_type = models.BooleanField(null=True) group = models.ForeignKey(Group, on_delete=models.CASCADE) request_info = models.CharField(max_length=254) - action = models.BooleanField(default=0) + action = models.BooleanField(default=False) request_actor = models.ForeignKey(User, on_delete=models.CASCADE) date = models.DateTimeField(auto_now_add=True) diff --git a/allianceauth/groupmanagement/templates/groupmanagement/index.html b/allianceauth/groupmanagement/templates/groupmanagement/index.html index 5a383501..c8e7c298 100644 --- a/allianceauth/groupmanagement/templates/groupmanagement/index.html +++ b/allianceauth/groupmanagement/templates/groupmanagement/index.html @@ -29,7 +29,7 @@ - {% if not auto_leave %} + {% if not show_leave_tab %}
  • {% translate "Leave Requests" %} @@ -102,7 +102,7 @@ {% endif %} - {% if not auto_leave %} + {% if not show_leave_tab %}
    {% if leaverequests %}
    diff --git a/allianceauth/groupmanagement/tests/test_views.py b/allianceauth/groupmanagement/tests/test_views.py index e0c9245b..a8bcfe58 100644 --- a/allianceauth/groupmanagement/tests/test_views.py +++ b/allianceauth/groupmanagement/tests/test_views.py @@ -1,6 +1,7 @@ from django.test import RequestFactory, TestCase, override_settings from django.urls import reverse +from allianceauth.groupmanagement.models import Group, GroupRequest from allianceauth.tests.auth_utils import AuthUtils from .. import views @@ -16,6 +17,7 @@ class TestViews(TestCase): self.factory = RequestFactory() self.user = AuthUtils.create_user('Peter Parker') self.user_with_manage_permission = AuthUtils.create_user('Bruce Wayne') + self.group = Group.objects.create(name="Example group") # set permissions AuthUtils.add_permission_to_user_by_name( @@ -83,3 +85,19 @@ class TestViews(TestCase): self.assertEqual(response.status_code, 200) self.assertNotIn('', content) self.assertNotIn('
    ', content) + + @override_settings(GROUPMANAGEMENT_AUTO_LEAVE=True) + def test_should_not_hide_leave_requests_tab_when_there_are_open_requests(self): + # given + request = self.factory.get(reverse('groupmanagement:management')) + request.user = self.user_with_manage_permission + GroupRequest.objects.create(user=self.user, group=self.group, leave_request=True) + + # when + response = views.group_management(request) + + # then + content = response_content_to_str(response) + self.assertEqual(response.status_code, 200) + self.assertIn('', content) + self.assertIn('
    ', content) diff --git a/allianceauth/groupmanagement/views.py b/allianceauth/groupmanagement/views.py index 8ab1af22..13fe33bc 100644 --- a/allianceauth/groupmanagement/views.py +++ b/allianceauth/groupmanagement/views.py @@ -2,13 +2,12 @@ import logging from django.conf import settings from django.contrib import messages -from django.contrib.auth.decorators import login_required -from django.contrib.auth.decorators import user_passes_test +from django.contrib.auth.decorators import login_required, user_passes_test from django.contrib.auth.models import Group from django.core.exceptions import ObjectDoesNotExist, PermissionDenied from django.db.models import Count from django.http import Http404 -from django.shortcuts import render, redirect, get_object_or_404 +from django.shortcuts import get_object_or_404, redirect, render from django.utils.translation import gettext_lazy as _ from allianceauth.notifications import notify @@ -16,7 +15,6 @@ from allianceauth.notifications import notify from .managers import GroupManager from .models import GroupRequest, RequestLog - logger = logging.getLogger(__name__) @@ -45,10 +43,15 @@ def group_management(request): logger.debug("Providing user {} with {} acceptrequests and {} leaverequests.".format( request.user, len(acceptrequests), len(leaverequests))) + show_leave_tab = ( + getattr(settings, 'GROUPMANAGEMENT_AUTO_LEAVE', False) + and not GroupRequest.objects.filter(leave_request=True).exists() + ) + render_items = { 'acceptrequests': acceptrequests, 'leaverequests': leaverequests, - 'auto_leave': getattr(settings, 'GROUPMANAGEMENT_AUTO_LEAVE', False), + 'show_leave_tab': show_leave_tab, } return render(request, 'groupmanagement/index.html', context=render_items) From 3480c4e0e81dcc30e951e2f657429a15cdb60ffe Mon Sep 17 00:00:00 2001 From: Erik Kalkoken Date: Wed, 8 Nov 2023 13:05:24 +0000 Subject: [PATCH 5/8] New Feature: Assign/remove users on group form --- allianceauth/groupmanagement/forms.py | 39 ++++++- .../groupmanagement/tests/test_admin.py | 110 +++++++++++++++--- 2 files changed, 130 insertions(+), 19 deletions(-) diff --git a/allianceauth/groupmanagement/forms.py b/allianceauth/groupmanagement/forms.py index 1214a7c2..73230c4e 100644 --- a/allianceauth/groupmanagement/forms.py +++ b/allianceauth/groupmanagement/forms.py @@ -1,6 +1,10 @@ +import functools + from django import forms -from django.contrib.auth.models import Group +from django.contrib.admin.widgets import FilteredSelectMultiple +from django.contrib.auth.models import Group, User from django.core.exceptions import ValidationError +from django.db.models.functions import Lower from django.utils.timezone import now from django.utils.translation import gettext_lazy as _ @@ -8,6 +12,39 @@ from .models import ReservedGroupName class GroupAdminForm(forms.ModelForm): + users = forms.ModelMultipleChoiceField( + queryset=User.objects.order_by(Lower('username')), + required=False, + widget=FilteredSelectMultiple(verbose_name=_("Users"), is_stacked=False), + ) + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + if self.instance and self.instance.pk: + self.fields["users"].initial = self.instance.user_set.all() + + def save(self, commit=True): + group: Group = super().save(commit=False) + + if commit: + group.save() + + users = self.cleaned_data["users"] + if group.pk: + self._save_m2m_and_users(group, users) + else: + self.save_m2m = functools.partial( + self._save_m2m_and_users, group=group, users=users + ) + + return group + + def _save_m2m_and_users(self, group, users): + """Save m2m relations incl. users.""" + group.user_set.set(users) + self._save_m2m() + def clean_name(self): my_name = self.cleaned_data['name'] if ReservedGroupName.objects.filter(name__iexact=my_name).exists(): diff --git a/allianceauth/groupmanagement/tests/test_admin.py b/allianceauth/groupmanagement/tests/test_admin.py index 3873fe4c..3b9605a1 100644 --- a/allianceauth/groupmanagement/tests/test_admin.py +++ b/allianceauth/groupmanagement/tests/test_admin.py @@ -6,22 +6,22 @@ from django.conf import settings from django.contrib import admin from django.contrib.admin.sites import AdminSite from django.contrib.auth.models import User -from django.test import TestCase, RequestFactory, Client, override_settings +from django.test import Client, RequestFactory, TestCase, override_settings from allianceauth.authentication.models import CharacterOwnership, State from allianceauth.eveonline.models import ( - EveCharacter, EveCorporationInfo, EveAllianceInfo + EveAllianceInfo, EveCharacter, EveCorporationInfo, ) from allianceauth.tests.auth_utils import AuthUtils -from . import get_admin_change_view_url -from ..admin import HasLeaderFilter, GroupAdmin, Group +from ..admin import Group, GroupAdmin, HasLeaderFilter from ..models import ReservedGroupName - +from . import get_admin_change_view_url if 'allianceauth.eveonline.autogroups' in settings.INSTALLED_APPS: _has_auto_groups = True from allianceauth.eveonline.autogroups.models import AutogroupsConfig + from ..admin import IsAutoGroupFilter else: _has_auto_groups = False @@ -621,21 +621,16 @@ class TestGroupAdmin2(TestCase): response = self.client.post( f"/admin/groupmanagement/group/{group.pk}/change/", data={ - "name": f"{group.name}", - "authgroup-TOTAL_FORMS": "1", - "authgroup-INITIAL_FORMS": "1", - "authgroup-MIN_NUM_FORMS": "0", - "authgroup-MAX_NUM_FORMS": "1", - "authgroup-0-description": "", - "authgroup-0-states": f"{member_state.pk}", + "name": group.name, + "users": [user_member.pk, user_guest.pk], + "authgroup-TOTAL_FORMS": 1, + "authgroup-INITIAL_FORMS": 1, + "authgroup-MIN_NUM_FORMS": 0, + "authgroup-MAX_NUM_FORMS": 1, + "authgroup-0-states": member_state.pk, "authgroup-0-internal": "on", "authgroup-0-hidden": "on", - "authgroup-0-group": f"{group.pk}", - "authgroup-__prefix__-description": "", - "authgroup-__prefix__-internal": "on", - "authgroup-__prefix__-hidden": "on", - "authgroup-__prefix__-group": f"{group.pk}", - "_save": "Save" + "authgroup-0-group": group.pk, } ) # then @@ -644,6 +639,85 @@ class TestGroupAdmin2(TestCase): self.assertIn(group, user_member.groups.all()) self.assertNotIn(group, user_guest.groups.all()) + def test_should_add_user_to_existing_group(self): + # given + user_bruce = AuthUtils.create_user("Bruce Wayne") + user_lex = AuthUtils.create_user("Lex Luthor") + group = Group.objects.create(name="dummy") + user_bruce.groups.add(group) + self.client.force_login(self.superuser) + # when + response = self.client.post( + f"/admin/groupmanagement/group/{group.pk}/change/", + data={ + "name": group.name, + "users": [user_bruce.pk, user_lex.pk], + "authgroup-TOTAL_FORMS": 1, + "authgroup-INITIAL_FORMS": 1, + "authgroup-MIN_NUM_FORMS": 0, + "authgroup-MAX_NUM_FORMS": 1, + "authgroup-0-internal": "on", + "authgroup-0-hidden": "on", + "authgroup-0-group": group.pk, + } + ) + # then + self.assertEqual(response.status_code, 302) + self.assertEqual(response.url, "/admin/groupmanagement/group/") + self.assertIn(group, user_bruce.groups.all()) + self.assertIn(group, user_lex.groups.all()) + + def test_should_remove_user_from_existing_group(self): + # given + user_bruce = AuthUtils.create_user("Bruce Wayne") + user_lex = AuthUtils.create_user("Lex Luthor") + group = Group.objects.create(name="dummy") + user_bruce.groups.add(group) + user_lex.groups.add(group) + self.client.force_login(self.superuser) + # when + response = self.client.post( + f"/admin/groupmanagement/group/{group.pk}/change/", + data={ + "name": group.name, + "users": user_bruce.pk, + "authgroup-TOTAL_FORMS": 1, + "authgroup-INITIAL_FORMS": 1, + "authgroup-MIN_NUM_FORMS": 0, + "authgroup-MAX_NUM_FORMS": 1, + "authgroup-0-internal": "on", + "authgroup-0-hidden": "on", + "authgroup-0-group": group.pk, + } + ) + # then + self.assertEqual(response.status_code, 302) + self.assertEqual(response.url, "/admin/groupmanagement/group/") + self.assertIn(group, user_bruce.groups.all()) + self.assertNotIn(group, user_lex.groups.all()) + + def test_should_include_user_when_creating_group(self): + # given + user_bruce = AuthUtils.create_user("Bruce Wayne") + self.client.force_login(self.superuser) + # when + response = self.client.post( + "/admin/groupmanagement/group/add/", + data={ + "name": "new group", + "users": user_bruce.pk, + "authgroup-TOTAL_FORMS": 1, + "authgroup-INITIAL_FORMS": 0, + "authgroup-MIN_NUM_FORMS": 0, + "authgroup-MAX_NUM_FORMS": 1, + } + ) + # then + self.assertEqual(response.status_code, 302) + self.assertEqual(response.url, "/admin/groupmanagement/group/") + group = Group.objects.get(name="new group") + self.assertIn(group, user_bruce.groups.all()) + class TestReservedGroupNameAdmin(TestCase): @classmethod From e5d29629a5763ce08dfb97fe5648566b2a197814 Mon Sep 17 00:00:00 2001 From: Ariel Rin Date: Wed, 8 Nov 2023 13:48:26 +0000 Subject: [PATCH 6/8] Update from Transifex --- .tx/config | 2 +- .tx/config_20230406134150.bak | 10 - .tx/transifex.yml | 10 + allianceauth/locale/de/LC_MESSAGES/django.po | 171 ++--- allianceauth/locale/es/LC_MESSAGES/django.po | 10 +- .../locale/fr_FR/LC_MESSAGES/django.po | 18 +- .../locale/it_IT/LC_MESSAGES/django.po | 583 ++++++++++-------- allianceauth/locale/ja/LC_MESSAGES/django.po | 7 +- .../locale/ko_KR/LC_MESSAGES/django.po | 18 +- allianceauth/locale/ru/LC_MESSAGES/django.po | 8 +- allianceauth/locale/uk/LC_MESSAGES/django.po | 60 +- .../locale/zh_Hans/LC_MESSAGES/django.po | 55 +- 12 files changed, 500 insertions(+), 452 deletions(-) delete mode 100644 .tx/config_20230406134150.bak create mode 100644 .tx/transifex.yml diff --git a/.tx/config b/.tx/config index 102c800f..6a041df7 100644 --- a/.tx/config +++ b/.tx/config @@ -1,5 +1,5 @@ [main] -host = https://www.transifex.com +host = https://app.transifex.com lang_map = zh-Hans: zh_Hans [o:alliance-auth:p:alliance-auth:r:django-po] diff --git a/.tx/config_20230406134150.bak b/.tx/config_20230406134150.bak deleted file mode 100644 index b3c32185..00000000 --- a/.tx/config_20230406134150.bak +++ /dev/null @@ -1,10 +0,0 @@ -[main] -host = https://www.transifex.com -lang_map = zh-Hans:zh_Hans - -[alliance-auth.django-po] -file_filter = allianceauth/locale//LC_MESSAGES/django.po -minimum_perc = 0 -source_file = allianceauth/locale/en/LC_MESSAGES/django.po -source_lang = en -type = PO diff --git a/.tx/transifex.yml b/.tx/transifex.yml new file mode 100644 index 00000000..26a515d5 --- /dev/null +++ b/.tx/transifex.yml @@ -0,0 +1,10 @@ +filters: + - filter_type: file + file_format: PO + source_file: allianceauth/locale/en/LC_MESSAGES/django.po + source_language: en + translation_files_expression: allianceauth/locale//LC_MESSAGES/django.po + +settings: + language_mapping: + zh-Hans: zh_Hans diff --git a/allianceauth/locale/de/LC_MESSAGES/django.po b/allianceauth/locale/de/LC_MESSAGES/django.po index 9dfe0130..edf00a0b 100644 --- a/allianceauth/locale/de/LC_MESSAGES/django.po +++ b/allianceauth/locale/de/LC_MESSAGES/django.po @@ -4,9 +4,9 @@ # FIRST AUTHOR , YEAR. # # Translators: -# Erik Kalkoken , 2020 -# Joel Falknau , 2021 -# Peter Pfeufer, 2022 +# Erik Kalkoken , 2023 +# Joel Falknau , 2023 +# Peter Pfeufer, 2023 # #, fuzzy msgid "" @@ -14,8 +14,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \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, 2022\n" +"PO-Revision-Date: 2023-10-08 09:23+0000\n" +"Last-Translator: Peter Pfeufer, 2023\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" @@ -34,7 +34,8 @@ msgstr "Google Analytics V4" #: allianceauth/authentication/decorators.py:37 msgid "A main character is required to perform that action. Add one below." msgstr "" -"Für diese Aktion wird ein Hauptcharacter benötigt. Bitte füge einen hinzu." +"Zur Ausführung dieser Aktion ist ein Hauptcharakter erforderlich. Füge unten" +" einen hinzu." #: allianceauth/authentication/forms.py:12 msgid "Email" @@ -131,7 +132,7 @@ msgstr "Hauptcharakter ändern" #: allianceauth/authentication/templates/authentication/dashboard.html:125 msgid "Group Memberships" -msgstr "Gruppen" +msgstr "Gruppenmitgliedschaften" #: allianceauth/authentication/templates/authentication/dashboard.html:145 #: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticscorpview.html:21 @@ -206,7 +207,7 @@ msgstr "" #: allianceauth/authentication/views.py:83 #, python-format msgid "Changed main character to %(char)s" -msgstr "Haupcharakter geändert zu %(char)s" +msgstr "Haupcharakter zu %(char)s geändert" #: allianceauth/authentication/views.py:92 #, python-format @@ -233,13 +234,12 @@ msgid "" "Sent confirmation email. Please follow the link to confirm your email " "address." msgstr "" -"Bestätigungsmail gesendet. Bitte folge dem Link in der E-Mail zur " -"Bestätigung." +"Bestätigungs-E-Mail gesendet. Bitte folge dem Link, um Deine E-Mail-Adresse " +"zu bestätigen." #: allianceauth/authentication/views.py:257 msgid "Confirmed your email address. Please login to continue." -msgstr "" -"Deine E-Mail Adresse wurde bestätigt. Bitte log Dich ein um fortzufahren." +msgstr "Deine E-Mail Adresse wurde bestätigt. Bitte einloggen zum Fortfahren." #: allianceauth/authentication/views.py:262 msgid "Registration of new accounts is not allowed at this time." @@ -274,7 +274,7 @@ msgstr "Hauptcharaktere" #: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticsview.html:22 #: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:14 msgid "Members" -msgstr "Mitgliederzahl" +msgstr "Mitglieder" #: allianceauth/corputils/templates/corputils/corpstats.html:35 msgid "Unregistered" @@ -282,7 +282,7 @@ msgstr "Nicht registriert" #: allianceauth/corputils/templates/corputils/corpstats.html:38 msgid "Last update:" -msgstr "Letzes Update:" +msgstr "Letzte Aktualisierung:" #: allianceauth/corputils/templates/corputils/corpstats.html:74 #: allianceauth/corputils/templates/corputils/corpstats.html:112 @@ -382,11 +382,11 @@ msgstr "Charakter nicht registriert!" #: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/characternotexisting.html:19 msgid "This character is not associated with an auth account." -msgstr "Dieser Charakter ist mit keinen Auth Konto verbunden." +msgstr "Dieser Charakter ist keinem Auth Konto zugeordnet." #: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/characternotexisting.html:19 msgid "Add it here" -msgstr "Füge es hier hinzu" +msgstr "Füge ihn hier hinzu" #: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/characternotexisting.html:19 msgid "before attempting to click fleet attendance links." @@ -394,7 +394,7 @@ msgstr "bevor Du versuchst auf FAT-Links zu klicken." #: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkformatter.html:5 msgid "Create Fatlink" -msgstr "Erstelle FAT-Link" +msgstr "FAT-Link erstellen" #: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkformatter.html:9 #: allianceauth/optimer/templates/optimer/add.html:13 @@ -409,20 +409,20 @@ msgstr "Fehlerhafte Anfrage!" #: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkformatter.html:24 #: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:63 msgid "Create fatlink" -msgstr "Erstelle FAT-Link" +msgstr "FAT-Link erstellen" #: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html:3 #: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:4 msgid "Fatlink view" -msgstr "FAT-Link sehen" +msgstr "FAT-Link ansehen" #: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html:7 msgid "Edit fatlink" -msgstr "Editiere FAT-Link" +msgstr "FAT-Link bearbeiten" #: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html:11 msgid "Delete fat" -msgstr "Lösche FAT" +msgstr "FAT löschen" #: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html:17 msgid "Registered characters" @@ -497,7 +497,7 @@ msgstr[1] "%(user)s hat diesen Monat %(links)s FAT-Links eingesammelt." #: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkpersonalmonthlystatisticsview.html:26 msgid "Times used" -msgstr "male genutzt" +msgstr "Wie oft genutzt" #: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkpersonalmonthlystatisticsview.html:37 #, python-format @@ -570,7 +570,7 @@ msgstr "FAT-Link Statistik" #: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticsview.html:20 msgid "Ticker" -msgstr "Ticker: " +msgstr "Ticker" #: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:8 msgid "Participation data" @@ -594,7 +594,7 @@ msgstr "Letzter FAT-Link" #: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:58 msgid "View statistics" -msgstr "Statistik" +msgstr "Statistiken ansehen" #: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:95 msgid "No created fatlinks on record." @@ -713,8 +713,8 @@ msgid "" "States listed here will have the ability to join this group provided they " "have the proper permissions.
    " msgstr "" -"Hier gelistete Ränge können dieser Gruppe beitreten, vorausgesetzt sie haben" -" die entsprechenden Berechtigungen.
    " +"Die hier aufgeführten Status können dieser Gruppe beitreten, sofern sie über" +" die entsprechenden Berechtigungen verfügen.
    " #: allianceauth/groupmanagement/models.py:171 msgid "" @@ -814,7 +814,7 @@ msgstr "Gruppenmitglieder" #: allianceauth/groupmanagement/templates/groupmanagement/index.html:113 #: allianceauth/permissions_tool/templates/permissions_tool/audit.html:21 msgid "Organization" -msgstr "Organization" +msgstr "Organisation" #: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:49 #: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:75 @@ -933,18 +933,18 @@ msgstr "Gruppenverwaltung" #: allianceauth/groupmanagement/templates/groupmanagement/index.html:24 msgid "Join Requests" -msgstr "Beitrittsgesuche" +msgstr "Beitrittsanfragen" #: allianceauth/groupmanagement/templates/groupmanagement/index.html:35 msgid "Leave Requests" -msgstr "Austrittsgesuche" +msgstr "Austrittsanfragen" #: allianceauth/groupmanagement/templates/groupmanagement/index.html:57 #: allianceauth/groupmanagement/templates/groupmanagement/index.html:114 #: allianceauth/permissions_tool/templates/permissions_tool/audit.html:18 #: allianceauth/services/modules/openfire/forms.py:6 msgid "Group" -msgstr "Gruppen" +msgstr "Gruppe" #: allianceauth/groupmanagement/templates/groupmanagement/index.html:88 #: allianceauth/groupmanagement/templates/groupmanagement/index.html:145 @@ -968,7 +968,7 @@ msgstr "Keine Gruppenaustrittsanfragen" #: allianceauth/groupmanagement/templates/groupmanagement/menu.html:8 #: allianceauth/templates/allianceauth/top-menu.html:8 msgid "Toggle navigation" -msgstr "Toggle Navigation" +msgstr "Navigation umschalten" #: allianceauth/groupmanagement/templates/groupmanagement/menu.html:19 msgid "Group Requests" @@ -994,7 +994,7 @@ msgstr "Gruppe existiert nicht" #: allianceauth/groupmanagement/views.py:195 #, python-format msgid "Accepted application from %(mainchar)s to %(group)s." -msgstr "Beitrittsgesuch von %(mainchar)s zur Gruppe %(group)s zugestimmt." +msgstr "Beitrittsanfrage von %(mainchar)s zur Gruppe %(group)s akzeptiert." #: allianceauth/groupmanagement/views.py:201 #: allianceauth/groupmanagement/views.py:232 @@ -1003,18 +1003,18 @@ msgid "" "An unhandled error occurred while processing the application from " "%(mainchar)s to %(group)s." msgstr "" -"Bei der Bearbeitung des Beitrittsgesuchs von %(mainchar)s zur Gruppe " +"Bei der Bearbeitung des Beitrittsanfrage von %(mainchar)s zur Gruppe " "%(group)s ist ein unbehandelter Fehler aufgetreten." #: allianceauth/groupmanagement/views.py:226 #, python-format msgid "Rejected application from %(mainchar)s to %(group)s." -msgstr "Beitrittsgesuch von %(mainchar)s zur Gruppe %(group)s abgelehnt." +msgstr "Beitrittsanfrage von %(mainchar)s zur Gruppe %(group)s abgelehnt." #: allianceauth/groupmanagement/views.py:261 #, python-format msgid "Accepted application from %(mainchar)s to leave %(group)s." -msgstr "Austrittsgesuch von %(mainchar)s für Gruppe %(group)s akzeptiert." +msgstr "Austrittsanfrage von %(mainchar)s für Gruppe %(group)s akzeptiert." #: allianceauth/groupmanagement/views.py:266 #: allianceauth/groupmanagement/views.py:298 @@ -1023,13 +1023,13 @@ msgid "" "An unhandled error occurred while processing the application from " "%(mainchar)s to leave %(group)s." msgstr "" -"Bei der Bearbeitung des Austrittsgesuchs von %(mainchar)s für Gruppe " +"Bei der Bearbeitung des Austrittsanfrage von %(mainchar)s für Gruppe " "%(group)s ist ein unbehandelter Fehler aufgetreten." #: allianceauth/groupmanagement/views.py:292 #, python-format msgid "Rejected application from %(mainchar)s to leave %(group)s." -msgstr "Austrittsgesuch von %(mainchar)s für Gruppe %(group)s abgelehnt." +msgstr "Austrittsanfrage von %(mainchar)s für Gruppe %(group)s abgelehnt." #: allianceauth/groupmanagement/views.py:336 #: allianceauth/groupmanagement/views.py:346 @@ -1042,7 +1042,7 @@ msgstr "Du bist bereits Mitglied dieser Gruppe." #: allianceauth/groupmanagement/views.py:358 msgid "You already have a pending application for that group." -msgstr "Du hast Dich bereits für diese Gruppe beworben." +msgstr "Du hast bereits für diese Gruppe angefragt." #: allianceauth/groupmanagement/views.py:367 #, python-format @@ -1059,12 +1059,12 @@ msgstr "Du bist kein Mitglied dieser Gruppe" #: allianceauth/groupmanagement/views.py:393 msgid "You already have a pending leave request for that group." -msgstr "Du hast bereits ein ausstehendes Austrittsgesuch für diese Gruppe." +msgstr "Du hast bereits eine ausstehendes Austrittsanfrage für diese Gruppe." #: allianceauth/groupmanagement/views.py:409 #, python-format msgid "Applied to leave group %(group)s." -msgstr "Austrittsgesuch für Gruppe %(group)s gesendet." +msgstr "Austrittsanfrage für Gruppe %(group)s gesendet." #: allianceauth/hrapplications/auth_hooks.py:14 msgid "Applications" @@ -1086,11 +1086,11 @@ msgstr "Wähle eine Corporation" #: allianceauth/hrapplications/templates/hrapplications/corpchoice.html:10 msgid "Available Corps" -msgstr "Zur Auswahl stehende Corporations" +msgstr "Verfügbare Corporationen" #: allianceauth/hrapplications/templates/hrapplications/corpchoice.html:22 msgid "No corps are accepting applications at this time." -msgstr "Zur Zeit nimmt keine Corp Bewerbungen entgegen." +msgstr "Zur Zeit nimmt keine Corp Bewerbungen an." #: allianceauth/hrapplications/templates/hrapplications/create.html:4 #: allianceauth/hrapplications/templates/hrapplications/create.html:7 @@ -1186,7 +1186,7 @@ msgstr "Keine angesehenen Bewerbungen" #: allianceauth/hrapplications/templates/hrapplications/searchview.html:62 #: allianceauth/hrapplications/templates/hrapplications/view.html:134 msgid "Close" -msgstr "Geschlossen" +msgstr "Schließen" #: allianceauth/hrapplications/templates/hrapplications/management.html:177 #: allianceauth/hrapplications/templates/hrapplications/searchview.html:63 @@ -1200,7 +1200,7 @@ msgstr "Suche" #: allianceauth/hrapplications/templates/hrapplications/searchview.html:11 msgid "Application Search Results" -msgstr "Bewerbungen Suchergebnisse" +msgstr "Ergebnisse der Bewerbungssuche" #: allianceauth/hrapplications/templates/hrapplications/searchview.html:22 msgid "Application ID" @@ -1342,12 +1342,12 @@ msgstr "Operationsart" #: allianceauth/optimer/form.py:17 #: allianceauth/srp/templates/srp/management.html:38 msgid "Fleet Commander" -msgstr "Flottenkommandeur" +msgstr "Flottenkommandant" #: allianceauth/optimer/form.py:22 allianceauth/srp/form.py:14 #: allianceauth/srp/templates/srp/data.html:91 msgid "Additional Info" -msgstr "Zusätzliche Info" +msgstr "Zusätzliche Informationen" #: allianceauth/optimer/form.py:23 msgid "(Optional) Describe the operation with a couple of short words." @@ -1360,7 +1360,7 @@ msgstr "Operation erstellen" #: allianceauth/optimer/templates/optimer/fleetoptable.html:12 msgid "Form Up System" -msgstr "Form Up System" +msgstr "Startsystem" #: allianceauth/optimer/templates/optimer/fleetoptable.html:14 #: allianceauth/timerboard/templates/timerboard/view.html:36 @@ -1384,20 +1384,20 @@ msgstr "Flottenoperationen Zeiten" #: allianceauth/optimer/templates/optimer/management.html:20 #: allianceauth/timerboard/templates/timerboard/view.html:22 msgid "Current Eve Time:" -msgstr "Momentane Eve Zeit" +msgstr "Aktuelle Eve Zeit" #: allianceauth/optimer/templates/optimer/management.html:26 msgid "Next Fleet Operations" -msgstr "Anstehende Flottenoperationen" +msgstr "Anstehende Flotten" #: allianceauth/optimer/templates/optimer/management.html:30 #: allianceauth/timerboard/templates/timerboard/view.html:362 msgid "No upcoming timers." -msgstr "Keine kommenden Timer." +msgstr "Keine bevorstehenden Timer." #: allianceauth/optimer/templates/optimer/management.html:33 msgid "Past Fleet Operations" -msgstr "Vergangene Flottenoperationen" +msgstr "Vergangene Flotten" #: allianceauth/optimer/templates/optimer/management.html:37 #: allianceauth/timerboard/templates/timerboard/view.html:535 @@ -1408,7 +1408,7 @@ msgstr "Keine vergangenen Timer." #: allianceauth/optimer/templates/optimer/update.html:15 #: allianceauth/optimer/templates/optimer/update.html:27 msgid "Update Fleet Operation" -msgstr "Aktualisiere Flottenoperationen" +msgstr "Aktualisiere Flottenoperation" #: allianceauth/optimer/templates/optimer/update.html:21 msgid "Fleet Operation Does Not Exist" @@ -1432,7 +1432,7 @@ msgstr "Änderungen für Operation timer %(opname)s gespeichert." #: allianceauth/permissions_tool/templates/permissions_tool/audit.html:4 #: allianceauth/permissions_tool/templates/permissions_tool/audit.html:8 msgid "Permissions Audit" -msgstr "Berechtigungsübersicht" +msgstr "Berechtigungsprüfung" #: allianceauth/permissions_tool/templates/permissions_tool/audit.html:20 msgid "User / Character" @@ -1494,11 +1494,11 @@ msgstr "Dienste" #: allianceauth/services/forms.py:6 msgid "Name of Fleet:" -msgstr "SRP Flotte erstellen:" +msgstr "Name der Flotte:" #: allianceauth/services/forms.py:7 msgid "Fleet Commander:" -msgstr "Flottenkommandeur:" +msgstr "Flottenkommandant:" #: allianceauth/services/forms.py:8 msgid "Fleet Comms:" @@ -1514,11 +1514,11 @@ msgstr "Schiffspriorität:" #: allianceauth/services/forms.py:11 msgid "Formup Location:" -msgstr "Formup Location:" +msgstr "Startsystem:" #: allianceauth/services/forms.py:12 msgid "Formup Time:" -msgstr "Formup Zeit:" +msgstr "Startzeit:" #: allianceauth/services/forms.py:13 msgid "Expected Duration:" @@ -1530,7 +1530,7 @@ msgstr "Grund:" #: allianceauth/services/forms.py:15 msgid "Reimbursable?*" -msgstr "Erstattungsfähig?" +msgstr "Erstattungsfähig?*" #: allianceauth/services/forms.py:15 allianceauth/services/forms.py:16 msgid "Yes" @@ -1542,7 +1542,7 @@ msgstr "Nein" #: allianceauth/services/forms.py:16 msgid "Important?*" -msgstr "Wichtig?" +msgstr "Wichtig?*" #: allianceauth/services/forms.py:21 allianceauth/services/forms.py:31 msgid "Password" @@ -1550,7 +1550,7 @@ msgstr "Passwort" #: allianceauth/services/forms.py:26 allianceauth/services/forms.py:36 msgid "Password must be at least 8 characters long." -msgstr "Passwort muss mindestens 8 Zeichen lang sein" +msgstr "Das Passwort muss mindestens 8 Zeichen lang sein" #: allianceauth/services/modules/discord/models.py:187 msgid "Discord Account Disabled" @@ -1591,7 +1591,7 @@ msgstr "Discord Konto deaktiviert." #: allianceauth/services/modules/discord/views.py:36 #: allianceauth/services/modules/discord/views.py:59 msgid "An error occurred while processing your Discord account." -msgstr "Es gab einen Fehler bei der Verarbeitung Deines Discord Kontos." +msgstr "Es gab einen Fehler während der Verarbeitung Deines Discord Kontos." #: allianceauth/services/modules/discord/views.py:102 msgid "Your Discord account has been successfully activated." @@ -1607,7 +1607,7 @@ msgstr "" #: allianceauth/services/modules/discourse/views.py:29 msgid "You are not authorized to access Discourse." -msgstr "Du bist nicht autorisiert auf Discorse zuzugreifen." +msgstr "Du bist nicht autorisiert auf Discourse zuzugreifen." #: allianceauth/services/modules/discourse/views.py:34 msgid "You must have a main character set to access Discourse." @@ -1619,14 +1619,14 @@ msgid "" "No SSO payload or signature. Please contact support if this problem " "persists." msgstr "" -"Keine SSO-Nutzdaten oder Signaturen. Bitte wenden Sie sich an den Support, " -"wenn das Problem weiterhin besteht." +"Keine SSO-Nutzdaten oder Signaturen. Bitte wende Dich an den Support, wenn " +"das Problem weiterhin besteht." #: 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 "" -"Ungültige Nutzdaten. Bitte wenden Sie sich an den Support, wenn das Problem " +"Ungültige Nutzdaten. Bitte wenden Dich an den Support, wenn das Problem " "weiterhin besteht." #: allianceauth/services/modules/ips4/views.py:31 @@ -1638,7 +1638,7 @@ msgstr "IP4Suite Konto aktiviert." #: allianceauth/services/modules/ips4/views.py:81 #: allianceauth/services/modules/ips4/views.py:101 msgid "An error occurred while processing your IPSuite4 account." -msgstr "Es gab einen Fehler bei der Verarbeitung Deines IPSuite4 Kontos." +msgstr "Es gab einen Fehler während der Verarbeitung Deines IPSuite4 Kontos." #: allianceauth/services/modules/ips4/views.py:52 msgid "Reset IPSuite4 password." @@ -1660,7 +1660,7 @@ msgstr "Jabber" #: allianceauth/services/modules/openfire/templates/services/openfire/broadcast.html:5 #: allianceauth/services/modules/openfire/templates/services/openfire/broadcast.html:10 msgid "Jabber Broadcast" -msgstr "Jabber Übertragung" +msgstr "Jabber Ankündigung" #: allianceauth/services/modules/openfire/auth_hooks.py:94 msgid "Fleet Broadcast Formatter" @@ -1672,11 +1672,11 @@ msgstr "Nachricht" #: allianceauth/services/modules/openfire/templates/services/openfire/broadcast.html:16 msgid "Broadcast Sent!!" -msgstr "Übertragung gesendet!!" +msgstr "Ankündigung gesendet!!" #: allianceauth/services/modules/openfire/templates/services/openfire/broadcast.html:22 msgid "Broadcast" -msgstr "Übertragungen" +msgstr "Ankündigung" #: allianceauth/services/modules/openfire/views.py:35 msgid "Activated jabber account." @@ -1687,7 +1687,7 @@ msgstr "Jabber Konto aktiviert." #: allianceauth/services/modules/openfire/views.py:76 #: allianceauth/services/modules/openfire/views.py:147 msgid "An error occurred while processing your jabber account." -msgstr "Es gab einen Fehler bei der Verarbeitung Deines Jabber Kontos." +msgstr "Es gab einen Fehler während der Verarbeitung Deines Jabber Kontos." #: allianceauth/services/modules/openfire/views.py:69 msgid "Reset jabber password." @@ -1696,7 +1696,7 @@ msgstr "Jabber Passwort zurücksetzen." #: allianceauth/services/modules/openfire/views.py:115 #, python-format msgid "Sent jabber broadcast to %s" -msgstr "Sende Jabber Durchsage an %s" +msgstr "Sende Jabber Ankündigung an %s" #: allianceauth/services/modules/openfire/views.py:144 msgid "Set jabber password." @@ -1711,7 +1711,7 @@ msgstr "Forum Konto aktiviert." #: allianceauth/services/modules/phpbb3/views.py:78 #: allianceauth/services/modules/phpbb3/views.py:101 msgid "An error occurred while processing your forum account." -msgstr "Es gab einen Fehler bei der Verarbeitung Deines Forum Kontos." +msgstr "Es gab einen Fehler während der Verarbeitung Deines Forum Kontos." #: allianceauth/services/modules/phpbb3/views.py:53 msgid "Deactivated forum account." @@ -1734,7 +1734,7 @@ msgstr "SMF Konto aktiviert." #: allianceauth/services/modules/smf/views.py:102 #: allianceauth/services/modules/smf/views.py:124 msgid "An error occurred while processing your SMF account." -msgstr "Es gab einen Fehler bei der Verarbeitung Deines SMF Kontos." +msgstr "Es gab einen Fehler während der Verarbeitung Deines SMF Kontos." #: allianceauth/services/modules/smf/views.py:78 msgid "Deactivated SMF account." @@ -1751,7 +1751,7 @@ msgstr "Setze SMF Passwort." #: allianceauth/services/modules/teamspeak3/forms.py:14 #, python-format msgid "Unable to locate user %s on server" -msgstr "Kann den Benutzer %s auf dem Server nicht finden" +msgstr "Der Benutzer %s konnte auf dem Server nicht gefunden werden" #: allianceauth/services/modules/teamspeak3/templates/admin/teamspeak3/authts/change_list.html:8 msgid "Update TS3 groups" @@ -1783,7 +1783,8 @@ msgstr "TeamSpeak3 Konto aktiviert." #: allianceauth/services/modules/teamspeak3/views.py:74 #: allianceauth/services/modules/teamspeak3/views.py:100 msgid "An error occurred while processing your TeamSpeak3 account." -msgstr "Es gab einen Fehler bei der Verarbeitung Deines TeamSpeak3 Kontos." +msgstr "" +"Es gab einen Fehler während der Verarbeitung Deines TeamSpeak3 Kontos." #: allianceauth/services/modules/teamspeak3/views.py:71 msgid "Deactivated TeamSpeak3 account." @@ -1802,7 +1803,7 @@ msgstr "XenForo Konto aktiviert." #: allianceauth/services/modules/xenforo/views.py:73 #: allianceauth/services/modules/xenforo/views.py:94 msgid "An error occurred while processing your XenForo account." -msgstr "Es gab einen Fehler bei der Verarbeitung Deines XenForo Kontos." +msgstr "Es gab einen Fehler während der Verarbeitung Deines XenForo Kontos." #: allianceauth/services/modules/xenforo/views.py:50 msgid "Deactivated XenForo account." @@ -1832,7 +1833,7 @@ msgstr "Formatieren" #: allianceauth/services/templates/services/service_confirm_delete.html:12 #, python-format msgid "Delete %(service_name)s Account?" -msgstr "Konto %(service_name)s löschen?" +msgstr " %(service_name)s Konto löschen?" #: allianceauth/services/templates/services/service_confirm_delete.html:20 #, python-format @@ -1856,7 +1857,7 @@ msgstr "%(service_name)s Passwort ändern" #: allianceauth/services/templates/services/service_password.html:9 #, python-format msgid "Set %(service_name)s Password" -msgstr "%(service_name)s Passwort" +msgstr "%(service_name)s Passwort setzen" #: allianceauth/services/templates/services/service_password.html:17 msgid "Set Password" @@ -1927,7 +1928,7 @@ msgstr "SRP Flotten Daten" #: allianceauth/srp/templates/srp/data.html:50 msgid "SRP Fleet Data" -msgstr "SRP-Flotte Daten" +msgstr "SRP Flotte Daten" #: allianceauth/srp/templates/srp/data.html:55 msgid "Mark Incomplete" @@ -2005,7 +2006,7 @@ msgstr "Füge SRP Flotte hinzu" #: allianceauth/srp/templates/srp/management.html:39 msgid "Fleet AAR" -msgstr "Flotten AAR" +msgstr "Flottenbericht" #: allianceauth/srp/templates/srp/management.html:40 msgid "Fleet SRP Code" @@ -2033,7 +2034,7 @@ msgstr "Deaktiviert" #: allianceauth/srp/templates/srp/management.html:83 msgid "Completed" -msgstr "Fertig" +msgstr "Abgeschlossen" #: allianceauth/srp/templates/srp/management.html:101 msgid "Are you sure you want to delete this SRP code and its contents?" @@ -2086,7 +2087,7 @@ msgstr "SRP Link für %(fleetname)s aktiviert." #: allianceauth/srp/views.py:140 #, python-format msgid "Marked SRP fleet %(fleetname)s as completed." -msgstr "SRP Flotte %(fleetname)s als vollständig markiert." +msgstr "SRP Flotte %(fleetname)s als abgeschlossen markiert." #: allianceauth/srp/views.py:153 #, python-format @@ -2204,7 +2205,7 @@ msgstr "Testversion verfügbar" #: allianceauth/templates/allianceauth/admin-status/overview.html:78 msgid "Task Queue" -msgstr "Warteschlange" +msgstr "Task-Warteschlange" #: allianceauth/templates/allianceauth/admin-status/overview.html:81 #, python-format @@ -2249,7 +2250,7 @@ msgstr "Ausloggen" #: allianceauth/timerboard/form.py:53 msgid "Other" -msgstr "anderes" +msgstr "Anderes" #: allianceauth/timerboard/form.py:54 #: allianceauth/timerboard/templates/timerboard/view.html:62 @@ -2353,7 +2354,7 @@ msgstr "Timer löschen" #: allianceauth/timerboard/templates/timerboard/timer_confirm_delete.html:19 #, python-format msgid "Are you sure you want to delete timer \"%(object)s\"?" -msgstr "Bist Du sicher das Du Timer \"%(object)s\" löschen möchtest?" +msgstr "Bist Du sicher das Du Timer „%(object)s“ löschen möchtest?" #: allianceauth/timerboard/templates/timerboard/timer_create_form.html:5 #: allianceauth/timerboard/templates/timerboard/timer_create_form.html:13 diff --git a/allianceauth/locale/es/LC_MESSAGES/django.po b/allianceauth/locale/es/LC_MESSAGES/django.po index 27a35480..1facc81a 100644 --- a/allianceauth/locale/es/LC_MESSAGES/django.po +++ b/allianceauth/locale/es/LC_MESSAGES/django.po @@ -4,11 +4,11 @@ # FIRST AUTHOR , YEAR. # # Translators: -# frank1210 , 2021 -# Joel Falknau , 2021 -# Young Anexo, 2023 # Fegpawn Kaundur, 2023 +# frank1210 , 2023 # trenus, 2023 +# Joel Falknau , 2023 +# Young Anexo, 2023 # #, fuzzy msgid "" @@ -16,8 +16,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-10-09 18:20+1000\n" -"PO-Revision-Date: 2020-02-18 03:14+0000\n" -"Last-Translator: trenus, 2023\n" +"PO-Revision-Date: 2023-10-08 09:23+0000\n" +"Last-Translator: Young Anexo, 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" diff --git a/allianceauth/locale/fr_FR/LC_MESSAGES/django.po b/allianceauth/locale/fr_FR/LC_MESSAGES/django.po index 6867b96a..7e5156ec 100644 --- a/allianceauth/locale/fr_FR/LC_MESSAGES/django.po +++ b/allianceauth/locale/fr_FR/LC_MESSAGES/django.po @@ -4,14 +4,14 @@ # FIRST AUTHOR , YEAR. # # Translators: -# François LACROIX-DURANT , 2020 -# Philippe Querin-Laporte , 2020 -# Keven D. , 2020 -# Idea ., 2021 -# Mickael PATTE, 2021 -# Geoffrey Fabbro, 2021 +# Keven D. , 2023 +# rockclodbuster, 2023 +# Geoffrey Fabbro, 2023 # Mohssine Daghghar, 2023 -# Ludovick Fortin, 2023 +# François LACROIX-DURANT , 2023 +# Mickael PATTE, 2023 +# Philippe Querin-Laporte , 2023 +# Idea ., 2023 # #, fuzzy msgid "" @@ -19,8 +19,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-10-09 18:20+1000\n" -"PO-Revision-Date: 2020-02-18 03:14+0000\n" -"Last-Translator: Ludovick Fortin, 2023\n" +"PO-Revision-Date: 2023-10-08 09:23+0000\n" +"Last-Translator: Idea ., 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" diff --git a/allianceauth/locale/it_IT/LC_MESSAGES/django.po b/allianceauth/locale/it_IT/LC_MESSAGES/django.po index c8eb9841..f12e7cb6 100644 --- a/allianceauth/locale/it_IT/LC_MESSAGES/django.po +++ b/allianceauth/locale/it_IT/LC_MESSAGES/django.po @@ -4,7 +4,7 @@ # FIRST AUTHOR , YEAR. # # Translators: -# Alessandro Cresti, 2021 +# Alessandro Cresti, 2023 # Linus Hope, 2023 # #, fuzzy @@ -13,7 +13,7 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-10-09 18:20+1000\n" -"PO-Revision-Date: 2020-02-18 03:14+0000\n" +"PO-Revision-Date: 2023-10-08 09:23+0000\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" @@ -119,7 +119,7 @@ msgstr "" #: allianceauth/authentication/templates/authentication/dashboard.html:101 msgid "No main character set." -msgstr "Nessun personaggio principale impostato" +msgstr "Nessun personaggio principale impostato." #: allianceauth/authentication/templates/authentication/dashboard.html:109 msgid "Add Character" @@ -185,7 +185,7 @@ msgstr "Gestisci applicazioni ESI" #: allianceauth/authentication/templates/public/register.html:6 msgid "Registration" -msgstr "Iscriviti" +msgstr "Registrazione" #: allianceauth/authentication/templates/public/register.html:21 msgid "Register" @@ -223,18 +223,18 @@ msgstr "" #: allianceauth/authentication/views.py:133 msgid "Unable to authenticate as the selected character." -msgstr "Impossibile autenticarsi con il personaggio selezioanto." +msgstr "Impossibile autenticarsi con il personaggio selezionato." #: allianceauth/authentication/views.py:197 msgid "Registration token has expired." -msgstr "L'invito per registrarsi è scaduto." +msgstr "Il token di registrazione è scaduto." #: allianceauth/authentication/views.py:252 msgid "" "Sent confirmation email. Please follow the link to confirm your email " "address." msgstr "" -"Un messaggio di conferma è stato inviato. Per favore, utilizza il link per " +"Una e-mail di conferma è stata inviata. Per favore, utilizza il link per " "confermare il tuo indirizzo di posta elettronica." #: allianceauth/authentication/views.py:257 @@ -352,7 +352,8 @@ msgstr "La corporazione selezionata dispone già di un modulo statistiche." #: allianceauth/corputils/views.py:56 msgid "Failed to gather corporation statistics with selected token." msgstr "" -"Impossibile raccogliere informazioni sulla corporazione con questo codice." +"Raccolta di statistiche della corpoazione non riuscita con il token " +"selezionato." #: allianceauth/fleetactivitytracking/auth_hooks.py:9 msgid "Fleet Activity Tracking" @@ -403,7 +404,7 @@ msgstr "Crea Fatlink" #: allianceauth/optimer/templates/optimer/add.html:13 #: allianceauth/optimer/templates/optimer/add.html:22 msgid "Create Fleet Operation" -msgstr "Crea Fleet Operation" +msgstr "Crea operazione di flotta" #: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkformatter.html:13 msgid "Bad request!" @@ -575,7 +576,7 @@ msgstr "Statistiche fatlink" #: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticsview.html:20 msgid "Ticker" -msgstr "" +msgstr "Ticker" #: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:8 msgid "Participation data" @@ -583,7 +584,9 @@ msgstr "Statistiche di partecipazione" #: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:12 msgid "Most recent clicked fatlinks" -msgstr "Fatlink più recentemente selezionati" +msgstr "" +"Fatlink selezionati più di recente\n" +" " #: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:17 msgid "Personal statistics" @@ -654,8 +657,8 @@ msgid "" "etc.
    Overrides Hidden and Open options when selected." msgstr "" "Gruppo interno, gli utenti non possono vedere, unirsi o fare richiesta di " -"adesione a questo gruppo.
    Utilizzato per gruppi come Membri, Corpazioni," -" Alleanze, etc.
    Sovrascrive opzioni nascoste e aperte quando " +"adesione a questo.
    Utilizzato per gruppi come Membri, Corpazioni, " +"Alleanze, etc.
    Sovrascrive opzioni nascoste e aperte quando " "seleazionato." #: allianceauth/groupmanagement/models.py:113 @@ -670,7 +673,7 @@ msgid "" "group is not open users will need their request manually approved." msgstr "" "Il gruppo è aperto e gli utenti saranno automaticamente aggiunti a seguito " -"richiesta.
    Se il gruppo non è aperto gli utenti dovranno necessitare di " +"di richiesta.
    Se il gruppo non è aperto gli utenti necessiteranno di " "approvazione manuale." #: allianceauth/groupmanagement/models.py:126 @@ -680,12 +683,18 @@ msgid "" "remove users from this group automatically when they are no longer " "authenticated." msgstr "" +"Il gruppo è pubblico. Qualsiasi utente registrato può unirsi a questo " +"gruppo, con visibilità basata sulle altre opzioni impostate per questo " +"gruppo.
    Auth non rimuoverà automaticamente gli utenti da questo gruppo " +"quando non sono più autenticati." #: allianceauth/groupmanagement/models.py:135 msgid "" "Group is restricted. This means that adding or removing users for this group" " requires a superuser admin." msgstr "" +"Il gruppo è limitato. Ciò significa che l'aggiunta o la rimozione di utenti " +"per questo gruppo richiede un amministratore." #: allianceauth/groupmanagement/models.py:144 msgid "" @@ -693,6 +702,9 @@ msgid "" "auth.group_management permission to allow a user to manage all " "groups.
    " msgstr "" +"I leader del gruppo possono elaborare le richieste per questo gruppo. Usa " +"l'autorizzazione auth.group_management per consentire ad un " +"utente di gestire tutti i gruppi.
    " #: allianceauth/groupmanagement/models.py:154 msgid "" @@ -700,54 +712,61 @@ msgid "" "auth.group_management permission to allow a user to manage all " "groups.
    " msgstr "" +"I membri dei gruppi leader possono elaborare le richieste per questo gruppo." +" Usa l'autorizzazione auth.group_management per consentire ad " +"un utente di gestire tutti i gruppi.
    " #: allianceauth/groupmanagement/models.py:163 msgid "" "States listed here will have the ability to join this group provided they " "have the proper permissions.
    " msgstr "" +"Gli stati qui elencati avranno la possibilità di aderire a questo gruppo a " +"condizione che dispongano delle opportune autorizzazioni.
    " #: allianceauth/groupmanagement/models.py:171 msgid "" "Short description (max. 512 characters) of the group shown to users." msgstr "" +"Breve descrizione (max. 512 caratteri) del gruppo da mostrare agli " +"utenti." #: allianceauth/groupmanagement/models.py:178 msgid "Can request non-public groups" -msgstr "" +msgstr "Può fare richiesta a gruppi non pubblici" #: allianceauth/groupmanagement/models.py:209 msgid "name" -msgstr "" +msgstr "nome" #: allianceauth/groupmanagement/models.py:212 msgid "Name that can not be used for groups." -msgstr "" +msgstr "Il nome scelto non può essere utilizzato per gruppi." #: allianceauth/groupmanagement/models.py:215 msgid "reason" -msgstr "" +msgstr "ragione" #: allianceauth/groupmanagement/models.py:215 msgid "Reason why this name is reserved." -msgstr "" +msgstr "Ragione per la quale questo nome è riservato." #: allianceauth/groupmanagement/models.py:218 msgid "created by" -msgstr "" +msgstr "creato da" #: allianceauth/groupmanagement/models.py:223 msgid "created at" -msgstr "" +msgstr "creato il" #: allianceauth/groupmanagement/models.py:223 msgid "Date when this entry was created" -msgstr "" +msgstr "Data in cui è stata creata questa voce." #: allianceauth/groupmanagement/templates/groupmanagement/audit.html:4 #: allianceauth/groupmanagement/templates/groupmanagement/audit.html:13 msgid "Audit Log" -msgstr "" +msgstr "Registro di controllo" #: allianceauth/groupmanagement/templates/groupmanagement/audit.html:19 #: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:20 @@ -788,7 +807,7 @@ msgstr "Rimosso" #: allianceauth/groupmanagement/templates/groupmanagement/audit.html:60 msgid "All times displayed are EVE/UTC." -msgstr "Tutti gli orari visualizzati sono in riferimento al EVE/UTC" +msgstr "Tutti gli orari visualizzati sono riferiti a EVE/UTC" #: allianceauth/groupmanagement/templates/groupmanagement/audit.html:67 msgid "No entries found for this group." @@ -808,13 +827,13 @@ msgstr "Organizzazione" #: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:49 #: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:75 msgid "Group leader" -msgstr "" +msgstr "Responsabile del gruppo" #: 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 "(sconosciuto)" #: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:65 msgid "Remove from group" @@ -860,7 +879,7 @@ msgstr "Nascosto" #: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:44 #: allianceauth/templates/allianceauth/admin-status/overview.html:14 msgid "Open" -msgstr "Libero" +msgstr "Aperto" #: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:46 msgid "Requestable" @@ -902,7 +921,7 @@ msgstr "Abbandona" #: allianceauth/srp/templates/srp/data.html:135 #: allianceauth/srp/templates/srp/management.html:79 msgid "Pending" -msgstr "" +msgstr "In attesa" #: allianceauth/groupmanagement/templates/groupmanagement/groups.html:39 msgid "Join" @@ -914,7 +933,7 @@ msgstr "Richiedi" #: allianceauth/groupmanagement/templates/groupmanagement/groups.html:58 msgid "No groups available." -msgstr "Nessun gruppo disponibile" +msgstr "Nessun gruppo disponibile." #: allianceauth/groupmanagement/templates/groupmanagement/index.html:5 msgid "Groups Management" @@ -965,12 +984,12 @@ msgstr "Richieste" #: allianceauth/groupmanagement/templates/groupmanagement/menu.html:22 msgid "Group Membership" -msgstr "" +msgstr "Membri del gruppo" #: allianceauth/groupmanagement/views.py:163 #, python-format msgid "Removed user %(user)s from group %(group)s." -msgstr "Rimosso il membro %(user)s da %(group)s." +msgstr "Rimosso il membro %(user)s dal gruppo %(group)s." #: allianceauth/groupmanagement/views.py:165 msgid "User does not exist in that group" @@ -1014,7 +1033,7 @@ msgid "" "An unhandled error occurred while processing the application from " "%(mainchar)s to leave %(group)s." msgstr "" -"Si è verificato un’errore durante l’elaborazione della domanda di comgedo da" +"Si è verificato un’errore durante l’elaborazione della domanda di congedo da" " parte di %(mainchar)s per %(group)s." #: allianceauth/groupmanagement/views.py:292 @@ -1027,15 +1046,16 @@ msgstr "" #: allianceauth/groupmanagement/views.py:336 #: allianceauth/groupmanagement/views.py:346 msgid "You cannot join that group" -msgstr "Non puoi aderire a questo gruppo" +msgstr "Non puoi unirti a questo gruppo" #: allianceauth/groupmanagement/views.py:341 msgid "You are already a member of that group." -msgstr "Sei già parte del gruppo selezionato." +msgstr "Fai già parte del gruppo selezionato." #: allianceauth/groupmanagement/views.py:358 msgid "You already have a pending application for that group." -msgstr "La tua domanda per questo gruppo non è ancora stata valutata." +msgstr "" +"Hai già una candidatura in attesa di essere elaborata per questo gruppo" #: allianceauth/groupmanagement/views.py:367 #, python-format @@ -1052,7 +1072,7 @@ msgstr "Non sei un membro di questo gruppo." #: allianceauth/groupmanagement/views.py:393 msgid "You already have a pending leave request for that group." -msgstr "La tua domanda di congedo non è ancora stata valutata." +msgstr "Hai già una richiesta di congedo in sospeso per quel gruppo." #: allianceauth/groupmanagement/views.py:409 #, python-format @@ -1083,7 +1103,7 @@ msgstr "Corporazioni disponibili" #: allianceauth/hrapplications/templates/hrapplications/corpchoice.html:22 msgid "No corps are accepting applications at this time." -msgstr "Nessuna corporazione accetta domanda al momento." +msgstr "Nessuna corporazione accetta domande al momento." #: allianceauth/hrapplications/templates/hrapplications/create.html:4 #: allianceauth/hrapplications/templates/hrapplications/create.html:7 @@ -1097,7 +1117,7 @@ msgstr "Invia" #: allianceauth/hrapplications/templates/hrapplications/management.html:5 #: allianceauth/hrapplications/templates/hrapplications/searchview.html:5 msgid "HR Application Management" -msgstr "HR Risorse umane" +msgstr "Gestione delle applicazioni HR" #: allianceauth/hrapplications/templates/hrapplications/management.html:10 msgid "Personal Applications" @@ -1165,7 +1185,7 @@ msgstr "Data" #: allianceauth/hrapplications/templates/hrapplications/management.html:138 #: allianceauth/hrapplications/templates/hrapplications/view.html:22 msgid "Reviewer:" -msgstr "" +msgstr "Revisore:" #: allianceauth/hrapplications/templates/hrapplications/management.html:113 msgid "No pending applications." @@ -1173,7 +1193,7 @@ msgstr "Nessuna domanda in sospeso." #: allianceauth/hrapplications/templates/hrapplications/management.html:162 msgid "No reviewed applications." -msgstr "Nessuna domanda revisionata." +msgstr "Nessuna candidatura esaminata." #: allianceauth/hrapplications/templates/hrapplications/management.html:176 #: allianceauth/hrapplications/templates/hrapplications/searchview.html:62 @@ -1266,11 +1286,11 @@ msgstr "Letto" #: allianceauth/notifications/templates/notifications/list.html:17 msgid "Mark All Read" -msgstr "Seleziona tutto visionato" +msgstr "Segna tutto come letto" #: allianceauth/notifications/templates/notifications/list.html:18 msgid "Delete All Read" -msgstr "Cancella tutti i visionati" +msgstr "Elimina tutti i letti" #: allianceauth/notifications/templates/notifications/list_partial.html:7 msgid "Timestamp" @@ -1282,340 +1302,347 @@ msgstr "Titolo" #: allianceauth/notifications/templates/notifications/list_partial.html:28 msgid "No notifications." -msgstr "" +msgstr "Nessuna notifica." #: allianceauth/notifications/templates/notifications/view.html:4 #: allianceauth/notifications/templates/notifications/view.html:8 msgid "View Notification" -msgstr "" +msgstr "Vedi notifiche" #: allianceauth/notifications/views.py:52 msgid "You are not authorized to view that notification." -msgstr "" +msgstr "Non sei autorizzato a visualizzare questa notifica." #: allianceauth/notifications/views.py:68 msgid "Deleted notification." -msgstr "" +msgstr "Elimina notifiche." #: allianceauth/notifications/views.py:75 msgid "Failed to locate notification." -msgstr "" +msgstr "Impossibile trovare la notifica." #: allianceauth/notifications/views.py:83 msgid "Marked all notifications as read." -msgstr "" +msgstr "Contrassegna tutte le notifiche come lette." #: allianceauth/notifications/views.py:91 msgid "Deleted all read notifications." -msgstr "" +msgstr "Elimina tutte le notifiche lette." #: allianceauth/optimer/auth_hooks.py:10 msgid "Fleet Operations" -msgstr "" +msgstr "Operazioni di flotta" #: allianceauth/optimer/form.py:12 #: allianceauth/optimer/templates/optimer/fleetoptable.html:11 msgid "Doctrine" -msgstr "" +msgstr "Dottrina" #: allianceauth/optimer/form.py:14 #: allianceauth/optimer/templates/optimer/fleetoptable.html:13 msgid "Start Time" -msgstr "" +msgstr "Ora di inizio" #: allianceauth/optimer/form.py:15 #: allianceauth/optimer/templates/optimer/fleetoptable.html:9 msgid "Operation Name" -msgstr "" +msgstr "Nome dell'operazione" #: allianceauth/optimer/form.py:16 msgid "Operation Type" -msgstr "" +msgstr "Tipo di operazione" #: allianceauth/optimer/form.py:17 #: allianceauth/srp/templates/srp/management.html:38 msgid "Fleet Commander" -msgstr "" +msgstr "Comandante della flotta" #: allianceauth/optimer/form.py:22 allianceauth/srp/form.py:14 #: allianceauth/srp/templates/srp/data.html:91 msgid "Additional Info" -msgstr "" +msgstr "Informazioni aggiuntive" #: allianceauth/optimer/form.py:23 msgid "(Optional) Describe the operation with a couple of short words." -msgstr "" +msgstr "(Facoltativo) Breve descrizione del tipo di operazione." #: allianceauth/optimer/templates/optimer/add.html:6 #: allianceauth/optimer/templates/optimer/management.html:13 msgid "Create Operation" -msgstr "" +msgstr "Crea operazione" #: allianceauth/optimer/templates/optimer/fleetoptable.html:12 msgid "Form Up System" -msgstr "" +msgstr "Sistema di partenza" #: allianceauth/optimer/templates/optimer/fleetoptable.html:14 #: allianceauth/timerboard/templates/timerboard/view.html:36 #: allianceauth/timerboard/templates/timerboard/view.html:203 #: allianceauth/timerboard/templates/timerboard/view.html:376 msgid "Local Time" -msgstr "" +msgstr "Ora locale" #: allianceauth/optimer/templates/optimer/fleetoptable.html:16 msgid "FC" -msgstr "" +msgstr "Comandante della flotta" #: allianceauth/optimer/templates/optimer/management.html:5 msgid "Fleet Operation Management" -msgstr "" +msgstr "Gestione delle operazioni di flotta" #: allianceauth/optimer/templates/optimer/management.html:10 msgid "Fleet Operation Timers" -msgstr "" +msgstr "Timer delle operazioni di flotta" #: allianceauth/optimer/templates/optimer/management.html:20 #: allianceauth/timerboard/templates/timerboard/view.html:22 msgid "Current Eve Time:" -msgstr "" +msgstr "Ora EVE attuale:" #: allianceauth/optimer/templates/optimer/management.html:26 msgid "Next Fleet Operations" -msgstr "" +msgstr "Prossime operazioni di flotta" #: allianceauth/optimer/templates/optimer/management.html:30 #: allianceauth/timerboard/templates/timerboard/view.html:362 msgid "No upcoming timers." -msgstr "" +msgstr "Nessun timer prossimo." #: allianceauth/optimer/templates/optimer/management.html:33 msgid "Past Fleet Operations" -msgstr "" +msgstr "Operazioni di flotta passate" #: allianceauth/optimer/templates/optimer/management.html:37 #: allianceauth/timerboard/templates/timerboard/view.html:535 msgid "No past timers." -msgstr "" +msgstr "Nessun timer passato." #: allianceauth/optimer/templates/optimer/update.html:6 #: allianceauth/optimer/templates/optimer/update.html:15 #: allianceauth/optimer/templates/optimer/update.html:27 msgid "Update Fleet Operation" -msgstr "" +msgstr "Aggiorna operazioni di flotta" #: allianceauth/optimer/templates/optimer/update.html:21 msgid "Fleet Operation Does Not Exist" -msgstr "" +msgstr "L'operazione di flotta non esiste" #: allianceauth/optimer/views.py:69 #, python-format msgid "Created operation timer for %(opname)s." -msgstr "" +msgstr "Creato il timer per l'operazione %(opname)s." #: allianceauth/optimer/views.py:87 #, python-format msgid "Removed operation timer for %(opname)s." -msgstr "" +msgstr "Rimosso il timer per l'operazione %(opname)s." #: allianceauth/optimer/views.py:125 #, python-format msgid "Saved changes to operation timer for %(opname)s." -msgstr "" +msgstr "Salvati i cambiamenti per l'operazione %(opname)s." #: allianceauth/permissions_tool/templates/permissions_tool/audit.html:4 #: allianceauth/permissions_tool/templates/permissions_tool/audit.html:8 msgid "Permissions Audit" -msgstr "" +msgstr "Verifica dei permessi" #: allianceauth/permissions_tool/templates/permissions_tool/audit.html:20 msgid "User / Character" -msgstr "" +msgstr "Utente / Personaggio" #: allianceauth/permissions_tool/templates/permissions_tool/overview.html:4 #: allianceauth/permissions_tool/templates/permissions_tool/overview.html:8 msgid "Permissions Overview" -msgstr "" +msgstr "Panoramica dei permessi" #: allianceauth/permissions_tool/templates/permissions_tool/overview.html:11 msgid "Showing only applied permissions" -msgstr "" +msgstr "Mostrando solo i permessi applicati" #: allianceauth/permissions_tool/templates/permissions_tool/overview.html:12 msgid "Show All" -msgstr "" +msgstr "Mostra tutto" #: allianceauth/permissions_tool/templates/permissions_tool/overview.html:14 msgid "Showing all permissions" -msgstr "" +msgstr "Mostrando tutti i permessi" #: allianceauth/permissions_tool/templates/permissions_tool/overview.html:15 msgid "Show Applied" -msgstr "" +msgstr "Mostra applicati" #: allianceauth/permissions_tool/templates/permissions_tool/overview.html:23 msgid "App" -msgstr "" +msgstr "App" #: allianceauth/permissions_tool/templates/permissions_tool/overview.html:26 msgid "Model" -msgstr "" +msgstr "Modello" #: allianceauth/permissions_tool/templates/permissions_tool/overview.html:29 msgid "Code Name" -msgstr "" +msgstr "Nome del codice" #: allianceauth/permissions_tool/templates/permissions_tool/overview.html:35 msgid "Users" -msgstr "" +msgstr "Utenti" #: allianceauth/permissions_tool/templates/permissions_tool/overview.html:41 msgid "States" -msgstr "" +msgstr "Stati" #: allianceauth/services/abstract.py:72 msgid "That service account already exists" -msgstr "" +msgstr "Un account per questo servizio già esiste" #: allianceauth/services/abstract.py:103 #, python-brace-format msgid "Successfully set your {self.service_name} password" -msgstr "" +msgstr "La password del {self.service_name} è stata impostata con sucesso" #: allianceauth/services/auth_hooks.py:12 msgid "Services" -msgstr "" +msgstr "Servizi" #: allianceauth/services/forms.py:6 msgid "Name of Fleet:" -msgstr "" +msgstr "Nome della flotta:" #: allianceauth/services/forms.py:7 msgid "Fleet Commander:" -msgstr "" +msgstr "Comandante della flotta:" #: allianceauth/services/forms.py:8 msgid "Fleet Comms:" -msgstr "" +msgstr "Canale voce della flotta:" #: allianceauth/services/forms.py:9 msgid "Fleet Type:" -msgstr "" +msgstr "Tipo di flotta:" #: allianceauth/services/forms.py:10 msgid "Ship Priorities:" -msgstr "" +msgstr "Navi prioritarie:" #: allianceauth/services/forms.py:11 msgid "Formup Location:" -msgstr "" +msgstr "Sistema di partenza:" #: allianceauth/services/forms.py:12 msgid "Formup Time:" -msgstr "" +msgstr "Ora di partenza:" #: allianceauth/services/forms.py:13 msgid "Expected Duration:" -msgstr "" +msgstr "Durata stimata:" #: allianceauth/services/forms.py:14 msgid "Purpose:" -msgstr "" +msgstr "Obiettivo:" #: allianceauth/services/forms.py:15 msgid "Reimbursable?*" -msgstr "" +msgstr "SRP?*" #: allianceauth/services/forms.py:15 allianceauth/services/forms.py:16 msgid "Yes" -msgstr "" +msgstr "Si" #: allianceauth/services/forms.py:15 allianceauth/services/forms.py:16 msgid "No" -msgstr "" +msgstr "No" #: allianceauth/services/forms.py:16 msgid "Important?*" -msgstr "" +msgstr "Importante?*" #: allianceauth/services/forms.py:21 allianceauth/services/forms.py:31 msgid "Password" -msgstr "" +msgstr "Password" #: allianceauth/services/forms.py:26 allianceauth/services/forms.py:36 msgid "Password must be at least 8 characters long." -msgstr "" +msgstr "La password deve contenere almeno 8 caratteri." #: allianceauth/services/modules/discord/models.py:187 msgid "Discord Account Disabled" -msgstr "" +msgstr "Account discord disabilitato" #: 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 "" +"Il tuo account discord è stato disabilitato automaticamente dall'Auth. Se " +"pensi questo sia un errore per favore contatta un ammistratore." #: 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 "Unisciti al server discord" #: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:22 msgid "Leave- and rejoin the Discord Server (Reset)" -msgstr "" +msgstr "Abbandona e unisciti nuovamente al server discord (ripristino)" #: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:25 msgid "Leave the Discord server" -msgstr "" +msgstr "Lascia il server discord" #: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:32 msgid "Link Discord Server" -msgstr "" +msgstr "Collega server discord" #: allianceauth/services/modules/discord/views.py:30 msgid "Deactivated Discord account." -msgstr "" +msgstr "Disabilita l'account discord" #: allianceauth/services/modules/discord/views.py:36 #: allianceauth/services/modules/discord/views.py:59 msgid "An error occurred while processing your Discord account." msgstr "" +"Si è verificato un errore durante l'elaborazione del tuo account discord." #: allianceauth/services/modules/discord/views.py:102 msgid "Your Discord account has been successfully activated." -msgstr "" +msgstr "Il tuo account discord è stato attivato con successo." #: allianceauth/services/modules/discord/views.py:108 msgid "" "An error occurred while trying to activate your Discord account. Please try " "again." msgstr "" +"Si è verificato un errore durante l'attivazione del tuo account discord. Per" +" favore ritenta." #: allianceauth/services/modules/discourse/views.py:29 msgid "You are not authorized to access Discourse." -msgstr "" +msgstr "Non sei autorizzato ad accedere Discourse." #: allianceauth/services/modules/discourse/views.py:34 msgid "You must have a main character set to access Discourse." msgstr "" +"Devi avere impostato un personaggio principale per poter accedere Discourse." #: allianceauth/services/modules/discourse/views.py:44 msgid "" "No SSO payload or signature. Please contact support if this problem " "persists." msgstr "" +"Nessun payload o firma SSO. Contatta l'assistenza se il 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 "" +msgstr "Payload non valido. Contatta l'assistenza se il problema persiste." #: allianceauth/services/modules/ips4/views.py:31 msgid "Activated IPSuite4 account." -msgstr "" +msgstr "Attiva account IPSuite4." #: allianceauth/services/modules/ips4/views.py:39 #: allianceauth/services/modules/ips4/views.py:60 @@ -1623,32 +1650,33 @@ msgstr "" #: allianceauth/services/modules/ips4/views.py:101 msgid "An error occurred while processing your IPSuite4 account." msgstr "" +"Si è verificato un errore durante l'elaborazione del tuo account IPSuite4." #: allianceauth/services/modules/ips4/views.py:52 msgid "Reset IPSuite4 password." -msgstr "" +msgstr "Reimposta password IPSuite4." #: allianceauth/services/modules/ips4/views.py:78 msgid "Set IPSuite4 password." -msgstr "" +msgstr "Imposta password IPSuite4." #: allianceauth/services/modules/ips4/views.py:98 msgid "Deactivated IPSuite4 account." -msgstr "" +msgstr "Disattiva account IPSuite4." #: 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 #: allianceauth/services/modules/openfire/templates/services/openfire/broadcast.html:10 msgid "Jabber Broadcast" -msgstr "" +msgstr "Jabber broadcast" #: allianceauth/services/modules/openfire/auth_hooks.py:94 msgid "Fleet Broadcast Formatter" -msgstr "" +msgstr "Strumento formattazione broadcast" #: allianceauth/services/modules/openfire/forms.py:7 msgid "Message" @@ -1656,15 +1684,15 @@ msgstr "Messaggio" #: allianceauth/services/modules/openfire/templates/services/openfire/broadcast.html:16 msgid "Broadcast Sent!!" -msgstr "" +msgstr "Broadcast inviato!" #: allianceauth/services/modules/openfire/templates/services/openfire/broadcast.html:22 msgid "Broadcast" -msgstr "" +msgstr "Broadcast" #: allianceauth/services/modules/openfire/views.py:35 msgid "Activated jabber account." -msgstr "" +msgstr "Attivato account jabber." #: allianceauth/services/modules/openfire/views.py:43 #: allianceauth/services/modules/openfire/views.py:56 @@ -1672,23 +1700,24 @@ msgstr "" #: allianceauth/services/modules/openfire/views.py:147 msgid "An error occurred while processing your jabber account." msgstr "" +"Si è verificato un errore durante l'elaborazione del tuo account jabber." #: allianceauth/services/modules/openfire/views.py:69 msgid "Reset jabber password." -msgstr "" +msgstr "Reimposta password jabber." #: allianceauth/services/modules/openfire/views.py:115 #, python-format msgid "Sent jabber broadcast to %s" -msgstr "" +msgstr "Broadcast jabber inviato a %s" #: allianceauth/services/modules/openfire/views.py:144 msgid "Set jabber password." -msgstr "" +msgstr "Imposta password jabber." #: allianceauth/services/modules/phpbb3/views.py:34 msgid "Activated forum account." -msgstr "" +msgstr "Account forum attivato." #: allianceauth/services/modules/phpbb3/views.py:42 #: allianceauth/services/modules/phpbb3/views.py:56 @@ -1696,90 +1725,92 @@ msgstr "" #: allianceauth/services/modules/phpbb3/views.py:101 msgid "An error occurred while processing your forum account." msgstr "" +"Si è verificato un errore durante l'elaborazione del tuo account forum." #: allianceauth/services/modules/phpbb3/views.py:53 msgid "Deactivated forum account." -msgstr "" +msgstr "Disattivato account forum." #: allianceauth/services/modules/phpbb3/views.py:70 msgid "Reset forum password." -msgstr "" +msgstr "Reimposta password forum." #: allianceauth/services/modules/phpbb3/views.py:98 msgid "Set forum password." -msgstr "" +msgstr "Imposta password forum." #: allianceauth/services/modules/smf/views.py:52 msgid "Activated SMF account." -msgstr "" +msgstr "Attivato account 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 "Si è verificato un errore durante l'elaborazione del tuo account SMF." #: allianceauth/services/modules/smf/views.py:78 msgid "Deactivated SMF account." -msgstr "" +msgstr "Disattivato account SMF." #: allianceauth/services/modules/smf/views.py:95 msgid "Reset SMF password." -msgstr "" +msgstr "Reimposta password SMF." #: allianceauth/services/modules/smf/views.py:121 msgid "Set SMF password." -msgstr "" +msgstr "Imposta password SMF." #: allianceauth/services/modules/teamspeak3/forms.py:14 #, python-format msgid "Unable to locate user %s on server" -msgstr "" +msgstr "Impossibile trovare utente %s nel server" #: allianceauth/services/modules/teamspeak3/templates/admin/teamspeak3/authts/change_list.html:8 msgid "Update TS3 groups" -msgstr "" +msgstr "Aggiorna gruppi TS3" #: allianceauth/services/modules/teamspeak3/templates/services/teamspeak3/teamspeakjoin.html:5 msgid "Verify Teamspeak" -msgstr "" +msgstr "Verifica Teamspeak" #: allianceauth/services/modules/teamspeak3/templates/services/teamspeak3/teamspeakjoin.html:10 msgid "Verify Teamspeak Identity" -msgstr "" +msgstr "Verifica identità teamspeak" #: allianceauth/services/modules/teamspeak3/templates/services/teamspeak3/teamspeakjoin.html:13 msgid "Join Server" -msgstr "" +msgstr "Unisciti al server" #: allianceauth/services/modules/teamspeak3/templates/services/teamspeak3/teamspeakjoin.html:19 #: allianceauth/services/templates/services/service_credentials.html:19 #: allianceauth/srp/templates/srp/add.html:31 msgid "Continue" -msgstr "" +msgstr "Continua" #: allianceauth/services/modules/teamspeak3/views.py:35 msgid "Activated TeamSpeak3 account." -msgstr "" +msgstr "Account Teamspeak3 attivato." #: 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 "" +"Si è verificato un errore durante l'elaborazione del tuo account Teamspeak3." #: allianceauth/services/modules/teamspeak3/views.py:71 msgid "Deactivated TeamSpeak3 account." -msgstr "" +msgstr "Disattivato account TeamSpeak3." #: allianceauth/services/modules/teamspeak3/views.py:97 msgid "Reset TeamSpeak3 permission key." -msgstr "" +msgstr "Reimposta la chiave di autorizzazione TeamSpeak3." #: allianceauth/services/modules/xenforo/views.py:30 msgid "Activated XenForo account." -msgstr "" +msgstr "Attivato account XenForo." #: allianceauth/services/modules/xenforo/views.py:40 #: allianceauth/services/modules/xenforo/views.py:52 @@ -1787,310 +1818,317 @@ msgstr "" #: allianceauth/services/modules/xenforo/views.py:94 msgid "An error occurred while processing your XenForo account." msgstr "" +"Si è verificato un errore durante l'elaborazione del tuo account XenForo." #: allianceauth/services/modules/xenforo/views.py:50 msgid "Deactivated XenForo account." -msgstr "" +msgstr "Disattivato account XenForo." #: allianceauth/services/modules/xenforo/views.py:65 msgid "Reset XenForo account password." -msgstr "" +msgstr "Reimposta password dell'account XenForo." #: allianceauth/services/modules/xenforo/views.py:91 msgid "Changed XenForo password." -msgstr "" +msgstr "Password XenForo modificata." #: allianceauth/services/templates/services/fleetformattertool.html:5 msgid "Fleet Formatter Tool" -msgstr "" +msgstr "Strumento formattazione della flotta" #: allianceauth/services/templates/services/fleetformattertool.html:10 msgid "Fleet Broadcast Formatter Tool" -msgstr "" +msgstr "Strumento formattazione brocast della flotta" #: allianceauth/services/templates/services/fleetformattertool.html:23 msgid "Format" -msgstr "" +msgstr "Formato" #: allianceauth/services/templates/services/service_confirm_delete.html:6 #: allianceauth/services/templates/services/service_confirm_delete.html:12 #, python-format msgid "Delete %(service_name)s Account?" -msgstr "" +msgstr "Eliminare l'account %(service_name)s?" #: allianceauth/services/templates/services/service_confirm_delete.html:20 #, python-format msgid "" "Are you sure you want to delete your %(service_name)s account %(object)s?" -msgstr "" +msgstr "Sei sicuro di voler eliminare l'account %(service_name)s %(object)s?" #: allianceauth/services/templates/services/service_credentials.html:4 #: allianceauth/services/templates/services/service_credentials.html:8 #, python-format msgid "%(service_name)s Credentials" -msgstr "" +msgstr "%(service_name)s Credenziali" #: allianceauth/services/templates/services/service_password.html:5 #, python-format msgid "%(service_name)s Password Change" -msgstr "" +msgstr "%(service_name)s Modifica password" #: allianceauth/services/templates/services/service_password.html:9 #, python-format msgid "Set %(service_name)s Password" -msgstr "" +msgstr "Imposta password %(service_name)s " #: allianceauth/services/templates/services/service_password.html:17 msgid "Set Password" -msgstr "" +msgstr "Imposta password" #: allianceauth/services/templates/services/services.html:4 msgid "Services Management" -msgstr "" +msgstr "Gestione dei servizi" #: allianceauth/services/templates/services/services.html:9 msgid "Available Services" -msgstr "" +msgstr "Servizi disponibili" #: allianceauth/services/templates/services/services.html:14 msgid "Service" -msgstr "" +msgstr "Servizio" #: allianceauth/services/templates/services/services.html:16 msgid "Domain" -msgstr "" +msgstr "Dominio" #: allianceauth/srp/auth_hooks.py:13 msgid "Ship Replacement" -msgstr "" +msgstr "Sostituzione della nave" #: allianceauth/srp/form.py:9 #: allianceauth/srp/templates/srp/management.html:36 msgid "Fleet Time" -msgstr "" +msgstr "Orario della flotta" #: allianceauth/srp/form.py:10 #: allianceauth/srp/templates/srp/management.html:37 msgid "Fleet Doctrine" -msgstr "" +msgstr "Dottrina della flotta" #: allianceauth/srp/form.py:16 msgid "Killboard Link (zkillboard.com or kb.evetools.org)" -msgstr "" +msgstr "Killboard link (zkillboard.com o kb.evetools.org) " #: allianceauth/srp/form.py:34 msgid "Invalid Link. Please use zkillboard.com or kb.evetools.org" -msgstr "" +msgstr "Link non valido. Per favore utilizza zkillboard.com o kb.evetools.org" #: allianceauth/srp/form.py:46 msgid "Invalid Link. Please post a direct link to a killmail." msgstr "" +"Link non valido. Per favore utilizza un link direttamente collegato alla " +"killmail." #: allianceauth/srp/form.py:53 msgid "After Action Report Link" -msgstr "" +msgstr "Link di resoconto della flotta" #: allianceauth/srp/templates/srp/add.html:5 msgid "SRP Fleet Create" -msgstr "" +msgstr "Crea SRP della flotta" #: allianceauth/srp/templates/srp/add.html:13 #: allianceauth/srp/templates/srp/add.html:23 msgid "Create SRP Fleet" -msgstr "" +msgstr "Crea SRP della flotta" #: allianceauth/srp/templates/srp/add.html:26 msgid "Give this link to the line members" -msgstr "" +msgstr "Fornisci questo link ai membri" #: allianceauth/srp/templates/srp/data.html:5 msgid "Srp Fleet Data" -msgstr "" +msgstr "Dati del SRP della flotta" #: allianceauth/srp/templates/srp/data.html:50 msgid "SRP Fleet Data" -msgstr "" +msgstr "Dati del SRP della flotta" #: allianceauth/srp/templates/srp/data.html:55 msgid "Mark Incomplete" -msgstr "" +msgstr "Contrassegna incompleto" #: allianceauth/srp/templates/srp/data.html:59 msgid "Mark Completed" -msgstr "" +msgstr "Contrassegna completo" #: allianceauth/srp/templates/srp/data.html:71 #: allianceauth/srp/templates/srp/data.html:157 msgid "Total Losses:" -msgstr "" +msgstr "Perdite totali:" #: allianceauth/srp/templates/srp/data.html:72 #: allianceauth/srp/templates/srp/data.html:158 #: allianceauth/srp/templates/srp/management.html:28 msgid "Total ISK Cost:" -msgstr "" +msgstr "Costo totale in ISK:" #: allianceauth/srp/templates/srp/data.html:80 #: allianceauth/srp/templates/srp/data.html:166 msgid "Are you sure you want to delete SRP requests?" -msgstr "" +msgstr "Sei sicuro di voler eliminare la richiesta di SRP?" #: allianceauth/srp/templates/srp/data.html:89 msgid "Pilot Name" -msgstr "" +msgstr "Nome del pilota" #: allianceauth/srp/templates/srp/data.html:90 msgid "Killboard Link" -msgstr "" +msgstr "Link killboard" #: allianceauth/srp/templates/srp/data.html:92 msgid "Ship Type" -msgstr "" +msgstr "Tipologia nave" #: allianceauth/srp/templates/srp/data.html:93 msgid "Killboard Loss Amt" -msgstr "" +msgstr "Valore delle perdite Killboard" #: allianceauth/srp/templates/srp/data.html:94 msgid "SRP ISK Cost" -msgstr "" +msgstr "Costo in ISK del SRP" #: allianceauth/srp/templates/srp/data.html:95 msgid "Click value to edit Enter to save & next ESC to cancel" msgstr "" +"Fai clic sul valore per modificare, Invio per salvare e proseguire, ESC per " +"annullare" #: allianceauth/srp/templates/srp/data.html:98 msgid "Post Time" -msgstr "" +msgstr "Ora di pubblicazione" #: allianceauth/srp/templates/srp/data.html:175 msgid "No SRP requests for this fleet." -msgstr "" +msgstr "Nessuna richiesta di SRP per questa flotta." #: allianceauth/srp/templates/srp/management.html:6 msgid "Srp Management" -msgstr "" +msgstr "Gestione SRP" #: allianceauth/srp/templates/srp/management.html:12 msgid "SRP Management" -msgstr "" +msgstr "Gestione SRP" #: allianceauth/srp/templates/srp/management.html:16 msgid "View All" -msgstr "" +msgstr "Vedi tutti" #: allianceauth/srp/templates/srp/management.html:21 msgid "Add SRP Fleet" -msgstr "" +msgstr "Aggiungi SRP alla flotta" #: allianceauth/srp/templates/srp/management.html:39 msgid "Fleet AAR" -msgstr "" +msgstr "Resoconto della flotta" #: allianceauth/srp/templates/srp/management.html:40 msgid "Fleet SRP Code" -msgstr "" +msgstr "Codice SRP della flotta" #: allianceauth/srp/templates/srp/management.html:41 msgid "Fleet ISK Cost" -msgstr "" +msgstr "Costo in ISK della flotta" #: allianceauth/srp/templates/srp/management.html:42 msgid "SRP Status" -msgstr "" +msgstr "Status del SRP" #: allianceauth/srp/templates/srp/management.html:43 msgid "Pending Requests" -msgstr "" +msgstr "Richieste in sospeso" #: allianceauth/srp/templates/srp/management.html:62 msgid "Link" -msgstr "" +msgstr "Link" #: allianceauth/srp/templates/srp/management.html:70 msgid "Disabled" -msgstr "" +msgstr "Disabilitato" #: allianceauth/srp/templates/srp/management.html:83 msgid "Completed" -msgstr "" +msgstr "Completato" #: allianceauth/srp/templates/srp/management.html:101 msgid "Are you sure you want to delete this SRP code and its contents?" -msgstr "" +msgstr "Sei sicuro di voler eliminare questo codice SRP e i suoi contenuti?" #: allianceauth/srp/templates/srp/management.html:122 msgid "No SRP fleets created." -msgstr "" +msgstr "Nessun SRP delle flotte creato." #: allianceauth/srp/templates/srp/request.html:5 msgid "SRP Request" -msgstr "" +msgstr "Richieste SRP" #: allianceauth/srp/templates/srp/request.html:10 #: allianceauth/srp/templates/srp/request.html:19 msgid "Create SRP Request" -msgstr "" +msgstr "Crea richiesta SRP" #: allianceauth/srp/templates/srp/update.html:5 #: allianceauth/srp/templates/srp/update.html:10 #: allianceauth/srp/templates/srp/update.html:22 msgid "Update AAR Link" -msgstr "" +msgstr "Aggiorna resoconto della flotta" #: allianceauth/srp/templates/srp/update.html:16 msgid "SRP Fleet Does Not Exist" -msgstr "" +msgstr "SRP della flotta non esiste" #: allianceauth/srp/views.py:85 #, python-format msgid "Created SRP fleet %(fleetname)s." -msgstr "" +msgstr "Creato SRP della flotta %(fleetname)s." #: allianceauth/srp/views.py:103 #, python-format msgid "Removed SRP fleet %(fleetname)s." -msgstr "" +msgstr "Rimosso SRP della flotta %(fleetname)s." #: allianceauth/srp/views.py:115 #, python-format msgid "Disabled SRP fleet %(fleetname)s." -msgstr "" +msgstr "Disabilitato SRP della flotta %(fleetname)s." #: allianceauth/srp/views.py:127 #, python-format msgid "Enabled SRP fleet %(fleetname)s." -msgstr "" +msgstr "Abilitato SRP della flotta %(fleetname)s." #: allianceauth/srp/views.py:140 #, python-format msgid "Marked SRP fleet %(fleetname)s as completed." -msgstr "" +msgstr "SRP della flotta %(fleetname)s è stato contrassegnato completato." #: allianceauth/srp/views.py:153 #, python-format msgid "Marked SRP fleet %(fleetname)s as incomplete." -msgstr "" +msgstr "L'SRP della flotta %(fleetname)s è stato contrassegnato incompleto." #: allianceauth/srp/views.py:165 #, python-format msgid "Unable to locate SRP code with ID %(srpfleetid)s" -msgstr "" +msgstr "Impossibile trovare il codice di SRP con ID %(srpfleetid)s" #: allianceauth/srp/views.py:179 msgid "This kill mail has already been posted." -msgstr "" +msgstr "Questa killmail è già stata pubblicata." #: allianceauth/srp/views.py:200 msgid "" "Your SRP request Killmail link is invalid. Please make sure you are using " "zKillboard." msgstr "" +"La tua richiesta di SRP contiente un link killmail non valido. Per favore " +"assicurarti di utilizzare zKillboard." #: allianceauth/srp/views.py:212 #, python-format msgid "Submitted SRP request for your %(ship)s." -msgstr "" +msgstr "Richiesta di SRP inviata per la tua nave %(ship)s." #: allianceauth/srp/views.py:216 #, python-format @@ -2098,88 +2136,90 @@ msgid "" "Character %(charid)s does not belong to your Auth account. Please add the " "API key for this character and try again" msgstr "" +"Il personaggio %(charid)s non è collegato al tuo profilo Auth. Per favore " +"aggiungi le API key di questo personaggio e ritenta." #: allianceauth/srp/views.py:236 allianceauth/srp/views.py:262 #: allianceauth/srp/views.py:300 msgid "No SRP requests selected" -msgstr "" +msgstr "Nessuna richiesta di SRP selezionata" #: allianceauth/srp/views.py:247 allianceauth/srp/views.py:285 msgid "Unable to locate selected SRP request." -msgstr "" +msgstr "Impossible trovare la richiesta di SRP selezionata." #: allianceauth/srp/views.py:250 #, python-format msgid "Deleted %(numrequests)s SRP requests" -msgstr "" +msgstr "Eliminata/e %(numrequests)s richiesta/e di SRP" #: allianceauth/srp/views.py:288 #, python-format msgid "Approved %(numrequests)s SRP requests" -msgstr "" +msgstr "Approvata/e %(numrequests)srichiesta/e di SRP" #: allianceauth/srp/views.py:320 msgid "Unable to locate selected SRP request" -msgstr "" +msgstr "Impossible trovare la richiesta di SRP selezionata" #: allianceauth/srp/views.py:323 #, python-format msgid "Rejected %(numrequests)s SRP requests." -msgstr "" +msgstr "Rifiutata/e %(numrequests)s richiesta/e di SRP." #: allianceauth/srp/views.py:336 #, python-format msgid "Unable to locate SRP request with ID %(requestid)s" -msgstr "" +msgstr "Impossibile trovare la richiesta di SRP con ID %(requestid)s" #: allianceauth/srp/views.py:360 #, python-format msgid "Saved changes to SRP fleet %(fleetname)s" -msgstr "" +msgstr "Salvati i cambiamenti al SRP della flotta %(fleetname)s" #: allianceauth/templates/allianceauth/admin-status/overview.html:8 msgid "Alliance Auth Notifications" -msgstr "" +msgstr "Notifiche Auth Alleanza" #: allianceauth/templates/allianceauth/admin-status/overview.html:16 msgid "Closed" -msgstr "" +msgstr "Chiuso" #: allianceauth/templates/allianceauth/admin-status/overview.html:28 msgid "Powered by GitLab" -msgstr "" +msgstr "Powered by GitLab" #: allianceauth/templates/allianceauth/admin-status/overview.html:35 msgid "Support Discord" -msgstr "" +msgstr "Discord di supporto" #: allianceauth/templates/allianceauth/admin-status/overview.html:43 msgid "Software Version" -msgstr "" +msgstr "Versione del software" #: allianceauth/templates/allianceauth/admin-status/overview.html:47 msgid "Current" -msgstr "" +msgstr "Attuale" #: allianceauth/templates/allianceauth/admin-status/overview.html:53 msgid "Latest Stable" -msgstr "" +msgstr "Ultima versione stabile" #: allianceauth/templates/allianceauth/admin-status/overview.html:59 msgid "Update available" -msgstr "" +msgstr "Aggiornamento disponibile" #: allianceauth/templates/allianceauth/admin-status/overview.html:64 msgid "Latest Pre-Release" -msgstr "" +msgstr "Ultima versione preliminare" #: allianceauth/templates/allianceauth/admin-status/overview.html:70 msgid "Pre-Release available" -msgstr "" +msgstr "Versione preliminare disponibile" #: allianceauth/templates/allianceauth/admin-status/overview.html:78 msgid "Task Queue" -msgstr "" +msgstr "Coda delle attività" #: allianceauth/templates/allianceauth/admin-status/overview.html:81 #, python-format @@ -2188,6 +2228,9 @@ msgid "" " Status of %(total)s processed tasks • last %(latest)s\n" " " msgstr "" +"\n" +" Stato di %(total)s attività elaborate • ultimo %(latest)s\n" +" " #: allianceauth/templates/allianceauth/admin-status/overview.html:95 #, python-format @@ -2196,183 +2239,185 @@ msgid "" " %(queue_length)s queued tasks\n" " " msgstr "" +"\n" +"%(queue_length)scompiti in coda" #: allianceauth/templates/allianceauth/top-menu-admin.html:9 msgid "Admin" -msgstr "" +msgstr "Amministratore" #: allianceauth/templates/allianceauth/top-menu-admin.html:19 msgid "AA Documentation" -msgstr "" +msgstr "Documentazione AA" #: allianceauth/templates/allianceauth/top-menu-admin.html:26 msgid "AA Support Discord" -msgstr "" +msgstr "AA Discord di supporto" #: allianceauth/templates/allianceauth/top-menu-user-dropdown.html:10 #: allianceauth/templates/allianceauth/top-menu-user-dropdown.html:14 msgid "User Menu" -msgstr "" +msgstr "Menu utente" #: allianceauth/templates/allianceauth/top-menu-user-dropdown.html:56 msgid "Logout" -msgstr "" +msgstr "Disconnettersi" #: allianceauth/timerboard/form.py:53 msgid "Other" -msgstr "" +msgstr "Altro" #: allianceauth/timerboard/form.py:54 #: allianceauth/timerboard/templates/timerboard/view.html:62 #: allianceauth/timerboard/templates/timerboard/view.html:229 #: allianceauth/timerboard/templates/timerboard/view.html:402 msgid "Friendly" -msgstr "" +msgstr "Amichevole" #: allianceauth/timerboard/form.py:55 #: allianceauth/timerboard/templates/timerboard/view.html:57 #: allianceauth/timerboard/templates/timerboard/view.html:224 #: allianceauth/timerboard/templates/timerboard/view.html:397 msgid "Hostile" -msgstr "" +msgstr "Ostile" #: allianceauth/timerboard/form.py:56 #: allianceauth/timerboard/templates/timerboard/view.html:67 #: allianceauth/timerboard/templates/timerboard/view.html:234 #: allianceauth/timerboard/templates/timerboard/view.html:407 msgid "Neutral" -msgstr "" +msgstr "Neutrale" #: allianceauth/timerboard/form.py:58 #: allianceauth/timerboard/templates/timerboard/view.html:31 #: allianceauth/timerboard/templates/timerboard/view.html:198 #: allianceauth/timerboard/templates/timerboard/view.html:371 msgid "Details" -msgstr "" +msgstr "Dettagli" #: allianceauth/timerboard/form.py:60 msgid "Planet/Moon" -msgstr "" +msgstr "Pianeta/Luna" #: allianceauth/timerboard/form.py:61 msgid "Structure Type" -msgstr "" +msgstr "Tipologia di struttura" #: allianceauth/timerboard/form.py:62 msgid "Timer Type" -msgstr "" +msgstr "Tipologia di timer" #: allianceauth/timerboard/form.py:63 #: allianceauth/timerboard/templates/timerboard/view.html:32 #: allianceauth/timerboard/templates/timerboard/view.html:199 #: allianceauth/timerboard/templates/timerboard/view.html:372 msgid "Objective" -msgstr "" +msgstr "Obiettivo" #: allianceauth/timerboard/form.py:64 msgid "Days Remaining" -msgstr "" +msgstr "Giorni rimanenti" #: allianceauth/timerboard/form.py:65 msgid "Hours Remaining" -msgstr "" +msgstr "Ore rimanenti" #: allianceauth/timerboard/form.py:67 msgid "Minutes Remaining" -msgstr "" +msgstr "Minuti rimanenti " #: allianceauth/timerboard/form.py:69 msgid "Important" -msgstr "" +msgstr "Importante" #: allianceauth/timerboard/form.py:70 msgid "Corp-Restricted" -msgstr "" +msgstr "Limitato alla corporazione" #: allianceauth/timerboard/models.py:14 msgid "Not Specified" -msgstr "" +msgstr "Non specificato" #: allianceauth/timerboard/models.py:15 msgid "Shield" -msgstr "" +msgstr "Scudo" #: allianceauth/timerboard/models.py:16 msgid "Armor" -msgstr "" +msgstr "Armatura" #: allianceauth/timerboard/models.py:17 msgid "Hull" -msgstr "" +msgstr "Struttura" #: allianceauth/timerboard/models.py:18 msgid "Final" -msgstr "" +msgstr "Ultimo" #: allianceauth/timerboard/models.py:19 msgid "Anchoring" -msgstr "" +msgstr "In ancoraggio" #: allianceauth/timerboard/models.py:20 msgid "Unanchoring" -msgstr "" +msgstr "In disancoraggio" #: allianceauth/timerboard/templates/timerboard/timer_confirm_delete.html:11 msgid "Delete Timer" -msgstr "" +msgstr "Elimina timer " #: allianceauth/timerboard/templates/timerboard/timer_confirm_delete.html:19 #, python-format msgid "Are you sure you want to delete timer \"%(object)s\"?" -msgstr "" +msgstr "Sei sicuro di voler eliminare il timer \"%(object)s\"?" #: allianceauth/timerboard/templates/timerboard/timer_create_form.html:5 #: allianceauth/timerboard/templates/timerboard/timer_create_form.html:13 msgid "Create Timer" -msgstr "" +msgstr "Crea timer" #: allianceauth/timerboard/templates/timerboard/timer_create_form.html:9 #: allianceauth/timerboard/templates/timerboard/view.html:15 msgid "Create Structure Timer" -msgstr "" +msgstr "Crea timer struttura" #: allianceauth/timerboard/templates/timerboard/timer_update_form.html:5 #: allianceauth/timerboard/templates/timerboard/timer_update_form.html:9 #: allianceauth/timerboard/templates/timerboard/timer_update_form.html:13 msgid "Update Structure Timer" -msgstr "" +msgstr "Aggiorna timer struttura" #: allianceauth/timerboard/templates/timerboard/view.html:6 msgid "Structure Timer Management" -msgstr "" +msgstr "Gestione timer strutture" #: allianceauth/timerboard/templates/timerboard/view.html:11 msgid "Structure Timers" -msgstr "" +msgstr "Timer delle strutture" #: allianceauth/timerboard/templates/timerboard/view.html:27 msgid "Corp Timers" -msgstr "" +msgstr "Timer di corporazione" #: allianceauth/timerboard/templates/timerboard/view.html:34 #: allianceauth/timerboard/templates/timerboard/view.html:201 #: allianceauth/timerboard/templates/timerboard/view.html:374 msgid "Structure" -msgstr "" +msgstr "Struttura" #: allianceauth/timerboard/templates/timerboard/view.html:193 msgid "Next Timers" -msgstr "" +msgstr "Timer prossimi" #: allianceauth/timerboard/templates/timerboard/view.html:366 msgid "Past Timers" -msgstr "" +msgstr "Timer passati" #: allianceauth/timerboard/views.py:74 #, python-format msgid "Added new timer in %(system)s at %(time)s." -msgstr "" +msgstr "Aggiunto un nuovo timer in %(system)salle %(time)s." #: allianceauth/timerboard/views.py:82 msgid "Saved changes to the timer." -msgstr "" +msgstr "Salvati i cambiamenti al timer." diff --git a/allianceauth/locale/ja/LC_MESSAGES/django.po b/allianceauth/locale/ja/LC_MESSAGES/django.po index 4e560a81..86b8a848 100644 --- a/allianceauth/locale/ja/LC_MESSAGES/django.po +++ b/allianceauth/locale/ja/LC_MESSAGES/django.po @@ -4,8 +4,9 @@ # FIRST AUTHOR , YEAR. # # Translators: -# Foch Petain , 2020 +# Foch Petain , 2023 # kotaneko, 2023 +# Joel Falknau , 2023 # #, fuzzy msgid "" @@ -13,8 +14,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-10-09 18:20+1000\n" -"PO-Revision-Date: 2020-02-18 03:14+0000\n" -"Last-Translator: kotaneko, 2023\n" +"PO-Revision-Date: 2023-10-08 09:23+0000\n" +"Last-Translator: Joel Falknau , 2023\n" "Language-Team: Japanese (https://app.transifex.com/alliance-auth/teams/107430/ja/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" diff --git a/allianceauth/locale/ko_KR/LC_MESSAGES/django.po b/allianceauth/locale/ko_KR/LC_MESSAGES/django.po index 9bbe48bc..e289e85a 100644 --- a/allianceauth/locale/ko_KR/LC_MESSAGES/django.po +++ b/allianceauth/locale/ko_KR/LC_MESSAGES/django.po @@ -4,13 +4,13 @@ # FIRST AUTHOR , YEAR. # # Translators: -# None None , 2020 -# Seowon Jung , 2020 -# Olgeda Choi , 2020 -# Lahty , 2020 -# Joel Falknau , 2020 -# ThatRagingKid, 2022 -# jackfrost, 2022 +# None None , 2023 +# Joel Falknau , 2023 +# Seowon Jung , 2023 +# Olgeda Choi , 2023 +# ThatRagingKid, 2023 +# Lahty , 2023 +# jackfrost, 2023 # #, fuzzy msgid "" @@ -18,8 +18,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \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" +"PO-Revision-Date: 2023-10-08 09:23+0000\n" +"Last-Translator: jackfrost, 2023\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" diff --git a/allianceauth/locale/ru/LC_MESSAGES/django.po b/allianceauth/locale/ru/LC_MESSAGES/django.po index 61cbd7f6..2de69488 100644 --- a/allianceauth/locale/ru/LC_MESSAGES/django.po +++ b/allianceauth/locale/ru/LC_MESSAGES/django.po @@ -4,9 +4,9 @@ # FIRST AUTHOR , YEAR. # # Translators: -# Alexander Gess , 2020 -# Yuriy K , 2020 -# Андрей Зубков , 2020 +# Yuriy K , 2023 +# Андрей Зубков , 2023 +# Alexander Gess , 2023 # Filipp Chertiev , 2023 # #, fuzzy @@ -15,7 +15,7 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-10-09 18:20+1000\n" -"PO-Revision-Date: 2020-02-18 03:14+0000\n" +"PO-Revision-Date: 2023-10-08 09:23+0000\n" "Last-Translator: Filipp Chertiev , 2023\n" "Language-Team: Russian (https://app.transifex.com/alliance-auth/teams/107430/ru/)\n" "MIME-Version: 1.0\n" diff --git a/allianceauth/locale/uk/LC_MESSAGES/django.po b/allianceauth/locale/uk/LC_MESSAGES/django.po index 658bd119..c89292c5 100644 --- a/allianceauth/locale/uk/LC_MESSAGES/django.po +++ b/allianceauth/locale/uk/LC_MESSAGES/django.po @@ -4,6 +4,7 @@ # FIRST AUTHOR , YEAR. # # Translators: +# Denys Ivchenko, 2023 # Kristof Swensen, 2023 # #, fuzzy @@ -12,7 +13,7 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-10-09 18:20+1000\n" -"PO-Revision-Date: 2020-02-18 03:14+0000\n" +"PO-Revision-Date: 2023-10-08 09:23+0000\n" "Last-Translator: Kristof Swensen, 2023\n" "Language-Team: Ukrainian (https://app.transifex.com/alliance-auth/teams/107430/uk/)\n" "MIME-Version: 1.0\n" @@ -32,7 +33,7 @@ msgstr "Google Analytics V4" #: allianceauth/authentication/decorators.py:37 msgid "A main character is required to perform that action. Add one below." msgstr "" -"Для виконання цієї дії потрібен головний персонаж. Додайте його нижче." +"Для виконання цієї дії потрібен основний персонаж. Додайте його нижче." #: allianceauth/authentication/forms.py:12 msgid "Email" @@ -124,7 +125,7 @@ msgstr "Додати персонажа" #: allianceauth/authentication/templates/authentication/dashboard.html:115 msgid "Change Main" -msgstr "Змінити головного персонажа" +msgstr "Змінити основного персонажа" #: allianceauth/authentication/templates/authentication/dashboard.html:125 msgid "Group Memberships" @@ -352,7 +353,7 @@ msgstr "Не вдалося зібрати статистику корпорац #: allianceauth/fleetactivitytracking/auth_hooks.py:9 msgid "Fleet Activity Tracking" -msgstr "Відстеження активності флоту" +msgstr "Відстеження активності флотів" #: allianceauth/fleetactivitytracking/forms.py:6 allianceauth/srp/form.py:8 #: allianceauth/srp/templates/srp/management.html:35 @@ -456,7 +457,7 @@ msgstr "Корабель" #: allianceauth/timerboard/templates/timerboard/view.html:202 #: allianceauth/timerboard/templates/timerboard/view.html:375 msgid "Eve Time" -msgstr "Час в грі" +msgstr "Ігровий час" #: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html:33 #: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:36 @@ -560,16 +561,16 @@ msgstr "Fats" #: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticscorpview.html:4 msgid "Fatlink Corp Statistics" -msgstr "Статистика корпорації Fatlink" +msgstr "Статистика фатів корпорації" #: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticscorpview.html:23 #: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticsview.html:24 msgid "Average fats" -msgstr "Середній показник fats" +msgstr "Середній показник фатів" #: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticsview.html:4 msgid "Fatlink statistics" -msgstr "Статистика Fatlink" +msgstr "Статистика фатів" #: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticsview.html:20 msgid "Ticker" @@ -625,7 +626,7 @@ msgid "" "Cannot register the fleet participation for {character.character_name}. The " "character needs to be online." msgstr "" -"Не можна зареєструвати участь в флоті для {character.character_name}. " +"Не вдалося зареєструвати участь в флоті для {character.character_name}. " "Персонаж повинен бути в мережі." #: allianceauth/groupmanagement/auth_hooks.py:17 @@ -659,8 +660,7 @@ msgstr "" #: 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 "" @@ -1045,7 +1045,7 @@ msgstr "Ви вже є членом цієї групи." #: allianceauth/groupmanagement/views.py:358 msgid "You already have a pending application for that group." -msgstr "У вас вже є очікуюча заявка на вступ до цієї групи." +msgstr "Ви вже подали заявку на вступ до цієї групи." #: allianceauth/groupmanagement/views.py:367 #, python-format @@ -1062,7 +1062,7 @@ msgstr "Ви не є учасником цієї групи" #: allianceauth/groupmanagement/views.py:393 msgid "You already have a pending leave request for that group." -msgstr "Ви вже маєте очікувану запит на вихід з цієї групи." +msgstr "Ви вже подали запит на вихід з цієї групи." #: allianceauth/groupmanagement/views.py:409 #, python-format @@ -1321,7 +1321,7 @@ msgstr "Всі прочитані повідомлення видалено." #: allianceauth/optimer/auth_hooks.py:10 msgid "Fleet Operations" -msgstr "Операції флоту" +msgstr "Флотові операції" #: allianceauth/optimer/form.py:12 #: allianceauth/optimer/templates/optimer/fleetoptable.html:11 @@ -1345,7 +1345,7 @@ msgstr "Тип операції" #: allianceauth/optimer/form.py:17 #: allianceauth/srp/templates/srp/management.html:38 msgid "Fleet Commander" -msgstr "Командувач флоту" +msgstr "Командир флоту" #: allianceauth/optimer/form.py:22 allianceauth/srp/form.py:14 #: allianceauth/srp/templates/srp/data.html:91 @@ -1400,7 +1400,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 @@ -1484,7 +1484,7 @@ msgstr "Стани" #: allianceauth/services/abstract.py:72 msgid "That service account already exists" -msgstr "Такий обліковий запис сервісу вже існує" +msgstr "Такий сервісний обліковий запис вже існує" #: allianceauth/services/abstract.py:103 #, python-brace-format @@ -1505,7 +1505,7 @@ msgstr "Командир флоту:" #: allianceauth/services/forms.py:8 msgid "Fleet Comms:" -msgstr "Комунікації флоту:" +msgstr "Голосовий канал флоту:" #: allianceauth/services/forms.py:9 msgid "Fleet Type:" @@ -1545,7 +1545,7 @@ msgstr "Ні" #: allianceauth/services/forms.py:16 msgid "Important?*" -msgstr "Важливо?*" +msgstr "Важливий?*" #: allianceauth/services/forms.py:21 allianceauth/services/forms.py:31 msgid "Password" @@ -1614,7 +1614,7 @@ msgstr "Ви не маєте прав на доступ до Discourse." #: allianceauth/services/modules/discourse/views.py:34 msgid "You must have a main character set to access Discourse." -msgstr "Ви повинні мати головний персонаж, щоб отримати доступ до Discourse." +msgstr "Ви повинні мати основний персонаж, щоб отримати доступ до Discourse." #: allianceauth/services/modules/discourse/views.py:44 msgid "" @@ -1702,7 +1702,7 @@ msgstr "Відправлено трансляцію Jabber на %s" #: allianceauth/services/modules/openfire/views.py:144 msgid "Set jabber password." -msgstr "Встановлення пароля Jabber." +msgstr "Встановити пароль Jabber." #: allianceauth/services/modules/phpbb3/views.py:34 msgid "Activated forum account." @@ -1713,7 +1713,7 @@ msgstr "Активований обліковий запис форуму." #: 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 "Виникла помилка під час обробки вашого облікового запису на форумі." #: allianceauth/services/modules/phpbb3/views.py:53 msgid "Deactivated forum account." @@ -1721,11 +1721,11 @@ msgstr "Деактивований обліковий запис форуму." #: allianceauth/services/modules/phpbb3/views.py:70 msgid "Reset forum password." -msgstr "Скидання пароля форуму." +msgstr "Скинути пароль форуму." #: allianceauth/services/modules/phpbb3/views.py:98 msgid "Set forum password." -msgstr "Встановлення пароля форуму." +msgstr "Встановити пароль форуму." #: allianceauth/services/modules/smf/views.py:52 msgid "Activated SMF account." @@ -1744,11 +1744,11 @@ msgstr "Деактивований обліковий запис SMF." #: allianceauth/services/modules/smf/views.py:95 msgid "Reset SMF password." -msgstr "Скидання пароля SMF." +msgstr "Скинути пароль SMF." #: allianceauth/services/modules/smf/views.py:121 msgid "Set SMF password." -msgstr "Встановлення пароля SMF." +msgstr "Встановити пароль SMF." #: allianceauth/services/modules/teamspeak3/forms.py:14 #, python-format @@ -1761,7 +1761,7 @@ msgstr "Оновити групи TS3" #: allianceauth/services/modules/teamspeak3/templates/services/teamspeak3/teamspeakjoin.html:5 msgid "Verify Teamspeak" -msgstr "Перевірте Teamspeak" +msgstr "Перевірити Teamspeak" #: allianceauth/services/modules/teamspeak3/templates/services/teamspeak3/teamspeakjoin.html:10 msgid "Verify Teamspeak Identity" @@ -1869,11 +1869,11 @@ msgstr "Керування послугами" #: allianceauth/services/templates/services/services.html:9 msgid "Available Services" -msgstr "Доступні послуги" +msgstr "Доступні сервіси" #: allianceauth/services/templates/services/services.html:14 msgid "Service" -msgstr "Послуга" +msgstr "Сервіс" #: allianceauth/services/templates/services/services.html:16 msgid "Domain" @@ -1881,7 +1881,7 @@ msgstr "Домен" #: allianceauth/srp/auth_hooks.py:13 msgid "Ship Replacement" -msgstr "Компенсація за корабель" +msgstr "Компенсації" #: allianceauth/srp/form.py:9 #: allianceauth/srp/templates/srp/management.html:36 diff --git a/allianceauth/locale/zh_Hans/LC_MESSAGES/django.po b/allianceauth/locale/zh_Hans/LC_MESSAGES/django.po index 81806592..b7767ec2 100644 --- a/allianceauth/locale/zh_Hans/LC_MESSAGES/django.po +++ b/allianceauth/locale/zh_Hans/LC_MESSAGES/django.po @@ -4,9 +4,10 @@ # FIRST AUTHOR , YEAR. # # Translators: -# Joel Falknau , 2020 -# Jesse . , 2020 -# Aaron BuBu <351793078@qq.com>, 2020 +# Jesse . , 2023 +# Aaron BuBu <351793078@qq.com>, 2023 +# Joel Falknau , 2023 +# Shen Yang, 2023 # #, fuzzy msgid "" @@ -14,8 +15,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \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" +"PO-Revision-Date: 2023-10-08 09:23+0000\n" +"Last-Translator: Shen Yang, 2023\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" @@ -46,48 +47,48 @@ msgstr "" #: allianceauth/authentication/models.py:80 msgid "English" -msgstr "" +msgstr "英语" #: allianceauth/authentication/models.py:81 msgid "German" -msgstr "" +msgstr "德语" #: allianceauth/authentication/models.py:82 msgid "Spanish" -msgstr "" +msgstr "西班牙语" #: allianceauth/authentication/models.py:83 msgid "Chinese Simplified" -msgstr "" +msgstr "简体中文" #: allianceauth/authentication/models.py:84 msgid "Russian" -msgstr "" +msgstr "俄语" #: allianceauth/authentication/models.py:85 msgid "Korean" -msgstr "" +msgstr "韩语" #: allianceauth/authentication/models.py:86 msgid "French" -msgstr "" +msgstr "法语" #: allianceauth/authentication/models.py:87 msgid "Japanese" -msgstr "" +msgstr "日语" #: allianceauth/authentication/models.py:88 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 @@ -696,7 +697,7 @@ msgstr "" #: allianceauth/groupmanagement/models.py:215 msgid "reason" -msgstr "" +msgstr "原因" #: allianceauth/groupmanagement/models.py:215 msgid "Reason why this name is reserved." @@ -754,7 +755,7 @@ 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." @@ -1198,11 +1199,11 @@ 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" @@ -1343,7 +1344,7 @@ msgstr "当前EVE游戏内时间" #: 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 @@ -1352,7 +1353,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 @@ -2257,15 +2258,15 @@ 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" @@ -2273,11 +2274,11 @@ 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" From 322131cd4f178b81a41f7a4d4eef38a4fef0fb49 Mon Sep 17 00:00:00 2001 From: Ariel Rin Date: Wed, 8 Nov 2023 23:56:16 +1000 Subject: [PATCH 7/8] Update source language strings --- allianceauth/locale/en/LC_MESSAGES/django.po | 238 +++++++++++-------- 1 file changed, 135 insertions(+), 103 deletions(-) diff --git a/allianceauth/locale/en/LC_MESSAGES/django.po b/allianceauth/locale/en/LC_MESSAGES/django.po index cc639fd7..1c14c6ca 100644 --- a/allianceauth/locale/en/LC_MESSAGES/django.po +++ b/allianceauth/locale/en/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-10-09 18:20+1000\n" +"POT-Creation-Date: 2023-11-08 23:55+1000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -26,7 +26,7 @@ msgstr "" msgid "Google Analytics V4" msgstr "" -#: allianceauth/authentication/decorators.py:37 +#: allianceauth/authentication/decorators.py:49 msgid "A main character is required to perform that action. Add one below." msgstr "" @@ -39,63 +39,68 @@ msgstr "" msgid "You are not allowed to add or remove these restricted groups: %s" msgstr "" -#: allianceauth/authentication/models.py:80 +#: allianceauth/authentication/models.py:71 msgid "English" msgstr "" -#: allianceauth/authentication/models.py:81 +#: allianceauth/authentication/models.py:72 msgid "German" msgstr "" -#: allianceauth/authentication/models.py:82 +#: allianceauth/authentication/models.py:73 msgid "Spanish" msgstr "" -#: allianceauth/authentication/models.py:83 +#: allianceauth/authentication/models.py:74 msgid "Chinese Simplified" msgstr "" -#: allianceauth/authentication/models.py:84 +#: allianceauth/authentication/models.py:75 msgid "Russian" msgstr "" -#: allianceauth/authentication/models.py:85 +#: allianceauth/authentication/models.py:76 msgid "Korean" msgstr "" -#: allianceauth/authentication/models.py:86 +#: allianceauth/authentication/models.py:77 msgid "French" msgstr "" -#: allianceauth/authentication/models.py:87 +#: allianceauth/authentication/models.py:78 msgid "Japanese" msgstr "" -#: allianceauth/authentication/models.py:88 +#: allianceauth/authentication/models.py:79 msgid "Italian" msgstr "" -#: allianceauth/authentication/models.py:91 -msgid "Language" +#: allianceauth/authentication/models.py:80 +msgid "Ukrainian" msgstr "" #: allianceauth/authentication/models.py:96 +msgid "Language" +msgstr "" + +#: allianceauth/authentication/models.py:101 #: allianceauth/templates/allianceauth/night-toggle.html:6 msgid "Night Mode" msgstr "" -#: allianceauth/authentication/models.py:110 +#: allianceauth/authentication/models.py:115 #, python-format msgid "State changed to: %s" msgstr "" -#: allianceauth/authentication/models.py:111 +#: allianceauth/authentication/models.py:116 #, python-format msgid "Your user's state is now: %(state)s" msgstr "" #: allianceauth/authentication/templates/authentication/dashboard.html:4 #: allianceauth/authentication/templates/authentication/dashboard.html:7 +#: allianceauth/authentication/templates/authentication/tokens.html:4 #: allianceauth/templates/allianceauth/side-menu.html:10 msgid "Dashboard" msgstr "" @@ -151,8 +156,49 @@ msgstr "" msgid "Alliance" msgstr "" +#: allianceauth/authentication/templates/authentication/tokens.html:7 +#: allianceauth/templates/allianceauth/top-menu-user-dropdown.html:62 +msgid "Token Management" +msgstr "" + +#: allianceauth/authentication/templates/authentication/tokens.html:12 +msgid "Scopes" +msgstr "" + +#: allianceauth/authentication/templates/authentication/tokens.html:13 +#: allianceauth/hrapplications/templates/hrapplications/management.html:28 +#: allianceauth/hrapplications/templates/hrapplications/management.html:83 +#: allianceauth/hrapplications/templates/hrapplications/management.html:127 +#: allianceauth/hrapplications/templates/hrapplications/searchview.html:27 +#: allianceauth/hrapplications/templates/hrapplications/view.html:73 +#: allianceauth/srp/templates/srp/data.html:101 +#: allianceauth/srp/templates/srp/management.html:44 +msgid "Actions" +msgstr "" + +#: allianceauth/authentication/templates/authentication/tokens.html:14 +#: allianceauth/corputils/templates/corputils/corpstats.html:74 +#: allianceauth/corputils/templates/corputils/corpstats.html:112 +#: allianceauth/corputils/templates/corputils/corpstats.html:156 +#: allianceauth/corputils/templates/corputils/search.html:13 +#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html:22 +#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:26 +#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:30 +#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:29 +#: allianceauth/groupmanagement/templates/groupmanagement/index.html:55 +#: allianceauth/groupmanagement/templates/groupmanagement/index.html:112 +msgid "Character" +msgstr "" + +#: allianceauth/authentication/templates/authentication/tokens.html:28 +msgid "" +"This page is a best attempt, but backups or database logs can still contain " +"your tokens. Always revoke tokens on https://community.eveonline.com/support/" +"third-party-applications/ where possible." +msgstr "" + #: allianceauth/authentication/templates/public/login.html:6 -#: allianceauth/templates/allianceauth/top-menu-user-dropdown.html:58 +#: allianceauth/templates/allianceauth/top-menu-user-dropdown.html:69 msgid "Login" msgstr "" @@ -184,47 +230,47 @@ msgstr "" msgid "Invalid or expired activation link." msgstr "" -#: allianceauth/authentication/views.py:77 +#: allianceauth/authentication/views.py:118 #, python-format msgid "" "Cannot change main character to %(char)s: character owned by a different " "account." msgstr "" -#: allianceauth/authentication/views.py:83 +#: allianceauth/authentication/views.py:124 #, python-format msgid "Changed main character to %(char)s" msgstr "" -#: allianceauth/authentication/views.py:92 +#: allianceauth/authentication/views.py:133 #, python-format msgid "Added %(name)s to your account." msgstr "" -#: allianceauth/authentication/views.py:94 +#: allianceauth/authentication/views.py:135 #, python-format msgid "Failed to add %(name)s to your account: they already have an account." msgstr "" -#: allianceauth/authentication/views.py:133 +#: allianceauth/authentication/views.py:174 msgid "Unable to authenticate as the selected character." msgstr "" -#: allianceauth/authentication/views.py:197 +#: allianceauth/authentication/views.py:238 msgid "Registration token has expired." msgstr "" -#: allianceauth/authentication/views.py:252 +#: allianceauth/authentication/views.py:296 msgid "" "Sent confirmation email. Please follow the link to confirm your email " "address." msgstr "" -#: allianceauth/authentication/views.py:257 +#: allianceauth/authentication/views.py:301 msgid "Confirmed your email address. Please login to continue." msgstr "" -#: allianceauth/authentication/views.py:262 +#: allianceauth/authentication/views.py:306 msgid "Registration of new accounts is not allowed at this time." msgstr "" @@ -267,19 +313,6 @@ msgstr "" msgid "Last update:" msgstr "" -#: allianceauth/corputils/templates/corputils/corpstats.html:74 -#: allianceauth/corputils/templates/corputils/corpstats.html:112 -#: allianceauth/corputils/templates/corputils/corpstats.html:156 -#: allianceauth/corputils/templates/corputils/search.html:13 -#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html:22 -#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:26 -#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:30 -#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:29 -#: allianceauth/groupmanagement/templates/groupmanagement/index.html:55 -#: allianceauth/groupmanagement/templates/groupmanagement/index.html:112 -msgid "Character" -msgstr "" - #: allianceauth/corputils/templates/corputils/corpstats.html:75 #: allianceauth/corputils/templates/corputils/search.html:14 #: allianceauth/groupmanagement/templates/groupmanagement/audit.html:31 @@ -611,36 +644,41 @@ msgstr "" msgid "Group Management" msgstr "" -#: allianceauth/groupmanagement/forms.py:15 +#: allianceauth/groupmanagement/forms.py:18 +#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:35 +msgid "Users" +msgstr "" + +#: allianceauth/groupmanagement/forms.py:52 msgid "This name has been reserved and can not be used for groups." msgstr "" -#: allianceauth/groupmanagement/forms.py:25 +#: allianceauth/groupmanagement/forms.py:62 msgid "(auto)" msgstr "" -#: allianceauth/groupmanagement/forms.py:34 +#: allianceauth/groupmanagement/forms.py:71 msgid "There already exists a group with that name." msgstr "" -#: allianceauth/groupmanagement/models.py:105 +#: allianceauth/groupmanagement/models.py:104 msgid "" "Internal group, users cannot see, join or request to join this group." "
    Used for groups such as Members, Corp_*, Alliance_* etc.
    Overrides " "Hidden and Open options when selected." msgstr "" -#: allianceauth/groupmanagement/models.py:113 +#: allianceauth/groupmanagement/models.py:112 msgid "Group is hidden from users but can still join with the correct link." msgstr "" -#: allianceauth/groupmanagement/models.py:119 +#: allianceauth/groupmanagement/models.py:118 msgid "" "Group is open and users will be automatically added upon request.
    If the " "group is not open users will need their request manually approved." msgstr "" -#: allianceauth/groupmanagement/models.py:126 +#: allianceauth/groupmanagement/models.py:125 msgid "" "Group is public. Any registered user is able to join this group, with " "visibility based on the other options set for this group.
    Auth will not " @@ -648,65 +686,65 @@ msgid "" "authenticated." msgstr "" -#: allianceauth/groupmanagement/models.py:135 +#: allianceauth/groupmanagement/models.py:134 msgid "" "Group is restricted. This means that adding or removing users for this group " "requires a superuser admin." msgstr "" -#: allianceauth/groupmanagement/models.py:144 +#: allianceauth/groupmanagement/models.py:143 msgid "" "Group leaders can process requests for this group. Use the auth." "group_management permission to allow a user to manage all groups.
    " msgstr "" -#: allianceauth/groupmanagement/models.py:154 +#: allianceauth/groupmanagement/models.py:153 msgid "" "Members of leader groups can process requests for this group. Use the " "auth.group_management permission to allow a user to manage all " "groups.
    " msgstr "" -#: allianceauth/groupmanagement/models.py:163 +#: allianceauth/groupmanagement/models.py:162 msgid "" "States listed here will have the ability to join this group provided they " "have the proper permissions.
    " msgstr "" -#: allianceauth/groupmanagement/models.py:171 +#: allianceauth/groupmanagement/models.py:170 msgid "" "Short description (max. 512 characters) of the group shown to users." msgstr "" -#: allianceauth/groupmanagement/models.py:178 +#: allianceauth/groupmanagement/models.py:177 msgid "Can request non-public groups" msgstr "" -#: allianceauth/groupmanagement/models.py:209 +#: allianceauth/groupmanagement/models.py:208 msgid "name" msgstr "" -#: allianceauth/groupmanagement/models.py:212 +#: allianceauth/groupmanagement/models.py:211 msgid "Name that can not be used for groups." msgstr "" -#: allianceauth/groupmanagement/models.py:215 +#: allianceauth/groupmanagement/models.py:214 msgid "reason" msgstr "" -#: allianceauth/groupmanagement/models.py:215 +#: allianceauth/groupmanagement/models.py:214 msgid "Reason why this name is reserved." msgstr "" -#: allianceauth/groupmanagement/models.py:218 +#: allianceauth/groupmanagement/models.py:217 msgid "created by" msgstr "" -#: allianceauth/groupmanagement/models.py:223 +#: allianceauth/groupmanagement/models.py:222 msgid "created at" msgstr "" -#: allianceauth/groupmanagement/models.py:223 +#: allianceauth/groupmanagement/models.py:222 msgid "Date when this entry was created" msgstr "" @@ -933,86 +971,86 @@ msgstr "" msgid "Group Membership" msgstr "" -#: allianceauth/groupmanagement/views.py:163 +#: allianceauth/groupmanagement/views.py:166 #, python-format msgid "Removed user %(user)s from group %(group)s." msgstr "" -#: allianceauth/groupmanagement/views.py:165 +#: allianceauth/groupmanagement/views.py:168 msgid "User does not exist in that group" msgstr "" -#: allianceauth/groupmanagement/views.py:168 +#: allianceauth/groupmanagement/views.py:171 msgid "Group does not exist" msgstr "" -#: allianceauth/groupmanagement/views.py:195 +#: allianceauth/groupmanagement/views.py:198 #, python-format msgid "Accepted application from %(mainchar)s to %(group)s." msgstr "" -#: allianceauth/groupmanagement/views.py:201 -#: allianceauth/groupmanagement/views.py:232 +#: allianceauth/groupmanagement/views.py:204 +#: allianceauth/groupmanagement/views.py:235 #, python-format msgid "" "An unhandled error occurred while processing the application from " "%(mainchar)s to %(group)s." msgstr "" -#: allianceauth/groupmanagement/views.py:226 +#: allianceauth/groupmanagement/views.py:229 #, python-format msgid "Rejected application from %(mainchar)s to %(group)s." msgstr "" -#: allianceauth/groupmanagement/views.py:261 +#: allianceauth/groupmanagement/views.py:264 #, python-format msgid "Accepted application from %(mainchar)s to leave %(group)s." msgstr "" -#: allianceauth/groupmanagement/views.py:266 -#: allianceauth/groupmanagement/views.py:298 +#: allianceauth/groupmanagement/views.py:269 +#: allianceauth/groupmanagement/views.py:301 #, python-format msgid "" "An unhandled error occurred while processing the application from " "%(mainchar)s to leave %(group)s." msgstr "" -#: allianceauth/groupmanagement/views.py:292 +#: allianceauth/groupmanagement/views.py:295 #, python-format msgid "Rejected application from %(mainchar)s to leave %(group)s." msgstr "" -#: allianceauth/groupmanagement/views.py:336 -#: allianceauth/groupmanagement/views.py:346 +#: allianceauth/groupmanagement/views.py:339 +#: allianceauth/groupmanagement/views.py:349 msgid "You cannot join that group" msgstr "" -#: allianceauth/groupmanagement/views.py:341 +#: allianceauth/groupmanagement/views.py:344 msgid "You are already a member of that group." msgstr "" -#: allianceauth/groupmanagement/views.py:358 +#: allianceauth/groupmanagement/views.py:361 msgid "You already have a pending application for that group." msgstr "" -#: allianceauth/groupmanagement/views.py:367 +#: allianceauth/groupmanagement/views.py:370 #, python-format msgid "Applied to group %(group)s." msgstr "" -#: allianceauth/groupmanagement/views.py:377 +#: allianceauth/groupmanagement/views.py:380 msgid "You cannot leave that group" msgstr "" -#: allianceauth/groupmanagement/views.py:381 +#: allianceauth/groupmanagement/views.py:384 msgid "You are not a member of that group" msgstr "" -#: allianceauth/groupmanagement/views.py:393 +#: allianceauth/groupmanagement/views.py:396 msgid "You already have a pending leave request for that group." msgstr "" -#: allianceauth/groupmanagement/views.py:409 +#: allianceauth/groupmanagement/views.py:412 #, python-format msgid "Applied to leave group %(group)s." msgstr "" @@ -1074,16 +1112,6 @@ msgstr "" msgid "Username" msgstr "" -#: allianceauth/hrapplications/templates/hrapplications/management.html:28 -#: allianceauth/hrapplications/templates/hrapplications/management.html:83 -#: allianceauth/hrapplications/templates/hrapplications/management.html:127 -#: allianceauth/hrapplications/templates/hrapplications/searchview.html:27 -#: allianceauth/hrapplications/templates/hrapplications/view.html:73 -#: allianceauth/srp/templates/srp/data.html:101 -#: allianceauth/srp/templates/srp/management.html:44 -msgid "Actions" -msgstr "" - #: allianceauth/hrapplications/templates/hrapplications/management.html:38 #: allianceauth/hrapplications/templates/hrapplications/management.html:99 #: allianceauth/hrapplications/templates/hrapplications/management.html:143 @@ -1422,10 +1450,6 @@ msgstr "" msgid "Code Name" msgstr "" -#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:35 -msgid "Users" -msgstr "" - #: allianceauth/permissions_tool/templates/permissions_tool/overview.html:41 msgid "States" msgstr "" @@ -2146,11 +2170,11 @@ msgid "" msgstr "" #: allianceauth/templates/allianceauth/admin-status/overview.html:95 -#, python-format -msgid "" -"\n" -" %(queue_length)s queued tasks\n" -" " +msgid "running" +msgstr "" + +#: allianceauth/templates/allianceauth/admin-status/overview.html:96 +msgid "queued" msgstr "" #: allianceauth/templates/allianceauth/top-menu-admin.html:9 @@ -2166,11 +2190,11 @@ msgid "AA Support Discord" msgstr "" #: allianceauth/templates/allianceauth/top-menu-user-dropdown.html:10 -#: allianceauth/templates/allianceauth/top-menu-user-dropdown.html:14 +#: allianceauth/templates/allianceauth/top-menu-user-dropdown.html:16 msgid "User Menu" msgstr "" -#: allianceauth/templates/allianceauth/top-menu-user-dropdown.html:56 +#: allianceauth/templates/allianceauth/top-menu-user-dropdown.html:67 msgid "Logout" msgstr "" @@ -2226,22 +2250,30 @@ msgid "Objective" msgstr "" #: allianceauth/timerboard/form.py:64 -msgid "Days Remaining" +msgid "Absolute Timer" msgstr "" #: allianceauth/timerboard/form.py:65 -msgid "Hours Remaining" +msgid "Date and Time" +msgstr "" + +#: allianceauth/timerboard/form.py:66 +msgid "Days Remaining" msgstr "" #: allianceauth/timerboard/form.py:67 -msgid "Minutes Remaining" +msgid "Hours Remaining" msgstr "" #: allianceauth/timerboard/form.py:69 +msgid "Minutes Remaining" +msgstr "" + +#: allianceauth/timerboard/form.py:71 msgid "Important" msgstr "" -#: allianceauth/timerboard/form.py:70 +#: allianceauth/timerboard/form.py:72 msgid "Corp-Restricted" msgstr "" From 9ce19390403ad43817a73134497435bffcf63a18 Mon Sep 17 00:00:00 2001 From: Ariel Rin Date: Thu, 9 Nov 2023 00:00:28 +1000 Subject: [PATCH 8/8] Version Bump 3.8.0 --- allianceauth/__init__.py | 2 +- allianceauth/locale/de/LC_MESSAGES/django.mo | Bin 37872 -> 37984 bytes allianceauth/locale/es/LC_MESSAGES/django.mo | Bin 37814 -> 37819 bytes .../locale/fr_FR/LC_MESSAGES/django.mo | Bin 37724 -> 37715 bytes .../locale/it_IT/LC_MESSAGES/django.mo | Bin 17209 -> 38636 bytes allianceauth/locale/ja/LC_MESSAGES/django.mo | Bin 41641 -> 41667 bytes .../locale/ko_KR/LC_MESSAGES/django.mo | Bin 36909 -> 36909 bytes allianceauth/locale/ru/LC_MESSAGES/django.mo | Bin 47123 -> 47123 bytes allianceauth/locale/uk/LC_MESSAGES/django.mo | Bin 48143 -> 48104 bytes .../locale/zh_Hans/LC_MESSAGES/django.mo | Bin 27229 -> 28075 bytes docker/.env.example | 2 +- docker/Dockerfile | 2 +- 12 files changed, 3 insertions(+), 3 deletions(-) diff --git a/allianceauth/__init__.py b/allianceauth/__init__.py index d4748f2c..d458df19 100644 --- a/allianceauth/__init__.py +++ b/allianceauth/__init__.py @@ -5,7 +5,7 @@ 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.7.1' +__version__ = '3.8.0' __title__ = 'Alliance Auth' __url__ = 'https://gitlab.com/allianceauth/allianceauth' NAME = f'{__title__} v{__version__}' diff --git a/allianceauth/locale/de/LC_MESSAGES/django.mo b/allianceauth/locale/de/LC_MESSAGES/django.mo index 58c63685e71b5fd8a2fa33262e44681a76b4510b..c403cb25dd97f1956d10801ebb266782ffb8b30c 100644 GIT binary patch delta 5280 zcmZwI32;@_9mnzeLLduESPTMTxr8;4AObCvXdw`y0#aF3ERg%i&C4Und-1)SXd>_c z!wvzw&{n~%N&zV<^D2&%sx|7ggIH*%hzk~>tt{4Mq&Oq3_WR4dWOSx844-q(J@1_V z`JW}9?@2kcH|6;cvJ&?ghS9XZFgoK!?21>hJ$71X7?ZFUPR0e;4xhwy+>1T&AYO+@ zF$d3J5Bv{y$LvLhaXsc^M=VB-KWmYZFtRBuq(M5UA8bGk_#_U-LpT~wV=wGdY8Y)X zAJuOZ4#Zn94Xe;Z2a9nBPQmwZBAOO`(XtX=hkZ0?rJtf!dSlQq_-EAe-~D(B>v85{ zZ-S$kLH#eNOq@oo?4PKBE@KvElo>`}?1@_OI2?+_I1;N96gp6N%i8OJ z<(KeQ>}Pu`sK7g@??VOhwQp*<7eFV})(pUIc(djjDB?y`AP=MV>Q^`n zU&boDfDJe=G7WFR(D9f1lU>3a-&Q~wyXz|?TdI0++*f(9ClO7)Mi zB?G9Gy@nb1w(lw5v#6ARf+hGh>UTv;ycJK!RO+Rub{nl*hWF8e>W-v zhfuem+4m&s&|N^KGPTkhsE2O>>iZH^2#i96--<}!q_Pi@*(w>j%KNj2J1k?gcP??+_ zA^+-F>NiyS9TTX4)}U5!!1oX;6R)6FcpOvk0&)S2PjDj6ih9?}MP=x9)Rw%D`u(S< zv+-?|{41i=8ZW|3>_oi_D#a%16yJpXa2|HSI@EycQ2lrMK7(4>OaAv`s7#$f6F)&^ zw&T6txWf|^G|&|6jCc8lQ9o?(U4#1JLpT+m_uH@frp3H1>W0dw>DPz*^>L`Jn2bYk z8tN=1;uI8d6KaosiCu7??{860^D)%nIfq$z6_wid@s_J^?ij`+m|N=| z;@{zZ>PJz5+*j8!Pr^u0&;;91_j3>G&>iu86BXcbRDgd+4RFc-{w2Og{l7R7Pu=G| z={`uLp?-=YweHvykzfn#>6V;$5ScNy^PSh!V7nS-CQMcg=D$s9H znag;)bmh*jYW-Hg4(jXFb6BJ7dB!-g~uuAZ9eS#4r)c0@ducO{f5-p$3|VTF5;(21o z2dHb9+UTvU2dZO#)c4_7gtKuH?m(^V6e<({!d$$9+UuUHz06ET1>~T{TZ+o`8Z>qP zw^Ptwy?{632~p#~`R+n1mwUWW>N8!B_VQHSvmYHLsUo{}bF%7q)-ho|c z;n)5U+3YoPmmbHD==PQ4_y~%G^oRMCVZt z&o`*U+Ix$a`a)E{x!3_is9WP;drYjSpj7WbrRvwHjwewoJ%^g$BARGy^?ukNHE;nc zgA-7PY8Gmxm6(DF%*RzY1)swq_-`D*XQR(HULzWcP=9o`;LZ3ts$r8w{MwjVR2wgEK2i~@jfBjy zupPH)s&vB9h#8JMrX7x$w_3F|&f*FyW>q?TwPWScSeYHG3NNl0VU{!>3E5_C#IYmp z+Y4?z*p4|P3}$g+VaJJI`yOq~ORibiCD0~Z5pf@0bbm&y z+S05H)1`E|J3ZLZ%?@7YRt2-%!=>4+^-HCLTFd#C*;=l!hP0OVTLW9mm#kdByyrWi z4RJ39r?u9jjYFvqbDI{=$eI!h*}+IS9=A=FXu5AL&T&)9Mz{7|(RjT(tL*d6XIDHn zXlOLJ#9r*=#m}zT<<79T^qfa(NJr3$+2-VEtR@<}wxni^d~p|UiM{jQ}` za!+M?z+GmW?%P#)9T>u_YCgnt{5Vn8H)&R92D-Hl9JH-i&*k@F~>%H~6ni0x)MIi2It zayu3=Nut?&gmK+18*|IMP)q(;DQD8Ea_r=(O+N_?DyH`& zJ5o#BF>?@cMI$^$ikTZ+ZO*o11mb2jb$9P{#EaKX6ooX4ywPuACcicW( rb26+53+4TC+=*MW`)QQ8wof^W>!tku8y4Go!tMD`x8&SyJ5&A#{`D-u delta 5217 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 L7S}A#jZga@b742i delta 4017 zcmXZcc~F-{9LMn$6%a)Z^8gipo@j^xim0Gij;Pq-Z5rZ*Ct{%BO^;V8o*m&+d1>yU%lYhu?u6etVaOc&n-z zQ*Wd(ZH+OTUoggpUtkZc!YFK)VN5jk#S+ZLrRX=xn4Y){{qZCQ;~5-*6&Qv|nZ|@; zKMcSO?0{LB#xuQXl+vLIe#Ah$j1gFgk74!EHjzfym^cYFJ{TKf4%Wn%Q46d@EnJFP zcpEmt53nwNi>>kUXwR6=H2lXHQy;sdb}$(A;8<*fxv0d}V>8^0-S8N8!TZ<|JB?)y zoQxXZjvBv$S|@UxF~e~nvNyBSqd}ET;CQ=07FH+D!P=OIAy|k?a5aYFyQm}Ek9w{G zwWCUBNR~0Rh!as2Nkwg-560jCOhj)14Q2Mevl0gq`zF{IW}p_F?_7l{{YF%2526w~ z<@zt9j`AKVv1$`-0>M~^xIXGGwLq?iXVPiRrlSmXw!TUB5~g50@hH?z)?ysKiS_Ul z>P#;>|HB~S(8)Hj#@K+k1FF=$(I2;B0Pepk<*1Fk>fDREQ>Rf!`IC#Quo3Hr#p z_@{3C7YwBTA-2Q7Y4-U9RAtgp^A5+yaU!@nY0vT#2g07E~f-E?GI@3rOw@2NT6x0z8MxFf()SvSeH@*RbiQjh~!@9)Y*EDn~DsTvz zJp1BMtVKB0#rderi%Nu;3%`=T<= zumdI!pC?|5N3jAQ;KrGJV)%Bxov?KQe?j6zRK=<=6mO#D^_yiAYJl2MJnFe*4AJ-h z6b+r(Ak+~IM_saU_yfL(ov<%|sdOyFG(3sA10i#a;je4Dpepk=YJqJSj(c4HQP+PG z8_<773-21dpIf{PP)DE&yf3SSiM8z0}ucJy@hFbU|)MY)3k$4ds;a${GhR?S< zjYcKd1EX;m>e9b7pZdqsD5FC!{Dey2PdtuyP&+=nz$Wl1YUk&$I$l71Mwe0l2fso) z?n5OSjd7Tanr9m7E6GP~sI-v!>$BKKhdzgLRD2x$@Egf0Xt&UoxFVQ3qwd-!-+zehISgh)PC2`qIU8c>cJh@8TVmZ z{0;R#2z%L%r=b!Z;LJeX^2yi?i&3B5UexD&37ccRR~Tn~lSo6E4@LceGO-3uK_xI9 zb&2MnCR~p?%Y)9(o!_C3=nAR=f1!>xcA34LT=yjUCQtkHsL2wKcs;eh?7tY<)YqOi`wx<)N}7)0DiWD`p=?qnhs^u zYo$GcbkqbxQJ+t~a~bNnw=f2`U{CxC_3N#>%1#`GI*K;v!$fR>!>}vP#kN@P(dbFz z0&3!>tL<%Wg|&#g;-kcz=@>-+K&*oqsESQNRct=S;X+KpeW<%oiLJ2B8oO|R)ZOs% zY1F2%3st%UsELoF{^h4ppVzObirhn$K4PsM?~E$tbEq>Pjw*FFJ~~R&&ex!x+lN}` z5c0fdj?>VsKJNx@V=(bUR3gE}cEU(!4EoWZf^nFNT`(8*r`(B3@C0_lYpA1YR$}ds z8lR03`u<;~(Tk4vFaiHYHfdU~Gv;aBkD8!bsU43+9nBcjQA|bctN?Wcg)Uxh1&pD|&2!OZe?BinWTAGY~3 Aj{pDw diff --git a/allianceauth/locale/fr_FR/LC_MESSAGES/django.mo b/allianceauth/locale/fr_FR/LC_MESSAGES/django.mo index 0ce53fff6632dc9bf699a4e8f5999c03e3e341ef..26fac9e22624a53a2d07bba981e186c54865789f 100644 GIT binary patch delta 4002 zcmXZfc~F-{9LMn$Q4mDv=LsnOKtu!y40Qq(LGT){G#WukMGh}S6V1EF`vC3GY09gn zbWl6Im{QBoawf0Q%A;now8@cgb8I$S#ao2xdyZd`~_q*TyKF`PxwE>rF0}hsk zd$moB=}=(I5M#`VLSrUi(0F6UVhN_;$If4HA$=bY$r|j9fknoIVJ5b~p*Ru8Vgw#S zAAW(scooy}dXe!=77gF?#x%z<7=#7b0Vks-F2X3>i0yEX`@P=vzeCOc9X0SWF z@2!bO^O7(Wb1)W1PV|iFMPoJtk+>UMVLis-1x&(wsK}!y*@feAApJ}ngv&4sPq}`; zWc&M2%wxO;bMR|?0e!{Bl;diT#!MP_QIU_EVk4Y{O65${N#>(6QiJVrHzwk7Y>Brp z2Jd4sK2c)l_eTXj#Py%S1p4DK1HBbA6yc{h08J^^0NJRNZpLujin@w@s6dWmYrKkW z@D3{AM%29EGJ?Qx)OalFxn%5$**KN`O*xHO3|z#{*pIyEBt@u`EWr@mgH?DKRSOBs zj>jDIV>yQ6I#i%rP?@U5XR#ieqi>ou5<}VF_-QD@9;j6IL2a0eqi~e_eJ6IIzXzM) zdDI5qplat1DuAZb?Q`L%Or@jN9f2ysLR5frurvFcRWx+RyHF`Qh8^*u9>BY(386Er zF{tsLsMm80wm=VqaRX|-&8TADi-C9q;D@3`^P zr~tom{RY%?_g%jcb+^qaBwa-qDihsM#hZq@vTRi52BQKfpGE$)P$dKUQY}WEqy}{r zJ8>u;#=-aywZOnio60GuJ6(f1*$z}q96)V&8Wq?DRLZZQA8()zXuR1rH3_H;@UAdE-$5&2jzp7*78!r?;O*A_MhUgtt-e zb>0g$@&eQXlTevifV%q)sFQ6$rFt9cj(4GI<~(YhJE-R#;S(4**V+y_uxAo!=q~!B z4+o(p7N7#EzzcX5BbpfVMiuozfA2h7-C6VP{E?^)o;?7{x&~DnAD|Zg2OpmlwL#!Qo0+z#^<%I- zCZYn(#whkTW8J_k)X6>c;TBX4)S@;xh1%deYN1Qm78|ewnnm`xNYwmT)LYXFd*f)- zcVG=hVl{d#Y3!z<2oIsE`BT*RB~(B+P$~Tjb+X{acH>A?ic?X=I2=`6g{Tuw$5yxm zpTcTP$ItL-{Btq+*Mdn)Y~+2Nxu^w(yZ-a2$jeX}nSq+O4x8eesONWJFWisH)J@bU zy8(5OR!i-{;!uI6E+zju`2YsA&@ha`k=PBVp+1?f;yA2Br80DxeJ%&}ToI<>YSh(y z{l==$wmGNwD@sU8ibwh*JS5@WC$JK;Xm0;f@_{0UVHf1qBw2dI;(kafZ! zR3@TPSD1qO5M`p)%f?*Pe|(bBdzXeDyokD!Yp4%No8`6^`k>y5k*Ey{QAIb)xe6oc zZ^Z4&Vh^OK#uP=WMcPyRLWIRhvJm@@vE$G*8ApbhS83t6R>gf{kD2ELTDVoX7~x} z+kFz1>dUANZ(|@nKz&O8LltG}M*D|H1?JIz-+2#pg}pb~*Eb)Pfyu5v6_t6fibevB zjo1zAup?eW-O;}oiV-i{2^~?X?TtG5VC;^?sLa)1OWcV%zoE+kqt^WuS;sSh zuh{zvKdiK@*#BhR_JYqd{|7Uu BD{24$ delta 4011 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 YgKxk_EE!sYw6+3u=8_u)>lq3D7xq5mTmS$7 delta 6737 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 diff --git a/allianceauth/locale/ja/LC_MESSAGES/django.mo b/allianceauth/locale/ja/LC_MESSAGES/django.mo index d917d5a9a8c412a05fddc3cf316ff79e319ae565..09421c026c9636b6f6c3e68470f72fdadd85e6d6 100644 GIT binary patch delta 4045 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 M`31EHb7F@5573E7oB#j- diff --git a/allianceauth/locale/ko_KR/LC_MESSAGES/django.mo b/allianceauth/locale/ko_KR/LC_MESSAGES/django.mo index 235e7c8af907fbd188ce184f5aa0e50c67ac599e..acb3fa85a8e642c7459c31cee64d598b8e35efa6 100644 GIT binary patch delta 34 qcmZ3xfNAXlrVX88yvDkQ2D%0o3I>)|M#ht;g{d+cZ{8DDXbAwuOA7!1 delta 34 qcmZ3xfNAXlrVX88yau`kM!JR;3I@hjh9;Azg{d+cZQc`BXbAwt$qM)Y diff --git a/allianceauth/locale/ru/LC_MESSAGES/django.mo b/allianceauth/locale/ru/LC_MESSAGES/django.mo index d342dbcf5f2039b44981714ac1d79eb48d893d54..e41d5000ffc535ba56fb119a47538a502d6cacf7 100644 GIT binary patch delta 28 kcmbRIfobvwrVYtayvDkQ2D%0o3I>)|M#h^9q87&j0F#9YfB*mh delta 28 kcmbRIfobvwrVYtayau`kM!JR;3I@hjh9;W}q87&j0FyHbc>n+a diff --git a/allianceauth/locale/uk/LC_MESSAGES/django.mo b/allianceauth/locale/uk/LC_MESSAGES/django.mo index d14537e99def09a881a3bc57152acfdce48fc437..3a8c0d0db9b16797b55b5cfb3dfbe30ba920d3e7 100644 GIT binary patch delta 4109 zcmY+`c~n)$9l-HH79#?(Ba8S@a2HTSMO1K!M&kmh)g(nlQx!r4v0|bnK0s8WRjF4& z0}=_cRTRP%1QoRLB=OXweJ`G-LXSrn!E55w^*9Ernnm70WcDC06P47cRkl?tR#Lc@5h#5wqLJb?q)fG6_w4rXst zDw=ve&czD!#b4t+{1|O`i*(9-4=@3Pw=3n3OK~)=MG3UnPNA7XBl=+akF=R6smw!J z-~jsLNy~F60rsM7VAT$#mSHwZy%S}jTPQpK!fKBwP-+78DJTKjGbqS_{Wt=va5#3O z416D>aKQRKYNt+V3dYmE9%WoP%D4-di0|M${0~atDKF}cJ%tg}Hz4EeY7d3SXsE^n ztVg+2eY%6Xk15m#zob+uE=D<`GL*~oHp=fqb}6+8m!M><9OJMSWyemGK)*%VaM*6S zYn*=^g@rU^p>#Zt67e0B!2W_>_&1b^U4E>0=#PV`KY`OR4M*YulzxpUm#qtB!5cUc z?^ty=o?Zm&t56Cua5~1~YLo%{FbH48aoA@4-iL0~AA4D;pQ1N%Pt|KU3w`$J%en+* z-aR-RYf#2rLJ9CH+GU6DQIN~`0nWrfSw<4w66$L(9BVNGdr&SETQ0iQ14(3O61R@q-Yn) zdg9qMvZ_unf7U%J;BR&*C9$#*a}lQ+`A#53EPosJ(@Pr06C} zD*I5*_)DCC-bZ!HW}@`V!6+=mG_1i<_ytN}{^k1B#GtgtqTH!;lyL{q7h8~Z?5c-C zG!6Z@4hK*sTF2F%g!vePH7J?rwAyc=C-pCJ1pXUkfzV?*#mVSHeLarHT#Ut&D4*VU zaJ0Pt&nUV5SeiJO`gN3d zKY;SRm{_4Roq*}Aua;U3)fi9RL^=C=mTr~$uUs@rCg!3WuEuHj15CzplvKZqE$Dty zsZH39b8z@6rIzDrlsk78?Wq(#r!XDkUe%XrGX_#`LOFsSOvO)8&U9jx-q8x2Ono;_ z!6uBuehfj+YMr4`DBqc6^u>i3j^D2)|I#s^hG2Zf>Uai&s5j%|cn#;F`)Qrx#h6Zg z6;8zllnMK+-~Wzs7Y5bn_Grsg96@^qJ`B8u{L9%k(I7kirPc9|mILTVd-!X5p~)x{ zXQC`vflT59M{Jdi@MTQOC=q{y zGND_8ULXSH%;uszqYPYyW!R5*aTazp>bvn3%DY!hI-p@FcO(&Id=^UJ$8n6j|4s^W zYwx1$+`CzSB4?mPJQv5{N|aRYM7f-Yu^j7A0-p9W{T*3`@@jVA<5-Kc@y{rki$16O z&%oiVuU1l!)MlX#3(*r#<27tTFU)Gu6BM94*D@T5*Dw@6M7d<&;1lR`UcdJ>7)HGw zB{SDi`u_^;%PHKakccxbaDi|uN=AN<+34G<1KN$U^L;oTt55=e3uR}0R{H~#j0Lyp z%Q^==sApgXK8GoIy^Z|;kb-(cr)m?Pi`VgX0z=SBo()D9R^&|&u}}=px%u;@UNJTo4fc{U>6dz z>gd)P%f77COVnF10AsG`0F%(4`g0hFJJAadq1>^klN5X?)L9MfDDSoh{qO_xe&p_C z?}W)y;wQ(?w8baQnwns4dp6v|z1Lan=rPMPXAkys^f=mV&QeFOv&gyEan)I2WNvxE zT$uG6cP~11IEx(Z&I)I-F*Y~GlWuL!5@&^@-Av0(bunIi!_PRKcg6_Gi#9iGo9Gp| z-(fPK*U|3ia&+6A2k2gGRu#6oJTlbSP!M9QCvl+e}!N!R_Ij+oVxY*0x99_;L zhrgG|@6HMvTzeRBn{z)QSDKTG*SZ?h z8beI8bimz}h)na~NB-WGOwcYJon?*=<9x*!^Uc%y-HlOoLB{&JGSU35?jzTswU6xn zv&OfLO-%u=-&?-OC~6w*{b2rF_WybF*%)I^xsc>xT-Z9;%)993 z5`E0kWg~!2M~97odmR^LL(+DMbRFfF%TA`O4K}(vMh$(WgZXtw${>AoMtNqqxw@;{ F^}h*BOECZd delta 4203 zcmZwJdr(!!9l-HLUSd%ZL_rWQ_#mR<6*Z+`MHC+xwXr&#(cp75Af`&xD8%R$L5zw* zIEn_r2Vi|g1&$YpppNNiG&adOO=oPaMw`*rq|v5{9gU5#-(UA++CTEwXMcOo+5PQr zcMsfq)S>KghlV>Lo;6CTh1p8Iir29Pr{pMAgMLet+KaUqhof_q>VgX#^RO$i2m50g z_Czlx;)fWF-{A-hTB_7o9E~wpxKw#m4;lyP5L+-AKf)I<@D-)VNzK5S*oKUyLVm4O zCtQn>Sc36*040&j7=;h84|ZCn)BsFCd2c%Q!mMQ;rMlBtL&rcY#h+s{?!t#yi(8lL z6%5H!svq$}9F3bX1TWzoyoN4pr<^k0O&pGaE0hYwRP2k>P!e6?p>dSP9_)f+S8AuD zlyW}G1o;?>TO6xV5nfbpx?Hk^$TA4Zv|9S7rWr@!-SRDn1SB|*g*cSB0%gVTp(J`AWx+pr zUCtW&@1l`G$1Icw_n~Bb1tqZ?7>svOw&H7)75c7aU-4)7Jf>qG%tv`{56WRXiZbD8 z9E4Y#_+J>!{HoI%`o(xmB%X-!!fKR(w&8PF?fiZb{fHmpTlg(FdVsF zmpU6Gh>KC)t3esJ7Co{;lZNa~JIYF~Vls9hyG%?)S=lCx#zPo~?_m_)MS0$5gYHkk zaN;>ATd)#GVI8{hHp+Y53aNiD8bb>83zM)L@m!QG$U{k}2)E%G?1vLJ>MdD{J&5yB zo-aeGTrJ9iT2NMc3CG|yOu~pFrNZ!qA~Kgfnny=0=AvX)iZOTuUHHD!e-9;LzhZs; z`e3*ZUp)K-uWq6m{Jwv)UeKmDSrGkuQRX?ZMPJKSbP?b1(2x>8MOnebtvd7B*oSxt z%HiAM^jD&+=n$@B;ATuG9#P822v;NLQ+3D`?G2YN0l3bKOLX9XdJjD>~yOV@{C^^ctnzc($yaFY`osI`_H1SE4 zdw(ATF|txuIu@rhze;vGwxXN(Aj;nV-tlXUBo5uJD=`@Th%;~mW@0L?M=A9gdJ^Q`A;dX2 z3@dRcUdEpI7^OlX)%r{fM5$mBM&Y<>>Msw@qoW6|aUR@(;l#UfJf6UG{061OBWoxf zjzvjuC(3{qP=3FOau&XD`h)lB-=D+Y^k<+XzHlG)m%S~gLss1EJb2adZ`h4~-~IX) zgrf{R31z}u48jr&#d6HRI*h@4C=&%9(BqH9Y~sl%6>IX)aM8GfGJyX-%D~T1N*PnDujx=sC!US6x78@Oa4XW}Znj#n@R>ksRRZaF@{{`5b^BQCe_loBW70L(-=YVOf@*gP{pxomxaS2AB(g~HIto$t;h=)-Uw^3Gh*Xe(Z zQn9!OeONOwfH()Ua5<*o?;5E8A{xPsx>T>?SmG9(hEGs3&ur3%a1qMsUyBJ?g^764 z@gd6n?rZ7<(orgsgYmcyrDBJ$A6_&)`kH+~hYUR6w4P`@MiXbDRHguB;8TttqEz7T zj^SQ?xYAHox)fi+6(}qI2;DfSS)a8ml**QSXh_V%}F0xEx@Us4XFE3cN(tK&z7@weaUTL<@S`EgL<@L@0)AJ?=cRg%1*o7{u$z_@L z2D{Qc^~Nb5qhdu^&~Dd+1*=|JvTUhwuDVCy5AB-u>wJog-k$P~Owz==n~g?KLUP9eQ>V!mPRoI30MkYQ>ZxcEF*rUexM`C>W$w;X0 zZ6qI^(UXx{tOgg0Jon$M8+nba&C;Veen$Ahm@d>`R@+1Y3Rz;mlPLjyOye~do%Z)} z*HLK_k%F@wUYEVo#Xy^-YIc#m!`>`oGl5;k0~FFoThhaLxg^YJ_I8bKr+=r6^?&ck Xa8el4@}_mr`)ZWWk1~h0zU%uRcCC$g diff --git a/allianceauth/locale/zh_Hans/LC_MESSAGES/django.mo b/allianceauth/locale/zh_Hans/LC_MESSAGES/django.mo index f0be3a20005565d75377e7cfaba5019628f88b15..d24dad4aeb33a6fb2d1015590c7bd27dd1f14a63 100644 GIT binary patch delta 9770 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