Compare commits

..

90 Commits

Author SHA1 Message Date
Ariel Rin
3452c3acd1 Version Bump v2.8.2 2021-02-05 12:19:25 +00:00
Ariel Rin
3c305fbf37 Merge branch 'wheel' into 'master'
Build wheel

See merge request allianceauth/allianceauth!1290
2021-01-26 12:59:56 +00:00
Rebecca Claire Murphy
a5e0721ec1 Build wheel 2021-01-26 12:59:56 +00:00
Ariel Rin
164a0d5376 Merge branch 'gitlab-announcements-fix' into 'master'
Only show open announcements

See merge request allianceauth/allianceauth!1291
2021-01-26 12:55:11 +00:00
Ariel Rin
2bcf6ec39a Merge branch 'master' into 'master'
Squash mumble migrations

See merge request allianceauth/allianceauth!1289
2021-01-26 12:30:35 +00:00
Peter Pfeufer
40824156bf Only show open announcements 2021-01-25 21:13:43 +01:00
Rebecca Claire Murphy
cec4495034 Merge branch 'master' of gitlab.com:allianceauth/allianceauth 2021-01-15 19:43:39 -05:00
Ariel Rin
74eb8621d9 Merge branch 'notifications_refresh' into 'master'
Notifications refresh v2 and session caching

See merge request allianceauth/allianceauth!1218
2021-01-16 00:09:49 +00:00
Erik Kalkoken
4394d25961 Notifications refresh v2 and session caching 2021-01-16 00:09:49 +00:00
Rebecca Claire Murphy
8113327d31 Squash mumble migrations 2021-01-08 12:28:12 -05:00
Ariel Rin
aeeb35bc60 Merge branch 'ceo_id' into 'master'
Add CEO ID to Corp Eve Model

See merge request allianceauth/allianceauth!1287
2021-01-08 10:37:33 +00:00
colcrunch
630aa3f320 Merge branch 'doc-fixes' into 'master'
It's TeamSpeak not Discord here

See merge request allianceauth/allianceauth!1288
2021-01-07 19:16:22 +00:00
Peter Pfeufer
3487a945c2 It's TeamSpeak not Discord here 2021-01-06 10:42:01 +01:00
Ariel Rin
1936ae44a3 Merge branch 'opengroupauditlogs' into 'master'
Add Open Group Audit Logs

Closes #1262

See merge request allianceauth/allianceauth!1279
2021-01-06 02:38:48 +00:00
Ariel Rin
3d7a84e786 Revert "Add Audit Logs to Open Groups and Autoleaves"
This reverts commit f64d81292e8b6c0531d610799098c3e3cf105c87.
2021-01-06 02:38:47 +00:00
Ariel Rin
a4d6730cb0 Merge branch 'docs' into 'master'
Document Permissions and other Docs Improvments

Closes #1253

See merge request allianceauth/allianceauth!1283
2021-01-06 02:37:29 +00:00
Ariel Rin
b724227a29 Merge branch 'dependencies' into 'master'
Bump Django-Redis-Cache to 3.x branch

Closes #1264

See merge request allianceauth/allianceauth!1280
2021-01-06 02:36:52 +00:00
AaronKable
d72964fd7c Add CEO Id to Corp Eve Model 2021-01-05 22:14:52 +08:00
Ariel Rin
d4a41cfb60 Merge branch 'transifex' into 'master'
Update from Transifex

See merge request allianceauth/allianceauth!1285
2020-12-28 07:11:50 +00:00
Ariel Rin
05859453df Update from Transifex 2020-12-28 07:11:50 +00:00
Ariel Rin
240d910c9b Document Permissions and other Docs Improvments 2020-12-26 16:10:42 +10:00
Ariel Rin
0c31bce7d0 Bump Django-Redis-Cache up to 3.x branch 2020-12-23 17:59:36 +10:00
Ariel Rin
f4c4ae36ed Merge branch 'fix_celeryonce_dependency' into 'master'
Prevent autoretry_for bug in celery_once

See merge request allianceauth/allianceauth!1278
2020-12-19 02:08:36 +00:00
Ariel Rin
b9931b2ceb Merge branch 'improve_groups_state_binding' into 'master'
Enable group state restrictions to work with internal groups

See merge request allianceauth/allianceauth!1276
2020-12-19 02:05:05 +00:00
Erik Kalkoken
4fd6f06c0b Enable group state restrictions to work with internal groups 2020-12-19 02:05:05 +00:00
ErikKalkoken
09573ba7ef fix dependency for celery_once 2020-12-17 22:53:27 +01:00
Ariel Rin
08e9676760 Version Bump v2.8.1 2020-12-07 04:46:55 +00:00
Ariel Rin
15ae737522 Merge branch 'user-agent' into 'master'
Bump minimum django-esi and add User Agent header.

See merge request allianceauth/allianceauth!1275
2020-12-07 04:32:10 +00:00
Ariel Rin
50ec9e563e Merge branch 'celery_result_logger' into 'master'
Remove result from default log message on task success

See merge request allianceauth/allianceauth!1273
2020-12-07 04:30:52 +00:00
colcrunch
cb40649f8b Add note to local.py on ESI_CONTACT_EMAIL setting 2020-12-06 22:54:31 -05:00
colcrunch
bccead0881 Add mention of ESI_USER_CONTACT_EMAIL to install documentation. 2020-12-02 17:42:03 -05:00
colcrunch
35ae710624 Add ESI_USER_CONTACT_EMAIL setting to local.py 2020-12-01 23:25:48 -05:00
colcrunch
75de4518f2 Use app_info_text in EveSwaggerProvider to set the User-Agent header on ESI requests. 2020-12-01 22:40:09 -05:00
colcrunch
bfcdfea6c8 Update minimum django-esi version to ensure support for user-agent header. 2020-12-01 17:17:55 -05:00
Ariel Rin
471553fa88 Add a minimal set of django deps needed to build docs 2020-12-01 07:14:22 +00:00
Ariel Rin
db59f5f69b Add Django to docs requirements 2020-11-30 14:41:01 +00:00
Ariel Rin
1b5413646e Correct Typos in Docs Requirements 2020-11-30 14:37:42 +00:00
Ariel Rin
0337d2517c use limited set of python packages for docs 2020-11-30 14:30:23 +00:00
ErikKalkoken
87e6eb9688 Remove result from default log message on task success 2020-11-28 22:10:41 +01:00
Ariel Rin
7b8c246ef8 Merge branch 'master' into 'master'
[Quickfix] Missing ^ added

See merge request allianceauth/allianceauth!1271
2020-11-19 13:26:53 +00:00
Peter Pfeufer
a268a8980a Missing ^ added 2020-11-18 22:50:27 +01:00
Ariel Rin
3b516c338e Merge branch 'groupmanagement-revamp' into 'master'
Group management improvements

See merge request allianceauth/allianceauth!1270
2020-11-17 11:56:16 +00:00
Peter Pfeufer
9952685805 textfield should not be Null=True 2020-11-16 18:04:57 +01:00
Peter Pfeufer
2f59c8df22 And of course I missed something ... 2020-10-26 01:10:41 +01:00
Peter Pfeufer
6cd0a42791 reverted code formatting for Aaron :-) 2020-10-26 01:06:58 +01:00
Peter Pfeufer
4c42153bfd stop member count header from line breaking 2020-10-25 13:53:17 +01:00
Peter Pfeufer
603bd9c37c make description a real description
textfield instead of charfield. a bit more user friendly in the backend
2020-10-25 12:40:10 +01:00
Peter Pfeufer
87c0c3ac73 tables formatted properly
align center is horrible to read ....
2020-10-25 11:55:03 +01:00
Peter Pfeufer
8a91e7f6ac navactive status fixed in left menu and top menu 2020-10-25 11:22:10 +01:00
Peter Pfeufer
281dbdbb01 proper URL structure established 2020-10-25 11:21:35 +01:00
Ariel Rin
8980d8d32f Version bump to 2.8.0 Stable 2020-10-13 05:33:54 +00:00
Ariel Rin
9d6cf9a62e Merge branch 'transifex' into 'master'
Add French and Japanese Translations + QoL Translation Fixes

See merge request allianceauth/allianceauth!1263
2020-10-13 04:17:37 +00:00
Ariel Rin
0fabb2b368 Add French and Japanese Translations + QoL Translation Fixes 2020-10-13 04:17:37 +00:00
Ariel Rin
9801ca0314 Merge branch 'emailoverrideredirect' into 'master'
Fix Redirect to dashboard if not verifying email

See merge request allianceauth/allianceauth!1268
2020-10-13 04:08:15 +00:00
Ariel Rin
fd86b26b39 Redirect to dashboard if not verifying email 2020-10-13 13:25:00 +10:00
Ariel Rin
b0dbef1587 Merge branch 'master' into 'master'
Expand mumble pwhash field to allow for passlib 1.7.3+

See merge request allianceauth/allianceauth!1267
2020-10-11 10:34:44 +00:00
Ariel Rin
a6e60bc23b expand mumble certhash to allow for hmac-sha-256 2020-10-11 20:11:56 +10:00
Ariel Rin
137e8a876d Merge branch 'add-corp-and-alliance-tags-to-srp' into 'master'
Add alliance and corp ticker to pilot name

See merge request allianceauth/allianceauth!1265
2020-10-11 03:42:56 +00:00
Ariel Rin
fe9538253f Merge branch 'highlight-active-menu-item' into 'master'
Highlight active menu item

See merge request allianceauth/allianceauth!1266
2020-10-11 03:41:17 +00:00
Peter Pfeufer
edda2c248e highlight active menu item 2020-10-02 20:12:21 +02:00
Peter Pfeufer
62275639e3 Added alliance and corp ticker to pilot name
Takes care of https://gitlab.com/allianceauth/allianceauth/-/issues/1228
2020-10-01 20:14:54 +02:00
Ariel Rin
d0c68b82f4 Merge branch 'docs' into 'master'
Docs Sphinx Upgrades

See merge request allianceauth/allianceauth!1264
2020-10-01 09:17:36 +00:00
Ariel Rin
78b5953bdf Merge branch 'master' of https://gitlab.com/allianceauth/allianceauth into docs 2020-10-01 18:59:14 +10:00
Ariel Rin
25e565b099 Docs Requirement upgrades 2020-10-01 18:54:04 +10:00
Ariel Rin
1fe0f78ad7 Exclude django-redis-cache 2.1.3 2020-10-01 01:59:48 +00:00
Ariel Rin
fc8b68156f Merge branch 'patch-4' into 'master'
Fixing FA icon

See merge request allianceauth/allianceauth!1262
2020-09-29 05:10:30 +00:00
Peter Pfeufer
b47cd197ce Fixing FA icon 2020-09-28 21:07:08 +00:00
Ariel Rin
3943426c4c Version Bump 2.8.0a2 2020-09-21 06:25:16 +00:00
Ariel Rin
08a9bd42a3 Merge branch 'django3' into 'master'
Django 3.1.1 bring up

See merge request allianceauth/allianceauth!1256
2020-09-21 06:16:44 +00:00
Ariel Rin
b2ff339efe Merge branch 'gitlabci2' into 'master'
Update Gitlab Deploy Python Version, Debian Distro to Stable

See merge request allianceauth/allianceauth!1260
2020-09-21 06:15:40 +00:00
Ariel Rin
c604131e04 Update Deploy Runner 2020-09-21 12:12:02 +10:00
Ariel Rin
f17607f126 Merge branch 'transifex' into 'master'
Update From Transifex

See merge request allianceauth/allianceauth!1258
2020-09-21 01:45:16 +00:00
Ariel Rin
94e455a57b Update From Transifex 2020-09-21 01:45:16 +00:00
Ariel Rin
3c9149db4a Merge branch 'improve_authtuilts_add_permission' into 'master'
Improve auth utils for permissions

See merge request allianceauth/allianceauth!1255
2020-09-21 01:09:03 +00:00
Ariel Rin
96cc615c07 Merge branch 'docs_mumbleavatars' into 'master'
Docs: Mumble Avatars Feature

See merge request allianceauth/allianceauth!1250
2020-09-21 00:01:35 +00:00
Ariel Rin
cd1f4a1c2b Docs: Mumble Avatars Feature 2020-09-21 00:01:35 +00:00
Ariel Rin
e0f99a42db Merge branch 'exiom-srp-update' into 'master'
SRP Module - Added Datatables & Sorting, Standardized Date/Time for Overall AA Consistency

See merge request allianceauth/allianceauth!1254
2020-09-20 23:55:22 +00:00
Exiom
3506e417d4 SRP Module - Added Datatables & Sorting, Standardized Date/Time for Overall AA Consistency 2020-09-20 23:55:22 +00:00
AaronKable
36197e2212 swap to reverse_lazy 2020-09-18 23:32:36 +08:00
AaronKable
fc5f42d01e remove whitespace in setup.py 2020-09-18 22:16:49 +08:00
AaronKable
e26d3767e0 update models as NullBooleanField is deprecated. 2020-09-18 22:16:24 +08:00
AaronKable
046b37c76a update auth and group model admins for django 3.1 2020-09-18 22:04:59 +08:00
AaronKable
925ff3e116 remove django req's from tox, they are managed in setup.py 2020-09-18 22:04:05 +08:00
AaronKable
e5ede4f7b6 Cant Reference what is already deleted 2020-09-18 22:03:16 +08:00
AaronKable
ded9301527 initial django3 bringup 2020-09-18 11:45:37 +08:00
ErikKalkoken
bd1ed6ff73 Add user as return value to add permission methods 2020-09-15 12:35:58 +02:00
Ariel Rin
feb65980d4 Merge branch 'fix_group_count_badge' into 'master'
Fix group count badge showing at zero

Closes #1258

See merge request allianceauth/allianceauth!1253
2020-09-12 02:05:22 +00:00
Ariel Rin
e81d75a782 Merge branch 'docs_settings_fix' into 'master'
Remove erroneous indents from settings in service module docs

See merge request allianceauth/allianceauth!1252
2020-09-12 02:04:37 +00:00
ErikKalkoken
ff305d13ae Fix group count badge showing at zero 2020-09-11 23:54:56 +02:00
colcrunch
8bcbc1a779 Remove erroneous indents from settings in service module docs. (Checked other docs, and there do not appear to be any more errors of this type) 2020-09-11 12:51:17 -04:00
142 changed files with 7744 additions and 1966 deletions

View File

@@ -41,13 +41,13 @@ test-3.8-all:
deploy_production:
stage: deploy
image: python:3.6-stretch
image: python:3.8-buster
before_script:
- pip install twine
- pip install twine wheel
script:
- python setup.py sdist
- python setup.py sdist bdist_wheel
- twine upload dist/*
rules:

View File

@@ -18,10 +18,6 @@ formats: all
# Optionally set the version of Python and requirements required to build your docs
python:
version: 3.7
install:
- method: pip
path: .
extra_requirements:
- testing
system_packages: true
version: 3.7
install:
- requirements: docs/requirements.txt

View File

@@ -1,7 +1,7 @@
# This will make sure the app is always imported when
# Django starts so that shared_task will use this app.
__version__ = '2.8.0a1'
__version__ = '2.8.2'
__title__ = 'Alliance Auth'
__url__ = 'https://gitlab.com/allianceauth/allianceauth'
NAME = '%s v%s' % (__title__, __version__)

View File

@@ -100,7 +100,7 @@ class UserProfileInline(admin.StackedInline):
formset.get_form_kwargs = get_kwargs
return formset
def has_add_permission(self, request):
def has_add_permission(self, request, obj=None):
return False
def has_delete_permission(self, request, obj=None):
@@ -549,7 +549,7 @@ class PermissionAdmin(admin.ModelAdmin):
def admin_name(obj):
return str(obj)
def has_add_permission(self, request):
def has_add_permission(self, request, obj=None):
return False
def has_delete_permission(self, request, obj=None):

View File

@@ -1,6 +1,8 @@
from django import forms
from django.utils.translation import ugettext_lazy as _
from allianceauth.authentication.models import User
class RegistrationForm(forms.Form):
email = forms.EmailField(label=_('Email'), max_length=254, required=True)
class _meta:
model = User

View File

@@ -10,5 +10,5 @@ urlpatterns = [
url(r'^register/$', views.RegistrationView.as_view(), name='registration_register'),
url(r'^register/complete/$', views.registration_complete, name='registration_complete'),
url(r'^register/closed/$', views.registration_closed, name='registration_disallowed'),
url(r'', include('registration.auth_urls')),
url(r'', include('django.contrib.auth.urls')),
]

View File

@@ -1,5 +1,5 @@
{% extends "allianceauth/base.html" %}
{% load staticfiles %}
{% load static %}
{% load i18n %}
{% block page_title %}{% trans "Dashboard" %}{% endblock %}

View File

@@ -1,7 +1,7 @@
{% load staticfiles %}
{% extends 'public/base.html' %}
{% load static %}
{% load bootstrap %}
{% load i18n %}
{% extends 'public/base.html' %}
{% block page_title %}Registration{% endblock %}
{% block extra_include %}
{% include 'bundles/bootstrap-css.html' %}

View File

@@ -6,20 +6,21 @@ from django.contrib.auth import login, authenticate
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from django.core import signing
from django.urls import reverse
from django.http import JsonResponse
from django.shortcuts import redirect, render
from django.urls import reverse, reverse_lazy
from django.utils.translation import gettext_lazy as _
from allianceauth.eveonline.models import EveCharacter
from esi.decorators import token_required
from esi.models import Token
from registration.backends.hmac.views import (
from django_registration.backends.activation.views import (
RegistrationView as BaseRegistrationView,
ActivationView as BaseActivationView,
REGISTRATION_SALT
)
from registration.signals import user_registered
from django_registration.signals import user_registered
from .models import CharacterOwnership
from .forms import RegistrationForm
@@ -134,11 +135,14 @@ def sso_login(request, token):
# Step 2
class RegistrationView(BaseRegistrationView):
form_class = RegistrationForm
success_url = 'authentication:dashboard'
template_name = "public/register.html"
email_body_template = "registration/activation_email.txt"
email_subject_template = "registration/activation_email_subject.txt"
success_url = reverse_lazy('registration_complete')
def get_success_url(self, user):
if not getattr(settings, 'REGISTRATION_VERIFY_EMAIL', True):
return 'authentication:dashboard', (), {}
return reverse_lazy('authentication:dashboard')
return super().get_success_url(user)
def dispatch(self, request, *args, **kwargs):
@@ -176,6 +180,9 @@ class RegistrationView(BaseRegistrationView):
# Step 3
class ActivationView(BaseActivationView):
template_name = "registration/activate.html"
success_url = reverse_lazy('registration_activation_complete')
def validate_key(self, activation_key):
try:
dump = signing.loads(activation_key, salt=REGISTRATION_SALT,
@@ -207,5 +214,5 @@ def activation_complete(request):
def registration_closed(request):
messages.error(request, _('Registraion of new accounts it not allowed at this time.'))
messages.error(request, _('Registration of new accounts is not allowed at this time.'))
return redirect('authentication:login')

View File

@@ -0,0 +1,18 @@
# Generated by Django 3.1.1 on 2021-01-05 14:11
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('eveonline', '0012_index_additions'),
]
operations = [
migrations.AddField(
model_name='evecorporationinfo',
name='ceo_id',
field=models.PositiveIntegerField(blank=True, default=None, null=True),
),
]

View File

@@ -0,0 +1,17 @@
# Generated by Django 3.1.1 on 2021-01-05 14:13
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('eveonline', '0013_evecorporationinfo_ceo_id'),
]
operations = [
migrations.AddIndex(
model_name='evecorporationinfo',
index=models.Index(fields=['ceo_id'], name='eveonline_e_ceo_id_eea7b8_idx'),
),
]

View File

@@ -82,6 +82,7 @@ class EveCorporationInfo(models.Model):
corporation_name = models.CharField(max_length=254, unique=True)
corporation_ticker = models.CharField(max_length=254)
member_count = models.IntegerField()
ceo_id = models.PositiveIntegerField(blank=True, null=True, default=None)
alliance = models.ForeignKey(
EveAllianceInfo, blank=True, null=True, on_delete=models.SET_NULL
)
@@ -89,10 +90,16 @@ class EveCorporationInfo(models.Model):
objects = EveCorporationManager()
provider = EveCorporationProviderManager()
class Meta:
indexes = [
models.Index(fields=['ceo_id',]),
]
def update_corporation(self, corp: providers.Corporation = None):
if corp is None:
corp = self.provider.get_corporation(self.corporation_id)
self.member_count = corp.members
self.ceo_id = corp.ceo_id
try:
self.alliance = EveAllianceInfo.objects.get(alliance_id=corp.alliance_id)
except EveAllianceInfo.DoesNotExist:

View File

@@ -7,6 +7,8 @@ from jsonschema.exceptions import RefResolutionError
from django.conf import settings
from esi.clients import esi_client_factory
from allianceauth import __version__
SWAGGER_SPEC_PATH = os.path.join(os.path.dirname(
os.path.abspath(__file__)), 'swagger.json'
@@ -166,7 +168,7 @@ class EveSwaggerProvider(EveProvider):
else:
try:
self._client = esi_client_factory(
token=token, spec_file=SWAGGER_SPEC_PATH
token=token, spec_file=SWAGGER_SPEC_PATH, app_info_text=("allianceauth v" + __version__)
)
except (HTTPError, RefResolutionError):
logger.exception(
@@ -182,7 +184,7 @@ class EveSwaggerProvider(EveProvider):
def client(self):
if self._client is None:
self._client = esi_client_factory(
token=self._token, spec_file=SWAGGER_SPEC_PATH
token=self._token, spec_file=SWAGGER_SPEC_PATH, app_info_text=("allianceauth v" + __version__)
)
return self._client

View File

@@ -592,3 +592,12 @@ class TestEveSwaggerProvider(TestCase):
self.assertTrue(mock_esi_client_factory.called)
self.assertIsNotNone(my_provider._client)
self.assertEqual(my_client, 'my_client')
@patch(MODULE_PATH + '.__version__', '1.0.0')
def test_user_agent_header(self):
my_provider = EveSwaggerProvider()
my_client = my_provider.client
operation = my_client.Status.get_status()
self.assertEqual(
operation.future.request.headers['User-Agent'], 'allianceauth v1.0.0'
)

View File

@@ -1,6 +1,6 @@
{% extends "allianceauth/base.html" %}
{% load bootstrap %}
{% load staticfiles %}
{% load static %}
{% load i18n %}
{% block page_title %}{% trans "Create Fatlink" %}{% endblock page_title %}

View File

@@ -1,6 +1,6 @@
{% extends "allianceauth/base.html" %}
{% load bootstrap %}
{% load staticfiles %}
{% load static %}
{% load i18n %}
{% block page_title %}{% trans "Fatlink view" %}{% endblock page_title %}

View File

@@ -1,6 +1,6 @@
{% extends "allianceauth/base.html" %}
{% load bootstrap %}
{% load staticfiles %}
{% load static %}
{% load i18n %}
{% block page_title %}{% trans "Personal fatlink statistics" %}{% endblock page_title %}

View File

@@ -1,6 +1,6 @@
{% extends "allianceauth/base.html" %}
{% load bootstrap %}
{% load staticfiles %}
{% load static %}
{% load i18n %}
{% block page_title %}{% trans "Personal fatlink statistics" %}{% endblock page_title %}

View File

@@ -1,6 +1,6 @@
{% extends "allianceauth/base.html" %}
{% load bootstrap %}
{% load staticfiles %}
{% load static %}
{% load i18n %}
{% block page_title %}{% trans "Fatlink Corp Statistics" %}{% endblock page_title %}

View File

@@ -1,6 +1,6 @@
{% extends "allianceauth/base.html" %}
{% load bootstrap %}
{% load staticfiles %}
{% load static %}
{% load i18n %}
{% block page_title %}{% trans "Fatlink statistics" %}{% endblock page_title %}

View File

@@ -1,6 +1,6 @@
{% extends "allianceauth/base.html" %}
{% load bootstrap %}
{% load staticfiles %}
{% load static %}
{% load i18n %}
{% block page_title %}{% trans "Fatlink view" %}{% endblock page_title %}

View File

@@ -41,7 +41,7 @@ class AuthGroupInlineAdmin(admin.StackedInline):
kwargs["queryset"] = Group.objects.order_by(Lower('name'))
return super().formfield_for_manytomany(db_field, request, **kwargs)
def has_add_permission(self, request):
def has_add_permission(self, request, obj=None):
return False
def has_delete_permission(self, request, obj=None):

View File

@@ -9,29 +9,35 @@ from .managers import GroupManager
class GroupManagementMenuItem(MenuItemHook):
""" This class ensures only authorized users will see the menu entry """
def __init__(self):
# setup menu entry for sidebar
MenuItemHook.__init__(
self,
text=_('Group Management'),
classes='fas fa-users-cog fa-fw',
url_name='groupmanagement:management',
text=_("Group Management"),
classes="fas fa-users-cog fa-fw",
url_name="groupmanagement:management",
order=50,
navactive=['groupmanagement:management']
navactive=[
"groupmanagement:management", # group requests view
"groupmanagement:membership", # group membership view
"groupmanagement:audit_log", # group audit log view
],
)
def render(self, request):
if GroupManager.can_manage_groups(request.user):
self.count = GroupManager.pending_requests_count_for_user(request.user)
app_count = GroupManager.pending_requests_count_for_user(request.user)
self.count = app_count if app_count and app_count > 0 else None
return MenuItemHook.render(self, request)
return ''
return ""
@hooks.register('menu_item_hook')
@hooks.register("menu_item_hook")
def register_menu():
return GroupManagementMenuItem()
@hooks.register('url_hook')
@hooks.register("url_hook")
def register_urls():
return UrlHook(urls, 'group', r'^group/')
return UrlHook(urls, "group", r"^groups/")

View File

@@ -0,0 +1,18 @@
# Generated by Django 3.1.1 on 2020-09-18 14:12
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('groupmanagement', '0013_fix_requestlog_date_field'),
]
operations = [
migrations.AlterField(
model_name='requestlog',
name='request_type',
field=models.BooleanField(null=True),
),
]

View File

@@ -0,0 +1,22 @@
# Generated by Django 3.1.2 on 2020-10-25 11:09
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("groupmanagement", "0014_auto_20200918_1412"),
]
operations = [
migrations.AlterField(
model_name="authgroup",
name="description",
field=models.TextField(
blank=True,
help_text="Short description <i>(max. 512 characters)</i> of the group shown to users.",
max_length=512,
),
),
]

View File

@@ -25,7 +25,7 @@ class GroupRequest(models.Model):
class RequestLog(models.Model):
request_type = models.NullBooleanField(default=0)
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)
@@ -107,7 +107,7 @@ class AuthGroup(models.Model):
help_text="States listed here will have the ability to join this group provided "
"they have the proper permissions.")
description = models.CharField(max_length=512, blank=True, help_text="Description of the group shown to users.")
description = models.TextField(max_length=512, blank=True, help_text="Short description <i>(max. 512 characters)</i> of the group shown to users.")
def __str__(self):
return self.group.name

View File

@@ -1,16 +1,22 @@
from allianceauth.authentication.signals import state_changed
from .managers import GroupManager
from .models import Group
from django.dispatch import receiver
import logging
from django.dispatch import receiver
from allianceauth.authentication.signals import state_changed
logger = logging.getLogger(__name__)
@receiver(state_changed)
def check_groups_on_state_change(sender, user, state, **kwargs):
logger.debug("Updating auth groups for {}".format(user))
visible_groups = GroupManager.get_joinable_groups(state)
visible_groups = visible_groups | Group.objects.select_related('authgroup').filter(authgroup__internal=True)
groups = user.groups.all()
for g in groups:
if g not in visible_groups:
user.groups.remove(g)
logger.debug(
"Checking group memberships for %s based on new state %s" % (user, state)
)
state_groups = (
user.groups.select_related("authgroup").exclude(authgroup__states=None)
)
for group in state_groups:
if not group.authgroup.states.filter(id=state.id).exists():
logger.info(
"Removing user %s from group %s due to missing state" % (user, group)
)
user.groups.remove(group)

View File

@@ -1,5 +1,5 @@
{% extends "allianceauth/base.html" %}
{% load staticfiles %}
{% load static %}
{% load i18n %}
{% block page_title %}{{ group }} {% trans "Audit Log" %}{% endblock page_title %}
@@ -8,58 +8,65 @@
<div class="col-lg-12">
<br>
{% include 'groupmanagement/menu.html' %}
<div class="panel panel-default">
<div class="panel-heading">
{{ group }} - {% trans 'Audit Log' %}
{{ group }} - {% trans "Audit Log" %}
</div>
<div class="panel-body">
<p>
<div class="panel-body">
<p>
<a class="btn btn-default" href="{% url 'groupmanagement:membership' %}" role="button">
{% trans "Back" %}
</a>
</p>
</p>
{% if entries %}
<div class="table-responsive">
<table class="table table-striped" id="log-entries">
<thead>
<th class="text-center" scope="col">{% trans "Date/Time" %}</th>
<th class="text-center" scope="col">{% trans "Requestor" %}</th>
<th class="text-center" scope="col">{% trans "Character" %}</th>
<th class="text-center" scope="col">{% trans "Corporation" %}</th>
<th class="text-center" scope="col">{% trans "Type" %}</th>
<th class="text-center" scope="col">{% trans "Action" %}</th>
<th class="text-center" scope="col">{% trans "Actor" %}</th>
<th scope="col">{% trans "Date/Time" %}</th>
<th scope="col">{% trans "Requestor" %}</th>
<th scope="col">{% trans "Character" %}</th>
<th scope="col">{% trans "Corporation" %}</th>
<th scope="col">{% trans "Type" %}</th>
<th scope="col">{% trans "Action" %}</th>
<th scope="col">{% trans "Actor" %}</th>
</thead>
<tbody>
{% for entry in entries %}
<tr>
<td class="text-center">{{ entry.date|date:"Y-M-d, H:i" }}</td>
<td class="text-center">{{ entry.requestor }}</td>
<td class="text-center">{{ entry.req_char }}</td>
<td class="text-center">{{ entry.req_char.corporation_name }}</td>
<td class="text-center">{{ entry.type_to_str }}</td>
<td>{{ entry.date|date:"Y-M-d, H:i" }}</td>
<td>{{ entry.requestor }}</td>
<td>{{ entry.req_char }}</td>
<td>{{ entry.req_char.corporation_name }}</td>
<td>{{ entry.type_to_str }}</td>
{% if entry.request_type is None %}
<td class="text-center"> Removed</td>
<td>{% trans "Removed" %}</td>
{% else %}
<td class="text-center">{{ entry.action_to_str }}</td>
<td>{{ entry.action_to_str }}</td>
{% endif %}
<td class="text-center">{{ entry.request_actor }}</td>
<td>{{ entry.request_actor }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<p class="text-muted">
All times displayed are EVE/UTC.
{% trans "All times displayed are EVE/UTC." %}
</p>
</div>
{% else %}
{% else %}
<div class="clearfix"></div>
<br>
<div class="alert alert-warning text-center">
<div class="alert alert-warning text-center">
{% trans "No entries found for this group." %}
</div>
</div>
{% endif %}
</div>
</div>
</div>
</div>
{% endblock %}
@@ -75,31 +82,30 @@
{% endblock %}
{% block extra_script %}
$.fn.dataTable.moment = function ( format, locale ) {
$.fn.dataTable.moment = function(format, locale) {
var types = $.fn.dataTable.ext.type;
// Add type detection
types.detect.unshift( function ( d ) {
return moment( d, format, locale, true ).isValid() ?
types.detect.unshift(function(d) {
return moment(d, format, locale, true).isValid() ?
'moment-'+format :
null;
} );
});
// Add sorting method - use an integer for the sorting
types.order[ 'moment-'+format+'-pre' ] = function ( d ) {
return moment( d, format, locale, true ).unix();
types.order[ 'moment-'+format+'-pre' ] = function(d) {
return moment(d, format, locale, true).unix();
};
};
$(document).ready(function(){
$.fn.dataTable.moment( 'YYYY-MMM-D, HH:mm' );
$.fn.dataTable.moment('YYYY-MMM-D, HH:mm');
$('#log-entries').DataTable({
order: [[ 0, 'desc' ], [ 1, 'asc' ] ],
order: [[0, 'desc'], [1, 'asc']],
filterDropDown:
{
columns: [
columns: [
{
idx: 1
},
@@ -124,4 +130,3 @@
});
});
{% endblock %}

View File

@@ -1,5 +1,5 @@
{% extends "allianceauth/base.html" %}
{% load staticfiles %}
{% load static %}
{% load i18n %}
{% load evelinks %}
@@ -9,38 +9,35 @@
<div class="col-lg-12">
<br>
{% include 'groupmanagement/menu.html' %}
<div class="panel panel-default">
<div class="panel-heading">
{{ group.name }} - {% trans 'Members' %}
</div>
<div class="panel-body">
<p>
<div class="panel-body">
<p>
<a class="btn btn-default" href="{% url 'groupmanagement:membership' %}" role="button">
{% trans "Back" %}
</a>
</p>
{% if group.user_set %}
</p>
{% if group.user_set %}
<div class="table-responsive">
<table class="table table-aa" id="tab_group_members">
<thead>
<tr>
<th class="text-right">{% trans "Portrait" %}</th>
<th class="text-center">{% trans "Character" %}</th>
<th class="text-center">{% trans "Organization" %}</th>
<th class="text-center"></th>
<tr>
<th>{% trans "Character" %}</th>
<th>{% trans "Organization" %}</th>
<th></th>
</tr>
</thead>
<tbody>
{% for member in members %}
<tr>
<td class="text-right">
{% if member.is_leader %}
<i class="fas fa-star"></i>&nbsp;
{% endif %}
<img src="{{ member.main_char|character_portrait_url:32 }}" class="img-circle">
</td>
<td class="text-center">
<tr>
<td>
<img src="{{ member.main_char|character_portrait_url:32 }}" class="img-circle" style="margin-right: 1rem;">
{% if member.main_char %}
<a href="{{ member.main_char|evewho_character_url }}" target="_blank">
{{ member.main_char.character_name }}
@@ -48,28 +45,36 @@
{% else %}
{{ member.user.username }}
{% endif %}
{% if member.is_leader %}
<i class="fas fa-star" title="{% trans "Group leader" %}" style="margin-left: 1rem;"></i>&nbsp;
{% endif %}
</td>
<td class="text-center">
<td>
{% if member.main_char %}
<a href="{{ member.main_char|dotlan_corporation_url }}" target="_blank">
{{ member.main_char.corporation_name }}
</a><br>
{{ member.main_char.alliance_name|default_if_none:"" }}
{% else %}
(unknown)
{% trans "(unknown)" %}
{% endif %}
</td>
<td class="text-center">
<a href="{% url 'groupmanagement:membership_remove' group.id member.user.id %}" class="btn btn-danger"
title="{% trans "Remove from group" %}">
<i class="glyphicon glyphicon-remove"></i>
</td>
<td class="text-right">
<a href="{% url 'groupmanagement:membership_remove' group.id member.user.id %}" class="btn btn-danger" title="{% trans "Remove from group" %}">
<i class="glyphicon glyphicon-remove"></i>
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<p class="text-muted"><i class="fas fa-star"></i>: Group leader</p>
<p class="text-muted">
<i class="fas fa-star"></i>: {% trans "Group leader" %}
</p>
</div>
{% else %}
<div class="alert alert-warning text-center">
@@ -77,7 +82,7 @@
</div>
{% endif %}
</div>
</div>
</div>
{% endblock content %}
@@ -93,10 +98,13 @@
{% block extra_script %}
$(document).ready(function(){
$('#tab_group_members').DataTable({
order: [ [ 1, "asc" ] ],
order: [[0, "asc"]],
columnDefs: [
{ "sortable": false, "targets": [0, 3] },
{
"sortable": false,
"targets": [2]
},
]
});
});
{% endblock %}
{% endblock %}

View File

@@ -1,5 +1,5 @@
{% extends "allianceauth/base.html" %}
{% load staticfiles %}
{% load static %}
{% load i18n %}
{% block page_title %}{% trans "Groups Membership" %}{% endblock page_title %}
@@ -9,31 +9,36 @@
<div class="col-lg-12">
<br>
{% include 'groupmanagement/menu.html' %}
<div class="panel panel-default">
<div class="panel-heading">
{% trans "Groups" %}
</div>
<div class="panel-body">
{% if groups %}
{% if groups %}
<div class="table-responsive">
<table class="table table-aa">
<thead>
<tr>
<th class="text-center">{% trans "Name" %}</th>
<th class="text-center">{% trans "Description" %}</th>
<th class="text-center">{% trans "Status" %}</th>
<th class="text-center">{% trans "Member Count" %}</th>
<th class="text-center"></th>
<th>{% trans "Name" %}</th>
<th>{% trans "Description" %}</th>
<th>{% trans "Status" %}</th>
<th style="white-space: nowrap;">{% trans "Member Count" %}</th>
<th style="min-width: 170px;"></th>
</tr>
</thead>
<tbody>
{% for group in groups %}
<tr>
<td class="text-center">
<a href="{% url 'groupmanagement:membership_list' group.id %}">{{ group.name }}</a>
<td>
<a href="{% url 'groupmanagement:membership' group.id %}">{{ group.name }}</a>
</td>
<td class="text-center">{{ group.authgroup.description }}</td>
<td class="text-center">
<td>{{ group.authgroup.description|linebreaks|urlize }}</td>
<td>
{% if group.authgroup.hidden %}
<span class="label label-info">{% trans "Hidden" %}</span>
{% elif group.authgroup.open %}
@@ -42,21 +47,23 @@
<span class="label label-default">{% trans "Requestable" %}</span>
{% endif %}
</td>
<td class="text-center">
<td class="text-right">
{{ group.num_members }}
</td>
<td class="text-center">
<a href="{% url 'groupmanagement:membership_list' group.id %}" class="btn btn-primary"
title="{% trans "View Members" %}">
<i class="glyphicon glyphicon-eye-open"></i>
<td class="text-right">
<a href="{% url 'groupmanagement:membership' group.id %}" class="btn btn-primary" title="{% trans "View Members" %}">
<i class="glyphicon glyphicon-eye-open"></i>
</a>
<a href="{% url "groupmanagement:audit_log" group.id %}" class="btn btn-info" title="{% trans "Audit Members" %}">
<i class="glyphicon glyphicon-list-alt"></i>
</a>
<a id="clipboard-copy" data-clipboard-text="{{ request.scheme }}://{{request.get_host}}{% url 'groupmanagement:request_add' group.id %}" class="btn btn-warning" title="{% trans "Copy Direct Join Link" %}">
<i class="glyphicon glyphicon-copy"></i>
</a>
</td>
</tr>
{% endfor %}
@@ -72,9 +79,11 @@
</div>
</div>
{% endblock content %}
{% block extra_javascript %}
{% block extra_javascript %}
{% include 'bundles/clipboard-js.html' %}
<script>
new ClipboardJS('#clipboard-copy');
</script>
{% endblock %}
<script>
new ClipboardJS('#clipboard-copy');
</script>
{% endblock %}

View File

@@ -1,10 +1,10 @@
{% extends "allianceauth/base.html" %}
{% load staticfiles %}
{% load static %}
{% load i18n %}
{% block page_title %}{% trans "Available Groups" %}{% endblock page_title %}
{% block extra_css %}{% endblock extra_css %}
url
{% block content %}
<div class="col-lg-12">
<h1 class="page-header text-center">{% trans "Available Groups" %}</h1>
@@ -12,17 +12,18 @@ url
<table class="table table-aa">
<thead>
<tr>
<th class="text-center">{% trans "Name" %}</th>
<th class="text-center">{% trans "Description" %}</th>
<th class="text-center">{% trans "Action" %}</th>
<th>{% trans "Name" %}</th>
<th>{% trans "Description" %}</th>
<th></th>
</tr>
</thead>
<tbody>
{% for g in groups %}
<tr>
<td class="text-center">{{ g.group.name }}</td>
<td class="text-center">{{ g.group.authgroup.description|urlize }}</td>
<td class="text-center">
<td>{{ g.group.name }}</td>
<td>{{ g.group.authgroup.description|linebreaks|urlize }}</td>
<td class="text-right">
{% if g.group in user.groups.all %}
{% if not g.request %}
<a href="{% url 'groupmanagement:request_leave' g.group.id %}" class="btn btn-danger">
@@ -59,5 +60,4 @@ url
</div>
{% endif %}
</div>
{% endblock content %}

View File

@@ -1,28 +1,29 @@
{% extends "allianceauth/base.html" %}
{% load staticfiles %}
{% load static %}
{% load i18n %}
{% load evelinks %}
{% block page_title %}{% trans "Groups Management" %}{% endblock page_title %}
{% block extra_css %}
<style>
.nav-tabs>li.active>a {
background-color: #ECF0F1 !important;
color: #2C3E50;
}
</style>
{% block extra_css %}
<style>
.nav-tabs > li.active > a {
background-color: rgb(236, 240, 241) !important;
color: rgb(44, 62, 80);
}
</style>
{% endblock extra_css %}
{% block content %}
<div class="col-lg-12">
<br>
{% include 'groupmanagement/menu.html' %}
<ul class="nav nav-tabs">
<li class="active">
<a data-toggle="tab" href="#add">
{% trans "Join Requests" %}
{% trans "Join Requests" %}
{% if acceptrequests %}
<span class="badge">{{ acceptrequests|length }}</span>
{% endif %}
@@ -31,133 +32,130 @@
<li>
<a data-toggle="tab" href="#leave">
{% trans "Leave Requests" %}
{% if leaverequests %}
<span class="badge">{{ leaverequests|length }}</span>
{% endif %}
</a>
</li>
</ul>
<div class="tab-content">
<div class="tab-content">
<div id="add" class="tab-pane fade in active panel panel-default">
<div class="panel-body">
{% if acceptrequests %}
<div class="table-responsive">
<table class="table table-aa">
<thead>
<tr>
<th class="text-center"></th>
<th class="text-center">{% trans "Character" %}</th>
<th class="text-center">{% trans "Organization" %}</th>
<th class="text-center">{% trans "Group" %}</th>
<th class="text-center"></th>
</tr>
</thead>
<tbody>
{% for acceptrequest in acceptrequests %}
<tr>
<td class="text-right">
<img src="{{ acceptrequest.main_char|character_portrait_url:32 }}" class="img-circle">
</td>
<td class="text-center">
{% if acceptrequest.main_char %}
<a href="{{ acceptrequest.main_char|evewho_character_url }}" target="_blank">
{{ acceptrequest.main_char.character_name }}
</a>
{% else %}
{{ acceptrequest.user.username }}
{% endif %}
</td>
<td class="text-center">
{% if acceptrequest.main_char %}
<a href="{{ acceptrequest.main_char|dotlan_corporation_url }}" target="_blank">
{{ acceptrequest.main_char.corporation_name }}
</a><br>
{{ acceptrequest.main_char.alliance_name|default_if_none:"" }}
{% else %}
(unknown)
{% endif %}
</td>
<td class="text-center">{{ acceptrequest.group.name }}</td>
<td class="text-center">
<a href="{% url 'groupmanagement:accept_request' acceptrequest.id %}" class="btn btn-success">
{% trans "Accept" %}
</a>
<a href="{% url 'groupmanagement:reject_request' acceptrequest.id %}" class="btn btn-danger">
{% trans "Reject" %}
</a>
</td>
{% if acceptrequests %}
<div class="table-responsive">
<table class="table table-aa">
<thead>
<tr>
<th>{% trans "Character" %}</th>
<th>{% trans "Organization" %}</th>
<th>{% trans "Group" %}</th>
<th></th>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<div class="alert alert-warning text-center">{% trans "No group add requests." %}</div>
{% endif %}
</thead>
<tbody>
{% for acceptrequest in acceptrequests %}
<tr>
<td>
<img src="{{ acceptrequest.main_char|character_portrait_url:32 }}" class="img-circle" style="margin-right: 1rem;">
{% if acceptrequest.main_char %}
<a href="{{ acceptrequest.main_char|evewho_character_url }}" target="_blank">
{{ acceptrequest.main_char.character_name }}
</a>
{% else %}
{{ acceptrequest.user.username }}
{% endif %}
</td>
<td>
{% if acceptrequest.main_char %}
<a href="{{ acceptrequest.main_char|dotlan_corporation_url }}" target="_blank">
{{ acceptrequest.main_char.corporation_name }}
</a><br>
{{ acceptrequest.main_char.alliance_name|default_if_none:"" }}
{% else %}
{% trans "(unknown)" %}
{% endif %}
</td>
<td>{{ acceptrequest.group.name }}</td>
<td class="text-right">
<a href="{% url 'groupmanagement:accept_request' acceptrequest.id %}" class="btn btn-success">
{% trans "Accept" %}
</a>
<a href="{% url 'groupmanagement:reject_request' acceptrequest.id %}" class="btn btn-danger">
{% trans "Reject" %}
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<div class="alert alert-warning text-center">{% trans "No group add requests." %}</div>
{% endif %}
</div>
</div>
<div id="leave" class="tab-pane fade panel panel-default">
<div class="panel-body">
{% if leaverequests %}
<div class="table-responsive">
<table class="table table-aa">
<thead>
<tr>
<th class="text-center"></th>
<th class="text-center">{% trans "Character" %}</th>
<th class="text-center">{% trans "Organization" %}</th>
<th class="text-center">{% trans "Group" %}</th>
<th class="text-center"></th>
</tr>
</thead>
<tbody>
{% for leaverequest in leaverequests %}
<tr>
<td class="text-right">
<img src="{{ leaverequest.main_char|character_portrait_url:32 }}" class="img-circle">
</td>
<td class="text-center">
{% if leaverequest.main_char %}
<a href="{{ leaverequest.main_char|evewho_character_url }}" target="_blank">
{{ leaverequest.main_char.character_name }}
</a>
{% else %}
{{ leaverequest.user.username }}
{% endif %}
</td>
<td class="text-center">
{% if leaverequest.main_char %}
<a href="{{ leaverequest.main_char|dotlan_corporation_url }}" target="_blank">
{{ leaverequest.main_char.corporation_name }}
</a><br>
{{ leaverequest.main_char.alliance_name|default_if_none:"" }}
{% else %}
(unknown)
{% endif %}
</td>
<td class="text-center">{{ leaverequest.group.name }}</td>
<td class="text-center">
<a href="{% url 'groupmanagement:leave_accept_request' leaverequest.id %}" class="btn btn-success">
{% trans "Accept" %}
</a>
<a href="{% url 'groupmanagement:leave_reject_request' leaverequest.id %}" class="btn btn-danger">
{% trans "Reject" %}
</a>
</td>
{% if leaverequests %}
<div class="table-responsive">
<table class="table table-aa">
<thead>
<tr>
<th>{% trans "Character" %}</th>
<th>{% trans "Organization" %}</th>
<th>{% trans "Group" %}</th>
<th></th>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<div class="alert alert-warning text-center">{% trans "No group leave requests." %}</div>
{% endif %}
</thead>
<tbody>
{% for leaverequest in leaverequests %}
<tr>
<td>
<img src="{{ leaverequest.main_char|character_portrait_url:32 }}" class="img-circle" style="margin-right: 1rem;">
{% if leaverequest.main_char %}
<a href="{{ leaverequest.main_char|evewho_character_url }}" target="_blank">
{{ leaverequest.main_char.character_name }}
</a>
{% else %}
{{ leaverequest.user.username }}
{% endif %}
</td>
<td>
{% if leaverequest.main_char %}
<a href="{{ leaverequest.main_char|dotlan_corporation_url }}" target="_blank">
{{ leaverequest.main_char.corporation_name }}
</a><br>
{{ leaverequest.main_char.alliance_name|default_if_none:"" }}
{% else %}
{% trans "(unknown)" %}
{% endif %}
</td>
<td>{{ leaverequest.group.name }}</td>
<td class="text-right">
<a href="{% url 'groupmanagement:leave_accept_request' leaverequest.id %}" class="btn btn-success">
{% trans "Accept" %}
</a>
<a href="{% url 'groupmanagement:leave_reject_request' leaverequest.id %}" class="btn btn-danger">
{% trans "Reject" %}
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<div class="alert alert-warning text-center">{% trans "No group leave requests." %}</div>
{% endif %}
</div>
</div>
</div>
</div>
{% endblock content %}

View File

@@ -1,10 +1,9 @@
{% load staticfiles %}
{% load static %}
{% load i18n %}
{% load navactive %}
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">{% trans "Toggle navigation" %}</span>
@@ -12,7 +11,7 @@
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="">{% trans "Group Management" %}</a>
<a class="navbar-brand" href="{% url 'groupmanagement:management' %}">{% trans "Group Management" %}</a>
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
@@ -20,11 +19,10 @@
<li class="{% navactive request 'groupmanagement:management' %}">
<a href="{% url 'groupmanagement:management' %}">{% trans "Group Requests" %}</a>
</li>
<li class="{% renavactive request '^/group/membership/' %}">
<li class="{% navactive request 'groupmanagement:membership groupmanagement:audit_log' %}">
<a href="{% url 'groupmanagement:membership' %}">{% trans "Group Membership" %}</a>
</li>
</ul>
</div>
</div>
</nav>

View File

@@ -1,61 +1,100 @@
from unittest import mock
from django.test import TestCase
from django.contrib.auth.models import User, Group
from allianceauth.eveonline.models import EveCorporationInfo, EveAllianceInfo
from allianceauth.eveonline.models import EveCorporationInfo
from allianceauth.eveonline.autogroups.models import AutogroupsConfig
from allianceauth.tests.auth_utils import AuthUtils
from ..signals import check_groups_on_state_change
class GroupManagementStateTestCase(TestCase):
class TestCheckGroupsOnStateChange(TestCase):
@classmethod
def setUpTestData(cls):
cls.user = AuthUtils.create_user('test')
AuthUtils.add_main_character(
cls.user, 'test character', '1', corp_id='2', corp_name='test_corp', corp_ticker='TEST', alliance_id='3', alliance_name='TEST'
cls.character = AuthUtils.add_main_character_2(
cls.user, 'test character', 1001, corp_id=2001, corp_name='test corp 1', corp_ticker='TEST'
)
cls.user.profile.refresh_from_db()
cls.alliance = EveAllianceInfo.objects.create(
alliance_id='3', alliance_name='test alliance', alliance_ticker='TEST', executor_corp_id='2'
cls.user.profile.refresh_from_db()
cls.corp_1 = EveCorporationInfo.objects.create(
corporation_id=2001, corporation_name='test corp 1', corporation_ticker='C1', member_count=1
)
cls.corp = EveCorporationInfo.objects.create(
corporation_id='2', corporation_name='test corp', corporation_ticker='TEST', alliance=cls.alliance, member_count=1
cls.corp_2 = EveCorporationInfo.objects.create(
corporation_id=2002, corporation_name='test corp 2', corporation_ticker='C2', member_count=1
)
cls.state_group = Group.objects.create(name='state_group')
cls.open_group = Group.objects.create(name='open_group')
cls.state = AuthUtils.create_state('test state', 500)
cls.state_group.authgroup.states.add(cls.state)
cls.state_group.authgroup.internal = False
cls.state_group.save()
cls.guest_state = AuthUtils.get_guest_state()
cls.test_state_1 = AuthUtils.create_state('test_state_1', 500)
cls.test_state_2 = AuthUtils.create_state('test_state_2', 600)
def setUp(self):
self.user.refresh_from_db()
self.state.refresh_from_db()
self.user.refresh_from_db()
def _refresh_user(self):
self.user = User.objects.get(pk=self.user.pk)
def _refresh_test_group(self):
self.state_group = Group.objects.get(pk=self.state_group.pk)
def test_drop_state_group(self):
self.user.groups.add(self.open_group)
self.user.groups.add(self.state_group)
self.assertEqual(self.user.profile.state.name, "Guest")
self.state.member_corporations.add(self.corp)
"""
given user is member of: state group, normal group and auto group
when user looses state
then user is automatically kicked from state group
and remains member of normal group and auto group
"""
# setup
state_group = Group.objects.create(name='state_group')
state_group.authgroup.states.add(self.test_state_1)
state_group.authgroup.internal = False
state_group.save()
normal_group = Group.objects.create(name='normal_group')
normal_group.authgroup.internal = False
normal_group.save()
internal_group = Group.objects.create(name='internal_group')
autogroup_config = AutogroupsConfig.objects.create(corp_groups=True)
autogroup_config.states.add(self.test_state_1)
autogroup_config.states.add(self.guest_state)
auto_group = autogroup_config.corp_managed_groups.first()
internal_state_group = Group.objects.create(name='internal_state_group')
internal_state_group.authgroup.states.add(self.test_state_1)
self.test_state_1.member_corporations.add(self.corp_1)
self.user.groups.add(normal_group)
self.user.groups.add(internal_group)
self.user.groups.add(state_group)
self.user.groups.add(internal_state_group)
# user changes state back to guest
self.test_state_1.member_corporations.clear()
# assert
self._refresh_user()
self.assertEqual(self.user.profile.state, self.state)
self.assertEqual(self.user.profile.state, self.guest_state)
groups = self.user.groups.all()
self.assertIn(self.state_group, groups) #keeps group
self.assertIn(self.open_group, groups) #public group unafected
self.assertNotIn(state_group, groups) # looses state group
self.assertNotIn(internal_state_group, groups) # looses state group
self.assertIn(normal_group, groups) # normal group unafected
self.assertIn(internal_group, groups) # internal group unafected
self.assertIn(auto_group, groups) # auto group unafected
self.state.member_corporations.clear()
def test_change_to_other_state(self):
"""
given a state group with 2 allowed states
when user changes from one state to the other
then user remains member of that group
"""
# setup
state_group = Group.objects.create(name='state_group')
state_group.authgroup.states.add(self.test_state_1)
state_group.authgroup.states.add(self.test_state_2)
self.test_state_1.member_corporations.add(self.corp_1)
self.test_state_2.member_corporations.add(self.corp_2)
self.user.groups.add(state_group)
# user changes state back to guest
self.character.corporation_id = 2002
self.character.corporation_name = "test corp 2"
self.character.save()
# assert
self._refresh_user()
self.assertEqual(self.user.profile.state.name, "Guest")
groups = self.user.groups.all()
self.assertNotIn(self.state_group, groups) #looses group
self.assertIn(self.open_group, groups) #public group unafected
self.assertEqual(self.user.profile.state, self.test_state_2)
groups = self.user.groups.all()
self.assertIn(state_group, groups)

View File

@@ -1,29 +1,52 @@
from . import views
from django.conf.urls import url
app_name = 'groupmanagement'
app_name = "groupmanagement"
urlpatterns = [
url(r'^groups/', views.groups_view, name='groups'),
url(r'^management/', views.group_management,
name='management'),
url(r'^membership/$', views.group_membership,
name='membership'),
url(r'^membership/(\w+)/$', views.group_membership_list,
name='membership_list'),
url(r'^membership/(\w+)/audit/$', views.group_membership_audit, name="audit_log"),
url(r'^membership/(\w+)/remove/(\w+)/$', views.group_membership_remove,
name='membership_remove'),
url(r'^request_add/(\w+)', views.group_request_add,
name='request_add'),
url(r'^request/accept/(\w+)', views.group_accept_request,
name='accept_request'),
url(r'^request/reject/(\w+)', views.group_reject_request,
name='reject_request'),
url(r'^request_leave/(\w+)', views.group_request_leave,
name='request_leave'),
url(r'leave_request/accept/(\w+)', views.group_leave_accept_request,
name='leave_accept_request'),
url(r'^leave_request/reject/(\w+)', views.group_leave_reject_request,
name='leave_reject_request'),
# groups
url(r"^groups/$", views.groups_view, name="groups"),
url(r"^group/request/join/(\w+)/$", views.group_request_add, name="request_add"),
url(
r"^group/request/leave/(\w+)/$", views.group_request_leave, name="request_leave"
),
# group management
url(r"^groupmanagement/requests/$", views.group_management, name="management"),
url(r"^groupmanagement/membership/$", views.group_membership, name="membership"),
url(
r"^groupmanagement/membership/(\w+)/$",
views.group_membership_list,
name="membership",
),
url(
r"^groupmanagement/membership/(\w+)/audit-log/$",
views.group_membership_audit,
name="audit_log",
),
url(
r"^groupmanagement/membership/(\w+)/remove/(\w+)/$",
views.group_membership_remove,
name="membership_remove",
),
url(
r"^groupmanagement/request/join/accept/(\w+)/$",
views.group_accept_request,
name="accept_request",
),
url(
r"^groupmanagement/request/join/reject/(\w+)/$",
views.group_reject_request,
name="reject_request",
),
url(
r"^groupmanagement/request/leave/accept/(\w+)/$",
views.group_leave_accept_request,
name="leave_accept_request",
),
url(
r"^groupmanagement/request/leave/reject/(\w+)/$",
views.group_leave_reject_request,
name="leave_reject_request",
),
]

View File

@@ -103,7 +103,7 @@ def group_membership_list(request, group_id):
# Check its a joinable group i.e. not corp or internal
# And the user has permission to manage it
if (not GroupManager.check_internal_group(group)
if (not GroupManager.check_internal_group(group)
or not GroupManager.can_manage_group(request.user, group)
):
logger.warning(
@@ -132,7 +132,7 @@ def group_membership_list(request, group_id):
render_items = {'group': group, 'members': members}
return render(
request, 'groupmanagement/groupmembers.html',
request, 'groupmanagement/groupmembers.html',
context=render_items
)
@@ -166,7 +166,7 @@ def group_membership_remove(request, group_id, user_id):
except ObjectDoesNotExist:
messages.warning(request, _("Group does not exist"))
return redirect('groupmanagement:membership_list', group_id)
return redirect('groupmanagement:membership', group_id)
@login_required
@@ -312,18 +312,18 @@ def group_leave_reject_request(request, group_request_id):
@login_required
def groups_view(request):
logger.debug("groups_view called by user %s" % request.user)
groups_qs = GroupManager.get_joinable_groups_for_user(
request.user, include_hidden=False
)
groups_qs = groups_qs.order_by('name')
groups = []
for group in groups_qs:
for group in groups_qs:
group_request = GroupRequest.objects\
.filter(user=request.user)\
.filter(group=group)
groups.append({
'group': group,
'group': group,
'request': group_request[0] if group_request else None
})
@@ -356,6 +356,9 @@ def group_request_add(request, group_id):
if group.authgroup.open:
logger.info("%s joining %s as is an open group" % (request.user, group))
request.user.groups.add(group)
request_info = request.user.username + ":" + group.name
log = RequestLog(request_type=False, group=group, request_info=request_info, action=1, request_actor=request.user)
log.save()
return redirect("groupmanagement:groups")
req = GroupRequest.objects.filter(user=request.user, group=group)
if len(req) > 0:
@@ -389,6 +392,9 @@ def group_request_leave(request, group_id):
return redirect('groupmanagement:groups')
if group.authgroup.open:
logger.info("%s leaving %s as is an open group" % (request.user, group))
request_info = request.user.username + ":" + group.name
log = RequestLog(request_type=True, group=group, request_info=request_info, action=1, request_actor=request.user)
log.save()
request.user.groups.remove(group)
return redirect("groupmanagement:groups")
req = GroupRequest.objects.filter(user=request.user, group=group)
@@ -398,6 +404,9 @@ def group_request_leave(request, group_id):
return redirect("groupmanagement:groups")
if getattr(settings, 'AUTO_LEAVE', False):
logger.info("%s leaving joinable group %s due to auto_leave" % (request.user, group))
request_info = request.user.username + ":" + group.name
log = RequestLog(request_type=True, group=group, request_info=request_info, action=1, request_actor=request.user)
log.save()
request.user.groups.remove(group)
return redirect('groupmanagement:groups')
grouprequest = GroupRequest()

View File

@@ -0,0 +1,18 @@
# Generated by Django 3.1.1 on 2020-09-18 14:12
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('hrapplications', '0006_remove_legacy_models'),
]
operations = [
migrations.AlterField(
model_name='application',
name='approved',
field=models.BooleanField(blank=True, default=None, null=True),
),
]

View File

@@ -35,7 +35,7 @@ class ApplicationForm(models.Model):
class Application(models.Model):
form = models.ForeignKey(ApplicationForm, on_delete=models.CASCADE, related_name='applications')
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='applications')
approved = models.NullBooleanField(blank=True, null=True, default=None)
approved = models.BooleanField(blank=True, null=True, default=None)
reviewer = models.ForeignKey(User, on_delete=models.SET_NULL, blank=True, null=True)
reviewer_character = models.ForeignKey(EveCharacter, on_delete=models.SET_NULL, blank=True, null=True)
created = models.DateTimeField(auto_now_add=True)

View File

@@ -1,5 +1,5 @@
{% extends "allianceauth/base.html" %}
{% load staticfiles %}
{% load static %}
{% load i18n %}
{% block page_title %}{% trans "Choose a Corp" %}{% endblock page_title %}

View File

@@ -1,5 +1,5 @@
{% extends "allianceauth/base.html" %}
{% load staticfiles %}
{% load static %}
{% load i18n %}
{% block page_title %}{% trans "Apply To" %} {{ corp.corporation_name }}{% endblock page_title %}

View File

@@ -1,6 +1,6 @@
{% extends "allianceauth/base.html" %}
{% load bootstrap %}
{% load staticfiles %}
{% load static %}
{% load i18n %}
{% block page_title %}{% trans "HR Application Management" %}{% endblock page_title %}

View File

@@ -1,6 +1,6 @@
{% extends "allianceauth/base.html" %}
{% load bootstrap %}
{% load staticfiles %}
{% load static %}
{% load i18n %}
{% block page_title %}HR Application Management{% endblock page_title %}

View File

@@ -1,5 +1,5 @@
{% extends "allianceauth/base.html" %}
{% load staticfiles %}
{% load static %}
{% load bootstrap %}
{% load i18n %}

View File

@@ -6,16 +6,16 @@
# Translators:
# Erik Kalkoken <erik.kalkoken@gmail.com>, 2020
# Joel Falknau <ozirascal@gmail.com>, 2020
# Rounon Dax <rounon.dax@terra-nanotech.de>, 2020
# Peter Pfeufer <rounon.dax@terra-nanotech.de>, 2020
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-07-29 04:56+0000\n"
"POT-Creation-Date: 2020-11-20 05:33+0000\n"
"PO-Revision-Date: 2020-02-18 03:14+0000\n"
"Last-Translator: Rounon Dax <rounon.dax@terra-nanotech.de>, 2020\n"
"Last-Translator: Peter Pfeufer <rounon.dax@terra-nanotech.de>, 2020\n"
"Language-Team: German (https://www.transifex.com/alliance-auth/teams/107430/de/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -28,7 +28,7 @@ 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."
#: allianceauth/authentication/forms.py:6
#: allianceauth/authentication/forms.py:5
msgid "Email"
msgstr "E-Mail"
@@ -44,7 +44,7 @@ msgstr "Dein Nutzerstatus ist nun %(state)s"
#: allianceauth/authentication/templates/authentication/dashboard.html:5
#: allianceauth/authentication/templates/authentication/dashboard.html:8
#: allianceauth/templates/allianceauth/side-menu.html:12
#: allianceauth/templates/allianceauth/side-menu.html:11
msgid "Dashboard"
msgstr "Dashboard"
@@ -82,7 +82,7 @@ msgstr "Charaktere"
#: allianceauth/authentication/templates/authentication/dashboard.html:129
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:73
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:22
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:24
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:15
#: allianceauth/hrapplications/templates/hrapplications/view.html:45
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:34
@@ -168,11 +168,11 @@ msgstr ""
msgid "Unable to authenticate as the selected character."
msgstr "Authentifizierung mit dem ausgewählten Charakter nicht möglich."
#: allianceauth/authentication/views.py:148
#: allianceauth/authentication/views.py:151
msgid "Registration token has expired."
msgstr "Token zur Registrierung ist abgelaufen."
#: allianceauth/authentication/views.py:200
#: allianceauth/authentication/views.py:206
msgid ""
"Sent confirmation email. Please follow the link to confirm your email "
"address."
@@ -180,13 +180,13 @@ msgstr ""
"Bestätigungsmail gesendet. Bitte folge dem Link in der E-Mail zur "
"Bestätigung."
#: allianceauth/authentication/views.py:205
#: allianceauth/authentication/views.py:211
msgid "Confirmed your email address. Please login to continue."
msgstr ""
"Deine E-Mail Adresse wurde bestätigt. Bitte log Dich ein um fortzufahren."
#: allianceauth/authentication/views.py:210
msgid "Registraion of new accounts it not allowed at this time."
#: allianceauth/authentication/views.py:216
msgid "Registration of new accounts is not allowed at this time."
msgstr "Registrierung von neuen Konten ist zur Zeit nicht erlaubt."
#: allianceauth/corputils/auth_hooks.py:10
@@ -234,16 +234,16 @@ msgstr "Letzes Update:"
#: allianceauth/corputils/templates/corputils/search.html:13
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html:24
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:28
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:27
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:29
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:30
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:30
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:51
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:110
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:109
msgid "Character"
msgstr "Charakter"
#: allianceauth/corputils/templates/corputils/corpstats.html:76
#: allianceauth/corputils/templates/corputils/search.html:14
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:28
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:31
#: allianceauth/hrapplications/templates/hrapplications/management.html:27
#: allianceauth/hrapplications/templates/hrapplications/management.html:84
#: allianceauth/hrapplications/templates/hrapplications/management.html:129
@@ -552,31 +552,35 @@ msgstr "Flottenteilnahme registriert."
msgid "FAT link has expired."
msgstr "FAT-Link ist abgelaufen."
#: allianceauth/groupmanagement/auth_hooks.py:17
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:14
msgid "Group Management"
msgstr "Gruppenverwaltung"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:5
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:13
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:14
msgid "Audit Log"
msgstr "Protokoll"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:18
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:20
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:20
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:21
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:13
msgid "Back"
msgstr "Zurück"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:25
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:28
msgid "Date/Time"
msgstr "Datum/Uhrzeit"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:26
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:29
msgid "Requestor"
msgstr "Antragsteller"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:29
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:32
msgid "Type"
msgstr "Typ"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:30
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:17
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:33
#: allianceauth/notifications/templates/notifications/list.html:37
#: allianceauth/notifications/templates/notifications/list.html:69
#: allianceauth/optimer/templates/optimer/fleetoptable.html:18
@@ -587,11 +591,19 @@ msgstr "Typ"
msgid "Action"
msgstr "Aktion"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:31
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:34
msgid "Actor"
msgstr "Ausführender"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:47
msgid "Removed"
msgstr "Entfernt"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:59
msgid "All times displayed are EVE/UTC."
msgstr "Alle angezeigten Zeiten sind EVE/UTC"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:66
msgid "No entries found for this group."
msgstr "Keine Einträge für diese Gruppe gefunden."
@@ -599,22 +611,24 @@ msgstr "Keine Einträge für diese Gruppe gefunden."
msgid "Group Members"
msgstr "Gruppenmitglieder"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:28
msgid "Portrait"
msgstr "Portrait"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:30
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:31
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:52
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:111
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:110
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:23
msgid "Organization"
msgstr "Organization"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:64
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:61
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:78
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:136
msgid "(unknown)"
msgstr "(unbekannt)"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:66
msgid "Remove from group"
msgstr "Aus Gruppe entfernen"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:76
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:81
msgid "No group members to list."
msgstr "Keine Gruppenmitglieder vorhanden."
@@ -622,56 +636,56 @@ msgstr "Keine Gruppenmitglieder vorhanden."
msgid "Groups Membership"
msgstr "Gruppenmitgliedschaft"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:14
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:15
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:40
#: allianceauth/templates/allianceauth/side-menu.html:17
#: allianceauth/templates/allianceauth/side-menu.html:16
msgid "Groups"
msgstr "Gruppen"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:23
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:25
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:16
msgid "Description"
msgstr "Beschreibung"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:24
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:26
#: allianceauth/hrapplications/templates/hrapplications/management.html:28
#: allianceauth/hrapplications/templates/hrapplications/management.html:85
#: allianceauth/hrapplications/templates/hrapplications/management.html:130
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:27
#: allianceauth/srp/templates/srp/data.html:97
#: allianceauth/srp/templates/srp/data.html:98
msgid "Status"
msgstr "Status"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:25
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:27
msgid "Member Count"
msgstr "Mitgliederzahl"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:38
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:43
msgid "Hidden"
msgstr "Verborgen"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:40
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:45
#: allianceauth/templates/allianceauth/admin-status/overview.html:12
msgid "Open"
msgstr "Öffnen"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:42
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:47
msgid "Requestable"
msgstr "Anfragbar"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:50
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:56
msgid "View Members"
msgstr "Mitglieder ansehen"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:53
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:60
msgid "Audit Members"
msgstr "Mitglieder Protokoll"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:56
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:64
msgid "Copy Direct Join Link"
msgstr "Direktlink kopieren"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:68
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:75
msgid "No groups to list."
msgstr "Keine Gruppen vorhanden."
@@ -680,19 +694,19 @@ msgstr "Keine Gruppen vorhanden."
msgid "Available Groups"
msgstr "Verfügbare Gruppen"
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:29
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:30
msgid "Leave"
msgstr "Verlassen"
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:39
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:40
msgid "Join"
msgstr "Beitreten"
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:43
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:44
msgid "Request"
msgstr "Anfrage"
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:58
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:59
msgid "No groups available."
msgstr "Keine Gruppen verfügbar"
@@ -704,24 +718,24 @@ msgstr "Gruppenverwaltung"
msgid "Join Requests"
msgstr "Beitrittsgesuche"
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:33
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:34
msgid "Leave Requests"
msgstr "Austrittsgesuche"
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:53
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:112
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:111
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:20
#: allianceauth/services/modules/openfire/forms.py:6
msgid "Group"
msgstr "Gruppen"
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:85
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:144
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:84
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:142
msgid "Accept"
msgstr "Akzeptieren"
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:88
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:147
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:146
#: allianceauth/hrapplications/templates/hrapplications/view.html:85
msgid "Reject"
msgstr "Ablehnen"
@@ -730,24 +744,19 @@ msgstr "Ablehnen"
msgid "No group add requests."
msgstr "Keine Gruppenbeitrittsanfragen."
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:156
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:155
msgid "No group leave requests."
msgstr "Keine Gruppenaustrittsanfragen"
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:10
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:9
msgid "Toggle navigation"
msgstr "Toggle Navigation"
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:15
#: allianceauth/templates/allianceauth/side-menu.html:25
msgid "Group Management"
msgstr "Gruppenverwaltung"
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:21
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:20
msgid "Group Requests"
msgstr "Gruppenanfragen"
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:24
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:23
msgid "Group Membership"
msgstr "Gruppenmitgliedschaft"
@@ -825,7 +834,7 @@ msgstr "Du hast Dich bereits für diese Gruppe beworben."
#: allianceauth/hrapplications/templates/hrapplications/management.html:144
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:38
#: allianceauth/hrapplications/templates/hrapplications/view.html:20
#: allianceauth/srp/templates/srp/data.html:125
#: allianceauth/srp/templates/srp/data.html:134
#: allianceauth/srp/templates/srp/management.html:81
msgid "Pending"
msgstr "Beantragt"
@@ -852,7 +861,7 @@ msgstr "Du hast bereits ein ausstehendes Austrittsgesuch für diese Gruppe."
msgid "Applied to leave group %(group)s."
msgstr "Austrittsgesuch für Gruppe %(group)s gesendet."
#: allianceauth/hrapplications/auth_hooks.py:10
#: allianceauth/hrapplications/auth_hooks.py:13
msgid "Applications"
msgstr "Bewerbungen"
@@ -909,7 +918,7 @@ msgstr "Benutzername"
#: allianceauth/hrapplications/templates/hrapplications/management.html:131
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:28
#: allianceauth/hrapplications/templates/hrapplications/view.html:75
#: allianceauth/srp/templates/srp/data.html:99
#: allianceauth/srp/templates/srp/data.html:100
#: allianceauth/srp/templates/srp/management.html:46
msgid "Actions"
msgstr "Aktionen"
@@ -919,7 +928,7 @@ msgstr "Aktionen"
#: allianceauth/hrapplications/templates/hrapplications/management.html:147
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:40
#: allianceauth/hrapplications/templates/hrapplications/view.html:16
#: allianceauth/srp/templates/srp/data.html:117
#: allianceauth/srp/templates/srp/data.html:126
msgid "Approved"
msgstr "Akzeptiert"
@@ -927,7 +936,7 @@ msgstr "Akzeptiert"
#: allianceauth/hrapplications/templates/hrapplications/management.html:104
#: allianceauth/hrapplications/templates/hrapplications/management.html:149
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:42
#: allianceauth/srp/templates/srp/data.html:121
#: allianceauth/srp/templates/srp/data.html:130
msgid "Rejected"
msgstr "Abgelehnt"
@@ -1033,7 +1042,7 @@ msgstr "Ungelesen"
#: allianceauth/notifications/templates/notifications/list.html:18
msgid "Read"
msgstr "Lesen"
msgstr "Gelesen"
#: allianceauth/notifications/templates/notifications/list.html:22
msgid "Mark All Read"
@@ -1264,7 +1273,7 @@ msgstr "Flotten Comms:"
#: allianceauth/services/forms.py:9
msgid "Fleet Type:"
msgstr "Flottenzeit:"
msgstr "Flottenart:"
#: allianceauth/services/forms.py:10
msgid "Ship Priorities:"
@@ -1310,13 +1319,13 @@ msgstr "Passwort"
msgid "Password must be at least 8 characters long."
msgstr "Passwort muss mindestens 8 Zeichen lang sein"
#: allianceauth/services/modules/discord/models.py:224
#: allianceauth/services/modules/discord/models.py:225
msgid "Discord Account Disabled"
msgstr "Discord Konto deaktiviert"
#: allianceauth/services/modules/discord/models.py:226
#: allianceauth/services/modules/discord/models.py:227
msgid ""
"Your Discord account was disabeled automatically by Auth. If you think this "
"Your Discord account was disabled automatically by Auth. If you think this "
"was a mistake, please contact an admin."
msgstr ""
"Dein Discord Konto wurde automatisch durch Auth deaktiviert. Wenn Du glaubst"
@@ -1628,7 +1637,7 @@ msgstr "Dienst"
msgid "Domain"
msgstr "Domain"
#: allianceauth/srp/auth_hooks.py:9
#: allianceauth/srp/auth_hooks.py:12
msgid "Ship Replacement"
msgstr "Schiffserstattung"
@@ -1642,7 +1651,7 @@ msgstr "Flottenzeit"
msgid "Fleet Doctrine"
msgstr "Flottendoktrin"
#: allianceauth/srp/form.py:12 allianceauth/srp/templates/srp/data.html:89
#: allianceauth/srp/form.py:12 allianceauth/srp/templates/srp/data.html:90
msgid "Additional Info"
msgstr "Zusätzliche Info"
@@ -1671,65 +1680,65 @@ msgstr "SRP-Flotte erstellen"
msgid "Give this link to the line members"
msgstr "Gib diesen Link an Deine Piloten weiter"
#: allianceauth/srp/templates/srp/data.html:48
#: allianceauth/srp/templates/srp/data.html:49
msgid "SRP Fleet Data"
msgstr "SRP-Flotte Daten"
#: allianceauth/srp/templates/srp/data.html:53
#: allianceauth/srp/templates/srp/data.html:54
msgid "Mark Incomplete"
msgstr "Als unvollständig markieren"
#: allianceauth/srp/templates/srp/data.html:57
#: allianceauth/srp/templates/srp/data.html:58
msgid "Mark Completed"
msgstr "Als vollständig markieren"
#: allianceauth/srp/templates/srp/data.html:69
#: allianceauth/srp/templates/srp/data.html:145
#: allianceauth/srp/templates/srp/data.html:70
#: allianceauth/srp/templates/srp/data.html:156
msgid "Total Losses:"
msgstr "Verluste insgesamt:"
#: allianceauth/srp/templates/srp/data.html:70
#: allianceauth/srp/templates/srp/data.html:146
#: allianceauth/srp/templates/srp/data.html:71
#: allianceauth/srp/templates/srp/data.html:157
#: allianceauth/srp/templates/srp/management.html:30
msgid "Total ISK Cost:"
msgstr "ISK-Kosten insgesamt:"
#: allianceauth/srp/templates/srp/data.html:78
#: allianceauth/srp/templates/srp/data.html:154
#: allianceauth/srp/templates/srp/data.html:79
#: allianceauth/srp/templates/srp/data.html:165
msgid "Are you sure you want to delete SRP requests?"
msgstr "Bist Du sicher das Du SRP Anfragen löschen willst?"
#: allianceauth/srp/templates/srp/data.html:87
#: allianceauth/srp/templates/srp/data.html:88
msgid "Pilot Name"
msgstr "Name des Piloten"
#: allianceauth/srp/templates/srp/data.html:88
#: allianceauth/srp/templates/srp/data.html:89
msgid "Killboard Link"
msgstr "Killboard Link"
#: allianceauth/srp/templates/srp/data.html:90
#: allianceauth/srp/templates/srp/data.html:91
msgid "Ship Type"
msgstr "Schiffstyp"
#: allianceauth/srp/templates/srp/data.html:91
#: allianceauth/srp/templates/srp/data.html:92
msgid "Killboard Loss Amt"
msgstr "Summe Killboard Verluste"
#: allianceauth/srp/templates/srp/data.html:92
#: allianceauth/srp/templates/srp/data.html:93
msgid "SRP ISK Cost"
msgstr "SRP ISK-Kosten"
#: allianceauth/srp/templates/srp/data.html:93
#: allianceauth/srp/templates/srp/data.html:94
msgid "Click value to edit Enter to save & next ESC to cancel"
msgstr ""
"Klicke auf den Wert um diesen zu bearbeiten, Enter zum Speichern und um zum "
"nächsten Wert zu springen, ESC zum Beenden."
#: allianceauth/srp/templates/srp/data.html:96
#: allianceauth/srp/templates/srp/data.html:97
msgid "Post Time"
msgstr "Veröffentlichungszeit"
#: allianceauth/srp/templates/srp/data.html:163
#: allianceauth/srp/templates/srp/data.html:174
msgid "No SRP requests for this fleet."
msgstr "Keine SRP Anfragen für diese Flotte."
@@ -2089,3 +2098,6 @@ msgstr "Neuen Timer hinzugefügt in %(system)s um %(time)s."
#: allianceauth/timerboard/views.py:83
msgid "Saved changes to the timer."
msgstr "Änderungen am Timer gespeichert"
#~ msgid "Portrait"
#~ msgstr "Portrait"

File diff suppressed because it is too large Load Diff

View File

@@ -12,7 +12,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-05-08 00:57+0000\n"
"POT-Creation-Date: 2020-11-20 05:33+0000\n"
"PO-Revision-Date: 2020-02-18 03:14+0000\n"
"Last-Translator: frank1210 <francolopez_16@hotmail.com>, 2020\n"
"Language-Team: Spanish (https://www.transifex.com/alliance-auth/teams/107430/es/)\n"
@@ -27,74 +27,72 @@ msgid "A main character is required to perform that action. Add one below."
msgstr ""
"Un personaje principal es requerido para completar esta accion. Agregue uno"
#: allianceauth/authentication/forms.py:6
#: allianceauth/authentication/forms.py:5
msgid "Email"
msgstr "E-mail"
#: allianceauth/authentication/models.py:76
msgid "State Changed"
msgstr "Estado Cambiado"
#: allianceauth/authentication/models.py:77
#: allianceauth/authentication/models.py:78
#, python-format
msgid "Your user state has been changed to %(state)s"
msgstr "Tu estado de usuario fue cambiado a %(state)s"
msgid "State changed to: %s"
msgstr ""
#: allianceauth/authentication/models.py:79
#, python-format
msgid "Your user's state is now: %(state)s"
msgstr ""
#: allianceauth/authentication/templates/authentication/dashboard.html:5
#: allianceauth/authentication/templates/authentication/dashboard.html:8
#: allianceauth/templates/allianceauth/side-menu.html:10
#: allianceauth/templates/allianceauth/side-menu.html:11
msgid "Dashboard"
msgstr "Pagina Principal"
#: allianceauth/authentication/templates/authentication/dashboard.html:17
#: allianceauth/corputils/templates/corputils/corpstats.html:116
#: allianceauth/corputils/templates/corputils/search.html:16
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticscorpview.html:22
#: allianceauth/hrapplications/templates/hrapplications/management.html:83
#: allianceauth/hrapplications/templates/hrapplications/management.html:128
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:25
#: allianceauth/hrapplications/templates/hrapplications/view.html:32
msgid "Main Character"
msgstr "Personaje Principal"
#: allianceauth/authentication/templates/authentication/dashboard.html:18
#, python-format
msgid ""
"\n"
" Main Character (State: %(state)s)\n"
" "
msgstr ""
#: allianceauth/authentication/templates/authentication/dashboard.html:77
#: allianceauth/authentication/templates/authentication/dashboard.html:81
msgid "No main character set."
msgstr "No se ha seleccionado un personaje principal."
#: allianceauth/authentication/templates/authentication/dashboard.html:84
#: allianceauth/authentication/templates/authentication/dashboard.html:88
msgid "Add Character"
msgstr "Agregar Personaje"
#: allianceauth/authentication/templates/authentication/dashboard.html:88
#: allianceauth/authentication/templates/authentication/dashboard.html:92
msgid "Change Main"
msgstr "Cambiar Personaje Principal"
#: allianceauth/authentication/templates/authentication/dashboard.html:97
#: allianceauth/authentication/templates/authentication/dashboard.html:101
msgid "Group Memberships"
msgstr ""
#: allianceauth/authentication/templates/authentication/dashboard.html:117
#: allianceauth/authentication/templates/authentication/dashboard.html:121
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticscorpview.html:23
#: allianceauth/hrapplications/templates/hrapplications/view.html:41
msgid "Characters"
msgstr "Personajes"
#: allianceauth/authentication/templates/authentication/dashboard.html:125
#: allianceauth/authentication/templates/authentication/dashboard.html:129
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:73
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:22
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:24
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:15
#: allianceauth/hrapplications/templates/hrapplications/view.html:45
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:34
msgid "Name"
msgstr "Nombre"
#: allianceauth/authentication/templates/authentication/dashboard.html:126
#: allianceauth/authentication/templates/authentication/dashboard.html:130
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticsview.html:23
#: allianceauth/hrapplications/templates/hrapplications/view.html:46
msgid "Corp"
msgstr "Corporación"
#: allianceauth/authentication/templates/authentication/dashboard.html:127
#: allianceauth/authentication/templates/authentication/dashboard.html:131
#: allianceauth/corputils/templates/corputils/corpstats.html:77
#: allianceauth/hrapplications/templates/hrapplications/view.html:47
msgid "Alliance"
@@ -163,26 +161,26 @@ msgstr ""
msgid "Unable to authenticate as the selected character."
msgstr "Imposible validar con el personaje seleccionado."
#: allianceauth/authentication/views.py:148
#: allianceauth/authentication/views.py:151
msgid "Registration token has expired."
msgstr "El token de registracion expiro."
#: allianceauth/authentication/views.py:200
#: allianceauth/authentication/views.py:206
msgid ""
"Sent confirmation email. Please follow the link to confirm your email "
"address."
msgstr ""
"Confirmacion de mail enviada. Por favor siga el enlace para confirmar "
#: allianceauth/authentication/views.py:205
#: allianceauth/authentication/views.py:211
msgid "Confirmed your email address. Please login to continue."
msgstr ""
"Se ha confirmado su direccion de mail. Por favor igrese su token para "
"continuar."
#: allianceauth/authentication/views.py:210
msgid "Registraion of new accounts it not allowed at this time."
msgstr "Registracion de nuevas cuentas no es permitido por el momento."
#: allianceauth/authentication/views.py:216
msgid "Registration of new accounts is not allowed at this time."
msgstr ""
#: allianceauth/corputils/auth_hooks.py:10
msgid "Corporation Stats"
@@ -229,16 +227,16 @@ msgstr "Ultima Actualizacion:"
#: allianceauth/corputils/templates/corputils/search.html:13
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html:24
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:28
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:27
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:29
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:37
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:96
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:30
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:30
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:51
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:109
msgid "Character"
msgstr "Personaje"
#: allianceauth/corputils/templates/corputils/corpstats.html:76
#: allianceauth/corputils/templates/corputils/search.html:14
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:28
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:31
#: allianceauth/hrapplications/templates/hrapplications/management.html:27
#: allianceauth/hrapplications/templates/hrapplications/management.html:84
#: allianceauth/hrapplications/templates/hrapplications/management.html:129
@@ -254,6 +252,16 @@ msgstr "Corporacion"
msgid "Killboard"
msgstr "Killboard"
#: allianceauth/corputils/templates/corputils/corpstats.html:116
#: allianceauth/corputils/templates/corputils/search.html:16
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticscorpview.html:22
#: allianceauth/hrapplications/templates/hrapplications/management.html:83
#: allianceauth/hrapplications/templates/hrapplications/management.html:128
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:25
#: allianceauth/hrapplications/templates/hrapplications/view.html:32
msgid "Main Character"
msgstr "Personaje Principal"
#: allianceauth/corputils/templates/corputils/corpstats.html:117
#: allianceauth/corputils/templates/corputils/search.html:17
msgid "Main Corporation"
@@ -538,31 +546,35 @@ msgstr "Participacion de flota registrada."
msgid "FAT link has expired."
msgstr "Enlace de participacion expirado."
#: allianceauth/groupmanagement/auth_hooks.py:17
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:14
msgid "Group Management"
msgstr "Manejo de Grupo"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:5
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:13
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:14
msgid "Audit Log"
msgstr "Log de Auditoria"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:18
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:20
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:20
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:21
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:13
msgid "Back"
msgstr "Volver"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:25
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:28
msgid "Date/Time"
msgstr "Fecha/Hora"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:26
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:29
msgid "Requestor"
msgstr "Solicitante"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:29
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:32
msgid "Type"
msgstr "Tipo"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:30
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:17
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:33
#: allianceauth/notifications/templates/notifications/list.html:37
#: allianceauth/notifications/templates/notifications/list.html:69
#: allianceauth/optimer/templates/optimer/fleetoptable.html:18
@@ -573,11 +585,19 @@ msgstr "Tipo"
msgid "Action"
msgstr "Accion"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:31
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:34
msgid "Actor"
msgstr "Actor"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:47
msgid "Removed"
msgstr ""
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:59
msgid "All times displayed are EVE/UTC."
msgstr ""
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:66
msgid "No entries found for this group."
msgstr "No se encontraron entradas para este grupo."
@@ -585,22 +605,24 @@ msgstr "No se encontraron entradas para este grupo."
msgid "Group Members"
msgstr "Miembros del Grupo"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:28
msgid "Portrait"
msgstr "Retrato"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:30
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:38
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:97
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:31
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:52
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:110
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:23
msgid "Organization"
msgstr ""
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:64
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:61
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:78
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:136
msgid "(unknown)"
msgstr ""
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:66
msgid "Remove from group"
msgstr "Remover del grupo"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:76
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:81
msgid "No group members to list."
msgstr "no hay miembros para listar."
@@ -608,56 +630,56 @@ msgstr "no hay miembros para listar."
msgid "Groups Membership"
msgstr "Membresia de grupos"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:14
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:15
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:40
#: allianceauth/templates/allianceauth/side-menu.html:15
#: allianceauth/templates/allianceauth/side-menu.html:16
msgid "Groups"
msgstr "Grupos"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:23
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:25
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:16
msgid "Description"
msgstr "Descripcion"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:24
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:26
#: allianceauth/hrapplications/templates/hrapplications/management.html:28
#: allianceauth/hrapplications/templates/hrapplications/management.html:85
#: allianceauth/hrapplications/templates/hrapplications/management.html:130
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:27
#: allianceauth/srp/templates/srp/data.html:97
#: allianceauth/srp/templates/srp/data.html:98
msgid "Status"
msgstr "Estado"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:25
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:27
msgid "Member Count"
msgstr "Contador de miembros"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:38
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:43
msgid "Hidden"
msgstr "Escondido"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:40
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:45
#: allianceauth/templates/allianceauth/admin-status/overview.html:12
msgid "Open"
msgstr "Abierto"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:42
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:47
msgid "Requestable"
msgstr "Solicitable"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:50
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:56
msgid "View Members"
msgstr "Ver Miembros"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:53
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:60
msgid "Audit Members"
msgstr "Auditar Miembros"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:56
msgid "Copy Direrct Join Link"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:64
msgid "Copy Direct Join Link"
msgstr ""
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:68
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:75
msgid "No groups to list."
msgstr "No hay grupos para listar"
@@ -666,19 +688,19 @@ msgstr "No hay grupos para listar"
msgid "Available Groups"
msgstr "Grupos Disponibles"
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:29
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:30
msgid "Leave"
msgstr "Dejar"
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:39
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:40
msgid "Join"
msgstr "Unirse"
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:43
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:44
msgid "Request"
msgstr "Solicitar"
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:58
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:59
msgid "No groups available."
msgstr "No hay grupos disponibles"
@@ -686,77 +708,72 @@ msgstr "No hay grupos disponibles"
msgid "Groups Management"
msgstr "Manejo de Grupos"
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:23
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:25
msgid "Join Requests"
msgstr ""
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:24
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:34
msgid "Leave Requests"
msgstr ""
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:39
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:98
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:53
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:111
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:20
#: allianceauth/services/modules/openfire/forms.py:6
msgid "Group"
msgstr "Grupo"
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:71
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:130
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:84
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:142
msgid "Accept"
msgstr "Aceptar"
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:74
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:133
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:88
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:146
#: allianceauth/hrapplications/templates/hrapplications/view.html:85
msgid "Reject"
msgstr "Rechazar"
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:83
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:97
msgid "No group add requests."
msgstr "No hay solicitudes de ingreso."
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:142
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:155
msgid "No group leave requests."
msgstr "No hay solicitudes paradejar el grupo."
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:10
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:9
msgid "Toggle navigation"
msgstr "Navegacion"
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:15
#: allianceauth/templates/allianceauth/side-menu.html:23
msgid "Group Management"
msgstr "Manejo de Grupo"
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:21
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:20
msgid "Group Requests"
msgstr "Solicitudes de Grupo"
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:24
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:23
msgid "Group Membership"
msgstr "Membresia de Grupo"
#: allianceauth/groupmanagement/views.py:166
#: allianceauth/groupmanagement/views.py:162
#, python-format
msgid "Removed user %(user)s from group %(group)s."
msgstr "El usuario %(user)s fue removido del grupo %(group)s"
#: allianceauth/groupmanagement/views.py:168
#: allianceauth/groupmanagement/views.py:164
msgid "User does not exist in that group"
msgstr "El usuario no existe en ese grupos"
#: allianceauth/groupmanagement/views.py:171
#: allianceauth/groupmanagement/views.py:167
msgid "Group does not exist"
msgstr "El grupo no existe"
#: allianceauth/groupmanagement/views.py:198
#: allianceauth/groupmanagement/views.py:194
#, python-format
msgid "Accepted application from %(mainchar)s to %(group)s."
msgstr "Solicitud aceptada de %(mainchar)s a %(group)s"
#: allianceauth/groupmanagement/views.py:205
#: allianceauth/groupmanagement/views.py:238
#: allianceauth/groupmanagement/views.py:201
#: allianceauth/groupmanagement/views.py:234
#, python-format
msgid ""
"An unhandled error occurred while processing the application from "
@@ -765,79 +782,79 @@ msgstr ""
"Ocurrio un error cuando se intento procesar la informacion de %(mainchar)s "
"al grupo %(group)s."
#: allianceauth/groupmanagement/views.py:231
#: allianceauth/groupmanagement/views.py:227
#, python-format
msgid "Rejected application from %(mainchar)s to %(group)s."
msgstr "Se rechazo la solicitud de %(mainchar)s al grupo %(group)s."
#: allianceauth/groupmanagement/views.py:267
#: allianceauth/groupmanagement/views.py:263
#, python-format
msgid "Accepted application from %(mainchar)s to leave %(group)s."
msgstr "Se acepto la solicitud de %(mainchar)s para dejar el grupo %(group)s."
#: allianceauth/groupmanagement/views.py:273
#: allianceauth/groupmanagement/views.py:307
#: allianceauth/groupmanagement/views.py:269
#: allianceauth/groupmanagement/views.py:303
#, python-format
msgid ""
"An unhandled error occurred while processing the application from "
"%(mainchar)s to leave %(group)s."
msgstr ""
#: allianceauth/groupmanagement/views.py:300
#: allianceauth/groupmanagement/views.py:296
#, python-format
msgid "Rejected application from %(mainchar)s to leave %(group)s."
msgstr ""
"Se rechazo la solicitud de %(mainchar)s para dejar el grupo %(group)s."
#: allianceauth/groupmanagement/views.py:346
#: allianceauth/groupmanagement/views.py:358
#: allianceauth/groupmanagement/views.py:342
#: allianceauth/groupmanagement/views.py:354
msgid "You cannot join that group"
msgstr "No puedes unirte a ese grupo"
#: allianceauth/groupmanagement/views.py:352
#: allianceauth/groupmanagement/views.py:348
msgid "You are already a member of that group."
msgstr ""
#: allianceauth/groupmanagement/views.py:367
#: allianceauth/groupmanagement/views.py:363
msgid "You already have a pending application for that group."
msgstr ""
#: allianceauth/groupmanagement/views.py:370
#: allianceauth/groupmanagement/views.py:408
#: allianceauth/groupmanagement/views.py:366
#: allianceauth/groupmanagement/views.py:404
#: allianceauth/hrapplications/templates/hrapplications/management.html:37
#: allianceauth/hrapplications/templates/hrapplications/management.html:72
#: allianceauth/hrapplications/templates/hrapplications/management.html:99
#: allianceauth/hrapplications/templates/hrapplications/management.html:144
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:38
#: allianceauth/hrapplications/templates/hrapplications/view.html:20
#: allianceauth/srp/templates/srp/data.html:125
#: allianceauth/srp/templates/srp/data.html:134
#: allianceauth/srp/templates/srp/management.html:81
msgid "Pending"
msgstr "Pendiente"
#: allianceauth/groupmanagement/views.py:376
#: allianceauth/groupmanagement/views.py:372
#, python-format
msgid "Applied to group %(group)s."
msgstr "Solicitud enviada al grupo %(group)s."
#: allianceauth/groupmanagement/views.py:387
#: allianceauth/groupmanagement/views.py:383
msgid "You cannot leave that group"
msgstr "No puedes dejar el grupos"
#: allianceauth/groupmanagement/views.py:392
#: allianceauth/groupmanagement/views.py:388
msgid "You are not a member of that group"
msgstr "No eres miembro de ese grupo"
#: allianceauth/groupmanagement/views.py:401
#: allianceauth/groupmanagement/views.py:397
msgid "You already have a pending leave request for that group."
msgstr ""
#: allianceauth/groupmanagement/views.py:414
#: allianceauth/groupmanagement/views.py:410
#, python-format
msgid "Applied to leave group %(group)s."
msgstr "Solicitaste dejar el grupo %(group)s."
#: allianceauth/hrapplications/auth_hooks.py:10
#: allianceauth/hrapplications/auth_hooks.py:13
msgid "Applications"
msgstr "Solicitudes"
@@ -894,7 +911,7 @@ msgstr "Usuario"
#: allianceauth/hrapplications/templates/hrapplications/management.html:131
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:28
#: allianceauth/hrapplications/templates/hrapplications/view.html:75
#: allianceauth/srp/templates/srp/data.html:99
#: allianceauth/srp/templates/srp/data.html:100
#: allianceauth/srp/templates/srp/management.html:46
msgid "Actions"
msgstr "Acciones"
@@ -904,7 +921,7 @@ msgstr "Acciones"
#: allianceauth/hrapplications/templates/hrapplications/management.html:147
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:40
#: allianceauth/hrapplications/templates/hrapplications/view.html:16
#: allianceauth/srp/templates/srp/data.html:117
#: allianceauth/srp/templates/srp/data.html:126
msgid "Approved"
msgstr "Aprovado"
@@ -912,7 +929,7 @@ msgstr "Aprovado"
#: allianceauth/hrapplications/templates/hrapplications/management.html:104
#: allianceauth/hrapplications/templates/hrapplications/management.html:149
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:42
#: allianceauth/srp/templates/srp/data.html:121
#: allianceauth/srp/templates/srp/data.html:130
msgid "Rejected"
msgstr "Rechazado"
@@ -1295,22 +1312,49 @@ msgstr "Contraseña"
msgid "Password must be at least 8 characters long."
msgstr "La contraseña tiene que tener 8 caracteres de largo minimo"
#: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:23
#: allianceauth/services/modules/discord/models.py:225
msgid "Discord Account Disabled"
msgstr ""
#: allianceauth/services/modules/discord/models.py:227
msgid ""
"Your Discord account was disabled automatically by Auth. If you think this "
"was a mistake, please contact an admin."
msgstr ""
#: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:18
msgid "Join the Discord server"
msgstr ""
#: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:22
msgid "Leave- and rejoin the Discord Server (Reset)"
msgstr ""
#: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:25
msgid "Leave the Discord server"
msgstr ""
#: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:32
msgid "Link Discord Server"
msgstr "Enlace a servidor de Discord"
#: allianceauth/services/modules/discord/views.py:26
#: allianceauth/services/modules/discord/views.py:30
msgid "Deactivated Discord account."
msgstr ""
#: allianceauth/services/modules/discord/views.py:29
#: allianceauth/services/modules/discord/views.py:41
#: allianceauth/services/modules/discord/views.py:65
#: allianceauth/services/modules/discord/views.py:36
#: allianceauth/services/modules/discord/views.py:59
msgid "An error occurred while processing your Discord account."
msgstr ""
#: allianceauth/services/modules/discord/views.py:62
msgid "Activated Discord account."
#: allianceauth/services/modules/discord/views.py:102
msgid "Your Discord account has been successfully activated."
msgstr ""
#: allianceauth/services/modules/discord/views.py:108
msgid ""
"An error occurred while trying to activate your Discord account. Please try "
"again."
msgstr ""
#: allianceauth/services/modules/discourse/views.py:37
@@ -1575,7 +1619,7 @@ msgstr "Servicio"
msgid "Domain"
msgstr "Dominio"
#: allianceauth/srp/auth_hooks.py:9
#: allianceauth/srp/auth_hooks.py:12
msgid "Ship Replacement"
msgstr "Reemplazo de Nave"
@@ -1589,7 +1633,7 @@ msgstr "Hora de flota"
msgid "Fleet Doctrine"
msgstr "Doctrina"
#: allianceauth/srp/form.py:12 allianceauth/srp/templates/srp/data.html:89
#: allianceauth/srp/form.py:12 allianceauth/srp/templates/srp/data.html:90
msgid "Additional Info"
msgstr "Informacion Adicional"
@@ -1618,63 +1662,63 @@ msgstr "Crear SRP"
msgid "Give this link to the line members"
msgstr "Entregar este enlace a los miembros"
#: allianceauth/srp/templates/srp/data.html:48
#: allianceauth/srp/templates/srp/data.html:49
msgid "SRP Fleet Data"
msgstr "Informacion de SRP de la flota"
#: allianceauth/srp/templates/srp/data.html:53
#: allianceauth/srp/templates/srp/data.html:54
msgid "Mark Incomplete"
msgstr "Marcar como Incompleto"
#: allianceauth/srp/templates/srp/data.html:57
#: allianceauth/srp/templates/srp/data.html:58
msgid "Mark Completed"
msgstr "Marcar como Completo"
#: allianceauth/srp/templates/srp/data.html:69
#: allianceauth/srp/templates/srp/data.html:145
#: allianceauth/srp/templates/srp/data.html:70
#: allianceauth/srp/templates/srp/data.html:156
msgid "Total Losses:"
msgstr "Perdidas Totales:"
#: allianceauth/srp/templates/srp/data.html:70
#: allianceauth/srp/templates/srp/data.html:146
#: allianceauth/srp/templates/srp/data.html:71
#: allianceauth/srp/templates/srp/data.html:157
#: allianceauth/srp/templates/srp/management.html:30
msgid "Total ISK Cost:"
msgstr "Costo Total:"
#: allianceauth/srp/templates/srp/data.html:78
#: allianceauth/srp/templates/srp/data.html:154
#: allianceauth/srp/templates/srp/data.html:79
#: allianceauth/srp/templates/srp/data.html:165
msgid "Are you sure you want to delete SRP requests?"
msgstr "Estas seguro que quiere borrar las solicitudes de SRP"
#: allianceauth/srp/templates/srp/data.html:87
#: allianceauth/srp/templates/srp/data.html:88
msgid "Pilot Name"
msgstr "Nombre del Piloto"
#: allianceauth/srp/templates/srp/data.html:88
#: allianceauth/srp/templates/srp/data.html:89
msgid "Killboard Link"
msgstr "Enlace de la Muerte"
#: allianceauth/srp/templates/srp/data.html:90
#: allianceauth/srp/templates/srp/data.html:91
msgid "Ship Type"
msgstr "Tipo"
#: allianceauth/srp/templates/srp/data.html:91
#: allianceauth/srp/templates/srp/data.html:92
msgid "Killboard Loss Amt"
msgstr "Monto de la perdida en ZKB"
#: allianceauth/srp/templates/srp/data.html:92
#: allianceauth/srp/templates/srp/data.html:93
msgid "SRP ISK Cost"
msgstr "Costo del SRP"
#: allianceauth/srp/templates/srp/data.html:93
#: allianceauth/srp/templates/srp/data.html:94
msgid "Click value to edit Enter to save & next ESC to cancel"
msgstr ""
#: allianceauth/srp/templates/srp/data.html:96
#: allianceauth/srp/templates/srp/data.html:97
msgid "Post Time"
msgstr "Tiempo"
#: allianceauth/srp/templates/srp/data.html:163
#: allianceauth/srp/templates/srp/data.html:174
msgid "No SRP requests for this fleet."
msgstr "No hay solicitudes de SRP para esta flota."
@@ -1866,32 +1910,30 @@ msgid "Current"
msgstr "Actual"
#: allianceauth/templates/allianceauth/admin-status/overview.html:40
msgid "Latest Major"
msgstr "Ultimo Importante"
msgid "Latest Stable"
msgstr ""
#: allianceauth/templates/allianceauth/admin-status/overview.html:46
#: allianceauth/templates/allianceauth/admin-status/overview.html:56
#: allianceauth/templates/allianceauth/admin-status/overview.html:66
msgid "Update available"
msgstr "Actualizacion Disponible"
#: allianceauth/templates/allianceauth/admin-status/overview.html:50
msgid "Latest Minor"
msgstr "Ultimo no importante"
#: allianceauth/templates/allianceauth/admin-status/overview.html:51
msgid "Latest Pre-Release"
msgstr ""
#: allianceauth/templates/allianceauth/admin-status/overview.html:60
msgid "Latest Patch"
msgstr "Ultimo Parche"
#: allianceauth/templates/allianceauth/admin-status/overview.html:57
msgid "Pre-Release available"
msgstr ""
#: allianceauth/templates/allianceauth/admin-status/overview.html:73
#: allianceauth/templates/allianceauth/admin-status/overview.html:65
msgid "Task Queue"
msgstr "Cola de Tareas"
#: allianceauth/templates/allianceauth/admin-status/overview.html:90
#: allianceauth/templates/allianceauth/admin-status/overview.html:82
msgid "Error retrieving task queue length"
msgstr "Error al conseguir la cola de tareas"
#: allianceauth/templates/allianceauth/admin-status/overview.html:92
#: allianceauth/templates/allianceauth/admin-status/overview.html:84
#, python-format
msgid "%(tasks)s task"
msgid_plural "%(tasks)s tasks"
@@ -2032,3 +2074,6 @@ msgstr "Se agrego un nuevo timer en %(system)s a las %(time)s."
#: allianceauth/timerboard/views.py:83
msgid "Saved changes to the timer."
msgstr "Se guardaron los cambios en el timer."
#~ msgid "Portrait"
#~ msgstr "Retrato"

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -4,19 +4,20 @@
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
# Translators:
# Lahty <js03js70@gmail.com>, 2020
# Kim Hyundong <khd1226543@gmail.com>, 2020
# None None <khd1226543@gmail.com>, 2020
# Seowon Jung <seowon@hawaii.edu>, 2020
# Olgeda Choi <undead.choi@gmail.com>, 2020
# Lahty <js03js70@gmail.com>, 2020
# Joel Falknau <ozirascal@gmail.com>, 2020
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-05-08 00:57+0000\n"
"POT-Creation-Date: 2020-11-20 05:33+0000\n"
"PO-Revision-Date: 2020-02-18 03:14+0000\n"
"Last-Translator: Olgeda Choi <undead.choi@gmail.com>, 2020\n"
"Last-Translator: Joel Falknau <ozirascal@gmail.com>, 2020\n"
"Language-Team: Korean (Korea) (https://www.transifex.com/alliance-auth/teams/107430/ko_KR/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -28,74 +29,75 @@ msgstr ""
msgid "A main character is required to perform that action. Add one below."
msgstr "해당 기능을 수행하려면 주 캐릭터가 요구됨. 아래에 하나를 추가하시오."
#: allianceauth/authentication/forms.py:6
#: allianceauth/authentication/forms.py:5
msgid "Email"
msgstr "이메일"
#: allianceauth/authentication/models.py:76
msgid "State Changed"
msgstr "상태 변경됨"
#: allianceauth/authentication/models.py:77
#: allianceauth/authentication/models.py:78
#, python-format
msgid "Your user state has been changed to %(state)s"
msgstr "사용자의 상태가 %(state)s변경됨"
msgid "State changed to: %s"
msgstr "상태가 %s로 변경됐습니다."
#: allianceauth/authentication/models.py:79
#, python-format
msgid "Your user's state is now: %(state)s"
msgstr "사용자의 상태는 %(state)s입니다."
#: allianceauth/authentication/templates/authentication/dashboard.html:5
#: allianceauth/authentication/templates/authentication/dashboard.html:8
#: allianceauth/templates/allianceauth/side-menu.html:10
#: allianceauth/templates/allianceauth/side-menu.html:11
msgid "Dashboard"
msgstr "대시보드"
#: allianceauth/authentication/templates/authentication/dashboard.html:17
#: allianceauth/corputils/templates/corputils/corpstats.html:116
#: allianceauth/corputils/templates/corputils/search.html:16
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticscorpview.html:22
#: allianceauth/hrapplications/templates/hrapplications/management.html:83
#: allianceauth/hrapplications/templates/hrapplications/management.html:128
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:25
#: allianceauth/hrapplications/templates/hrapplications/view.html:32
msgid "Main Character"
msgstr "주 캐릭터"
#: allianceauth/authentication/templates/authentication/dashboard.html:18
#, python-format
msgid ""
"\n"
" Main Character (State: %(state)s)\n"
" "
msgstr ""
"\n"
" 메인 캐릭터 (상태: %(state)s)\n"
" "
#: allianceauth/authentication/templates/authentication/dashboard.html:77
#: allianceauth/authentication/templates/authentication/dashboard.html:81
msgid "No main character set."
msgstr "주 캐릭터가 지정되지 않음"
#: allianceauth/authentication/templates/authentication/dashboard.html:84
#: allianceauth/authentication/templates/authentication/dashboard.html:88
msgid "Add Character"
msgstr "캐릭터 추가"
#: allianceauth/authentication/templates/authentication/dashboard.html:88
#: allianceauth/authentication/templates/authentication/dashboard.html:92
msgid "Change Main"
msgstr "주 캐릭터 변경"
#: allianceauth/authentication/templates/authentication/dashboard.html:97
#: allianceauth/authentication/templates/authentication/dashboard.html:101
msgid "Group Memberships"
msgstr "그룹 멤버쉽"
#: allianceauth/authentication/templates/authentication/dashboard.html:117
#: allianceauth/authentication/templates/authentication/dashboard.html:121
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticscorpview.html:23
#: allianceauth/hrapplications/templates/hrapplications/view.html:41
msgid "Characters"
msgstr "캐릭터"
#: allianceauth/authentication/templates/authentication/dashboard.html:125
#: allianceauth/authentication/templates/authentication/dashboard.html:129
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:73
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:22
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:24
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:15
#: allianceauth/hrapplications/templates/hrapplications/view.html:45
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:34
msgid "Name"
msgstr "이름"
#: allianceauth/authentication/templates/authentication/dashboard.html:126
#: allianceauth/authentication/templates/authentication/dashboard.html:130
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticsview.html:23
#: allianceauth/hrapplications/templates/hrapplications/view.html:46
msgid "Corp"
msgstr "콥"
#: allianceauth/authentication/templates/authentication/dashboard.html:127
#: allianceauth/authentication/templates/authentication/dashboard.html:131
#: allianceauth/corputils/templates/corputils/corpstats.html:77
#: allianceauth/hrapplications/templates/hrapplications/view.html:47
msgid "Alliance"
@@ -151,33 +153,33 @@ msgstr "주 캐릭터가 %(char)s로 변경됨"
#: allianceauth/authentication/views.py:89
#, python-format
msgid "Added %(name)s to your account."
msgstr "%(name)s을(를) 계정에 추가함"
msgstr "계정에 %(name)s를 추가했습니다."
#: allianceauth/authentication/views.py:91
#, python-format
msgid "Failed to add %(name)s to your account: they already have an account."
msgstr "%(name)s을(를) 계정에 추가하는데 실패함. 이미 추가되어있음."
msgstr "계정에 %(name)s를 추가하지 못했습니다. 이미 추가된 계정입니다."
#: allianceauth/authentication/views.py:130
msgid "Unable to authenticate as the selected character."
msgstr "선택한 캐릭터로 인증을 수행할 수 없음"
#: allianceauth/authentication/views.py:148
#: allianceauth/authentication/views.py:151
msgid "Registration token has expired."
msgstr "등록토큰 만료"
#: allianceauth/authentication/views.py:200
#: allianceauth/authentication/views.py:206
msgid ""
"Sent confirmation email. Please follow the link to confirm your email "
"address."
msgstr "확인 메일 전송됨. 다음 링크를 눌러 이메일 주소를 확인하세요."
#: allianceauth/authentication/views.py:205
#: allianceauth/authentication/views.py:211
msgid "Confirmed your email address. Please login to continue."
msgstr "이메일 주소가 확인되었습니다. 로그인 해주세요."
#: allianceauth/authentication/views.py:210
msgid "Registraion of new accounts it not allowed at this time."
#: allianceauth/authentication/views.py:216
msgid "Registration of new accounts is not allowed at this time."
msgstr "현재 새로운 계정 등록은 받지않습니다."
#: allianceauth/corputils/auth_hooks.py:10
@@ -225,16 +227,16 @@ msgstr "마지막 업데이트"
#: allianceauth/corputils/templates/corputils/search.html:13
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html:24
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:28
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:27
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:29
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:37
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:96
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:30
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:30
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:51
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:109
msgid "Character"
msgstr "캐릭터"
#: allianceauth/corputils/templates/corputils/corpstats.html:76
#: allianceauth/corputils/templates/corputils/search.html:14
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:28
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:31
#: allianceauth/hrapplications/templates/hrapplications/management.html:27
#: allianceauth/hrapplications/templates/hrapplications/management.html:84
#: allianceauth/hrapplications/templates/hrapplications/management.html:129
@@ -250,6 +252,16 @@ msgstr "콥"
msgid "Killboard"
msgstr "킬보드"
#: allianceauth/corputils/templates/corputils/corpstats.html:116
#: allianceauth/corputils/templates/corputils/search.html:16
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticscorpview.html:22
#: allianceauth/hrapplications/templates/hrapplications/management.html:83
#: allianceauth/hrapplications/templates/hrapplications/management.html:128
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:25
#: allianceauth/hrapplications/templates/hrapplications/view.html:32
msgid "Main Character"
msgstr "주 캐릭터"
#: allianceauth/corputils/templates/corputils/corpstats.html:117
#: allianceauth/corputils/templates/corputils/search.html:17
msgid "Main Corporation"
@@ -531,31 +543,35 @@ msgstr "플릿 참여 등록됨"
msgid "FAT link has expired."
msgstr "플릿활동추적 링크 기한만료"
#: allianceauth/groupmanagement/auth_hooks.py:17
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:14
msgid "Group Management"
msgstr "그룹 관리"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:5
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:13
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:14
msgid "Audit Log"
msgstr "감사 기록"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:18
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:20
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:20
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:21
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:13
msgid "Back"
msgstr "돌아가기"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:25
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:28
msgid "Date/Time"
msgstr "날짜/시간"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:26
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:29
msgid "Requestor"
msgstr "요청인"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:29
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:32
msgid "Type"
msgstr "타입"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:30
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:17
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:33
#: allianceauth/notifications/templates/notifications/list.html:37
#: allianceauth/notifications/templates/notifications/list.html:69
#: allianceauth/optimer/templates/optimer/fleetoptable.html:18
@@ -566,11 +582,19 @@ msgstr "타입"
msgid "Action"
msgstr "활동"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:31
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:34
msgid "Actor"
msgstr "활동한 사람"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:47
msgid "Removed"
msgstr ""
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:59
msgid "All times displayed are EVE/UTC."
msgstr ""
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:66
msgid "No entries found for this group."
msgstr "이 그룹에는 항목 없음"
@@ -578,22 +602,24 @@ msgstr "이 그룹에는 항목 없음"
msgid "Group Members"
msgstr "그룹 멤버"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:28
msgid "Portrait"
msgstr "포트레잇"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:30
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:38
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:97
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:31
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:52
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:110
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:23
msgid "Organization"
msgstr "조직"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:64
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:61
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:78
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:136
msgid "(unknown)"
msgstr ""
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:66
msgid "Remove from group"
msgstr "그룹에서 제거"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:76
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:81
msgid "No group members to list."
msgstr "목록에 그룹 멤버 없음"
@@ -601,56 +627,56 @@ msgstr "목록에 그룹 멤버 없음"
msgid "Groups Membership"
msgstr "그룹 멤버쉽"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:14
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:15
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:40
#: allianceauth/templates/allianceauth/side-menu.html:15
#: allianceauth/templates/allianceauth/side-menu.html:16
msgid "Groups"
msgstr "그룹"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:23
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:25
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:16
msgid "Description"
msgstr "설명"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:24
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:26
#: allianceauth/hrapplications/templates/hrapplications/management.html:28
#: allianceauth/hrapplications/templates/hrapplications/management.html:85
#: allianceauth/hrapplications/templates/hrapplications/management.html:130
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:27
#: allianceauth/srp/templates/srp/data.html:97
#: allianceauth/srp/templates/srp/data.html:98
msgid "Status"
msgstr "상태"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:25
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:27
msgid "Member Count"
msgstr "멤버 수"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:38
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:43
msgid "Hidden"
msgstr "숨김"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:40
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:45
#: allianceauth/templates/allianceauth/admin-status/overview.html:12
msgid "Open"
msgstr "열기"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:42
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:47
msgid "Requestable"
msgstr "요청 가능"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:50
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:56
msgid "View Members"
msgstr "멤버 보기"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:53
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:60
msgid "Audit Members"
msgstr "멤버 검사"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:56
msgid "Copy Direrct Join Link"
msgstr ""
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:64
msgid "Copy Direct Join Link"
msgstr "직접 참여 링크 복사"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:68
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:75
msgid "No groups to list."
msgstr "목록에 그룹 없음"
@@ -659,19 +685,19 @@ msgstr "목록에 그룹 없음"
msgid "Available Groups"
msgstr "사용 가능한 그룹"
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:29
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:30
msgid "Leave"
msgstr "떠나기"
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:39
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:40
msgid "Join"
msgstr "참여하기"
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:43
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:44
msgid "Request"
msgstr "요청하기"
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:58
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:59
msgid "No groups available."
msgstr "사용 가능한 그룹 없음."
@@ -679,155 +705,150 @@ msgstr "사용 가능한 그룹 없음."
msgid "Groups Management"
msgstr "그룹 관리"
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:23
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:25
msgid "Join Requests"
msgstr "가입 요청"
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:24
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:34
msgid "Leave Requests"
msgstr "탈퇴 요청"
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:39
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:98
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:53
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:111
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:20
#: allianceauth/services/modules/openfire/forms.py:6
msgid "Group"
msgstr "그룹"
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:71
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:130
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:84
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:142
msgid "Accept"
msgstr "수락"
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:74
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:133
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:88
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:146
#: allianceauth/hrapplications/templates/hrapplications/view.html:85
msgid "Reject"
msgstr "거절"
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:83
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:97
msgid "No group add requests."
msgstr "가입 요청 없음"
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:142
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:155
msgid "No group leave requests."
msgstr "탈퇴 요청 없음"
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:10
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:9
msgid "Toggle navigation"
msgstr "네비게이션 전환"
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:15
#: allianceauth/templates/allianceauth/side-menu.html:23
msgid "Group Management"
msgstr "그룹 관리"
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:21
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:20
msgid "Group Requests"
msgstr "그룹 요청"
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:24
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:23
msgid "Group Membership"
msgstr "그룹 멤버쉽"
#: allianceauth/groupmanagement/views.py:166
#: allianceauth/groupmanagement/views.py:162
#, python-format
msgid "Removed user %(user)s from group %(group)s."
msgstr "유저 %(user)s이(가) %(group)s에서 제거됨."
#: allianceauth/groupmanagement/views.py:168
#: allianceauth/groupmanagement/views.py:164
msgid "User does not exist in that group"
msgstr "유저가 해당 그룹에 존재하지 않음."
#: allianceauth/groupmanagement/views.py:171
#: allianceauth/groupmanagement/views.py:167
msgid "Group does not exist"
msgstr "그룹이 존재하지 않음."
#: allianceauth/groupmanagement/views.py:198
#: allianceauth/groupmanagement/views.py:194
#, python-format
msgid "Accepted application from %(mainchar)s to %(group)s."
msgstr "%(mainchar)s의 %(group)s 그룹 신청 수락"
#: allianceauth/groupmanagement/views.py:205
#: allianceauth/groupmanagement/views.py:238
#: allianceauth/groupmanagement/views.py:201
#: allianceauth/groupmanagement/views.py:234
#, python-format
msgid ""
"An unhandled error occurred while processing the application from "
"%(mainchar)s to %(group)s."
msgstr "%(mainchar)s의 %(group)s 그룹 신청을 처리하는 중 알 수 없는 에러 발생"
#: allianceauth/groupmanagement/views.py:231
#: allianceauth/groupmanagement/views.py:227
#, python-format
msgid "Rejected application from %(mainchar)s to %(group)s."
msgstr "%(mainchar)s의 %(group)s 그룹 신청 거절"
#: allianceauth/groupmanagement/views.py:267
#: allianceauth/groupmanagement/views.py:263
#, python-format
msgid "Accepted application from %(mainchar)s to leave %(group)s."
msgstr "%(mainchar)s의 %(group)s 그룹 탈퇴 수락"
#: allianceauth/groupmanagement/views.py:273
#: allianceauth/groupmanagement/views.py:307
#: allianceauth/groupmanagement/views.py:269
#: allianceauth/groupmanagement/views.py:303
#, python-format
msgid ""
"An unhandled error occurred while processing the application from "
"%(mainchar)s to leave %(group)s."
msgstr "%(mainchar)s의 %(group)s 그룹 탈퇴를 처리하는 중 알 수 없는 에러 발생"
#: allianceauth/groupmanagement/views.py:300
#: allianceauth/groupmanagement/views.py:296
#, python-format
msgid "Rejected application from %(mainchar)s to leave %(group)s."
msgstr "%(mainchar)s의 %(group)s 그룹 탈퇴 거절"
#: allianceauth/groupmanagement/views.py:346
#: allianceauth/groupmanagement/views.py:358
#: allianceauth/groupmanagement/views.py:342
#: allianceauth/groupmanagement/views.py:354
msgid "You cannot join that group"
msgstr "해당 그룹에 참여할 수 없습니다."
#: allianceauth/groupmanagement/views.py:352
#: allianceauth/groupmanagement/views.py:348
msgid "You are already a member of that group."
msgstr "이미 해당 그룹에 가입되어 있습니다."
#: allianceauth/groupmanagement/views.py:367
#: allianceauth/groupmanagement/views.py:363
msgid "You already have a pending application for that group."
msgstr "해당 그룹에 대한 참여신청이 보류되었습니다."
#: allianceauth/groupmanagement/views.py:370
#: allianceauth/groupmanagement/views.py:408
#: allianceauth/groupmanagement/views.py:366
#: allianceauth/groupmanagement/views.py:404
#: allianceauth/hrapplications/templates/hrapplications/management.html:37
#: allianceauth/hrapplications/templates/hrapplications/management.html:72
#: allianceauth/hrapplications/templates/hrapplications/management.html:99
#: allianceauth/hrapplications/templates/hrapplications/management.html:144
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:38
#: allianceauth/hrapplications/templates/hrapplications/view.html:20
#: allianceauth/srp/templates/srp/data.html:125
#: allianceauth/srp/templates/srp/data.html:134
#: allianceauth/srp/templates/srp/management.html:81
msgid "Pending"
msgstr "보류 중"
#: allianceauth/groupmanagement/views.py:376
#: allianceauth/groupmanagement/views.py:372
#, python-format
msgid "Applied to group %(group)s."
msgstr "%(group)s그룹에 지원하였음."
#: allianceauth/groupmanagement/views.py:387
#: allianceauth/groupmanagement/views.py:383
msgid "You cannot leave that group"
msgstr "해당 그룹을 떠날 수 없습니다."
#: allianceauth/groupmanagement/views.py:392
#: allianceauth/groupmanagement/views.py:388
msgid "You are not a member of that group"
msgstr "해당그룹의 멤버가 아닙니다."
#: allianceauth/groupmanagement/views.py:401
#: allianceauth/groupmanagement/views.py:397
msgid "You already have a pending leave request for that group."
msgstr "해당 그룹의 탈퇴 신청이 접수된 상태입니다."
#: allianceauth/groupmanagement/views.py:414
#: allianceauth/groupmanagement/views.py:410
#, python-format
msgid "Applied to leave group %(group)s."
msgstr "%(group)s그룹의 탈퇴가 신청됨."
#: allianceauth/hrapplications/auth_hooks.py:10
#: allianceauth/hrapplications/auth_hooks.py:13
msgid "Applications"
msgstr "지원"
@@ -884,7 +905,7 @@ msgstr "사용자명"
#: allianceauth/hrapplications/templates/hrapplications/management.html:131
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:28
#: allianceauth/hrapplications/templates/hrapplications/view.html:75
#: allianceauth/srp/templates/srp/data.html:99
#: allianceauth/srp/templates/srp/data.html:100
#: allianceauth/srp/templates/srp/management.html:46
msgid "Actions"
msgstr "활동"
@@ -894,7 +915,7 @@ msgstr "활동"
#: allianceauth/hrapplications/templates/hrapplications/management.html:147
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:40
#: allianceauth/hrapplications/templates/hrapplications/view.html:16
#: allianceauth/srp/templates/srp/data.html:117
#: allianceauth/srp/templates/srp/data.html:126
msgid "Approved"
msgstr "승인"
@@ -902,7 +923,7 @@ msgstr "승인"
#: allianceauth/hrapplications/templates/hrapplications/management.html:104
#: allianceauth/hrapplications/templates/hrapplications/management.html:149
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:42
#: allianceauth/srp/templates/srp/data.html:121
#: allianceauth/srp/templates/srp/data.html:130
msgid "Rejected"
msgstr "거절"
@@ -1285,23 +1306,50 @@ msgstr "비밀번호"
msgid "Password must be at least 8 characters long."
msgstr "비밀번호는 8글자 이상이어야 합니다."
#: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:23
#: allianceauth/services/modules/discord/models.py:225
msgid "Discord Account Disabled"
msgstr "디스코드 계정 비활성화"
#: allianceauth/services/modules/discord/models.py:227
msgid ""
"Your Discord account was disabled automatically by Auth. If you think this "
"was a mistake, please contact an admin."
msgstr "Auth에 의해 자동으로 디스코드 계정이 비활성화됐습니다. 원치 않는 사항일 경우, 관리자에게 문의해 주세요."
#: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:18
msgid "Join the Discord server"
msgstr "디스코드 서버 입장"
#: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:22
msgid "Leave- and rejoin the Discord Server (Reset)"
msgstr "디스코드 서버를 나가고 다시 입장하기 (리셋)"
#: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:25
msgid "Leave the Discord server"
msgstr "디스코드 서버 나가기"
#: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:32
msgid "Link Discord Server"
msgstr "디스코드 서버 링크"
#: allianceauth/services/modules/discord/views.py:26
#: allianceauth/services/modules/discord/views.py:30
msgid "Deactivated Discord account."
msgstr "디스코드 계정 해제 완료"
#: allianceauth/services/modules/discord/views.py:29
#: allianceauth/services/modules/discord/views.py:41
#: allianceauth/services/modules/discord/views.py:65
#: allianceauth/services/modules/discord/views.py:36
#: allianceauth/services/modules/discord/views.py:59
msgid "An error occurred while processing your Discord account."
msgstr "디스코드 계정 처리 중 오류가 발생했습니다."
#: allianceauth/services/modules/discord/views.py:62
msgid "Activated Discord account."
msgstr "디스코드 계정 활성화 완료"
#: allianceauth/services/modules/discord/views.py:102
msgid "Your Discord account has been successfully activated."
msgstr "디스코드 계정과 성공적으로 연동됐습니다."
#: allianceauth/services/modules/discord/views.py:108
msgid ""
"An error occurred while trying to activate your Discord account. Please try "
"again."
msgstr "디스코드 계정 연동 중 오류가 발생했습니다. 다시 시도해 주세요."
#: allianceauth/services/modules/discourse/views.py:37
msgid "You are not authorized to access Discourse."
@@ -1565,7 +1613,7 @@ msgstr "서드파티"
msgid "Domain"
msgstr "도메인"
#: allianceauth/srp/auth_hooks.py:9
#: allianceauth/srp/auth_hooks.py:12
msgid "Ship Replacement"
msgstr "SRP"
@@ -1579,7 +1627,7 @@ msgstr "플릿 시간"
msgid "Fleet Doctrine"
msgstr "플릿 독트린"
#: allianceauth/srp/form.py:12 allianceauth/srp/templates/srp/data.html:89
#: allianceauth/srp/form.py:12 allianceauth/srp/templates/srp/data.html:90
msgid "Additional Info"
msgstr "추가 기재 사항"
@@ -1608,63 +1656,63 @@ msgstr "SRP 보상 플릿 생성"
msgid "Give this link to the line members"
msgstr "이 링크를 직계 멤버들에게 전달"
#: allianceauth/srp/templates/srp/data.html:48
#: allianceauth/srp/templates/srp/data.html:49
msgid "SRP Fleet Data"
msgstr "SRP 보상 플릿 데이터"
#: allianceauth/srp/templates/srp/data.html:53
#: allianceauth/srp/templates/srp/data.html:54
msgid "Mark Incomplete"
msgstr "표시 미완료"
#: allianceauth/srp/templates/srp/data.html:57
#: allianceauth/srp/templates/srp/data.html:58
msgid "Mark Completed"
msgstr "표시 완료"
#: allianceauth/srp/templates/srp/data.html:69
#: allianceauth/srp/templates/srp/data.html:145
#: allianceauth/srp/templates/srp/data.html:70
#: allianceauth/srp/templates/srp/data.html:156
msgid "Total Losses:"
msgstr "전체 손실:"
#: allianceauth/srp/templates/srp/data.html:70
#: allianceauth/srp/templates/srp/data.html:146
#: allianceauth/srp/templates/srp/data.html:71
#: allianceauth/srp/templates/srp/data.html:157
#: allianceauth/srp/templates/srp/management.html:30
msgid "Total ISK Cost:"
msgstr "전체 ISK 비용:"
#: allianceauth/srp/templates/srp/data.html:78
#: allianceauth/srp/templates/srp/data.html:154
#: allianceauth/srp/templates/srp/data.html:79
#: allianceauth/srp/templates/srp/data.html:165
msgid "Are you sure you want to delete SRP requests?"
msgstr "SRP 보상 요청을 삭제하시겠습니까?"
#: allianceauth/srp/templates/srp/data.html:87
#: allianceauth/srp/templates/srp/data.html:88
msgid "Pilot Name"
msgstr "파일럿 이름"
#: allianceauth/srp/templates/srp/data.html:88
#: allianceauth/srp/templates/srp/data.html:89
msgid "Killboard Link"
msgstr "킬보드 링크"
#: allianceauth/srp/templates/srp/data.html:90
#: allianceauth/srp/templates/srp/data.html:91
msgid "Ship Type"
msgstr "함선 종류"
#: allianceauth/srp/templates/srp/data.html:91
#: allianceauth/srp/templates/srp/data.html:92
msgid "Killboard Loss Amt"
msgstr "킬보드상 손실 금액"
#: allianceauth/srp/templates/srp/data.html:92
#: allianceauth/srp/templates/srp/data.html:93
msgid "SRP ISK Cost"
msgstr "SRP 보상 비용"
#: allianceauth/srp/templates/srp/data.html:93
#: allianceauth/srp/templates/srp/data.html:94
msgid "Click value to edit Enter to save & next ESC to cancel"
msgstr "금액을 수정하려면 클릭, 저장을 하고 다음으로 가려면 엔터, 취소를 하려면 ESC를 누르세요. "
#: allianceauth/srp/templates/srp/data.html:96
#: allianceauth/srp/templates/srp/data.html:97
msgid "Post Time"
msgstr "작성 시간"
#: allianceauth/srp/templates/srp/data.html:163
#: allianceauth/srp/templates/srp/data.html:174
msgid "No SRP requests for this fleet."
msgstr "이 플릿에는 SRP 보상 요청이 없습니다."
@@ -1856,32 +1904,30 @@ msgid "Current"
msgstr "현재"
#: allianceauth/templates/allianceauth/admin-status/overview.html:40
msgid "Latest Major"
msgstr "최근 주요 사항"
msgid "Latest Stable"
msgstr "최신 안정화 버전"
#: allianceauth/templates/allianceauth/admin-status/overview.html:46
#: allianceauth/templates/allianceauth/admin-status/overview.html:56
#: allianceauth/templates/allianceauth/admin-status/overview.html:66
msgid "Update available"
msgstr "업데이트 가능"
#: allianceauth/templates/allianceauth/admin-status/overview.html:50
msgid "Latest Minor"
msgstr "최근 기타 사항"
#: allianceauth/templates/allianceauth/admin-status/overview.html:51
msgid "Latest Pre-Release"
msgstr "최신 사전 출시 버전"
#: allianceauth/templates/allianceauth/admin-status/overview.html:60
msgid "Latest Patch"
msgstr "최근 패치"
#: allianceauth/templates/allianceauth/admin-status/overview.html:57
msgid "Pre-Release available"
msgstr "사전 출시 사용 가능"
#: allianceauth/templates/allianceauth/admin-status/overview.html:73
#: allianceauth/templates/allianceauth/admin-status/overview.html:65
msgid "Task Queue"
msgstr "대기 중인 할 일"
#: allianceauth/templates/allianceauth/admin-status/overview.html:90
#: allianceauth/templates/allianceauth/admin-status/overview.html:82
msgid "Error retrieving task queue length"
msgstr "대기 중인 할 일 목록 회수 에러"
#: allianceauth/templates/allianceauth/admin-status/overview.html:92
#: allianceauth/templates/allianceauth/admin-status/overview.html:84
#, python-format
msgid "%(tasks)s task"
msgid_plural "%(tasks)s tasks"
@@ -2021,3 +2067,6 @@ msgstr "%(time)s 에 있을 %(system)s 타이머를 추가했습니다."
#: allianceauth/timerboard/views.py:83
msgid "Saved changes to the timer."
msgstr "타이머 변경사항이 저장되었습니다."
#~ msgid "Portrait"
#~ msgstr "포트레잇"

View File

@@ -5,15 +5,17 @@
#
# Translators:
# Alexander Gess <de.alex.gess@gmail.com>, 2020
# Yuriy K <thedjcooltv@gmail.com>, 2020
# Андрей Зубков <and.vareba81@gmail.com>, 2020
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-07-29 04:56+0000\n"
"POT-Creation-Date: 2020-11-20 05:33+0000\n"
"PO-Revision-Date: 2020-02-18 03:14+0000\n"
"Last-Translator: Alexander Gess <de.alex.gess@gmail.com>, 2020\n"
"Last-Translator: Андрей Зубков <and.vareba81@gmail.com>, 2020\n"
"Language-Team: Russian (https://www.transifex.com/alliance-auth/teams/107430/ru/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -25,7 +27,7 @@ msgstr ""
msgid "A main character is required to perform that action. Add one below."
msgstr "Необходимо указать основного персонажа. Добавим?"
#: allianceauth/authentication/forms.py:6
#: allianceauth/authentication/forms.py:5
msgid "Email"
msgstr "Email"
@@ -41,7 +43,7 @@ msgstr "Статус пилота: %(state)s"
#: allianceauth/authentication/templates/authentication/dashboard.html:5
#: allianceauth/authentication/templates/authentication/dashboard.html:8
#: allianceauth/templates/allianceauth/side-menu.html:12
#: allianceauth/templates/allianceauth/side-menu.html:11
msgid "Dashboard"
msgstr "Панель показателей"
@@ -70,7 +72,7 @@ msgstr "Сменить основного персонажа"
#: allianceauth/authentication/templates/authentication/dashboard.html:101
msgid "Group Memberships"
msgstr "Групповое участие"
msgstr "Роли"
#: allianceauth/authentication/templates/authentication/dashboard.html:121
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticscorpview.html:23
@@ -80,7 +82,7 @@ msgstr "Персонажи"
#: allianceauth/authentication/templates/authentication/dashboard.html:129
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:73
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:22
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:24
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:15
#: allianceauth/hrapplications/templates/hrapplications/view.html:45
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:34
@@ -163,23 +165,23 @@ msgstr "Персонаж %(name)s уже добавлен."
msgid "Unable to authenticate as the selected character."
msgstr "Невозможно авторизировать этого персонажа. "
#: allianceauth/authentication/views.py:148
#: allianceauth/authentication/views.py:151
msgid "Registration token has expired."
msgstr "Регистрационный токен просрочен."
#: allianceauth/authentication/views.py:200
#: allianceauth/authentication/views.py:206
msgid ""
"Sent confirmation email. Please follow the link to confirm your email "
"address."
msgstr "Отправить подтверждающее письмо. Пожалуйста, подтвердите почту. "
#: allianceauth/authentication/views.py:205
#: allianceauth/authentication/views.py:211
msgid "Confirmed your email address. Please login to continue."
msgstr "Подтвердите Ваш email адрес. Зайти для подтверждения. "
#: allianceauth/authentication/views.py:210
msgid "Registraion of new accounts it not allowed at this time."
msgstr "Регистрация нового аккаунта сейчас невозможна."
#: allianceauth/authentication/views.py:216
msgid "Registration of new accounts is not allowed at this time."
msgstr "Регистрация новых аккаунтов в настоящее время невозможна."
#: allianceauth/corputils/auth_hooks.py:10
msgid "Corporation Stats"
@@ -226,16 +228,16 @@ msgstr "Последнее обновление: "
#: allianceauth/corputils/templates/corputils/search.html:13
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html:24
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:28
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:27
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:29
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:30
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:30
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:51
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:110
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:109
msgid "Character"
msgstr "Персонаж"
#: allianceauth/corputils/templates/corputils/corpstats.html:76
#: allianceauth/corputils/templates/corputils/search.html:14
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:28
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:31
#: allianceauth/hrapplications/templates/hrapplications/management.html:27
#: allianceauth/hrapplications/templates/hrapplications/management.html:84
#: allianceauth/hrapplications/templates/hrapplications/management.html:129
@@ -326,7 +328,7 @@ msgstr "Добавить сюда"
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/characternotexisting.html:19
msgid "before attempting to click fleet attendance links."
msgstr "перед вступлением проверте содержимое"
msgstr "перед вступлением проверьте содержимое"
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkformatter.html:6
msgid "Create Fatlink"
@@ -548,31 +550,35 @@ msgstr "Флотовое участие зарегистрированно."
msgid "FAT link has expired."
msgstr "ФлАк ссылка устарела"
#: allianceauth/groupmanagement/auth_hooks.py:17
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:14
msgid "Group Management"
msgstr "Управление Группой"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:5
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:13
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:14
msgid "Audit Log"
msgstr "Записи безопасности"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:18
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:20
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:20
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:21
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:13
msgid "Back"
msgstr "Назад"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:25
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:28
msgid "Date/Time"
msgstr "Дата / Время"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:26
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:29
msgid "Requestor"
msgstr "Запрос от"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:29
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:32
msgid "Type"
msgstr "Тип"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:30
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:17
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:33
#: allianceauth/notifications/templates/notifications/list.html:37
#: allianceauth/notifications/templates/notifications/list.html:69
#: allianceauth/optimer/templates/optimer/fleetoptable.html:18
@@ -583,11 +589,19 @@ msgstr "Тип"
msgid "Action"
msgstr "Действие"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:31
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:34
msgid "Actor"
msgstr "Исполнитель"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:47
msgid "Removed"
msgstr ""
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:59
msgid "All times displayed are EVE/UTC."
msgstr ""
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:66
msgid "No entries found for this group."
msgstr "Нет вхождений в эту группу"
@@ -595,22 +609,24 @@ msgstr "Нет вхождений в эту группу"
msgid "Group Members"
msgstr "Групповые Участники"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:28
msgid "Portrait"
msgstr "Портрет"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:30
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:31
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:52
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:111
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:110
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:23
msgid "Organization"
msgstr "Корпорация"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:64
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:61
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:78
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:136
msgid "(unknown)"
msgstr ""
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:66
msgid "Remove from group"
msgstr "Исключить из группы"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:76
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:81
msgid "No group members to list."
msgstr "Нет участников в группе"
@@ -618,56 +634,56 @@ msgstr "Нет участников в группе"
msgid "Groups Membership"
msgstr "Участники группы"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:14
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:15
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:40
#: allianceauth/templates/allianceauth/side-menu.html:17
#: allianceauth/templates/allianceauth/side-menu.html:16
msgid "Groups"
msgstr "Группы"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:23
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:25
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:16
msgid "Description"
msgstr "Описание"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:24
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:26
#: allianceauth/hrapplications/templates/hrapplications/management.html:28
#: allianceauth/hrapplications/templates/hrapplications/management.html:85
#: allianceauth/hrapplications/templates/hrapplications/management.html:130
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:27
#: allianceauth/srp/templates/srp/data.html:97
#: allianceauth/srp/templates/srp/data.html:98
msgid "Status"
msgstr "Статус"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:25
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:27
msgid "Member Count"
msgstr "Число участников"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:38
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:43
msgid "Hidden"
msgstr "Скрытые"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:40
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:45
#: allianceauth/templates/allianceauth/admin-status/overview.html:12
msgid "Open"
msgstr "Открыть"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:42
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:47
msgid "Requestable"
msgstr "Запрошено"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:50
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:56
msgid "View Members"
msgstr "Посмотреть участников"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:53
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:60
msgid "Audit Members"
msgstr "Проверить участников"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:56
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:64
msgid "Copy Direct Join Link"
msgstr "Скопировать ссылку подключения"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:68
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:75
msgid "No groups to list."
msgstr "Нет групп в списке"
@@ -676,19 +692,19 @@ msgstr "Нет групп в списке"
msgid "Available Groups"
msgstr "Доступные группы"
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:29
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:30
msgid "Leave"
msgstr "Покинуть"
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:39
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:40
msgid "Join"
msgstr "Присоединиться"
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:43
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:44
msgid "Request"
msgstr "Запрос"
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:58
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:59
msgid "No groups available."
msgstr "Нет доступных групп."
@@ -700,24 +716,24 @@ msgstr "Управление Группами"
msgid "Join Requests"
msgstr "Запрос на присоединение"
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:33
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:34
msgid "Leave Requests"
msgstr "Запрос на Выход"
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:53
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:112
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:111
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:20
#: allianceauth/services/modules/openfire/forms.py:6
msgid "Group"
msgstr "Группа"
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:85
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:144
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:84
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:142
msgid "Accept"
msgstr "Принять"
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:88
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:147
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:146
#: allianceauth/hrapplications/templates/hrapplications/view.html:85
msgid "Reject"
msgstr "Сбросить"
@@ -726,24 +742,19 @@ msgstr "Сбросить"
msgid "No group add requests."
msgstr "Нет групповых запросов на вступление"
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:156
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:155
msgid "No group leave requests."
msgstr "Нет групповых запросов на выход"
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:10
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:9
msgid "Toggle navigation"
msgstr "Проложить маршрут"
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:15
#: allianceauth/templates/allianceauth/side-menu.html:25
msgid "Group Management"
msgstr "Управление Группой"
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:21
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:20
msgid "Group Requests"
msgstr "Групповой запрос"
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:24
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:23
msgid "Group Membership"
msgstr "Групповое участие"
@@ -821,7 +832,7 @@ msgstr "Вы уже подали заявку на вступление этой
#: allianceauth/hrapplications/templates/hrapplications/management.html:144
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:38
#: allianceauth/hrapplications/templates/hrapplications/view.html:20
#: allianceauth/srp/templates/srp/data.html:125
#: allianceauth/srp/templates/srp/data.html:134
#: allianceauth/srp/templates/srp/management.html:81
msgid "Pending"
msgstr "Ожидание"
@@ -848,7 +859,7 @@ msgstr "Ваш запрос находится на рассмотрении"
msgid "Applied to leave group %(group)s."
msgstr "Запрос на выход из группы %(group)s."
#: allianceauth/hrapplications/auth_hooks.py:10
#: allianceauth/hrapplications/auth_hooks.py:13
msgid "Applications"
msgstr "Запросы"
@@ -905,7 +916,7 @@ msgstr "Пользователь"
#: allianceauth/hrapplications/templates/hrapplications/management.html:131
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:28
#: allianceauth/hrapplications/templates/hrapplications/view.html:75
#: allianceauth/srp/templates/srp/data.html:99
#: allianceauth/srp/templates/srp/data.html:100
#: allianceauth/srp/templates/srp/management.html:46
msgid "Actions"
msgstr "Действия"
@@ -915,7 +926,7 @@ msgstr "Действия"
#: allianceauth/hrapplications/templates/hrapplications/management.html:147
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:40
#: allianceauth/hrapplications/templates/hrapplications/view.html:16
#: allianceauth/srp/templates/srp/data.html:117
#: allianceauth/srp/templates/srp/data.html:126
msgid "Approved"
msgstr "Проверено"
@@ -923,7 +934,7 @@ msgstr "Проверено"
#: allianceauth/hrapplications/templates/hrapplications/management.html:104
#: allianceauth/hrapplications/templates/hrapplications/management.html:149
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:42
#: allianceauth/srp/templates/srp/data.html:121
#: allianceauth/srp/templates/srp/data.html:130
msgid "Rejected"
msgstr "Отменено "
@@ -1029,7 +1040,7 @@ msgstr "Не прочитанно"
#: allianceauth/notifications/templates/notifications/list.html:18
msgid "Read"
msgstr "Прочитать"
msgstr "Прочитано"
#: allianceauth/notifications/templates/notifications/list.html:22
msgid "Mark All Read"
@@ -1137,7 +1148,7 @@ msgstr "Таймера Флотовых операций"
#: allianceauth/optimer/templates/optimer/management.html:21
#: allianceauth/timerboard/templates/timerboard/view.html:23
msgid "Current Eve Time:"
msgstr "ET"
msgstr "Текущий EVE Time:"
#: allianceauth/optimer/templates/optimer/management.html:27
#: allianceauth/timerboard/templates/timerboard/view.html:189
@@ -1244,7 +1255,7 @@ msgstr "{} Пароль успешно обновлен."
#: allianceauth/services/auth_hooks.py:11
msgid "Services"
msgstr "Сервисные услуги"
msgstr "Подключение сервисов"
#: allianceauth/services/forms.py:6
msgid "Name of Fleet:"
@@ -1306,17 +1317,15 @@ msgstr "Пароль"
msgid "Password must be at least 8 characters long."
msgstr "Пароль должен быть не менее 8 символов."
#: allianceauth/services/modules/discord/models.py:224
#: allianceauth/services/modules/discord/models.py:225
msgid "Discord Account Disabled"
msgstr "Discord персонаж отключен"
#: allianceauth/services/modules/discord/models.py:226
#: allianceauth/services/modules/discord/models.py:227
msgid ""
"Your Discord account was disabeled automatically by Auth. If you think this "
"Your Discord account was disabled automatically by Auth. If you think this "
"was a mistake, please contact an admin."
msgstr ""
"Ваш доступ на сервер Discord был отменен. Если Вы считаете что по ошибке, "
"пожалуйста, свяжитесь с СЕО."
#: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:18
msgid "Join the Discord server"
@@ -1623,9 +1632,9 @@ msgstr "Сервис"
msgid "Domain"
msgstr "Домен"
#: allianceauth/srp/auth_hooks.py:9
#: allianceauth/srp/auth_hooks.py:12
msgid "Ship Replacement"
msgstr "Замена корабля"
msgstr "Компенсация корабля"
#: allianceauth/srp/form.py:7
#: allianceauth/srp/templates/srp/management.html:38
@@ -1637,7 +1646,7 @@ msgstr "Флотовое время"
msgid "Fleet Doctrine"
msgstr "Флотовая Доктрина"
#: allianceauth/srp/form.py:12 allianceauth/srp/templates/srp/data.html:89
#: allianceauth/srp/form.py:12 allianceauth/srp/templates/srp/data.html:90
msgid "Additional Info"
msgstr "Дополнительная информация"
@@ -1666,63 +1675,63 @@ msgstr "Создать SRP Флот"
msgid "Give this link to the line members"
msgstr "Поделиться ссылкой с рядовыми участниками"
#: allianceauth/srp/templates/srp/data.html:48
#: allianceauth/srp/templates/srp/data.html:49
msgid "SRP Fleet Data"
msgstr "SRP данные флота"
#: allianceauth/srp/templates/srp/data.html:53
#: allianceauth/srp/templates/srp/data.html:54
msgid "Mark Incomplete"
msgstr "Пометить незаконченным"
#: allianceauth/srp/templates/srp/data.html:57
#: allianceauth/srp/templates/srp/data.html:58
msgid "Mark Completed"
msgstr "Пометить законченным"
#: allianceauth/srp/templates/srp/data.html:69
#: allianceauth/srp/templates/srp/data.html:145
#: allianceauth/srp/templates/srp/data.html:70
#: allianceauth/srp/templates/srp/data.html:156
msgid "Total Losses:"
msgstr "Суммарные потери:"
#: allianceauth/srp/templates/srp/data.html:70
#: allianceauth/srp/templates/srp/data.html:146
#: allianceauth/srp/templates/srp/data.html:71
#: allianceauth/srp/templates/srp/data.html:157
#: allianceauth/srp/templates/srp/management.html:30
msgid "Total ISK Cost:"
msgstr "Оценочная стоимость (ISK):"
#: allianceauth/srp/templates/srp/data.html:78
#: allianceauth/srp/templates/srp/data.html:154
#: allianceauth/srp/templates/srp/data.html:79
#: allianceauth/srp/templates/srp/data.html:165
msgid "Are you sure you want to delete SRP requests?"
msgstr "Вы уверенны что хотите удалить запрос на SRP?"
#: allianceauth/srp/templates/srp/data.html:87
#: allianceauth/srp/templates/srp/data.html:88
msgid "Pilot Name"
msgstr "Имя Пилота"
#: allianceauth/srp/templates/srp/data.html:88
#: allianceauth/srp/templates/srp/data.html:89
msgid "Killboard Link"
msgstr "zKillBoard ссылка"
#: allianceauth/srp/templates/srp/data.html:90
#: allianceauth/srp/templates/srp/data.html:91
msgid "Ship Type"
msgstr "Тип корабля"
#: allianceauth/srp/templates/srp/data.html:91
#: allianceauth/srp/templates/srp/data.html:92
msgid "Killboard Loss Amt"
msgstr "потерь по zKillBoard на данный момент"
#: allianceauth/srp/templates/srp/data.html:92
#: allianceauth/srp/templates/srp/data.html:93
msgid "SRP ISK Cost"
msgstr "SRP ISK Стоимость"
#: allianceauth/srp/templates/srp/data.html:93
#: allianceauth/srp/templates/srp/data.html:94
msgid "Click value to edit Enter to save & next ESC to cancel"
msgstr "Нажмите на значение для редактирования и ESC для отмены"
#: allianceauth/srp/templates/srp/data.html:96
#: allianceauth/srp/templates/srp/data.html:97
msgid "Post Time"
msgstr "Опубликованно"
#: allianceauth/srp/templates/srp/data.html:163
#: allianceauth/srp/templates/srp/data.html:174
msgid "No SRP requests for this fleet."
msgstr "SRP запросы отсутствуют"
@@ -1974,14 +1983,14 @@ msgstr "Прочие"
#: allianceauth/timerboard/templates/timerboard/view.html:220
#: allianceauth/timerboard/templates/timerboard/view.html:388
msgid "Friendly"
msgstr "Дружествен"
msgstr "Дружественный"
#: allianceauth/timerboard/form.py:55
#: allianceauth/timerboard/templates/timerboard/view.html:53
#: allianceauth/timerboard/templates/timerboard/view.html:215
#: allianceauth/timerboard/templates/timerboard/view.html:383
msgid "Hostile"
msgstr "Заложник"
msgstr "Вражеский"
#: allianceauth/timerboard/form.py:56
#: allianceauth/timerboard/templates/timerboard/view.html:63
@@ -2083,3 +2092,6 @@ msgstr "Добавлен таймер в %(system)s на %(time)s."
#: allianceauth/timerboard/views.py:83
msgid "Saved changes to the timer."
msgstr "Изменения сохранены"
#~ msgid "Portrait"
#~ msgstr "Портрет"

View File

@@ -13,7 +13,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-07-29 03:24+0000\n"
"POT-Creation-Date: 2020-11-20 05:33+0000\n"
"PO-Revision-Date: 2020-02-18 03:14+0000\n"
"Last-Translator: Aaron BuBu <351793078@qq.com>, 2020\n"
"Language-Team: Chinese Simplified (https://www.transifex.com/alliance-auth/teams/107430/zh-Hans/)\n"
@@ -27,7 +27,7 @@ msgstr ""
msgid "A main character is required to perform that action. Add one below."
msgstr "只有主要角色才能执行这个操作。在下面添加一个"
#: allianceauth/authentication/forms.py:6
#: allianceauth/authentication/forms.py:5
msgid "Email"
msgstr "电子邮箱"
@@ -43,7 +43,7 @@ msgstr ""
#: allianceauth/authentication/templates/authentication/dashboard.html:5
#: allianceauth/authentication/templates/authentication/dashboard.html:8
#: allianceauth/templates/allianceauth/side-menu.html:12
#: allianceauth/templates/allianceauth/side-menu.html:11
msgid "Dashboard"
msgstr "账户总览"
@@ -79,7 +79,7 @@ msgstr "角色"
#: allianceauth/authentication/templates/authentication/dashboard.html:129
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:73
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:22
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:24
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:15
#: allianceauth/hrapplications/templates/hrapplications/view.html:45
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:34
@@ -159,23 +159,23 @@ msgstr "添加%(name)s到您的账户失败他们已经在一个账户中了"
msgid "Unable to authenticate as the selected character."
msgstr "无法作为选定的角色进行身份验证"
#: allianceauth/authentication/views.py:148
#: allianceauth/authentication/views.py:151
msgid "Registration token has expired."
msgstr "注册令牌过期。"
#: allianceauth/authentication/views.py:200
#: allianceauth/authentication/views.py:206
msgid ""
"Sent confirmation email. Please follow the link to confirm your email "
"address."
msgstr "已经发送了确认邮件。请按照链接确定您的电邮地址"
#: allianceauth/authentication/views.py:205
#: allianceauth/authentication/views.py:211
msgid "Confirmed your email address. Please login to continue."
msgstr "已确认您的电邮地址。请登录以继续"
#: allianceauth/authentication/views.py:210
msgid "Registraion of new accounts it not allowed at this time."
msgstr "现在不允许注册新账户。"
#: allianceauth/authentication/views.py:216
msgid "Registration of new accounts is not allowed at this time."
msgstr ""
#: allianceauth/corputils/auth_hooks.py:10
msgid "Corporation Stats"
@@ -222,16 +222,16 @@ msgstr "最后一次更新"
#: allianceauth/corputils/templates/corputils/search.html:13
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html:24
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:28
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:27
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:29
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:30
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:30
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:51
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:110
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:109
msgid "Character"
msgstr "角色"
#: allianceauth/corputils/templates/corputils/corpstats.html:76
#: allianceauth/corputils/templates/corputils/search.html:14
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:28
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:31
#: allianceauth/hrapplications/templates/hrapplications/management.html:27
#: allianceauth/hrapplications/templates/hrapplications/management.html:84
#: allianceauth/hrapplications/templates/hrapplications/management.html:129
@@ -538,31 +538,35 @@ msgstr "成功注册舰队PAP"
msgid "FAT link has expired."
msgstr "PAP链接已过期"
#: allianceauth/groupmanagement/auth_hooks.py:17
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:14
msgid "Group Management"
msgstr "用户组管理"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:5
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:13
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:14
msgid "Audit Log"
msgstr "审计日志"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:18
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:20
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:20
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:21
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:13
msgid "Back"
msgstr "返回"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:25
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:28
msgid "Date/Time"
msgstr "日期/时间"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:26
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:29
msgid "Requestor"
msgstr "申请人"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:29
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:32
msgid "Type"
msgstr "类型"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:30
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:17
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:33
#: allianceauth/notifications/templates/notifications/list.html:37
#: allianceauth/notifications/templates/notifications/list.html:69
#: allianceauth/optimer/templates/optimer/fleetoptable.html:18
@@ -573,11 +577,19 @@ msgstr "类型"
msgid "Action"
msgstr "操作"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:31
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:34
msgid "Actor"
msgstr "操作者"
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:47
msgid "Removed"
msgstr ""
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:59
msgid "All times displayed are EVE/UTC."
msgstr ""
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:66
msgid "No entries found for this group."
msgstr "这一用户组下面没有任何条目呀"
@@ -585,22 +597,24 @@ msgstr "这一用户组下面没有任何条目呀"
msgid "Group Members"
msgstr "群组成员"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:28
msgid "Portrait"
msgstr "人物头像"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:30
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:31
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:52
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:111
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:110
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:23
msgid "Organization"
msgstr "组织"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:64
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:61
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:78
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:136
msgid "(unknown)"
msgstr ""
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:66
msgid "Remove from group"
msgstr "从用户组中移除"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:76
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:81
msgid "No group members to list."
msgstr "用户组里没人呀,你叫我怎么列"
@@ -608,56 +622,56 @@ msgstr "用户组里没人呀,你叫我怎么列"
msgid "Groups Membership"
msgstr "用户组成员"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:14
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:15
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:40
#: allianceauth/templates/allianceauth/side-menu.html:17
#: allianceauth/templates/allianceauth/side-menu.html:16
msgid "Groups"
msgstr "群组"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:23
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:25
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:16
msgid "Description"
msgstr "描述"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:24
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:26
#: allianceauth/hrapplications/templates/hrapplications/management.html:28
#: allianceauth/hrapplications/templates/hrapplications/management.html:85
#: allianceauth/hrapplications/templates/hrapplications/management.html:130
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:27
#: allianceauth/srp/templates/srp/data.html:97
#: allianceauth/srp/templates/srp/data.html:98
msgid "Status"
msgstr "状态"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:25
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:27
msgid "Member Count"
msgstr "成员数量"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:38
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:43
msgid "Hidden"
msgstr "已隐藏"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:40
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:45
#: allianceauth/templates/allianceauth/admin-status/overview.html:12
msgid "Open"
msgstr "公开"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:42
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:47
msgid "Requestable"
msgstr "可申请"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:50
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:56
msgid "View Members"
msgstr "查看成员"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:53
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:60
msgid "Audit Members"
msgstr "编辑成员"
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:56
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:64
msgid "Copy Direct Join Link"
msgstr ""
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:68
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:75
msgid "No groups to list."
msgstr "无可用组"
@@ -666,19 +680,19 @@ msgstr "无可用组"
msgid "Available Groups"
msgstr "可用组"
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:29
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:30
msgid "Leave"
msgstr "离开"
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:39
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:40
msgid "Join"
msgstr "加入"
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:43
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:44
msgid "Request"
msgstr "申请"
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:58
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:59
msgid "No groups available."
msgstr "没有可用用户组"
@@ -690,24 +704,24 @@ msgstr "用户组管理"
msgid "Join Requests"
msgstr "入组的请求"
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:33
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:34
msgid "Leave Requests"
msgstr "离组的请求"
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:53
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:112
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:111
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:20
#: allianceauth/services/modules/openfire/forms.py:6
msgid "Group"
msgstr "用户组"
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:85
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:144
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:84
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:142
msgid "Accept"
msgstr "接受"
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:88
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:147
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:146
#: allianceauth/hrapplications/templates/hrapplications/view.html:85
msgid "Reject"
msgstr "拒绝"
@@ -716,24 +730,19 @@ msgstr "拒绝"
msgid "No group add requests."
msgstr "没有加入用户组的请求,小老弟你是不是摇不到人"
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:156
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:155
msgid "No group leave requests."
msgstr "没有离开用户组的请求,小老弟你人缘可以啊?"
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:10
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:9
msgid "Toggle navigation"
msgstr "打开导航栏"
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:15
#: allianceauth/templates/allianceauth/side-menu.html:25
msgid "Group Management"
msgstr "用户组管理"
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:21
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:20
msgid "Group Requests"
msgstr "用户组请求"
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:24
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:23
msgid "Group Membership"
msgstr "用户组成员"
@@ -807,7 +816,7 @@ msgstr "你已经有了该组的未决申请"
#: allianceauth/hrapplications/templates/hrapplications/management.html:144
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:38
#: allianceauth/hrapplications/templates/hrapplications/view.html:20
#: allianceauth/srp/templates/srp/data.html:125
#: allianceauth/srp/templates/srp/data.html:134
#: allianceauth/srp/templates/srp/management.html:81
msgid "Pending"
msgstr "待定"
@@ -834,7 +843,7 @@ msgstr "你已经有了该组的未决离开请求"
msgid "Applied to leave group %(group)s."
msgstr "已经离开群组%(group)s"
#: allianceauth/hrapplications/auth_hooks.py:10
#: allianceauth/hrapplications/auth_hooks.py:13
msgid "Applications"
msgstr "申请"
@@ -891,7 +900,7 @@ msgstr "用户名"
#: allianceauth/hrapplications/templates/hrapplications/management.html:131
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:28
#: allianceauth/hrapplications/templates/hrapplications/view.html:75
#: allianceauth/srp/templates/srp/data.html:99
#: allianceauth/srp/templates/srp/data.html:100
#: allianceauth/srp/templates/srp/management.html:46
msgid "Actions"
msgstr "操作"
@@ -901,7 +910,7 @@ msgstr "操作"
#: allianceauth/hrapplications/templates/hrapplications/management.html:147
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:40
#: allianceauth/hrapplications/templates/hrapplications/view.html:16
#: allianceauth/srp/templates/srp/data.html:117
#: allianceauth/srp/templates/srp/data.html:126
msgid "Approved"
msgstr "通过"
@@ -909,7 +918,7 @@ msgstr "通过"
#: allianceauth/hrapplications/templates/hrapplications/management.html:104
#: allianceauth/hrapplications/templates/hrapplications/management.html:149
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:42
#: allianceauth/srp/templates/srp/data.html:121
#: allianceauth/srp/templates/srp/data.html:130
msgid "Rejected"
msgstr "拒绝"
@@ -1292,13 +1301,13 @@ msgstr "密码"
msgid "Password must be at least 8 characters long."
msgstr "密码至少要有8个字符啊你也太不注重安全啦"
#: allianceauth/services/modules/discord/models.py:224
#: allianceauth/services/modules/discord/models.py:225
msgid "Discord Account Disabled"
msgstr ""
#: allianceauth/services/modules/discord/models.py:226
#: allianceauth/services/modules/discord/models.py:227
msgid ""
"Your Discord account was disabeled automatically by Auth. If you think this "
"Your Discord account was disabled automatically by Auth. If you think this "
"was a mistake, please contact an admin."
msgstr ""
@@ -1599,7 +1608,7 @@ msgstr "服务"
msgid "Domain"
msgstr "域名"
#: allianceauth/srp/auth_hooks.py:9
#: allianceauth/srp/auth_hooks.py:12
msgid "Ship Replacement"
msgstr "补损"
@@ -1613,7 +1622,7 @@ msgstr "集结时间"
msgid "Fleet Doctrine"
msgstr "舰队船型"
#: allianceauth/srp/form.py:12 allianceauth/srp/templates/srp/data.html:89
#: allianceauth/srp/form.py:12 allianceauth/srp/templates/srp/data.html:90
msgid "Additional Info"
msgstr "其他信息"
@@ -1642,63 +1651,63 @@ msgstr "创建补损舰队"
msgid "Give this link to the line members"
msgstr "把这个链接发送给火力狗们"
#: allianceauth/srp/templates/srp/data.html:48
#: allianceauth/srp/templates/srp/data.html:49
msgid "SRP Fleet Data"
msgstr "舰队补损信息"
#: allianceauth/srp/templates/srp/data.html:53
#: allianceauth/srp/templates/srp/data.html:54
msgid "Mark Incomplete"
msgstr "标记为未完成"
#: allianceauth/srp/templates/srp/data.html:57
#: allianceauth/srp/templates/srp/data.html:58
msgid "Mark Completed"
msgstr "标记为已完成"
#: allianceauth/srp/templates/srp/data.html:69
#: allianceauth/srp/templates/srp/data.html:145
#: allianceauth/srp/templates/srp/data.html:70
#: allianceauth/srp/templates/srp/data.html:156
msgid "Total Losses:"
msgstr "损失总额:"
#: allianceauth/srp/templates/srp/data.html:70
#: allianceauth/srp/templates/srp/data.html:146
#: allianceauth/srp/templates/srp/data.html:71
#: allianceauth/srp/templates/srp/data.html:157
#: allianceauth/srp/templates/srp/management.html:30
msgid "Total ISK Cost:"
msgstr "ISK花费总额"
#: allianceauth/srp/templates/srp/data.html:78
#: allianceauth/srp/templates/srp/data.html:154
#: allianceauth/srp/templates/srp/data.html:79
#: allianceauth/srp/templates/srp/data.html:165
msgid "Are you sure you want to delete SRP requests?"
msgstr "老哥,你确定要删了补损请求么?"
#: allianceauth/srp/templates/srp/data.html:87
#: allianceauth/srp/templates/srp/data.html:88
msgid "Pilot Name"
msgstr "玩家ID"
#: allianceauth/srp/templates/srp/data.html:88
#: allianceauth/srp/templates/srp/data.html:89
msgid "Killboard Link"
msgstr "KB网链接"
#: allianceauth/srp/templates/srp/data.html:90
#: allianceauth/srp/templates/srp/data.html:91
msgid "Ship Type"
msgstr "船型"
#: allianceauth/srp/templates/srp/data.html:91
#: allianceauth/srp/templates/srp/data.html:92
msgid "Killboard Loss Amt"
msgstr "KB网总损失"
#: allianceauth/srp/templates/srp/data.html:92
#: allianceauth/srp/templates/srp/data.html:93
msgid "SRP ISK Cost"
msgstr "补损ISK花费"
#: allianceauth/srp/templates/srp/data.html:93
#: allianceauth/srp/templates/srp/data.html:94
msgid "Click value to edit Enter to save & next ESC to cancel"
msgstr "点击数值就可以编辑啦按回车确认按ESC取消"
#: allianceauth/srp/templates/srp/data.html:96
#: allianceauth/srp/templates/srp/data.html:97
msgid "Post Time"
msgstr "发布时间"
#: allianceauth/srp/templates/srp/data.html:163
#: allianceauth/srp/templates/srp/data.html:174
msgid "No SRP requests for this fleet."
msgstr "这次起队没有补损请求!大捷"
@@ -2052,3 +2061,6 @@ msgstr "已经把%(system)s星系里%(time)s的时间节点设置好了CTA
#: allianceauth/timerboard/views.py:83
msgid "Saved changes to the timer."
msgstr "保存至新的计划表"
#~ msgid "Portrait"
#~ msgstr "人物头像"

View File

@@ -1,22 +1,9 @@
default_app_config = 'allianceauth.notifications.apps.NotificationsConfig'
import logging
logger = logging.getLogger(__name__)
MAX_NOTIFICATIONS = 50
def notify(user, title, message=None, level='info'):
def notify(
user: object, title: str, message: str = None, level: str = 'info'
) -> None:
"""Sends a new notification to user. Convenience function to manager pendant."""
from .models import Notification
if Notification.objects.filter(user=user).count() > MAX_NOTIFICATIONS:
for n in Notification.objects.filter(user=user)[MAX_NOTIFICATIONS-1:]:
n.delete()
notif = Notification()
notif.user = user
notif.title = title
if not message:
message = title
notif.message = message
notif.level = level
notif.save()
logger.info("Created notification %s" % notif)
Notification.objects.notify_user(user, title, message, level)

View File

@@ -1,11 +0,0 @@
from .models import Notification
from django.core.cache import cache
def user_notification_count(request):
user_id = request.user.id
notification_count = cache.get("u-note:{}".format(user_id), -1)
if notification_count<0:
notification_count = Notification.objects.filter(user__id=user_id).filter(viewed=False).count()
cache.set("u-note:{}".format(user_id),notification_count,5)
return {'notifications': notification_count}

View File

@@ -0,0 +1,101 @@
import logging
from django.conf import settings
from django.core.cache import cache
from django.db import models
from django.contrib.auth.models import User
logger = logging.getLogger(__name__)
class NotificationQuerySet(models.QuerySet):
"""Custom QuerySet for Notification model"""
def update(self, *args, **kwargs):
# overriden update to ensure cache is invaidated on very call
super().update(*args, **kwargs)
user_pks = set(self.select_related("user").values_list('user__pk', flat=True))
for user_pk in user_pks:
NotificationManager.invalidate_user_notification_cache(user_pk)
class NotificationManager(models.Manager):
USER_NOTIFICATION_COUNT_PREFIX = 'USER_NOTIFICATION_COUNT'
USER_NOTIFICATION_COUNT_CACHE_DURATION = 86_400
def get_queryset(self):
return NotificationQuerySet(self.model, using=self._db)
def notify_user(
self, user: object, title: str, message: str = None, level: str = 'info'
) -> object:
"""Sends a new notification to user. Returns newly created notification object.
"""
max_notifications = self._max_notifications_per_user()
if self.filter(user=user).count() >= max_notifications:
to_be_deleted_qs = self.filter(user=user).order_by(
"-timestamp"
)[max_notifications - 1:]
for notification in to_be_deleted_qs:
notification.delete()
if not message:
message = title
obj = self.create(user=user, title=title, message=message, level=level)
logger.info("Created notification %s", obj)
return obj
def _max_notifications_per_user(self):
"""return the maximum number of notifications allowed per user"""
max_notifications = getattr(settings, 'NOTIFICATIONS_MAX_PER_USER', None)
if (
max_notifications is None
or not isinstance(max_notifications, int)
or max_notifications < 0
):
logger.warning(
'NOTIFICATIONS_MAX_PER_USER setting is invalid. Using default.'
)
max_notifications = self.model.NOTIFICATIONS_MAX_PER_USER_DEFAULT
return max_notifications
def user_unread_count(self, user_pk: int) -> int:
"""returns the cached unread count for a user given by user PK
Will return -1 if user can not be found
"""
cache_key = self._user_notification_cache_key(user_pk)
unread_count = cache.get(key=cache_key)
if not unread_count:
try:
user = User.objects.get(pk=user_pk)
except User.DoesNotExist:
unread_count = -1
else:
logger.debug(
'Updating notification cache for user with pk %s', user_pk
)
unread_count = user.notification_set.filter(viewed=False).count()
cache.set(
key=cache_key,
value=unread_count,
timeout=self.USER_NOTIFICATION_COUNT_CACHE_DURATION
)
else:
logger.debug(
'Returning notification count from cache for user with pk %s', user_pk
)
return unread_count
@classmethod
def invalidate_user_notification_cache(cls, user_pk: int) -> None:
cache.delete(key=cls._user_notification_cache_key(user_pk))
logger.debug('Invalided notification cache for user with pk %s', user_pk)
@classmethod
def _user_notification_cache_key(cls, user_pk: int) -> str:
return f'{cls.USER_NOTIFICATION_COUNT_PREFIX}_{user_pk}'

View File

@@ -0,0 +1,27 @@
# Generated by Django 3.1.5 on 2021-01-07 21:09
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('notifications', '0003_make_strings_more_stringy'),
]
operations = [
migrations.AlterModelOptions(
name='notification',
options={},
),
migrations.AlterField(
model_name='notification',
name='timestamp',
field=models.DateTimeField(auto_now_add=True, db_index=True),
),
migrations.AlterField(
model_name='notification',
name='viewed',
field=models.BooleanField(db_index=True, default=False),
),
]

View File

@@ -1,11 +1,19 @@
import logging
from django.db import models
from django.contrib.auth.models import User
import logging
from .managers import NotificationManager
logger = logging.getLogger(__name__)
class Notification(models.Model):
"""Notification to a user within Auth"""
NOTIFICATIONS_MAX_PER_USER_DEFAULT = 50
NOTIFICATIONS_REFRESH_TIME_DEFAULT = 30
LEVEL_CHOICES = (
('danger', 'CRITICAL'),
('danger', 'ERROR'),
@@ -18,19 +26,41 @@ class Notification(models.Model):
level = models.CharField(choices=LEVEL_CHOICES, max_length=10)
title = models.CharField(max_length=254)
message = models.TextField()
timestamp = models.DateTimeField(auto_now_add=True)
viewed = models.BooleanField(default=False)
timestamp = models.DateTimeField(auto_now_add=True, db_index=True)
viewed = models.BooleanField(default=False, db_index=True)
def view(self):
objects = NotificationManager()
def __str__(self) -> str:
return "%s: %s" % (self.user, self.title)
def save(self, *args, **kwargs):
# overriden save to ensure cache is invaidated on very call
super().save(*args, **kwargs)
Notification.objects.invalidate_user_notification_cache(self.user.pk)
def delete(self, *args, **kwargs):
# overriden delete to ensure cache is invaidated on very call
super().delete(*args, **kwargs)
Notification.objects.invalidate_user_notification_cache(self.user.pk)
def mark_viewed(self) -> None:
"""mark notification as viewed"""
logger.info("Marking notification as viewed: %s" % self)
self.viewed = True
self.save()
def __str__(self):
return "%s: %s" % (self.user, self.title)
def set_level(self, level_name: str) -> None:
"""set notification level according to level name, e.g. 'CRITICAL'
raised exception on invalid level names
"""
try:
new_level = [
item[0] for item in self.LEVEL_CHOICES if item[1] == level_name
][0]
except IndexError:
raise ValueError('Invalid level name: %s' % level_name)
def set_level(self, level):
self.level = [item[0] for item in self.LEVEL_CHOICES if item[1] == level][0]
class Meta:
ordering = ['-timestamp']
self.level = new_level
self.save()

View File

@@ -1,5 +1,5 @@
{% extends "allianceauth/base.html" %}
{% load staticfiles %}
{% load static %}
{% load i18n %}
{% block page_title %}{% trans "Notifications" %}{% endblock %}

View File

@@ -1,5 +1,5 @@
{% extends "allianceauth/base.html" %}
{% load staticfiles %}
{% load static %}
{% load i18n %}
{% block page_title %}{% trans "View Notification" %}{% endblock page_title %}

View File

@@ -0,0 +1,43 @@
"""Templatetags for notifications
These template tags are required to enable the notifications refresh functionality
in the browser.
"""
import logging
from django import template
from django.conf import settings
from django.contrib.auth.models import User
from allianceauth.notifications.models import Notification
logger = logging.getLogger(__name__)
register = template.Library()
@register.filter
def user_unread_notification_count(user: object) -> int:
"""returns the number of unread notifications for user
Will return -1 on error
"""
if not isinstance(user, User):
unread_count = -1
else:
unread_count = Notification.objects.user_unread_count(user.pk)
return unread_count
@register.simple_tag
def notifications_refresh_time() -> int:
refresh_time = getattr(settings, 'NOTIFICATIONS_REFRESH_TIME', None)
if (
refresh_time is None or not isinstance(refresh_time, int) or refresh_time < 0
):
logger.warning('NOTIFICATIONS_REFRESH_TIME setting is invalid. Using default.')
refresh_time = Notification.NOTIFICATIONS_REFRESH_TIME_DEFAULT
return refresh_time

View File

@@ -0,0 +1,28 @@
from django.test import TestCase
from allianceauth.tests.auth_utils import AuthUtils
from .. import notify
from ..models import Notification
MODULE_PATH = 'allianceauth.notifications'
class TestUserNotificationCount(TestCase):
@classmethod
def setUpTestData(cls):
cls.user = AuthUtils.create_user('magic_mike')
AuthUtils.add_main_character(
cls.user,
'Magic Mike',
'1',
corp_id='2',
corp_name='Pole Riders',
corp_ticker='PRIDE',
alliance_id='3',
alliance_name='RIDERS'
)
def test_can_notify(self):
notify(self.user, 'dummy')
self.assertEqual(Notification.objects.filter(user=self.user).count(), 1)

View File

@@ -0,0 +1,206 @@
from unittest.mock import patch
from django.contrib.auth.models import User
from django.test import TestCase, override_settings
from allianceauth.tests.auth_utils import AuthUtils
from ..models import Notification
MODULE_PATH = 'allianceauth.notifications.models'
NOTIFICATIONS_MAX_PER_USER_DEFAULT = 42
class TestQuerySet(TestCase):
@classmethod
def setUpTestData(cls):
cls.user_1 = AuthUtils.create_user('Peter Parker')
cls.user_2 = AuthUtils.create_user('Clark Kent')
@patch(MODULE_PATH + '.Notification.objects.invalidate_user_notification_cache')
def test_update_will_invalidate_cache(
self, mock_invalidate_user_notification_cache
):
Notification.objects.notify_user(self.user_1, 'dummy_1')
Notification.objects.notify_user(self.user_2, 'dummy_2')
Notification.objects.update(viewed=True)
self.assertEquals(mock_invalidate_user_notification_cache.call_count, 2)
class TestUserNotify(TestCase):
@classmethod
def setUpTestData(cls):
cls.user = AuthUtils.create_user('magic_mike')
AuthUtils.add_main_character(
cls.user,
'Magic Mike',
'1',
corp_id='2',
corp_name='Pole Riders',
corp_ticker='PRIDE',
alliance_id='3',
alliance_name='RIDERS'
)
def test_can_notify(self):
title = 'dummy_title'
message = 'dummy message'
level = 'danger'
Notification.objects.notify_user(self.user, title, message, level)
self.assertEqual(Notification.objects.filter(user=self.user).count(), 1)
obj = Notification.objects.first()
self.assertEqual(obj.user, self.user)
self.assertEqual(obj.title, title)
self.assertEqual(obj.message, message)
self.assertEqual(obj.level, level)
def test_use_message_as_title_if_missing(self):
title = 'dummy_title'
Notification.objects.notify_user(self.user, title)
self.assertEqual(Notification.objects.filter(user=self.user).count(), 1)
obj = Notification.objects.first()
self.assertEqual(obj.user, self.user)
self.assertEqual(obj.title, title)
self.assertEqual(obj.message, title)
@override_settings(NOTIFICATIONS_MAX_PER_USER=3)
def test_remove_when_too_many_notifications(self):
Notification.objects.notify_user(self.user, 'dummy')
obj_2 = Notification.objects.notify_user(self.user, 'dummy')
obj_3 = Notification.objects.notify_user(self.user, 'dummy')
obj_4 = Notification.objects.notify_user(self.user, 'dummy')
expected = {obj_2.pk, obj_3.pk, obj_4.pk}
result = set(
Notification.objects.filter(user=self.user).values_list("pk", flat=True)
)
self.assertSetEqual(result, expected)
obj_5 = Notification.objects.notify_user(self.user, 'dummy')
expected = {obj_3.pk, obj_4.pk, obj_5.pk}
result = set(
Notification.objects.filter(user=self.user).values_list("pk", flat=True)
)
self.assertSetEqual(result, expected)
@patch(
MODULE_PATH + '.Notification.NOTIFICATIONS_MAX_PER_USER_DEFAULT',
NOTIFICATIONS_MAX_PER_USER_DEFAULT
)
class TestMaxNotificationsPerUser(TestCase):
@override_settings(NOTIFICATIONS_MAX_PER_USER=None)
def test_reset_to_default_if_not_defined(self):
result = Notification.objects._max_notifications_per_user()
expected = NOTIFICATIONS_MAX_PER_USER_DEFAULT
self.assertEquals(result, expected)
@override_settings(NOTIFICATIONS_MAX_PER_USER='11')
def test_reset_to_default_if_not_int(self):
result = Notification.objects._max_notifications_per_user()
expected = NOTIFICATIONS_MAX_PER_USER_DEFAULT
self.assertEquals(result, expected)
@override_settings(NOTIFICATIONS_MAX_PER_USER=-1)
def test_reset_to_default_if_lt_zero(self):
result = Notification.objects._max_notifications_per_user()
expected = NOTIFICATIONS_MAX_PER_USER_DEFAULT
self.assertEquals(result, expected)
@patch('allianceauth.notifications.managers.cache')
class TestUnreadCount(TestCase):
@classmethod
def setUpTestData(cls):
cls.user_1 = AuthUtils.create_user('magic_mike')
AuthUtils.add_main_character(
cls.user_1,
'Magic Mike',
'1',
corp_id='2',
corp_name='Pole Riders',
corp_ticker='PRIDE',
alliance_id='3',
alliance_name='RIDERS'
)
# test notifications for mike
Notification.objects.all().delete()
Notification.objects.create(
user=cls.user_1,
level="INFO",
title="Job 1 Failed",
message="Because it was broken",
viewed=True
)
Notification.objects.create(
user=cls.user_1,
level="INFO",
title="Job 2 Failed",
message="Because it was broken"
)
Notification.objects.create(
user=cls.user_1,
level="INFO",
title="Job 3 Failed",
message="Because it was broken"
)
cls.user_2 = AuthUtils.create_user('teh_kid')
AuthUtils.add_main_character(
cls.user_2,
'The Kid', '2',
corp_id='2',
corp_name='Pole Riders',
corp_ticker='PRIDE',
alliance_id='3',
alliance_name='RIDERS'
)
# Notifications for kid
Notification.objects.create(
user=cls.user_2,
level="INFO",
title="Job 6 Failed",
message="Because it was broken"
)
def test_update_cache_when_not_in_cache(self, mock_cache):
mock_cache.get.return_value = None
result = Notification.objects.user_unread_count(self.user_1.pk)
expected = 2
self.assertEqual(result, expected)
self.assertTrue(mock_cache.set.called)
args, kwargs = mock_cache.set.call_args
self.assertEqual(
kwargs['key'],
Notification.objects._user_notification_cache_key(self.user_1.pk)
)
self.assertEqual(kwargs['value'], expected)
def test_return_from_cache_when_in_cache(self, mock_cache):
mock_cache.get.return_value = 42
result = Notification.objects.user_unread_count(self.user_1.pk)
expected = 42
self.assertEqual(result, expected)
self.assertFalse(mock_cache.set.called)
def test_return_error_code_when_user_not_found(self, mock_cache):
mock_cache.get.return_value = None
invalid_user_id = max([user.pk for user in User.objects.all()]) + 1
result = Notification.objects.user_unread_count(invalid_user_id)
expected = -1
self.assertEqual(result, expected)
self.assertFalse(mock_cache.set.called)
def test_can_invalidate_cache(self, mock_cache):
Notification.objects.invalidate_user_notification_cache(self.user_1.pk)
self.assertTrue(mock_cache.delete)
args, kwargs = mock_cache.delete.call_args
self.assertEqual(
kwargs['key'],
Notification.objects._user_notification_cache_key(self.user_1.pk)
)

View File

@@ -0,0 +1,73 @@
from unittest.mock import patch
from django.test import TestCase
from allianceauth.tests.auth_utils import AuthUtils
from ..models import Notification
MODULE_PATH = 'allianceauth.notifications.models'
class TestUserNotify(TestCase):
@classmethod
def setUpTestData(cls):
cls.user = AuthUtils.create_user('magic_mike')
AuthUtils.add_main_character(
cls.user,
'Magic Mike',
'1',
corp_id='2',
corp_name='Pole Riders',
corp_ticker='PRIDE',
alliance_id='3',
alliance_name='RIDERS'
)
@patch(MODULE_PATH + '.Notification.objects.invalidate_user_notification_cache')
def test_save_will_invalidate_cache(self, mock_invalidate_user_notification_cache):
obj = Notification.objects.notify_user(self.user, 'dummy')
self.assertTrue(Notification.objects.filter(pk=obj.pk).exists())
self.assertEquals(mock_invalidate_user_notification_cache.call_count, 1)
@patch(MODULE_PATH + '.Notification.objects.invalidate_user_notification_cache')
def test_delete_will_invalidate_cache(
self, mock_invalidate_user_notification_cache
):
obj = Notification.objects.notify_user(self.user, 'dummy')
obj.delete()
self.assertFalse(Notification.objects.filter(pk=obj.pk).exists())
self.assertEquals(mock_invalidate_user_notification_cache.call_count, 2)
def test_can_view(self):
obj = Notification.objects.notify_user(self.user, 'dummy')
self.assertFalse(obj.viewed)
obj.mark_viewed()
obj.refresh_from_db()
self.assertTrue(obj.viewed)
def test_can_set_level(self):
obj = Notification.objects.notify_user(self.user, 'dummy', level='info')
obj.set_level('ERROR')
obj.refresh_from_db()
self.assertEqual(obj.level, 'danger')
obj.set_level('CRITICAL')
obj.refresh_from_db()
self.assertEqual(obj.level, 'danger')
obj.set_level('WARN')
obj.refresh_from_db()
self.assertEqual(obj.level, 'warning')
obj.set_level('INFO')
obj.refresh_from_db()
self.assertEqual(obj.level, 'info')
obj.set_level('DEBUG')
obj.refresh_from_db()
self.assertEqual(obj.level, 'success')
with self.assertRaises(ValueError):
obj.set_level('XXX')

View File

@@ -1,76 +0,0 @@
from unittest import mock
from django.test import TestCase
from allianceauth.notifications.context_processors import user_notification_count
from allianceauth.tests.auth_utils import AuthUtils
from django.core.cache import cache
from allianceauth.notifications.models import Notification
class TestNotificationCount(TestCase):
@classmethod
def setUpTestData(cls):
cls.user = AuthUtils.create_user('magic_mike')
AuthUtils.add_main_character(cls.user, 'Magic Mike', '1', corp_id='2', corp_name='Pole Riders', corp_ticker='PRIDE', alliance_id='3', alliance_name='RIDERS')
cls.user.profile.refresh_from_db()
### test notifications for mike
Notification.objects.all().delete()
Notification.objects.create(user=cls.user,
level="INFO",
title="Job 1 Failed",
message="Because it was broken",
viewed=True)
Notification.objects.create(user=cls.user,
level="INFO",
title="Job 2 Failed",
message="Because it was broken")
Notification.objects.create(user=cls.user,
level="INFO",
title="Job 3 Failed",
message="Because it was broken")
Notification.objects.create(user=cls.user,
level="INFO",
title="Job 4 Failed",
message="Because it was broken")
Notification.objects.create(user=cls.user,
level="INFO",
title="Job 5 Failed",
message="Because it was broken")
Notification.objects.create(user=cls.user,
level="INFO",
title="Job 6 Failed",
message="Because it was broken")
cls.user2 = AuthUtils.create_user('teh_kid')
AuthUtils.add_main_character(cls.user, 'The Kid', '2', corp_id='2', corp_name='Pole Riders', corp_ticker='PRIDE', alliance_id='3', alliance_name='RIDERS')
cls.user2.profile.refresh_from_db()
# Noitification for kid
Notification.objects.create(user=cls.user2,
level="INFO",
title="Job 6 Failed",
message="Because it was broken")
def test_no_cache(self):
mock_req = mock.MagicMock()
mock_req.user.id = self.user.id
cache.delete("u-note:{}".format(self.user.id)) # force the db to be hit
context_dict = user_notification_count(mock_req)
self.assertIsInstance(context_dict, dict)
self.assertEqual(context_dict.get('notifications'), 5) # 5 only
@mock.patch('allianceauth.notifications.models.Notification.objects')
def test_cache(self, mock_foo):
mock_foo.filter.return_value = mock_foo
mock_foo.count.return_value = 5
mock_req = mock.MagicMock()
mock_req.user.id = self.user.id
cache.set("u-note:{}".format(self.user.id),10,5)
context_dict = user_notification_count(mock_req)
self.assertIsInstance(context_dict, dict)
self.assertEqual(context_dict.get('notifications'), 10) # cached value
self.assertEqual(mock_foo.called, 0) # ensure the DB was not hit

View File

@@ -0,0 +1,86 @@
from unittest.mock import patch, Mock
from django.test import TestCase, override_settings
from allianceauth.tests.auth_utils import AuthUtils
from ..templatetags.auth_notifications import (
user_unread_notification_count, notifications_refresh_time
)
MODULE_PATH = 'allianceauth.notifications.templatetags.auth_notifications'
NOTIFICATIONS_REFRESH_TIME_DEFAULT = 66
MY_NOTIFICATIONS_REFRESH_TIME = 23
@patch(MODULE_PATH + '.Notification.objects.user_unread_count')
class TestUserNotificationCount(TestCase):
@classmethod
def setUpTestData(cls):
cls.user = AuthUtils.create_user('magic_mike')
AuthUtils.add_main_character(
cls.user,
'Magic Mike',
'1',
corp_id='2',
corp_name='Pole Riders',
corp_ticker='PRIDE',
alliance_id='3',
alliance_name='RIDERS'
)
def test_return_normal(self, mock_user_unread_count):
unread_count = 42
mock_user_unread_count.return_value = unread_count
result = user_unread_notification_count(self.user)
expected = unread_count
self.assertEqual(result, expected)
args, kwargs = mock_user_unread_count.call_args
self.assertEqual(args[0], self.user.pk)
def test_return_error_if_non_user(self, mock_user_unread_count):
unread_count = -1
mock_user_unread_count.return_value = unread_count
result = user_unread_notification_count('invalid')
expected = unread_count
self.assertEqual(result, expected)
@patch(
MODULE_PATH + '.Notification.NOTIFICATIONS_REFRESH_TIME_DEFAULT',
NOTIFICATIONS_REFRESH_TIME_DEFAULT
)
class TestNotificationsRefreshTime(TestCase):
@override_settings(NOTIFICATIONS_REFRESH_TIME=MY_NOTIFICATIONS_REFRESH_TIME)
def test_return_from_setting(self):
result = notifications_refresh_time()
expected = MY_NOTIFICATIONS_REFRESH_TIME
self.assertEqual(result, expected)
@override_settings(NOTIFICATIONS_REFRESH_TIME=0)
def test_refresh_time_can_be_zero(self):
result = notifications_refresh_time()
expected = 0
self.assertEqual(result, expected)
@override_settings(NOTIFICATIONS_REFRESH_TIME=None)
def test_return_default_refresh_time_if_not_exists(self):
result = notifications_refresh_time()
expected = NOTIFICATIONS_REFRESH_TIME_DEFAULT
self.assertEqual(result, expected)
@override_settings(NOTIFICATIONS_REFRESH_TIME='33')
def test_return_default_refresh_time_if_not_int(self):
result = notifications_refresh_time()
expected = NOTIFICATIONS_REFRESH_TIME_DEFAULT
self.assertEqual(result, expected)
@override_settings(NOTIFICATIONS_REFRESH_TIME=-1)
def test_return_default_refresh_time_if_lt_0(self):
result = notifications_refresh_time()
expected = NOTIFICATIONS_REFRESH_TIME_DEFAULT
self.assertEqual(result, expected)

View File

@@ -0,0 +1,49 @@
import json
from unittest.mock import patch, Mock
from django.test import TestCase, RequestFactory
from django.urls import reverse
from allianceauth.tests.auth_utils import AuthUtils
from ..views import user_notifications_count
MODULE_PATH = 'allianceauth.notifications.views'
class TestViews(TestCase):
@classmethod
def setUpTestData(cls):
cls.user = AuthUtils.create_user('magic_mike')
AuthUtils.add_main_character(
cls.user,
'Magic Mike',
'1',
corp_id='2',
corp_name='Pole Riders',
corp_ticker='PRIDE',
alliance_id='3',
alliance_name='RIDERS'
)
cls.factory = RequestFactory()
@patch(MODULE_PATH + '.Notification.objects.user_unread_count')
def test_user_notifications_count(self, mock_user_unread_count):
unread_count = 42
user_pk = 3
mock_user_unread_count.return_value = unread_count
request = self.factory.get(
reverse('notifications:user_notifications_count', args=[user_pk])
)
request.user = self.user
response = user_notifications_count(request, user_pk)
self.assertEqual(response.status_code, 200)
self.assertTrue(mock_user_unread_count.called)
expected = {'unread_count': unread_count}
result = json.loads(response.content.decode(response.charset))
self.assertDictEqual(result, expected)

View File

@@ -9,4 +9,9 @@ urlpatterns = [
url(r'^notifications/delete_all_read/$', views.delete_all_read, name='delete_all_read'),
url(r'^notifications/$', views.notification_list, name='list'),
url(r'^notifications/(\w+)/$', views.notification_view, name='view'),
url(
r'^user_notifications_count/(?P<user_pk>\d+)/$',
views.user_notifications_count,
name='user_notifications_count'
),
]

View File

@@ -1,9 +1,12 @@
from django.shortcuts import render, get_object_or_404, redirect
from .models import Notification
import logging
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.utils.translation import ugettext_lazy as _
import logging
from django.http import JsonResponse
from django.shortcuts import render, get_object_or_404, redirect
from django.utils.translation import gettext_lazy as _
from .models import Notification
logger = logging.getLogger(__name__)
@@ -11,9 +14,15 @@ logger = logging.getLogger(__name__)
@login_required
def notification_list(request):
logger.debug("notification_list called by user %s" % request.user)
new_notifs = Notification.objects.filter(user=request.user).filter(viewed=False)
old_notifs = Notification.objects.filter(user=request.user).filter(viewed=True)
logger.debug("User %s has %s unread and %s read notifications" % (request.user, len(new_notifs), len(old_notifs)))
notifications_qs = Notification.objects.filter(user=request.user).order_by("-timestamp")
new_notifs = notifications_qs.filter(viewed=False)
old_notifs = notifications_qs.filter(viewed=True)
logger.debug(
"User %s has %s unread and %s read notifications",
request.user,
len(new_notifs),
len(old_notifs)
)
context = {
'read': old_notifs,
'unread': new_notifs,
@@ -23,39 +32,53 @@ def notification_list(request):
@login_required
def notification_view(request, notif_id):
logger.debug("notification_view called by user %s for notif_id %s" % (request.user, notif_id))
logger.debug(
"notification_view called by user %s for notif_id %s",
request.user,
notif_id
)
notif = get_object_or_404(Notification, pk=notif_id)
if notif.user == request.user:
logger.debug("Providing notification for user %s" % request.user)
logger.debug("Providing notification for user %s", request.user)
context = {'notif': notif}
notif.view()
notif.mark_viewed()
return render(request, 'notifications/view.html', context)
else:
logger.warn(
"User %s not authorized to view notif_id %s belonging to user %s" % (request.user, notif_id, notif.user))
"User %s not authorized to view notif_id %s belonging to user %s",
request.user,
notif_id, notif.user
)
messages.error(request, _('You are not authorized to view that notification.'))
return redirect('notifications:list')
@login_required
def remove_notification(request, notif_id):
logger.debug("remove notification called by user %s for notif_id %s" % (request.user, notif_id))
logger.debug(
"remove notification called by user %s for notif_id %s",
request.user,
notif_id
)
notif = get_object_or_404(Notification, pk=notif_id)
if notif.user == request.user:
if Notification.objects.filter(id=notif_id).exists():
notif.delete()
logger.info("Deleting notif id %s by user %s" % (notif_id, request.user))
logger.info("Deleting notif id %s by user %s", notif_id, request.user)
messages.success(request, _('Deleted notification.'))
else:
logger.error(
"Unable to delete notif id %s for user %s - notif matching id not found." % (notif_id, request.user))
"Unable to delete notif id %s for user %s - notif matching id not found.",
notif_id,
request.user
)
messages.error(request, _('Failed to locate notification.'))
return redirect('notifications:list')
@login_required
def mark_all_read(request):
logger.debug('mark all notifications read called by user %s' % request.user)
logger.debug('mark all notifications read called by user %s', request.user)
Notification.objects.filter(user=request.user).update(viewed=True)
messages.success(request, _('Marked all notifications as read.'))
return redirect('notifications:list')
@@ -63,7 +86,17 @@ def mark_all_read(request):
@login_required
def delete_all_read(request):
logger.debug('delete all read notifications called by user %s' % request.user)
logger.debug('delete all read notifications called by user %s', request.user)
Notification.objects.filter(user=request.user).filter(viewed=True).delete()
messages.success(request, _('Deleted all read notifications.'))
return redirect('notifications:list')
def user_notifications_count(request, user_pk: int):
"""returns to notifications count for the give user as JSON
This view is public and does not require login
"""
unread_count = Notification.objects.user_unread_count(user_pk)
data = {'unread_count': unread_count}
return JsonResponse(data, safe=False)

View File

@@ -1,6 +1,6 @@
{% extends "allianceauth/base.html" %}
{% load bootstrap %}
{% load staticfiles %}
{% load static %}
{% load i18n %}
{% get_current_language as LANGUAGE_CODE %}

View File

@@ -1,5 +1,5 @@
{% extends "allianceauth/base.html" %}
{% load staticfiles %}
{% load static %}
{% load i18n %}
{% get_current_language as LANGUAGE_CODE %}

View File

@@ -1,6 +1,6 @@
{% extends "allianceauth/base.html" %}
{% load bootstrap %}
{% load staticfiles %}
{% load static %}
{% load i18n %}
{% get_current_language as LANGUAGE_CODE %}

View File

@@ -1,6 +1,6 @@
{% extends "allianceauth/base.html" %}
{% load bootstrap %}
{% load staticfiles %}
{% load static %}
{% load i18n %}
{% block page_title %}{{ permission.permission.codename }} - {% trans "Permissions Audit" %}{% endblock page_title %}

View File

@@ -1,6 +1,6 @@
{% extends "allianceauth/base.html" %}
{% load bootstrap %}
{% load staticfiles %}
{% load static %}
{% load i18n %}
{% block page_title %}{% trans "Permissions Overview" %}{% endblock page_title %}

View File

@@ -1,5 +1,6 @@
import os
from celery import Celery
from celery.app import trace
# set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', '{{ project_name }}.settings.local')
@@ -27,3 +28,6 @@ app.conf.ONCE = {
# Load task modules from all registered Django app configs.
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
# Remove result from default log message on task success
trace.LOG_SUCCESS = "Task %(name)s[%(id)s] succeeded in %(runtime)ss"

View File

@@ -64,12 +64,12 @@ BASE_DIR = os.path.dirname(PROJECT_DIR)
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.locale.LocaleMiddleware',
]
ROOT_URLCONF = 'allianceauth.urls'
@@ -86,6 +86,8 @@ LANGUAGES = (
('zh-hans', ugettext('Chinese Simplified')),
('ru', ugettext('Russian')),
('ko', ugettext('Korean')),
('fr', ugettext('French')),
('ja', ugettext('Japanese')),
)
TEMPLATES = [
@@ -102,8 +104,7 @@ TEMPLATES = [
'django.template.context_processors.i18n',
'django.template.context_processors.media',
'django.template.context_processors.static',
'django.template.context_processors.tz',
'allianceauth.notifications.context_processors.user_notification_count',
'django.template.context_processors.tz',
'allianceauth.context_processors.auth_settings',
],
},
@@ -138,6 +139,8 @@ AUTHENTICATION_BACKENDS = ['allianceauth.authentication.backends.StateBackend',
LANGUAGE_CODE = 'en-us'
LANGUAGE_COOKIE_AGE = 1209600
TIME_ZONE = 'UTC'
USE_I18N = True
@@ -169,6 +172,8 @@ CACHES = {
}
}
SESSION_ENGINE = "django.contrib.sessions.backends.cached_db"
DEBUG = True
ALLOWED_HOSTS = ['*']
DATABASES = {

View File

@@ -45,6 +45,7 @@ DATABASES['default'] = {
ESI_SSO_CLIENT_ID = ''
ESI_SSO_CLIENT_SECRET = ''
ESI_SSO_CALLBACK_URL = ''
ESI_USER_CONTACT_EMAIL = '' # A server maintainer that CCP can contact in case of issues.
# By default emails are validated before new users can log in.
# It's recommended to use a free service like SparkPost or Elastic Email to send email.

View File

@@ -211,6 +211,7 @@ class DiscordUser(models.Model):
Return None if user does no longer exist
"""
try:
_user = self.user
client = DiscordUser.objects._bot_client(is_rate_limited=is_rate_limited)
success = client.remove_guild_member(
guild_id=DISCORD_GUILD_ID, user_id=self.uid
@@ -220,31 +221,31 @@ class DiscordUser(models.Model):
if deleted_count > 0:
if notify_user:
notify(
user=self.user,
user=_user,
title=gettext_lazy('Discord Account Disabled'),
message=gettext_lazy(
'Your Discord account was disabeled automatically '
'Your Discord account was disabled automatically '
'by Auth. If you think this was a mistake, '
'please contact an admin.'
),
level='warning'
)
logger.info('Account for user %s was deleted.', self.user)
logger.info('Account for user %s was deleted.', _user)
return True
else:
logger.debug('Account for user %s was already deleted.', self.user)
logger.debug('Account for user %s was already deleted.', _user)
return None
else:
logger.warning(
'Failed to remove user %s from the Discord server', self.user
'Failed to remove user %s from the Discord server', _user
)
return False
except (HTTPError, ConnectionError, DiscordApiBackoff) as ex:
if handle_api_exceptions:
logger.exception(
'Failed to remove user %s from Discord server: %s', self.user, ex
'Failed to remove user %s from Discord server: %s',self.user, ex
)
return False
else:

View File

@@ -0,0 +1,70 @@
# Generated by Django 3.1.2 on 2021-01-08 13:54
from django.conf import settings
from django.db import migrations, models
import django.db.migrations.operations.special
import django.db.models.deletion
class Migration(migrations.Migration):
replaces = [('mumble', '0001_initial'), ('mumble', '0002_auto_20161212_0100'), ('mumble', '0003_mumbleuser_user'), ('mumble', '0004_auto_20161214_1024'), ('mumble', '0005_mumbleuser_hashfn'), ('mumble', '0006_service_permissions'), ('mumble', '0007_not_null_user'), ('mumble', '0008_mumbleuser_display_name'), ('mumble', '0009_set_mumble_dissplay_names'), ('mumble', '0010_mumbleuser_certhash'), ('mumble', '0011_auto_20201011_1009')]
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='MumbleUser',
fields=[
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, primary_key=True, related_name='mumble', serialize=False, to=settings.AUTH_USER_MODEL)),
('username', models.CharField(max_length=254, unique=True)),
('pwhash', models.CharField(max_length=40)),
('groups', models.TextField(blank=True, null=True)),
],
options={
'db_table': 'services_mumbleuser',
},
),
migrations.AlterModelTable(
name='mumbleuser',
table=None,
),
migrations.AddField(
model_name='mumbleuser',
name='hashfn',
field=models.CharField(default='sha1', max_length=20),
),
migrations.AlterField(
model_name='mumbleuser',
name='pwhash',
field=models.CharField(max_length=80),
),
migrations.AlterModelOptions(
name='mumbleuser',
options={'permissions': (('access_mumble', 'Can access the Mumble service'),)},
),
migrations.AddField(
model_name='mumbleuser',
name='display_name',
field=models.CharField(max_length=254, null=True),
),
migrations.AlterField(
model_name='mumbleuser',
name='display_name',
field=models.CharField(max_length=254, unique=True),
preserve_default=False,
),
migrations.AddField(
model_name='mumbleuser',
name='certhash',
field=models.CharField(blank=True, editable=False, help_text='Hash of Mumble client certificate as presented when user authenticates', max_length=254, null=True, verbose_name='Certificate Hash'),
),
migrations.AlterField(
model_name='mumbleuser',
name='pwhash',
field=models.CharField(max_length=90),
),
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 3.1.2 on 2020-10-11 10:09
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('mumble', '0010_mumbleuser_certhash'),
]
operations = [
migrations.AlterField(
model_name='mumbleuser',
name='pwhash',
field=models.CharField(max_length=90),
),
]

View File

@@ -63,7 +63,7 @@ class MumbleManager(models.Manager):
class MumbleUser(AbstractServiceModel):
username = models.CharField(max_length=254, unique=True)
pwhash = models.CharField(max_length=80)
pwhash = models.CharField(max_length=90)
hashfn = models.CharField(max_length=20, default='sha1')
groups = models.TextField(blank=True, null=True)
certhash = models.CharField(

View File

@@ -211,4 +211,4 @@ class MumbleManagerTestCase(TestCase):
pwhash = self.manager.gen_pwhash('test')
self.assertEqual(pwhash[:15], '$bcrypt-sha256$')
self.assertEqual(len(pwhash), 75)
self.assertEqual(len(pwhash), 83)

View File

@@ -1,6 +1,6 @@
{% extends "allianceauth/base.html" %}
{% load bootstrap %}
{% load staticfiles %}
{% load static %}
{% load i18n %}
{% block page_title %}{% trans "Jabber Broadcast" %}{% endblock page_title %}

View File

@@ -1,6 +1,6 @@
{% extends "allianceauth/base.html" %}
{% load bootstrap %}
{% load staticfiles %}
{% load static %}
{% load i18n %}
{% block page_title %}{% trans "Verify Teamspeak" %}{% endblock page_title %}

View File

@@ -1,6 +1,6 @@
{% extends "allianceauth/base.html" %}
{% load bootstrap %}
{% load staticfiles %}
{% load static %}
{% load i18n %}
{% block page_title %}{% trans "Fleet Formatter Tool" %}{% endblock page_title %}

View File

@@ -1,5 +1,5 @@
{% extends "allianceauth/base.html" %}
{% load staticfiles %}
{% load static %}
{% load i18n %}
{% block page_title %}{% blocktrans with service_name=view.service_name|title %}{{ service_name }} Credentials{% endblocktrans %}{% endblock page_title %}

View File

@@ -1,6 +1,6 @@
{% extends "allianceauth/base.html" %}
{% load bootstrap %}
{% load staticfiles %}
{% load static %}
{% load i18n %}
{% block page_title %}{% blocktrans with service_name=view.service_name|title %}{{ service_name }} Password Change{% endblocktrans %}{% endblock page_title %}

View File

@@ -1,5 +1,5 @@
{% extends "allianceauth/base.html" %}
{% load staticfiles %}
{% load static %}
{% load i18n %}
{% block page_title %}{% trans "Services Management" %}{% endblock page_title %}

View File

@@ -1,6 +1,6 @@
{% extends "allianceauth/base.html" %}
{% load bootstrap %}
{% load staticfiles %}
{% load static %}
{% load i18n %}
{% block page_title %}{% trans "SRP Fleet Create" %}{% endblock page_title %}

View File

@@ -1,12 +1,13 @@
{% extends "allianceauth/base.html" %}
{% load bootstrap %}
{% load staticfiles %}
{% load static %}
{% load i18n %}
{% load humanize %}
{% block page_title %}Srp Fleet Data{% endblock page_title %}
{% block extra_css %}
{% include 'bundles/x-editable.css.html' %}
{% include 'bundles/datatables-css.html' %}
{% include 'bundles/x-editable.css.html' %}
<link href="{% static 'css/checkbox.css' %}" rel="stylesheet" type="text/css">
<style>
.radio label, .checkbox label {
@@ -60,7 +61,7 @@
{% endif %}
</div>
</h1>
{% if srpfleetrequests %}
<form method="POST">
{% csrf_token %}
@@ -82,8 +83,8 @@
</div>
</div>
<div class="table-responsive">
<table class="table">
<tr>
<table class="table srplist">
<thead>
<th class="text-center">{% trans "Pilot Name" %}</th>
<th class="text-center">{% trans "Killboard Link" %}</th>
<th class="text-center">{% trans "Additional Info" %}</th>
@@ -98,19 +99,27 @@ ESC to cancel{% endblocktrans %}"id="blah"></i></th>
{% if perms.auth.srp_management %}
<th class="text-center">{% trans "Actions" %}</th>
{% endif %}
</tr>
</thead>
<tbody>
{% for srpfleetrequest in srpfleetrequests %}
<tr>
<td class="text-center">{{ srpfleetrequest.character.character_name }}</td>
<td class="text-center">
{% if srpfleetrequest.character.alliance.alliance_ticker %}
{{ srpfleetrequest.character.alliance.alliance_ticker }}
{% endif %}
[{{ srpfleetrequest.character.corporation.corporation_ticker }}]
{{ srpfleetrequest.character.character_name }}
</td>
<td class="text-center">
<a href="{{ srpfleetrequest.killboard_link }}"
target="_blank" class="label label-warning">Link</a>
</td>
<td class="text-center">{{ srpfleetrequest.additional_info }}</td>
<td class="text-center">{{ srpfleetrequest.srp_ship_name }}</td>
<td class="text-center">{{ srpfleetrequest.kb_total_loss | intcomma }} ISK</td>
<td class="srp" data-name="srp_total_amount" data-type="number" data-pk="{{srpfleetrequest.id}}" data-url="{% url 'srp:request_update_amount' srpfleetrequest.id %}" data-params="{csrfmiddlewaretoken:'{{csrf_token}}'}" class="text-center">{{ srpfleetrequest.srp_total_amount | intcomma }} ISK</td>
<td class="text-center">{{ srpfleetrequest.post_time | date:"Y-m-d H:i" }}</td>
<td class="text-center" data-sort="{{ srpfleetrequest.kb_total_loss }}">{{ srpfleetrequest.kb_total_loss | intcomma }} ISK</td>
<td class="srp text-center" data-name="srp_total_amount" data-type="number" data-pk="{{srpfleetrequest.id}}" data-url="{% url 'srp:request_update_amount' srpfleetrequest.id %}" data-params="{csrfmiddlewaretoken:'{{csrf_token}}'}" data-sort="{{ srpfleetrequest.srp_total_amount }}">{{ srpfleetrequest.srp_total_amount | intcomma }} ISK</td>
<td class="text-center" data-sort="{{ srpfleetrequest.post_time | date:"Y-m-d H:i" }}">{{ srpfleetrequest.post_time | date:"Y-M-d H:i" }}</td>
<td class="text-center">
{% if srpfleetrequest.srp_status == "Approved" %}
<div class="label label-success">
@@ -133,11 +142,13 @@ ESC to cancel{% endblocktrans %}"id="blah"></i></th>
<input type="checkbox" name="{{srpfleetrequest.id}}">
<span class="cr"><i class="cr-icon fas fa-check"></i></span>
</label>
</div>
</div>
</td>
{% endif %}
</tr>
{% endfor %}
{% endfor %}
<tbody>
</table>
</div>
<div class="alert alert-info" role="alert">
@@ -168,7 +179,9 @@ ESC to cancel{% endblocktrans %}"id="blah"></i></th>
{% endblock content %}
{% block extra_javascript %}
{% include 'bundles/datatables-js.html' %}
{% include 'bundles/x-editable-js.html' %}
{% include 'bundles/moment-js.html' %}
{% endblock %}
{% block extra_script %}
@@ -198,11 +211,47 @@ ESC to cancel{% endblocktrans %}"id="blah"></i></th>
var $next = $(this).closest('tr').next().find('.editable');
setTimeout(function() {
$next.editable('show');
}, 400);
}, 400);
}
});
});
$(document).ready(function(){
$("[rel=tooltip]").tooltip({ placement: 'top'});
});
});
$.fn.dataTable.moment = function(format, locale) {
var types = $.fn.dataTable.ext.type;
// Add type detection
types.detect.unshift(function(d) {
return moment(d, format, locale, true).isValid() ?
'moment-'+format :
null;
} );
// Add sorting method - use an integer for the sorting
types.order[ 'moment-'+format+'-pre' ] = function(d) {
return moment(d, format, locale, true).unix();
};
};
$(document).ready( function(){
$.fn.dataTable.moment('YYYY-MMM-D, HH:mm');
$('table.srplist').DataTable({
"order": [[ 6, "asc" ]],
"paging": false,
"columnDefs": [{
"targets": [1, 8],
"orderable": false
},
{
"targets": [4, 5],
"type": "num"
}]
});
});
{% endblock extra_script %}

View File

@@ -1,6 +1,6 @@
{% extends "allianceauth/base.html" %}
{% load bootstrap %}
{% load staticfiles %}
{% load static %}
{% load i18n %}
{% load humanize %}

View File

@@ -1,6 +1,6 @@
{% extends "allianceauth/base.html" %}
{% load bootstrap %}
{% load staticfiles %}
{% load static %}
{% load i18n %}
{% block page_title %}{% trans "SRP Request" %}{% endblock page_title %}

View File

@@ -1,6 +1,6 @@
{% extends "allianceauth/base.html" %}
{% load bootstrap %}
{% load staticfiles %}
{% load static %}
{% load i18n %}
{% block page_title %}{% trans "Update AAR Link" %}{% endblock page_title %}

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