mirror of
https://gitlab.com/allianceauth/allianceauth.git
synced 2026-02-04 14:16:21 +01:00
Compare commits
127 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3452c3acd1 | ||
|
|
3c305fbf37 | ||
|
|
a5e0721ec1 | ||
|
|
164a0d5376 | ||
|
|
2bcf6ec39a | ||
|
|
40824156bf | ||
|
|
cec4495034 | ||
|
|
74eb8621d9 | ||
|
|
4394d25961 | ||
|
|
8113327d31 | ||
|
|
aeeb35bc60 | ||
|
|
630aa3f320 | ||
|
|
3487a945c2 | ||
|
|
1936ae44a3 | ||
|
|
3d7a84e786 | ||
|
|
a4d6730cb0 | ||
|
|
b724227a29 | ||
|
|
d72964fd7c | ||
|
|
d4a41cfb60 | ||
|
|
05859453df | ||
|
|
240d910c9b | ||
|
|
0c31bce7d0 | ||
|
|
f4c4ae36ed | ||
|
|
b9931b2ceb | ||
|
|
4fd6f06c0b | ||
|
|
09573ba7ef | ||
|
|
08e9676760 | ||
|
|
15ae737522 | ||
|
|
50ec9e563e | ||
|
|
cb40649f8b | ||
|
|
bccead0881 | ||
|
|
35ae710624 | ||
|
|
75de4518f2 | ||
|
|
bfcdfea6c8 | ||
|
|
471553fa88 | ||
|
|
db59f5f69b | ||
|
|
1b5413646e | ||
|
|
0337d2517c | ||
|
|
87e6eb9688 | ||
|
|
7b8c246ef8 | ||
|
|
a268a8980a | ||
|
|
3b516c338e | ||
|
|
9952685805 | ||
|
|
2f59c8df22 | ||
|
|
6cd0a42791 | ||
|
|
4c42153bfd | ||
|
|
603bd9c37c | ||
|
|
87c0c3ac73 | ||
|
|
8a91e7f6ac | ||
|
|
281dbdbb01 | ||
|
|
8980d8d32f | ||
|
|
9d6cf9a62e | ||
|
|
0fabb2b368 | ||
|
|
9801ca0314 | ||
|
|
fd86b26b39 | ||
|
|
b0dbef1587 | ||
|
|
a6e60bc23b | ||
|
|
137e8a876d | ||
|
|
fe9538253f | ||
|
|
edda2c248e | ||
|
|
62275639e3 | ||
|
|
d0c68b82f4 | ||
|
|
78b5953bdf | ||
|
|
25e565b099 | ||
|
|
1fe0f78ad7 | ||
|
|
fc8b68156f | ||
|
|
b47cd197ce | ||
|
|
3943426c4c | ||
|
|
08a9bd42a3 | ||
|
|
b2ff339efe | ||
|
|
c604131e04 | ||
|
|
f17607f126 | ||
|
|
94e455a57b | ||
|
|
3c9149db4a | ||
|
|
96cc615c07 | ||
|
|
cd1f4a1c2b | ||
|
|
e0f99a42db | ||
|
|
3506e417d4 | ||
|
|
36197e2212 | ||
|
|
fc5f42d01e | ||
|
|
e26d3767e0 | ||
|
|
046b37c76a | ||
|
|
925ff3e116 | ||
|
|
e5ede4f7b6 | ||
|
|
ded9301527 | ||
|
|
bd1ed6ff73 | ||
|
|
feb65980d4 | ||
|
|
e81d75a782 | ||
|
|
ff305d13ae | ||
|
|
8bcbc1a779 | ||
|
|
3874aa6fee | ||
|
|
103e9f3a11 | ||
|
|
d02c25f421 | ||
|
|
228af38a4a | ||
|
|
051a48885c | ||
|
|
6bcdc6052f | ||
|
|
af3527e64f | ||
|
|
17ef3dd07a | ||
|
|
1f165ecd2a | ||
|
|
70d1d450a9 | ||
|
|
b667892698 | ||
|
|
dc11add0e9 | ||
|
|
cb429a0b88 | ||
|
|
b51039cfc0 | ||
|
|
eadd959d95 | ||
|
|
1856e03d88 | ||
|
|
7dcfa622a3 | ||
|
|
64251b9b3c | ||
|
|
6b073dd5fc | ||
|
|
0911fabfb2 | ||
|
|
050d3f5e63 | ||
|
|
bbe3f78ad1 | ||
|
|
8204c18895 | ||
|
|
b91c788897 | ||
|
|
1d20a3029f | ||
|
|
9cfebc9ae3 | ||
|
|
ddabb4539b | ||
|
|
ada35e221b | ||
|
|
6fef9d904e | ||
|
|
67cf2b5904 | ||
|
|
3bebe792f6 | ||
|
|
00b4d89181 | ||
|
|
f729c6b650 | ||
|
|
df95f8c3f3 | ||
|
|
fe36e57d72 | ||
|
|
31197812b6 | ||
|
|
bd3fe01a12 |
@@ -41,13 +41,13 @@ test-3.8-all:
|
|||||||
|
|
||||||
deploy_production:
|
deploy_production:
|
||||||
stage: deploy
|
stage: deploy
|
||||||
image: python:3.6-stretch
|
image: python:3.8-buster
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
- pip install twine
|
- pip install twine wheel
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- python setup.py sdist
|
- python setup.py sdist bdist_wheel
|
||||||
- twine upload dist/*
|
- twine upload dist/*
|
||||||
|
|
||||||
rules:
|
rules:
|
||||||
|
|||||||
@@ -18,10 +18,6 @@ formats: all
|
|||||||
|
|
||||||
# Optionally set the version of Python and requirements required to build your docs
|
# Optionally set the version of Python and requirements required to build your docs
|
||||||
python:
|
python:
|
||||||
version: 3.7
|
version: 3.7
|
||||||
install:
|
install:
|
||||||
- method: pip
|
- requirements: docs/requirements.txt
|
||||||
path: .
|
|
||||||
extra_requirements:
|
|
||||||
- testing
|
|
||||||
system_packages: true
|
|
||||||
@@ -36,7 +36,7 @@ Main features:
|
|||||||
|
|
||||||
- Can be easily extended with additional services and apps. Many are provided by the community and can be found here: [Community Creations](https://gitlab.com/allianceauth/community-creations)
|
- Can be easily extended with additional services and apps. Many are provided by the community and can be found here: [Community Creations](https://gitlab.com/allianceauth/community-creations)
|
||||||
|
|
||||||
- Chinese :cn:, English :us:, German :de: and Spanish :es: localization
|
- English :flag_gb:, Chinese :flag_cn:, German :flag_de:, Spanish :flag_es:, Korean :flag_kr: and Russian :flag_ru: localization
|
||||||
|
|
||||||
For further details about AA - including an installation guide and a full list of included services and plugin apps - please see the [official documentation](http://allianceauth.rtfd.io).
|
For further details about AA - including an installation guide and a full list of included services and plugin apps - please see the [official documentation](http://allianceauth.rtfd.io).
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# This will make sure the app is always imported when
|
# This will make sure the app is always imported when
|
||||||
# Django starts so that shared_task will use this app.
|
# Django starts so that shared_task will use this app.
|
||||||
|
|
||||||
__version__ = '2.7.3'
|
__version__ = '2.8.2'
|
||||||
__title__ = 'Alliance Auth'
|
__title__ = 'Alliance Auth'
|
||||||
__url__ = 'https://gitlab.com/allianceauth/allianceauth'
|
__url__ = 'https://gitlab.com/allianceauth/allianceauth'
|
||||||
NAME = '%s v%s' % (__title__, __version__)
|
NAME = '%s v%s' % (__title__, __version__)
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ class UserProfileInline(admin.StackedInline):
|
|||||||
formset.get_form_kwargs = get_kwargs
|
formset.get_form_kwargs = get_kwargs
|
||||||
return formset
|
return formset
|
||||||
|
|
||||||
def has_add_permission(self, request):
|
def has_add_permission(self, request, obj=None):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def has_delete_permission(self, request, obj=None):
|
def has_delete_permission(self, request, obj=None):
|
||||||
@@ -549,7 +549,7 @@ class PermissionAdmin(admin.ModelAdmin):
|
|||||||
def admin_name(obj):
|
def admin_name(obj):
|
||||||
return str(obj)
|
return str(obj)
|
||||||
|
|
||||||
def has_add_permission(self, request):
|
def has_add_permission(self, request, obj=None):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def has_delete_permission(self, request, obj=None):
|
def has_delete_permission(self, request, obj=None):
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
from django import forms
|
from django import forms
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
from allianceauth.authentication.models import User
|
||||||
|
|
||||||
class RegistrationForm(forms.Form):
|
class RegistrationForm(forms.Form):
|
||||||
email = forms.EmailField(label=_('Email'), max_length=254, required=True)
|
email = forms.EmailField(label=_('Email'), max_length=254, required=True)
|
||||||
|
|
||||||
|
class _meta:
|
||||||
|
model = User
|
||||||
|
|||||||
@@ -10,5 +10,5 @@ urlpatterns = [
|
|||||||
url(r'^register/$', views.RegistrationView.as_view(), name='registration_register'),
|
url(r'^register/$', views.RegistrationView.as_view(), name='registration_register'),
|
||||||
url(r'^register/complete/$', views.registration_complete, name='registration_complete'),
|
url(r'^register/complete/$', views.registration_complete, name='registration_complete'),
|
||||||
url(r'^register/closed/$', views.registration_closed, name='registration_disallowed'),
|
url(r'^register/closed/$', views.registration_closed, name='registration_disallowed'),
|
||||||
url(r'', include('registration.auth_urls')),
|
url(r'', include('django.contrib.auth.urls')),
|
||||||
]
|
]
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
{% extends "allianceauth/base.html" %}
|
{% extends "allianceauth/base.html" %}
|
||||||
{% load staticfiles %}
|
{% load static %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block page_title %}{% trans "Dashboard" %}{% endblock %}
|
{% block page_title %}{% trans "Dashboard" %}{% endblock %}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{% load staticfiles %}
|
{% extends 'public/base.html' %}
|
||||||
|
{% load static %}
|
||||||
{% load bootstrap %}
|
{% load bootstrap %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% extends 'public/base.html' %}
|
|
||||||
{% block page_title %}Registration{% endblock %}
|
{% block page_title %}Registration{% endblock %}
|
||||||
{% block extra_include %}
|
{% block extra_include %}
|
||||||
{% include 'bundles/bootstrap-css.html' %}
|
{% include 'bundles/bootstrap-css.html' %}
|
||||||
|
|||||||
@@ -83,9 +83,8 @@ class TestStatusOverviewTag(TestCase):
|
|||||||
}
|
}
|
||||||
mock_current_version_info.return_value = version_info
|
mock_current_version_info.return_value = version_info
|
||||||
mock_fetch_celery_queue_length.return_value = 3
|
mock_fetch_celery_queue_length.return_value = 3
|
||||||
|
|
||||||
context = {}
|
result = status_overview()
|
||||||
result = status_overview(context)
|
|
||||||
expected = {
|
expected = {
|
||||||
'notifications': GITHUB_NOTIFICATION_ISSUES[:5],
|
'notifications': GITHUB_NOTIFICATION_ISSUES[:5],
|
||||||
'latest_major': True,
|
'latest_major': True,
|
||||||
@@ -128,6 +127,13 @@ class TestNotifications(TestCase):
|
|||||||
result = _current_notifications()
|
result = _current_notifications()
|
||||||
self.assertEqual(result['notifications'], list())
|
self.assertEqual(result['notifications'], list())
|
||||||
|
|
||||||
|
@patch(MODULE_PATH + '.admin_status.cache')
|
||||||
|
def test_current_notifications_is_none(self, mock_cache):
|
||||||
|
mock_cache.get_or_set.return_value = None
|
||||||
|
|
||||||
|
result = _current_notifications()
|
||||||
|
self.assertEqual(result['notifications'], list())
|
||||||
|
|
||||||
|
|
||||||
class TestCeleryQueueLength(TestCase):
|
class TestCeleryQueueLength(TestCase):
|
||||||
|
|
||||||
@@ -170,6 +176,15 @@ class TestVersionTags(TestCase):
|
|||||||
result = _fetch_tags_from_gitlab()
|
result = _fetch_tags_from_gitlab()
|
||||||
self.assertEqual(result, GITHUB_TAGS)
|
self.assertEqual(result, GITHUB_TAGS)
|
||||||
|
|
||||||
|
@patch(MODULE_PATH + '.admin_status.__version__', TEST_VERSION)
|
||||||
|
@patch(MODULE_PATH + '.admin_status.cache')
|
||||||
|
def test_current_version_info_return_no_data(self, mock_cache):
|
||||||
|
mock_cache.get_or_set.return_value = None
|
||||||
|
|
||||||
|
expected = {}
|
||||||
|
result = _current_version_summary()
|
||||||
|
self.assertEqual(result, expected)
|
||||||
|
|
||||||
|
|
||||||
class TestLatestsVersion(TestCase):
|
class TestLatestsVersion(TestCase):
|
||||||
|
|
||||||
|
|||||||
@@ -6,20 +6,21 @@ from django.contrib.auth import login, authenticate
|
|||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.core import signing
|
from django.core import signing
|
||||||
from django.urls import reverse
|
from django.http import JsonResponse
|
||||||
from django.shortcuts import redirect, render
|
from django.shortcuts import redirect, render
|
||||||
|
from django.urls import reverse, reverse_lazy
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from allianceauth.eveonline.models import EveCharacter
|
from allianceauth.eveonline.models import EveCharacter
|
||||||
from esi.decorators import token_required
|
from esi.decorators import token_required
|
||||||
from esi.models import Token
|
from esi.models import Token
|
||||||
|
|
||||||
from registration.backends.hmac.views import (
|
from django_registration.backends.activation.views import (
|
||||||
RegistrationView as BaseRegistrationView,
|
RegistrationView as BaseRegistrationView,
|
||||||
ActivationView as BaseActivationView,
|
ActivationView as BaseActivationView,
|
||||||
REGISTRATION_SALT
|
REGISTRATION_SALT
|
||||||
)
|
)
|
||||||
from registration.signals import user_registered
|
from django_registration.signals import user_registered
|
||||||
|
|
||||||
from .models import CharacterOwnership
|
from .models import CharacterOwnership
|
||||||
from .forms import RegistrationForm
|
from .forms import RegistrationForm
|
||||||
@@ -134,11 +135,14 @@ def sso_login(request, token):
|
|||||||
# Step 2
|
# Step 2
|
||||||
class RegistrationView(BaseRegistrationView):
|
class RegistrationView(BaseRegistrationView):
|
||||||
form_class = RegistrationForm
|
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):
|
def get_success_url(self, user):
|
||||||
if not getattr(settings, 'REGISTRATION_VERIFY_EMAIL', True):
|
if not getattr(settings, 'REGISTRATION_VERIFY_EMAIL', True):
|
||||||
return 'authentication:dashboard', (), {}
|
return reverse_lazy('authentication:dashboard')
|
||||||
return super().get_success_url(user)
|
return super().get_success_url(user)
|
||||||
|
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
@@ -176,6 +180,9 @@ class RegistrationView(BaseRegistrationView):
|
|||||||
|
|
||||||
# Step 3
|
# Step 3
|
||||||
class ActivationView(BaseActivationView):
|
class ActivationView(BaseActivationView):
|
||||||
|
template_name = "registration/activate.html"
|
||||||
|
success_url = reverse_lazy('registration_activation_complete')
|
||||||
|
|
||||||
def validate_key(self, activation_key):
|
def validate_key(self, activation_key):
|
||||||
try:
|
try:
|
||||||
dump = signing.loads(activation_key, salt=REGISTRATION_SALT,
|
dump = signing.loads(activation_key, salt=REGISTRATION_SALT,
|
||||||
@@ -207,5 +214,5 @@ def activation_complete(request):
|
|||||||
|
|
||||||
|
|
||||||
def registration_closed(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')
|
return redirect('authentication:login')
|
||||||
|
|||||||
@@ -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),
|
||||||
|
),
|
||||||
|
]
|
||||||
17
allianceauth/eveonline/migrations/0014_auto_20210105_1413.py
Normal file
17
allianceauth/eveonline/migrations/0014_auto_20210105_1413.py
Normal 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'),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -82,6 +82,7 @@ class EveCorporationInfo(models.Model):
|
|||||||
corporation_name = models.CharField(max_length=254, unique=True)
|
corporation_name = models.CharField(max_length=254, unique=True)
|
||||||
corporation_ticker = models.CharField(max_length=254)
|
corporation_ticker = models.CharField(max_length=254)
|
||||||
member_count = models.IntegerField()
|
member_count = models.IntegerField()
|
||||||
|
ceo_id = models.PositiveIntegerField(blank=True, null=True, default=None)
|
||||||
alliance = models.ForeignKey(
|
alliance = models.ForeignKey(
|
||||||
EveAllianceInfo, blank=True, null=True, on_delete=models.SET_NULL
|
EveAllianceInfo, blank=True, null=True, on_delete=models.SET_NULL
|
||||||
)
|
)
|
||||||
@@ -89,10 +90,16 @@ class EveCorporationInfo(models.Model):
|
|||||||
objects = EveCorporationManager()
|
objects = EveCorporationManager()
|
||||||
provider = EveCorporationProviderManager()
|
provider = EveCorporationProviderManager()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
indexes = [
|
||||||
|
models.Index(fields=['ceo_id',]),
|
||||||
|
]
|
||||||
|
|
||||||
def update_corporation(self, corp: providers.Corporation = None):
|
def update_corporation(self, corp: providers.Corporation = None):
|
||||||
if corp is None:
|
if corp is None:
|
||||||
corp = self.provider.get_corporation(self.corporation_id)
|
corp = self.provider.get_corporation(self.corporation_id)
|
||||||
self.member_count = corp.members
|
self.member_count = corp.members
|
||||||
|
self.ceo_id = corp.ceo_id
|
||||||
try:
|
try:
|
||||||
self.alliance = EveAllianceInfo.objects.get(alliance_id=corp.alliance_id)
|
self.alliance = EveAllianceInfo.objects.get(alliance_id=corp.alliance_id)
|
||||||
except EveAllianceInfo.DoesNotExist:
|
except EveAllianceInfo.DoesNotExist:
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ from jsonschema.exceptions import RefResolutionError
|
|||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from esi.clients import esi_client_factory
|
from esi.clients import esi_client_factory
|
||||||
|
|
||||||
|
from allianceauth import __version__
|
||||||
|
|
||||||
|
|
||||||
SWAGGER_SPEC_PATH = os.path.join(os.path.dirname(
|
SWAGGER_SPEC_PATH = os.path.join(os.path.dirname(
|
||||||
os.path.abspath(__file__)), 'swagger.json'
|
os.path.abspath(__file__)), 'swagger.json'
|
||||||
@@ -166,7 +168,7 @@ class EveSwaggerProvider(EveProvider):
|
|||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
self._client = esi_client_factory(
|
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):
|
except (HTTPError, RefResolutionError):
|
||||||
logger.exception(
|
logger.exception(
|
||||||
@@ -182,7 +184,7 @@ class EveSwaggerProvider(EveProvider):
|
|||||||
def client(self):
|
def client(self):
|
||||||
if self._client is None:
|
if self._client is None:
|
||||||
self._client = esi_client_factory(
|
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
|
return self._client
|
||||||
|
|
||||||
|
|||||||
@@ -5,35 +5,96 @@ from .models import EveAllianceInfo
|
|||||||
from .models import EveCharacter
|
from .models import EveCharacter
|
||||||
from .models import EveCorporationInfo
|
from .models import EveCorporationInfo
|
||||||
|
|
||||||
|
from . import providers
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
TASK_PRIORITY = 7
|
TASK_PRIORITY = 7
|
||||||
|
CHUNK_SIZE = 500
|
||||||
|
|
||||||
|
|
||||||
|
def chunks(lst, n):
|
||||||
|
"""Yield successive n-sized chunks from lst."""
|
||||||
|
for i in range(0, len(lst), n):
|
||||||
|
yield lst[i:i + n]
|
||||||
|
|
||||||
|
|
||||||
@shared_task
|
@shared_task
|
||||||
def update_corp(corp_id):
|
def update_corp(corp_id):
|
||||||
|
"""Update given corporation from ESI"""
|
||||||
EveCorporationInfo.objects.update_corporation(corp_id)
|
EveCorporationInfo.objects.update_corporation(corp_id)
|
||||||
|
|
||||||
|
|
||||||
@shared_task
|
@shared_task
|
||||||
def update_alliance(alliance_id):
|
def update_alliance(alliance_id):
|
||||||
|
"""Update given alliance from ESI"""
|
||||||
EveAllianceInfo.objects.update_alliance(alliance_id).populate_alliance()
|
EveAllianceInfo.objects.update_alliance(alliance_id).populate_alliance()
|
||||||
|
|
||||||
|
|
||||||
@shared_task
|
@shared_task
|
||||||
def update_character(character_id):
|
def update_character(character_id):
|
||||||
|
"""Update given character from ESI"""
|
||||||
EveCharacter.objects.update_character(character_id)
|
EveCharacter.objects.update_character(character_id)
|
||||||
|
|
||||||
|
|
||||||
@shared_task
|
@shared_task
|
||||||
def run_model_update():
|
def run_model_update():
|
||||||
|
"""Update all alliances, corporations and characters from ESI"""
|
||||||
|
|
||||||
# update existing corp models
|
# update existing corp models
|
||||||
for corp in EveCorporationInfo.objects.all().values('corporation_id'):
|
for corp in EveCorporationInfo.objects.all().values('corporation_id'):
|
||||||
update_corp.apply_async(args=[corp['corporation_id']], priority=TASK_PRIORITY)
|
update_corp.apply_async(
|
||||||
|
args=[corp['corporation_id']], priority=TASK_PRIORITY
|
||||||
|
)
|
||||||
|
|
||||||
# update existing alliance models
|
# update existing alliance models
|
||||||
for alliance in EveAllianceInfo.objects.all().values('alliance_id'):
|
for alliance in EveAllianceInfo.objects.all().values('alliance_id'):
|
||||||
update_alliance.apply_async(args=[alliance['alliance_id']], priority=TASK_PRIORITY)
|
update_alliance.apply_async(
|
||||||
|
args=[alliance['alliance_id']], priority=TASK_PRIORITY
|
||||||
|
)
|
||||||
|
|
||||||
#update existing character models
|
# update existing character models
|
||||||
for character in EveCharacter.objects.all().values('character_id'):
|
character_ids = EveCharacter.objects.all().values_list('character_id', flat=True)
|
||||||
update_character.apply_async(args=[character['character_id']], priority=TASK_PRIORITY)
|
for character_ids_chunk in chunks(character_ids, CHUNK_SIZE):
|
||||||
|
affiliations_raw = providers.provider.client.Character\
|
||||||
|
.post_characters_affiliation(characters=character_ids_chunk).result()
|
||||||
|
character_names = providers.provider.client.Universe\
|
||||||
|
.post_universe_names(ids=character_ids_chunk).result()
|
||||||
|
|
||||||
|
affiliations = {
|
||||||
|
affiliation.get('character_id'): affiliation
|
||||||
|
for affiliation in affiliations_raw
|
||||||
|
}
|
||||||
|
# add character names to affiliations
|
||||||
|
for character in character_names:
|
||||||
|
character_id = character.get('id')
|
||||||
|
if character_id in affiliations:
|
||||||
|
affiliations[character_id]['name'] = character.get('name')
|
||||||
|
|
||||||
|
# fetch current characters
|
||||||
|
characters = EveCharacter.objects.filter(character_id__in=character_ids_chunk)\
|
||||||
|
.values('character_id', 'corporation_id', 'alliance_id', 'character_name')
|
||||||
|
|
||||||
|
for character in characters:
|
||||||
|
character_id = character.get('character_id')
|
||||||
|
if character_id in affiliations:
|
||||||
|
affiliation = affiliations[character_id]
|
||||||
|
|
||||||
|
corp_changed = (
|
||||||
|
character.get('corporation_id') != affiliation.get('corporation_id')
|
||||||
|
)
|
||||||
|
|
||||||
|
alliance_id = character.get('alliance_id')
|
||||||
|
if not alliance_id:
|
||||||
|
alliance_id = None
|
||||||
|
alliance_changed = alliance_id != affiliation.get('alliance_id')
|
||||||
|
|
||||||
|
name_changed = False
|
||||||
|
fetched_name = affiliation.get('name', False)
|
||||||
|
if fetched_name:
|
||||||
|
name_changed = character.get('character_name') != fetched_name
|
||||||
|
|
||||||
|
if corp_changed or alliance_changed or name_changed:
|
||||||
|
update_character.apply_async(
|
||||||
|
args=[character.get('character_id')], priority=TASK_PRIORITY
|
||||||
|
)
|
||||||
|
|||||||
@@ -592,3 +592,12 @@ class TestEveSwaggerProvider(TestCase):
|
|||||||
self.assertTrue(mock_esi_client_factory.called)
|
self.assertTrue(mock_esi_client_factory.called)
|
||||||
self.assertIsNotNone(my_provider._client)
|
self.assertIsNotNone(my_provider._client)
|
||||||
self.assertEqual(my_client, 'my_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'
|
||||||
|
)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
from unittest.mock import patch
|
from unittest.mock import patch, Mock
|
||||||
|
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
|
|
||||||
@@ -44,55 +44,202 @@ class TestTasks(TestCase):
|
|||||||
mock_EveCharacter.objects.update_character.call_args[0][0], 42
|
mock_EveCharacter.objects.update_character.call_args[0][0], 42
|
||||||
)
|
)
|
||||||
|
|
||||||
@patch('allianceauth.eveonline.tasks.update_character')
|
|
||||||
@patch('allianceauth.eveonline.tasks.update_alliance')
|
@patch('allianceauth.eveonline.tasks.update_character')
|
||||||
@patch('allianceauth.eveonline.tasks.update_corp')
|
@patch('allianceauth.eveonline.tasks.update_alliance')
|
||||||
def test_run_model_update(
|
@patch('allianceauth.eveonline.tasks.update_corp')
|
||||||
self,
|
@patch('allianceauth.eveonline.providers.provider')
|
||||||
mock_update_corp,
|
@patch('allianceauth.eveonline.tasks.CHUNK_SIZE', 2)
|
||||||
mock_update_alliance,
|
class TestRunModelUpdate(TestCase):
|
||||||
mock_update_character,
|
|
||||||
):
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
super().setUpClass()
|
||||||
EveCorporationInfo.objects.all().delete()
|
EveCorporationInfo.objects.all().delete()
|
||||||
EveAllianceInfo.objects.all().delete()
|
EveAllianceInfo.objects.all().delete()
|
||||||
EveCharacter.objects.all().delete()
|
EveCharacter.objects.all().delete()
|
||||||
|
|
||||||
EveCorporationInfo.objects.create(
|
EveCorporationInfo.objects.create(
|
||||||
corporation_id=2345,
|
corporation_id=2345,
|
||||||
corporation_name='corp.name',
|
corporation_name='corp.name',
|
||||||
corporation_ticker='corp.ticker',
|
corporation_ticker='c.c.t',
|
||||||
member_count=10,
|
member_count=10,
|
||||||
alliance=None,
|
alliance=None,
|
||||||
)
|
)
|
||||||
EveAllianceInfo.objects.create(
|
EveAllianceInfo.objects.create(
|
||||||
alliance_id=3456,
|
alliance_id=3456,
|
||||||
alliance_name='alliance.name',
|
alliance_name='alliance.name',
|
||||||
alliance_ticker='alliance.ticker',
|
alliance_ticker='a.t',
|
||||||
executor_corp_id='78910',
|
executor_corp_id=5,
|
||||||
|
)
|
||||||
|
EveCharacter.objects.create(
|
||||||
|
character_id=1,
|
||||||
|
character_name='character.name1',
|
||||||
|
corporation_id=2345,
|
||||||
|
corporation_name='character.corp.name',
|
||||||
|
corporation_ticker='c.c.t', # max 5 chars
|
||||||
|
alliance_id=None
|
||||||
)
|
)
|
||||||
EveCharacter.objects.create(
|
EveCharacter.objects.create(
|
||||||
character_id=1234,
|
character_id=2,
|
||||||
character_name='character.name',
|
character_name='character.name2',
|
||||||
corporation_id=2345,
|
corporation_id=9876,
|
||||||
corporation_name='character.corp.name',
|
corporation_name='character.corp.name',
|
||||||
corporation_ticker='c.c.t', # max 5 chars
|
corporation_ticker='c.c.t', # max 5 chars
|
||||||
alliance_id=3456,
|
alliance_id=3456,
|
||||||
alliance_name='character.alliance.name',
|
alliance_name='character.alliance.name',
|
||||||
)
|
)
|
||||||
|
EveCharacter.objects.create(
|
||||||
|
character_id=3,
|
||||||
|
character_name='character.name3',
|
||||||
|
corporation_id=9876,
|
||||||
|
corporation_name='character.corp.name',
|
||||||
|
corporation_ticker='c.c.t', # max 5 chars
|
||||||
|
alliance_id=3456,
|
||||||
|
alliance_name='character.alliance.name',
|
||||||
|
)
|
||||||
|
EveCharacter.objects.create(
|
||||||
|
character_id=4,
|
||||||
|
character_name='character.name4',
|
||||||
|
corporation_id=9876,
|
||||||
|
corporation_name='character.corp.name',
|
||||||
|
corporation_ticker='c.c.t', # max 5 chars
|
||||||
|
alliance_id=3456,
|
||||||
|
alliance_name='character.alliance.name',
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
EveCharacter.objects.create(
|
||||||
|
character_id=5,
|
||||||
|
character_name='character.name5',
|
||||||
|
corporation_id=9876,
|
||||||
|
corporation_name='character.corp.name',
|
||||||
|
corporation_ticker='c.c.t', # max 5 chars
|
||||||
|
alliance_id=3456,
|
||||||
|
alliance_name='character.alliance.name',
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.affiliations = [
|
||||||
|
{'character_id': 1, 'corporation_id': 5},
|
||||||
|
{'character_id': 2, 'corporation_id': 9876, 'alliance_id': 3456},
|
||||||
|
{'character_id': 3, 'corporation_id': 9876, 'alliance_id': 7456},
|
||||||
|
{'character_id': 4, 'corporation_id': 9876, 'alliance_id': 3456}
|
||||||
|
]
|
||||||
|
self.names = [
|
||||||
|
{'id': 1, 'name': 'character.name1'},
|
||||||
|
{'id': 2, 'name': 'character.name2'},
|
||||||
|
{'id': 3, 'name': 'character.name3'},
|
||||||
|
{'id': 4, 'name': 'character.name4_new'}
|
||||||
|
]
|
||||||
|
|
||||||
|
def test_normal_run(
|
||||||
|
self,
|
||||||
|
mock_provider,
|
||||||
|
mock_update_corp,
|
||||||
|
mock_update_alliance,
|
||||||
|
mock_update_character,
|
||||||
|
):
|
||||||
|
def get_affiliations(characters: list):
|
||||||
|
response = [x for x in self.affiliations if x['character_id'] in characters]
|
||||||
|
mock_operator = Mock(**{'result.return_value': response})
|
||||||
|
return mock_operator
|
||||||
|
|
||||||
|
def get_names(ids: list):
|
||||||
|
response = [x for x in self.names if x['id'] in ids]
|
||||||
|
mock_operator = Mock(**{'result.return_value': response})
|
||||||
|
return mock_operator
|
||||||
|
|
||||||
|
mock_provider.client.Character.post_characters_affiliation.side_effect \
|
||||||
|
= get_affiliations
|
||||||
|
|
||||||
|
mock_provider.client.Universe.post_universe_names.side_effect = get_names
|
||||||
|
|
||||||
run_model_update()
|
run_model_update()
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
mock_provider.client.Character.post_characters_affiliation.call_count, 2
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
mock_provider.client.Universe.post_universe_names.call_count, 2
|
||||||
|
)
|
||||||
|
|
||||||
|
# character 1 has changed corp
|
||||||
|
# character 2 no change
|
||||||
|
# character 3 has changed alliance
|
||||||
|
# character 4 has changed name
|
||||||
self.assertEqual(mock_update_corp.apply_async.call_count, 1)
|
self.assertEqual(mock_update_corp.apply_async.call_count, 1)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
int(mock_update_corp.apply_async.call_args[1]['args'][0]), 2345
|
int(mock_update_corp.apply_async.call_args[1]['args'][0]), 2345
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertEqual(mock_update_alliance.apply_async.call_count, 1)
|
self.assertEqual(mock_update_alliance.apply_async.call_count, 1)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
int(mock_update_alliance.apply_async.call_args[1]['args'][0]), 3456
|
int(mock_update_alliance.apply_async.call_args[1]['args'][0]), 3456
|
||||||
)
|
)
|
||||||
|
characters_updated = {
|
||||||
|
x[1]['args'][0] for x in mock_update_character.apply_async.call_args_list
|
||||||
|
}
|
||||||
|
excepted = {1, 3, 4}
|
||||||
|
self.assertSetEqual(characters_updated, excepted)
|
||||||
|
|
||||||
|
def test_ignore_character_not_in_affiliations(
|
||||||
|
self,
|
||||||
|
mock_provider,
|
||||||
|
mock_update_corp,
|
||||||
|
mock_update_alliance,
|
||||||
|
mock_update_character,
|
||||||
|
):
|
||||||
|
def get_affiliations(characters: list):
|
||||||
|
response = [x for x in self.affiliations if x['character_id'] in characters]
|
||||||
|
mock_operator = Mock(**{'result.return_value': response})
|
||||||
|
return mock_operator
|
||||||
|
|
||||||
|
def get_names(ids: list):
|
||||||
|
response = [x for x in self.names if x['id'] in ids]
|
||||||
|
mock_operator = Mock(**{'result.return_value': response})
|
||||||
|
return mock_operator
|
||||||
|
|
||||||
|
del self.affiliations[0]
|
||||||
|
|
||||||
|
mock_provider.client.Character.post_characters_affiliation.side_effect \
|
||||||
|
= get_affiliations
|
||||||
|
|
||||||
|
mock_provider.client.Universe.post_universe_names.side_effect = get_names
|
||||||
|
|
||||||
self.assertEqual(mock_update_character.apply_async.call_count, 1)
|
run_model_update()
|
||||||
self.assertEqual(
|
characters_updated = {
|
||||||
int(mock_update_character.apply_async.call_args[1]['args'][0]), 1234
|
x[1]['args'][0] for x in mock_update_character.apply_async.call_args_list
|
||||||
)
|
}
|
||||||
|
excepted = {3, 4}
|
||||||
|
self.assertSetEqual(characters_updated, excepted)
|
||||||
|
|
||||||
|
def test_ignore_character_not_in_names(
|
||||||
|
self,
|
||||||
|
mock_provider,
|
||||||
|
mock_update_corp,
|
||||||
|
mock_update_alliance,
|
||||||
|
mock_update_character,
|
||||||
|
):
|
||||||
|
def get_affiliations(characters: list):
|
||||||
|
response = [x for x in self.affiliations if x['character_id'] in characters]
|
||||||
|
mock_operator = Mock(**{'result.return_value': response})
|
||||||
|
return mock_operator
|
||||||
|
|
||||||
|
def get_names(ids: list):
|
||||||
|
response = [x for x in self.names if x['id'] in ids]
|
||||||
|
mock_operator = Mock(**{'result.return_value': response})
|
||||||
|
return mock_operator
|
||||||
|
|
||||||
|
del self.names[3]
|
||||||
|
|
||||||
|
mock_provider.client.Character.post_characters_affiliation.side_effect \
|
||||||
|
= get_affiliations
|
||||||
|
|
||||||
|
mock_provider.client.Universe.post_universe_names.side_effect = get_names
|
||||||
|
|
||||||
|
run_model_update()
|
||||||
|
characters_updated = {
|
||||||
|
x[1]['args'][0] for x in mock_update_character.apply_async.call_args_list
|
||||||
|
}
|
||||||
|
excepted = {1, 3}
|
||||||
|
self.assertSetEqual(characters_updated, excepted)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{% extends "allianceauth/base.html" %}
|
{% extends "allianceauth/base.html" %}
|
||||||
{% load bootstrap %}
|
{% load bootstrap %}
|
||||||
{% load staticfiles %}
|
{% load static %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block page_title %}{% trans "Create Fatlink" %}{% endblock page_title %}
|
{% block page_title %}{% trans "Create Fatlink" %}{% endblock page_title %}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{% extends "allianceauth/base.html" %}
|
{% extends "allianceauth/base.html" %}
|
||||||
{% load bootstrap %}
|
{% load bootstrap %}
|
||||||
{% load staticfiles %}
|
{% load static %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% block page_title %}{% trans "Fatlink view" %}{% endblock page_title %}
|
{% block page_title %}{% trans "Fatlink view" %}{% endblock page_title %}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{% extends "allianceauth/base.html" %}
|
{% extends "allianceauth/base.html" %}
|
||||||
{% load bootstrap %}
|
{% load bootstrap %}
|
||||||
{% load staticfiles %}
|
{% load static %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block page_title %}{% trans "Personal fatlink statistics" %}{% endblock page_title %}
|
{% block page_title %}{% trans "Personal fatlink statistics" %}{% endblock page_title %}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{% extends "allianceauth/base.html" %}
|
{% extends "allianceauth/base.html" %}
|
||||||
{% load bootstrap %}
|
{% load bootstrap %}
|
||||||
{% load staticfiles %}
|
{% load static %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block page_title %}{% trans "Personal fatlink statistics" %}{% endblock page_title %}
|
{% block page_title %}{% trans "Personal fatlink statistics" %}{% endblock page_title %}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{% extends "allianceauth/base.html" %}
|
{% extends "allianceauth/base.html" %}
|
||||||
{% load bootstrap %}
|
{% load bootstrap %}
|
||||||
{% load staticfiles %}
|
{% load static %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block page_title %}{% trans "Fatlink Corp Statistics" %}{% endblock page_title %}
|
{% block page_title %}{% trans "Fatlink Corp Statistics" %}{% endblock page_title %}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{% extends "allianceauth/base.html" %}
|
{% extends "allianceauth/base.html" %}
|
||||||
{% load bootstrap %}
|
{% load bootstrap %}
|
||||||
{% load staticfiles %}
|
{% load static %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block page_title %}{% trans "Fatlink statistics" %}{% endblock page_title %}
|
{% block page_title %}{% trans "Fatlink statistics" %}{% endblock page_title %}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{% extends "allianceauth/base.html" %}
|
{% extends "allianceauth/base.html" %}
|
||||||
{% load bootstrap %}
|
{% load bootstrap %}
|
||||||
{% load staticfiles %}
|
{% load static %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block page_title %}{% trans "Fatlink view" %}{% endblock page_title %}
|
{% block page_title %}{% trans "Fatlink view" %}{% endblock page_title %}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ class AuthGroupInlineAdmin(admin.StackedInline):
|
|||||||
kwargs["queryset"] = Group.objects.order_by(Lower('name'))
|
kwargs["queryset"] = Group.objects.order_by(Lower('name'))
|
||||||
return super().formfield_for_manytomany(db_field, request, **kwargs)
|
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
|
return False
|
||||||
|
|
||||||
def has_delete_permission(self, request, obj=None):
|
def has_delete_permission(self, request, obj=None):
|
||||||
|
|||||||
43
allianceauth/groupmanagement/auth_hooks.py
Normal file
43
allianceauth/groupmanagement/auth_hooks.py
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
from allianceauth.services.hooks import MenuItemHook, UrlHook
|
||||||
|
from allianceauth import hooks
|
||||||
|
|
||||||
|
from . import urls
|
||||||
|
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",
|
||||||
|
order=50,
|
||||||
|
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):
|
||||||
|
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 ""
|
||||||
|
|
||||||
|
|
||||||
|
@hooks.register("menu_item_hook")
|
||||||
|
def register_menu():
|
||||||
|
return GroupManagementMenuItem()
|
||||||
|
|
||||||
|
|
||||||
|
@hooks.register("url_hook")
|
||||||
|
def register_urls():
|
||||||
|
return UrlHook(urls, "group", r"^groups/")
|
||||||
@@ -4,6 +4,7 @@ from django.contrib.auth.models import Group, User
|
|||||||
from django.db.models import Q, QuerySet
|
from django.db.models import Q, QuerySet
|
||||||
|
|
||||||
from allianceauth.authentication.models import State
|
from allianceauth.authentication.models import State
|
||||||
|
from .models import GroupRequest
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@@ -101,3 +102,18 @@ class GroupManager:
|
|||||||
if user.is_authenticated:
|
if user.is_authenticated:
|
||||||
return cls.has_management_permission(user) or cls.get_group_leaders_groups(user).filter(pk=group.pk).exists()
|
return cls.has_management_permission(user) or cls.get_group_leaders_groups(user).filter(pk=group.pk).exists()
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def pending_requests_count_for_user(cls, user: User) -> int:
|
||||||
|
"""Returns the number of pending group requests for the given user"""
|
||||||
|
|
||||||
|
if cls.has_management_permission(user):
|
||||||
|
return GroupRequest.objects.filter(status="pending").count()
|
||||||
|
else:
|
||||||
|
return (
|
||||||
|
GroupRequest.objects
|
||||||
|
.filter(status="pending")
|
||||||
|
.filter(group__authgroup__group_leaders__exact=user)
|
||||||
|
.select_related("group__authgroup__group_leaders")
|
||||||
|
.count()
|
||||||
|
)
|
||||||
|
|||||||
@@ -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),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -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,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -4,7 +4,6 @@ from django.db import models
|
|||||||
from django.db.models.signals import post_save
|
from django.db.models.signals import post_save
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
from allianceauth.authentication.models import State
|
from allianceauth.authentication.models import State
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
|
|
||||||
class GroupRequest(models.Model):
|
class GroupRequest(models.Model):
|
||||||
@@ -26,7 +25,7 @@ class GroupRequest(models.Model):
|
|||||||
|
|
||||||
|
|
||||||
class RequestLog(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)
|
group = models.ForeignKey(Group, on_delete=models.CASCADE)
|
||||||
request_info = models.CharField(max_length=254)
|
request_info = models.CharField(max_length=254)
|
||||||
action = models.BooleanField(default=0)
|
action = models.BooleanField(default=0)
|
||||||
@@ -108,7 +107,7 @@ class AuthGroup(models.Model):
|
|||||||
help_text="States listed here will have the ability to join this group provided "
|
help_text="States listed here will have the ability to join this group provided "
|
||||||
"they have the proper permissions.")
|
"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):
|
def __str__(self):
|
||||||
return self.group.name
|
return self.group.name
|
||||||
|
|||||||
@@ -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
|
import logging
|
||||||
|
from django.dispatch import receiver
|
||||||
|
from allianceauth.authentication.signals import state_changed
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@receiver(state_changed)
|
@receiver(state_changed)
|
||||||
def check_groups_on_state_change(sender, user, state, **kwargs):
|
def check_groups_on_state_change(sender, user, state, **kwargs):
|
||||||
logger.debug("Updating auth groups for {}".format(user))
|
logger.debug(
|
||||||
visible_groups = GroupManager.get_joinable_groups(state)
|
"Checking group memberships for %s based on new state %s" % (user, state)
|
||||||
visible_groups = visible_groups | Group.objects.select_related('authgroup').filter(authgroup__internal=True)
|
)
|
||||||
groups = user.groups.all()
|
state_groups = (
|
||||||
for g in groups:
|
user.groups.select_related("authgroup").exclude(authgroup__states=None)
|
||||||
if g not in visible_groups:
|
)
|
||||||
user.groups.remove(g)
|
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)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{% extends "allianceauth/base.html" %}
|
{% extends "allianceauth/base.html" %}
|
||||||
{% load staticfiles %}
|
{% load static %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block page_title %}{{ group }} {% trans "Audit Log" %}{% endblock page_title %}
|
{% block page_title %}{{ group }} {% trans "Audit Log" %}{% endblock page_title %}
|
||||||
@@ -8,65 +8,73 @@
|
|||||||
<div class="col-lg-12">
|
<div class="col-lg-12">
|
||||||
<br>
|
<br>
|
||||||
{% include 'groupmanagement/menu.html' %}
|
{% include 'groupmanagement/menu.html' %}
|
||||||
|
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
{{ group }} - {% trans 'Audit Log' %}
|
{{ group }} - {% trans "Audit Log" %}
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
|
||||||
<p>
|
<div class="panel-body">
|
||||||
|
<p>
|
||||||
<a class="btn btn-default" href="{% url 'groupmanagement:membership' %}" role="button">
|
<a class="btn btn-default" href="{% url 'groupmanagement:membership' %}" role="button">
|
||||||
{% trans "Back" %}
|
{% trans "Back" %}
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
{% if entries %}
|
{% if entries %}
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table table-striped" id="log-entries">
|
<table class="table table-striped" id="log-entries">
|
||||||
<thead>
|
<thead>
|
||||||
<th class="text-center" scope="col">{% trans "Date/Time" %}</th>
|
<th scope="col">{% trans "Date/Time" %}</th>
|
||||||
<th class="text-center" scope="col">{% trans "Requestor" %}</th>
|
<th scope="col">{% trans "Requestor" %}</th>
|
||||||
<th class="text-center" scope="col">{% trans "Character" %}</th>
|
<th scope="col">{% trans "Character" %}</th>
|
||||||
<th class="text-center" scope="col">{% trans "Corporation" %}</th>
|
<th scope="col">{% trans "Corporation" %}</th>
|
||||||
<th class="text-center" scope="col">{% trans "Type" %}</th>
|
<th scope="col">{% trans "Type" %}</th>
|
||||||
<th class="text-center" scope="col">{% trans "Action" %}</th>
|
<th scope="col">{% trans "Action" %}</th>
|
||||||
<th class="text-center" scope="col">{% trans "Actor" %}</th>
|
<th scope="col">{% trans "Actor" %}</th>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for entry in entries %}
|
{% for entry in entries %}
|
||||||
<tr>
|
<tr>
|
||||||
<td class="text-center">{{ entry.date|date:"Y-M-d H:i" }}</td>
|
<td>{{ entry.date|date:"Y-M-d, H:i" }}</td>
|
||||||
<td class="text-center">{{ entry.requestor }}</td>
|
<td>{{ entry.requestor }}</td>
|
||||||
<td class="text-center">{{ entry.req_char }}</td>
|
<td>{{ entry.req_char }}</td>
|
||||||
<td class="text-center">{{ entry.req_char.corporation_name }}</td>
|
<td>{{ entry.req_char.corporation_name }}</td>
|
||||||
<td class="text-center">{{ entry.type_to_str }}</td>
|
<td>{{ entry.type_to_str }}</td>
|
||||||
|
|
||||||
{% if entry.request_type is None %}
|
{% if entry.request_type is None %}
|
||||||
<td class="text-center"> Removed</td>
|
<td>{% trans "Removed" %}</td>
|
||||||
{% else %}
|
{% else %}
|
||||||
<td class="text-center">{{ entry.action_to_str }}</td>
|
<td>{{ entry.action_to_str }}</td>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<td class="text-center">{{ entry.request_actor }}</td>
|
|
||||||
|
<td>{{ entry.request_actor }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<p class="text-muted">
|
<p class="text-muted">
|
||||||
All times displayed are EVE/UTC.
|
{% trans "All times displayed are EVE/UTC." %}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="clearfix"></div>
|
<div class="clearfix"></div>
|
||||||
<br>
|
<br>
|
||||||
<div class="alert alert-warning text-center">
|
<div class="alert alert-warning text-center">
|
||||||
{% trans "No entries found for this group." %}
|
{% trans "No entries found for this group." %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block extra_javascript %}
|
{% block extra_javascript %}
|
||||||
{% include 'bundles/datatables-js.html' %}
|
{% include 'bundles/datatables-js.html' %}
|
||||||
<script type="text/javascript" src="{% static 'js/filterDropDown/filterDropDown.min.js' %}"></script>
|
{% include 'bundles/moment-js.html' with locale=True %}
|
||||||
|
<script type="application/javascript" src="{% static 'js/filterDropDown/filterDropDown.min.js' %}"></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block extra_css %}
|
{% block extra_css %}
|
||||||
@@ -74,12 +82,30 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block extra_script %}
|
{% block extra_script %}
|
||||||
|
$.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(){
|
$(document).ready(function(){
|
||||||
|
$.fn.dataTable.moment('YYYY-MMM-D, HH:mm');
|
||||||
|
|
||||||
$('#log-entries').DataTable({
|
$('#log-entries').DataTable({
|
||||||
order: [[ 0, 'desc' ], [ 1, 'asc' ] ],
|
order: [[0, 'desc'], [1, 'asc']],
|
||||||
filterDropDown:
|
filterDropDown:
|
||||||
{
|
{
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
idx: 1
|
idx: 1
|
||||||
},
|
},
|
||||||
@@ -104,4 +130,3 @@
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{% extends "allianceauth/base.html" %}
|
{% extends "allianceauth/base.html" %}
|
||||||
{% load staticfiles %}
|
{% load static %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load evelinks %}
|
{% load evelinks %}
|
||||||
|
|
||||||
@@ -9,38 +9,35 @@
|
|||||||
<div class="col-lg-12">
|
<div class="col-lg-12">
|
||||||
<br>
|
<br>
|
||||||
{% include 'groupmanagement/menu.html' %}
|
{% include 'groupmanagement/menu.html' %}
|
||||||
|
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
{{ group.name }} - {% trans 'Members' %}
|
{{ group.name }} - {% trans 'Members' %}
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
|
||||||
<p>
|
<div class="panel-body">
|
||||||
|
<p>
|
||||||
<a class="btn btn-default" href="{% url 'groupmanagement:membership' %}" role="button">
|
<a class="btn btn-default" href="{% url 'groupmanagement:membership' %}" role="button">
|
||||||
{% trans "Back" %}
|
{% trans "Back" %}
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
{% if group.user_set %}
|
|
||||||
|
{% if group.user_set %}
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table table-aa" id="tab_group_members">
|
<table class="table table-aa" id="tab_group_members">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="text-right">{% trans "Portrait" %}</th>
|
<th>{% trans "Character" %}</th>
|
||||||
<th class="text-center">{% trans "Character" %}</th>
|
<th>{% trans "Organization" %}</th>
|
||||||
<th class="text-center">{% trans "Organization" %}</th>
|
<th></th>
|
||||||
<th class="text-center"></th>
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for member in members %}
|
{% for member in members %}
|
||||||
<tr>
|
<tr>
|
||||||
<td class="text-right">
|
<td>
|
||||||
{% if member.is_leader %}
|
<img src="{{ member.main_char|character_portrait_url:32 }}" class="img-circle" style="margin-right: 1rem;">
|
||||||
<i class="fas fa-star"></i>
|
|
||||||
{% endif %}
|
|
||||||
<img src="{{ member.main_char|character_portrait_url:32 }}" class="img-circle">
|
|
||||||
</td>
|
|
||||||
<td class="text-center">
|
|
||||||
{% if member.main_char %}
|
{% if member.main_char %}
|
||||||
<a href="{{ member.main_char|evewho_character_url }}" target="_blank">
|
<a href="{{ member.main_char|evewho_character_url }}" target="_blank">
|
||||||
{{ member.main_char.character_name }}
|
{{ member.main_char.character_name }}
|
||||||
@@ -48,28 +45,36 @@
|
|||||||
{% else %}
|
{% else %}
|
||||||
{{ member.user.username }}
|
{{ member.user.username }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
{% if member.is_leader %}
|
||||||
|
<i class="fas fa-star" title="{% trans "Group leader" %}" style="margin-left: 1rem;"></i>
|
||||||
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<td class="text-center">
|
|
||||||
|
<td>
|
||||||
{% if member.main_char %}
|
{% if member.main_char %}
|
||||||
<a href="{{ member.main_char|dotlan_corporation_url }}" target="_blank">
|
<a href="{{ member.main_char|dotlan_corporation_url }}" target="_blank">
|
||||||
{{ member.main_char.corporation_name }}
|
{{ member.main_char.corporation_name }}
|
||||||
</a><br>
|
</a><br>
|
||||||
{{ member.main_char.alliance_name|default_if_none:"" }}
|
{{ member.main_char.alliance_name|default_if_none:"" }}
|
||||||
{% else %}
|
{% else %}
|
||||||
(unknown)
|
{% trans "(unknown)" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<td class="text-center">
|
|
||||||
<a href="{% url 'groupmanagement:membership_remove' group.id member.user.id %}" class="btn btn-danger"
|
<td class="text-right">
|
||||||
title="{% trans "Remove from group" %}">
|
<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>
|
<i class="glyphicon glyphicon-remove"></i>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</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>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="alert alert-warning text-center">
|
<div class="alert alert-warning text-center">
|
||||||
@@ -77,7 +82,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
@@ -93,10 +98,13 @@
|
|||||||
{% block extra_script %}
|
{% block extra_script %}
|
||||||
$(document).ready(function(){
|
$(document).ready(function(){
|
||||||
$('#tab_group_members').DataTable({
|
$('#tab_group_members').DataTable({
|
||||||
order: [ [ 1, "asc" ] ],
|
order: [[0, "asc"]],
|
||||||
columnDefs: [
|
columnDefs: [
|
||||||
{ "sortable": false, "targets": [0, 3] },
|
{
|
||||||
|
"sortable": false,
|
||||||
|
"targets": [2]
|
||||||
|
},
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{% extends "allianceauth/base.html" %}
|
{% extends "allianceauth/base.html" %}
|
||||||
{% load staticfiles %}
|
{% load static %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block page_title %}{% trans "Groups Membership" %}{% endblock page_title %}
|
{% block page_title %}{% trans "Groups Membership" %}{% endblock page_title %}
|
||||||
@@ -9,31 +9,36 @@
|
|||||||
<div class="col-lg-12">
|
<div class="col-lg-12">
|
||||||
<br>
|
<br>
|
||||||
{% include 'groupmanagement/menu.html' %}
|
{% include 'groupmanagement/menu.html' %}
|
||||||
|
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
{% trans "Groups" %}
|
{% trans "Groups" %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
{% if groups %}
|
{% if groups %}
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table table-aa">
|
<table class="table table-aa">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="text-center">{% trans "Name" %}</th>
|
<th>{% trans "Name" %}</th>
|
||||||
<th class="text-center">{% trans "Description" %}</th>
|
<th>{% trans "Description" %}</th>
|
||||||
<th class="text-center">{% trans "Status" %}</th>
|
<th>{% trans "Status" %}</th>
|
||||||
<th class="text-center">{% trans "Member Count" %}</th>
|
<th style="white-space: nowrap;">{% trans "Member Count" %}</th>
|
||||||
<th class="text-center"></th>
|
<th style="min-width: 170px;"></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for group in groups %}
|
{% for group in groups %}
|
||||||
<tr>
|
<tr>
|
||||||
<td class="text-center">
|
<td>
|
||||||
<a href="{% url 'groupmanagement:membership_list' group.id %}">{{ group.name }}</a>
|
<a href="{% url 'groupmanagement:membership' group.id %}">{{ group.name }}</a>
|
||||||
</td>
|
</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 %}
|
{% if group.authgroup.hidden %}
|
||||||
<span class="label label-info">{% trans "Hidden" %}</span>
|
<span class="label label-info">{% trans "Hidden" %}</span>
|
||||||
{% elif group.authgroup.open %}
|
{% elif group.authgroup.open %}
|
||||||
@@ -42,21 +47,23 @@
|
|||||||
<span class="label label-default">{% trans "Requestable" %}</span>
|
<span class="label label-default">{% trans "Requestable" %}</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<td class="text-center">
|
|
||||||
|
<td class="text-right">
|
||||||
{{ group.num_members }}
|
{{ group.num_members }}
|
||||||
</td>
|
</td>
|
||||||
<td class="text-center">
|
|
||||||
<a href="{% url 'groupmanagement:membership_list' group.id %}" class="btn btn-primary"
|
<td class="text-right">
|
||||||
title="{% trans "View Members" %}">
|
<a href="{% url 'groupmanagement:membership' group.id %}" class="btn btn-primary" title="{% trans "View Members" %}">
|
||||||
<i class="glyphicon glyphicon-eye-open"></i>
|
<i class="glyphicon glyphicon-eye-open"></i>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a href="{% url "groupmanagement:audit_log" group.id %}" class="btn btn-info" title="{% trans "Audit Members" %}">
|
<a href="{% url "groupmanagement:audit_log" group.id %}" class="btn btn-info" title="{% trans "Audit Members" %}">
|
||||||
<i class="glyphicon glyphicon-list-alt"></i>
|
<i class="glyphicon glyphicon-list-alt"></i>
|
||||||
</a>
|
</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" %}">
|
<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>
|
<i class="glyphicon glyphicon-copy"></i>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
@@ -72,9 +79,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
{% block extra_javascript %}
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.4/clipboard.min.js"></script>
|
{% block extra_javascript %}
|
||||||
<script>
|
{% include 'bundles/clipboard-js.html' %}
|
||||||
new ClipboardJS('#clipboard-copy');
|
|
||||||
</script>
|
<script>
|
||||||
{% endblock %}
|
new ClipboardJS('#clipboard-copy');
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
{% extends "allianceauth/base.html" %}
|
{% extends "allianceauth/base.html" %}
|
||||||
{% load staticfiles %}
|
{% load static %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block page_title %}{% trans "Available Groups" %}{% endblock page_title %}
|
{% block page_title %}{% trans "Available Groups" %}{% endblock page_title %}
|
||||||
{% block extra_css %}{% endblock extra_css %}
|
{% block extra_css %}{% endblock extra_css %}
|
||||||
url
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="col-lg-12">
|
<div class="col-lg-12">
|
||||||
<h1 class="page-header text-center">{% trans "Available Groups" %}</h1>
|
<h1 class="page-header text-center">{% trans "Available Groups" %}</h1>
|
||||||
@@ -12,17 +12,18 @@ url
|
|||||||
<table class="table table-aa">
|
<table class="table table-aa">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="text-center">{% trans "Name" %}</th>
|
<th>{% trans "Name" %}</th>
|
||||||
<th class="text-center">{% trans "Description" %}</th>
|
<th>{% trans "Description" %}</th>
|
||||||
<th class="text-center">{% trans "Action" %}</th>
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for g in groups %}
|
{% for g in groups %}
|
||||||
<tr>
|
<tr>
|
||||||
<td class="text-center">{{ g.group.name }}</td>
|
<td>{{ g.group.name }}</td>
|
||||||
<td class="text-center">{{ g.group.authgroup.description|urlize }}</td>
|
<td>{{ g.group.authgroup.description|linebreaks|urlize }}</td>
|
||||||
<td class="text-center">
|
<td class="text-right">
|
||||||
{% if g.group in user.groups.all %}
|
{% if g.group in user.groups.all %}
|
||||||
{% if not g.request %}
|
{% if not g.request %}
|
||||||
<a href="{% url 'groupmanagement:request_leave' g.group.id %}" class="btn btn-danger">
|
<a href="{% url 'groupmanagement:request_leave' g.group.id %}" class="btn btn-danger">
|
||||||
@@ -59,5 +60,4 @@ url
|
|||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|||||||
@@ -1,28 +1,29 @@
|
|||||||
{% extends "allianceauth/base.html" %}
|
{% extends "allianceauth/base.html" %}
|
||||||
{% load staticfiles %}
|
{% load static %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load evelinks %}
|
{% load evelinks %}
|
||||||
|
|
||||||
{% block page_title %}{% trans "Groups Management" %}{% endblock page_title %}
|
{% 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 %}
|
{% endblock extra_css %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="col-lg-12">
|
<div class="col-lg-12">
|
||||||
<br>
|
<br>
|
||||||
{% include 'groupmanagement/menu.html' %}
|
{% include 'groupmanagement/menu.html' %}
|
||||||
|
|
||||||
<ul class="nav nav-tabs">
|
<ul class="nav nav-tabs">
|
||||||
<li class="active">
|
<li class="active">
|
||||||
<a data-toggle="tab" href="#add">
|
<a data-toggle="tab" href="#add">
|
||||||
{% trans "Join Requests" %}
|
{% trans "Join Requests" %}
|
||||||
|
|
||||||
{% if acceptrequests %}
|
{% if acceptrequests %}
|
||||||
<span class="badge">{{ acceptrequests|length }}</span>
|
<span class="badge">{{ acceptrequests|length }}</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@@ -31,133 +32,130 @@
|
|||||||
<li>
|
<li>
|
||||||
<a data-toggle="tab" href="#leave">
|
<a data-toggle="tab" href="#leave">
|
||||||
{% trans "Leave Requests" %}
|
{% trans "Leave Requests" %}
|
||||||
|
|
||||||
{% if leaverequests %}
|
{% if leaverequests %}
|
||||||
<span class="badge">{{ leaverequests|length }}</span>
|
<span class="badge">{{ leaverequests|length }}</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<div class="tab-content">
|
|
||||||
|
|
||||||
|
<div class="tab-content">
|
||||||
<div id="add" class="tab-pane fade in active panel panel-default">
|
<div id="add" class="tab-pane fade in active panel panel-default">
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
{% if acceptrequests %}
|
{% if acceptrequests %}
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table table-aa">
|
<table class="table table-aa">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="text-center"></th>
|
<th>{% trans "Character" %}</th>
|
||||||
<th class="text-center">{% trans "Character" %}</th>
|
<th>{% trans "Organization" %}</th>
|
||||||
<th class="text-center">{% trans "Organization" %}</th>
|
<th>{% trans "Group" %}</th>
|
||||||
<th class="text-center">{% trans "Group" %}</th>
|
<th></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>
|
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
</thead>
|
||||||
</tbody>
|
|
||||||
</table>
|
<tbody>
|
||||||
</div>
|
{% for acceptrequest in acceptrequests %}
|
||||||
{% else %}
|
<tr>
|
||||||
<div class="alert alert-warning text-center">{% trans "No group add requests." %}</div>
|
<td>
|
||||||
{% endif %}
|
<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>
|
</div>
|
||||||
|
|
||||||
<div id="leave" class="tab-pane fade panel panel-default">
|
<div id="leave" class="tab-pane fade panel panel-default">
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
{% if leaverequests %}
|
{% if leaverequests %}
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table table-aa">
|
<table class="table table-aa">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="text-center"></th>
|
<th>{% trans "Character" %}</th>
|
||||||
<th class="text-center">{% trans "Character" %}</th>
|
<th>{% trans "Organization" %}</th>
|
||||||
<th class="text-center">{% trans "Organization" %}</th>
|
<th>{% trans "Group" %}</th>
|
||||||
<th class="text-center">{% trans "Group" %}</th>
|
<th></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>
|
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
</thead>
|
||||||
</tbody>
|
|
||||||
</table>
|
<tbody>
|
||||||
</div>
|
{% for leaverequest in leaverequests %}
|
||||||
{% else %}
|
<tr>
|
||||||
<div class="alert alert-warning text-center">{% trans "No group leave requests." %}</div>
|
<td>
|
||||||
{% endif %}
|
<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>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
{% load staticfiles %}
|
{% load static %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load navactive %}
|
{% load navactive %}
|
||||||
|
|
||||||
<nav class="navbar navbar-default">
|
<nav class="navbar navbar-default">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
|
|
||||||
<div class="navbar-header">
|
<div class="navbar-header">
|
||||||
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
|
<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>
|
<span class="sr-only">{% trans "Toggle navigation" %}</span>
|
||||||
@@ -12,7 +11,7 @@
|
|||||||
<span class="icon-bar"></span>
|
<span class="icon-bar"></span>
|
||||||
<span class="icon-bar"></span>
|
<span class="icon-bar"></span>
|
||||||
</button>
|
</button>
|
||||||
<a class="navbar-brand" href="">{% trans "Group Management" %}</a>
|
<a class="navbar-brand" href="{% url 'groupmanagement:management' %}">{% trans "Group Management" %}</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
|
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
|
||||||
@@ -20,11 +19,10 @@
|
|||||||
<li class="{% navactive request 'groupmanagement:management' %}">
|
<li class="{% navactive request 'groupmanagement:management' %}">
|
||||||
<a href="{% url 'groupmanagement:management' %}">{% trans "Group Requests" %}</a>
|
<a href="{% url 'groupmanagement:management' %}">{% trans "Group Requests" %}</a>
|
||||||
</li>
|
</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>
|
<a href="{% url 'groupmanagement:membership' %}">{% trans "Group Membership" %}</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
from django import template
|
|
||||||
from django.contrib.auth.models import User
|
|
||||||
|
|
||||||
from allianceauth.groupmanagement.managers import GroupManager
|
|
||||||
|
|
||||||
|
|
||||||
register = template.Library()
|
|
||||||
|
|
||||||
|
|
||||||
@register.filter
|
|
||||||
def can_manage_groups(user: User) -> bool:
|
|
||||||
"""returns True if the given user can manage groups. Returns False otherwise."""
|
|
||||||
if not isinstance(user, User):
|
|
||||||
return False
|
|
||||||
return GroupManager.can_manage_groups(user)
|
|
||||||
@@ -7,7 +7,7 @@ from django.urls import reverse
|
|||||||
from allianceauth.eveonline.models import EveCorporationInfo, EveAllianceInfo
|
from allianceauth.eveonline.models import EveCorporationInfo, EveAllianceInfo
|
||||||
from allianceauth.tests.auth_utils import AuthUtils
|
from allianceauth.tests.auth_utils import AuthUtils
|
||||||
|
|
||||||
from ..models import AuthGroup
|
from ..models import GroupRequest
|
||||||
from ..managers import GroupManager
|
from ..managers import GroupManager
|
||||||
|
|
||||||
|
|
||||||
@@ -15,6 +15,7 @@ class MockUserNotAuthenticated():
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.is_authenticated = False
|
self.is_authenticated = False
|
||||||
|
|
||||||
|
|
||||||
class GroupManagementVisibilityTestCase(TestCase):
|
class GroupManagementVisibilityTestCase(TestCase):
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpTestData(cls):
|
def setUpTestData(cls):
|
||||||
@@ -37,22 +38,20 @@ class GroupManagementVisibilityTestCase(TestCase):
|
|||||||
def _refresh_user(self):
|
def _refresh_user(self):
|
||||||
self.user = User.objects.get(pk=self.user.pk)
|
self.user = User.objects.get(pk=self.user.pk)
|
||||||
|
|
||||||
|
|
||||||
def test_get_group_leaders_groups(self):
|
def test_get_group_leaders_groups(self):
|
||||||
self.group1.authgroup.group_leaders.add(self.user)
|
self.group1.authgroup.group_leaders.add(self.user)
|
||||||
self.group2.authgroup.group_leader_groups.add(self.group1)
|
self.group2.authgroup.group_leader_groups.add(self.group1)
|
||||||
self._refresh_user()
|
self._refresh_user()
|
||||||
groups = GroupManager.get_group_leaders_groups(self.user)
|
groups = GroupManager.get_group_leaders_groups(self.user)
|
||||||
|
|
||||||
self.assertIn(self.group1, groups) #avail due to user
|
self.assertIn(self.group1, groups) #avail due to user
|
||||||
self.assertNotIn(self.group2, groups) #not avail due to group
|
self.assertNotIn(self.group2, groups) #not avail due to group
|
||||||
self.assertNotIn(self.group3, groups) #not avail at all
|
self.assertNotIn(self.group3, groups) #not avail at all
|
||||||
|
|
||||||
self.user.groups.add(self.group1)
|
self.user.groups.add(self.group1)
|
||||||
self._refresh_user()
|
self._refresh_user()
|
||||||
groups = GroupManager.get_group_leaders_groups(self.user)
|
groups = GroupManager.get_group_leaders_groups(self.user)
|
||||||
|
|
||||||
|
|
||||||
def test_can_manage_group(self):
|
def test_can_manage_group(self):
|
||||||
self.group1.authgroup.group_leaders.add(self.user)
|
self.group1.authgroup.group_leaders.add(self.user)
|
||||||
self.user.groups.add(self.group1)
|
self.user.groups.add(self.group1)
|
||||||
@@ -182,7 +181,6 @@ class TestGroupManager(TestCase):
|
|||||||
]:
|
]:
|
||||||
self.assertFalse(GroupManager.joinable_group(x, member_state))
|
self.assertFalse(GroupManager.joinable_group(x, member_state))
|
||||||
|
|
||||||
|
|
||||||
def test_joinable_group_guest(self):
|
def test_joinable_group_guest(self):
|
||||||
guest_state = AuthUtils.get_guest_state()
|
guest_state = AuthUtils.get_guest_state()
|
||||||
for x in [
|
for x in [
|
||||||
@@ -200,7 +198,6 @@ class TestGroupManager(TestCase):
|
|||||||
]:
|
]:
|
||||||
self.assertFalse(GroupManager.joinable_group(x, guest_state))
|
self.assertFalse(GroupManager.joinable_group(x, guest_state))
|
||||||
|
|
||||||
|
|
||||||
def test_get_all_non_internal_groups(self):
|
def test_get_all_non_internal_groups(self):
|
||||||
result = GroupManager.get_all_non_internal_groups()
|
result = GroupManager.get_all_non_internal_groups()
|
||||||
expected = {
|
expected = {
|
||||||
@@ -224,7 +221,7 @@ class TestGroupManager(TestCase):
|
|||||||
def test_get_joinable_groups_for_user_no_permission(self):
|
def test_get_joinable_groups_for_user_no_permission(self):
|
||||||
AuthUtils.assign_state(self.user, AuthUtils.get_guest_state())
|
AuthUtils.assign_state(self.user, AuthUtils.get_guest_state())
|
||||||
result = GroupManager.get_joinable_groups_for_user(self.user)
|
result = GroupManager.get_joinable_groups_for_user(self.user)
|
||||||
expected= {self.group_public_1, self.group_public_2}
|
expected = {self.group_public_1, self.group_public_2}
|
||||||
self.assertSetEqual(set(result), expected)
|
self.assertSetEqual(set(result), expected)
|
||||||
|
|
||||||
def test_get_joinable_groups_for_user_guest_w_permission_(self):
|
def test_get_joinable_groups_for_user_guest_w_permission_(self):
|
||||||
@@ -335,3 +332,96 @@ class TestGroupManager(TestCase):
|
|||||||
self.assertFalse(
|
self.assertFalse(
|
||||||
GroupManager.can_manage_group(user, self.group_default)
|
GroupManager.can_manage_group(user, self.group_default)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class TestPendingRequestsCountForUser(TestCase):
|
||||||
|
|
||||||
|
def setUp(self) -> None:
|
||||||
|
self.group_1 = Group.objects.create(name="Group 1")
|
||||||
|
self.group_2 = Group.objects.create(name="Group 2")
|
||||||
|
self.user_leader_1 = AuthUtils.create_member('Clark Kent')
|
||||||
|
self.group_1.authgroup.group_leaders.add(self.user_leader_1)
|
||||||
|
self.user_leader_2 = AuthUtils.create_member('Peter Parker')
|
||||||
|
self.group_2.authgroup.group_leaders.add(self.user_leader_2)
|
||||||
|
self.user_requestor = AuthUtils.create_member('Bruce Wayne')
|
||||||
|
|
||||||
|
def test_single_request_for_leader(self):
|
||||||
|
# given user_leader_1 is leader of group_1
|
||||||
|
# and user_leader_2 is leader of group_2
|
||||||
|
# when user_requestor is requesting access to group 1
|
||||||
|
# then return 1 for user_leader 1 and 0 for user_leader_2
|
||||||
|
GroupRequest.objects.create(
|
||||||
|
status="pending", user=self.user_requestor, group=self.group_1
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
GroupManager.pending_requests_count_for_user(self.user_leader_1), 1
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
GroupManager.pending_requests_count_for_user(self.user_leader_2), 0
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_return_none_for_none_leader(self):
|
||||||
|
# given user_requestor is leader of no group
|
||||||
|
# when user_requestor is requesting access to group 1
|
||||||
|
# then return 0 for user_requestor
|
||||||
|
GroupRequest.objects.create(
|
||||||
|
status="pending", user=self.user_requestor, group=self.group_1
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
GroupManager.pending_requests_count_for_user(self.user_requestor), 0
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_single_leave_request(self):
|
||||||
|
# given user_leader_2 is leader of group_2
|
||||||
|
# and user_requestor is member of group 2
|
||||||
|
# when user_requestor is requesting to leave group 2
|
||||||
|
# then return 1 for user_leader_2
|
||||||
|
self.user_requestor.groups.add(self.group_2)
|
||||||
|
|
||||||
|
GroupRequest.objects.create(
|
||||||
|
status="pending",
|
||||||
|
user=self.user_requestor,
|
||||||
|
group=self.group_2,
|
||||||
|
leave_request=True
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
GroupManager.pending_requests_count_for_user(self.user_leader_2), 1
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_join_and_leave_request(self):
|
||||||
|
# given user_leader_2 is leader of group_2
|
||||||
|
# and user_requestor is member of group 2
|
||||||
|
# when user_requestor is requesting to leave group 2
|
||||||
|
# and user_requestor_2 is requesting to join group 2
|
||||||
|
# then return 2 for user_leader_2
|
||||||
|
self.user_requestor.groups.add(self.group_2)
|
||||||
|
user_requestor_2 = AuthUtils.create_member("Lex Luther")
|
||||||
|
GroupRequest.objects.create(
|
||||||
|
status="pending",
|
||||||
|
user=user_requestor_2,
|
||||||
|
group=self.group_2
|
||||||
|
)
|
||||||
|
GroupRequest.objects.create(
|
||||||
|
status="pending",
|
||||||
|
user=self.user_requestor,
|
||||||
|
group=self.group_2,
|
||||||
|
leave_request=True
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
GroupManager.pending_requests_count_for_user(self.user_leader_2), 2
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_single_request_for_user_with_management_perm(self):
|
||||||
|
# given user_leader_4 which is leafer of no group
|
||||||
|
# but has the management permissions
|
||||||
|
# when user_requestor is requesting access to group 1
|
||||||
|
# then return 1 for user_leader_4
|
||||||
|
user_leader_4 = AuthUtils.create_member("Lex Luther")
|
||||||
|
AuthUtils.add_permission_to_user_by_name("auth.group_management", user_leader_4)
|
||||||
|
user_leader_4 = User.objects.get(pk=user_leader_4.pk)
|
||||||
|
GroupRequest.objects.create(
|
||||||
|
status="pending", user=self.user_requestor, group=self.group_1
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
GroupManager.pending_requests_count_for_user(self.user_leader_1), 1
|
||||||
|
)
|
||||||
|
|||||||
@@ -1,61 +1,100 @@
|
|||||||
from unittest import mock
|
|
||||||
|
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
from django.contrib.auth.models import User, Group
|
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 allianceauth.tests.auth_utils import AuthUtils
|
||||||
|
|
||||||
from ..signals import check_groups_on_state_change
|
|
||||||
|
|
||||||
|
class TestCheckGroupsOnStateChange(TestCase):
|
||||||
class GroupManagementStateTestCase(TestCase):
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpTestData(cls):
|
def setUpTestData(cls):
|
||||||
cls.user = AuthUtils.create_user('test')
|
cls.user = AuthUtils.create_user('test')
|
||||||
AuthUtils.add_main_character(
|
cls.character = AuthUtils.add_main_character_2(
|
||||||
cls.user, 'test character', '1', corp_id='2', corp_name='test_corp', corp_ticker='TEST', alliance_id='3', alliance_name='TEST'
|
cls.user, 'test character', 1001, corp_id=2001, corp_name='test corp 1', corp_ticker='TEST'
|
||||||
)
|
)
|
||||||
cls.user.profile.refresh_from_db()
|
cls.user.profile.refresh_from_db()
|
||||||
cls.alliance = EveAllianceInfo.objects.create(
|
cls.corp_1 = EveCorporationInfo.objects.create(
|
||||||
alliance_id='3', alliance_name='test alliance', alliance_ticker='TEST', executor_corp_id='2'
|
corporation_id=2001, corporation_name='test corp 1', corporation_ticker='C1', member_count=1
|
||||||
)
|
)
|
||||||
cls.corp = EveCorporationInfo.objects.create(
|
cls.corp_2 = EveCorporationInfo.objects.create(
|
||||||
corporation_id='2', corporation_name='test corp', corporation_ticker='TEST', alliance=cls.alliance, member_count=1
|
corporation_id=2002, corporation_name='test corp 2', corporation_ticker='C2', member_count=1
|
||||||
)
|
)
|
||||||
cls.state_group = Group.objects.create(name='state_group')
|
cls.guest_state = AuthUtils.get_guest_state()
|
||||||
cls.open_group = Group.objects.create(name='open_group')
|
cls.test_state_1 = AuthUtils.create_state('test_state_1', 500)
|
||||||
cls.state = AuthUtils.create_state('test state', 500)
|
cls.test_state_2 = AuthUtils.create_state('test_state_2', 600)
|
||||||
cls.state_group.authgroup.states.add(cls.state)
|
|
||||||
cls.state_group.authgroup.internal = False
|
|
||||||
cls.state_group.save()
|
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.user.refresh_from_db()
|
self.user.refresh_from_db()
|
||||||
self.state.refresh_from_db()
|
|
||||||
|
|
||||||
def _refresh_user(self):
|
def _refresh_user(self):
|
||||||
self.user = User.objects.get(pk=self.user.pk)
|
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):
|
def test_drop_state_group(self):
|
||||||
self.user.groups.add(self.open_group)
|
"""
|
||||||
self.user.groups.add(self.state_group)
|
given user is member of: state group, normal group and auto group
|
||||||
self.assertEqual(self.user.profile.state.name, "Guest")
|
when user looses state
|
||||||
|
then user is automatically kicked from state group
|
||||||
self.state.member_corporations.add(self.corp)
|
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._refresh_user()
|
||||||
self.assertEqual(self.user.profile.state, self.state)
|
self.assertEqual(self.user.profile.state, self.guest_state)
|
||||||
groups = self.user.groups.all()
|
groups = self.user.groups.all()
|
||||||
self.assertIn(self.state_group, groups) #keeps group
|
self.assertNotIn(state_group, groups) # looses state group
|
||||||
self.assertIn(self.open_group, groups) #public group unafected
|
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._refresh_user()
|
||||||
self.assertEqual(self.user.profile.state.name, "Guest")
|
self.assertEqual(self.user.profile.state, self.test_state_2)
|
||||||
groups = self.user.groups.all()
|
groups = self.user.groups.all()
|
||||||
self.assertNotIn(self.state_group, groups) #looses group
|
self.assertIn(state_group, groups)
|
||||||
self.assertIn(self.open_group, groups) #public group unafected
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
from unittest.mock import patch
|
|
||||||
|
|
||||||
from django.test import TestCase
|
|
||||||
from allianceauth.tests.auth_utils import AuthUtils
|
|
||||||
|
|
||||||
from ..templatetags.groupmanagement import can_manage_groups
|
|
||||||
|
|
||||||
MODULE_PATH = 'allianceauth.groupmanagement.templatetags.groupmanagement'
|
|
||||||
|
|
||||||
|
|
||||||
@patch(MODULE_PATH + '.GroupManager.can_manage_groups')
|
|
||||||
class TestCanManageGroups(TestCase):
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
self.user = AuthUtils.create_user('Bruce Wayne')
|
|
||||||
|
|
||||||
def test_return_normal_result(self, mock_can_manage_groups):
|
|
||||||
mock_can_manage_groups.return_value = True
|
|
||||||
|
|
||||||
self.assertTrue(can_manage_groups(self.user))
|
|
||||||
self.assertTrue(mock_can_manage_groups.called)
|
|
||||||
|
|
||||||
def test_return_false_if_not_user(self, mock_can_manage_groups):
|
|
||||||
mock_can_manage_groups.return_value = True
|
|
||||||
|
|
||||||
self.assertFalse(can_manage_groups('invalid'))
|
|
||||||
self.assertFalse(mock_can_manage_groups.called)
|
|
||||||
@@ -1,32 +1,52 @@
|
|||||||
from . import views
|
from . import views
|
||||||
|
|
||||||
from django.conf.urls import include, url
|
from django.conf.urls import url
|
||||||
app_name = 'groupmanagement'
|
|
||||||
|
app_name = "groupmanagement"
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^groups/', views.groups_view, name='groups'),
|
# groups
|
||||||
url(r'^group/', include([
|
url(r"^groups/$", views.groups_view, name="groups"),
|
||||||
url(r'^management/', views.group_management,
|
url(r"^group/request/join/(\w+)/$", views.group_request_add, name="request_add"),
|
||||||
name='management'),
|
url(
|
||||||
url(r'^membership/$', views.group_membership,
|
r"^group/request/leave/(\w+)/$", views.group_request_leave, name="request_leave"
|
||||||
name='membership'),
|
),
|
||||||
url(r'^membership/(\w+)/$', views.group_membership_list,
|
# group management
|
||||||
name='membership_list'),
|
url(r"^groupmanagement/requests/$", views.group_management, name="management"),
|
||||||
url(r'^membership/(\w+)/audit/$', views.group_membership_audit, name="audit_log"),
|
url(r"^groupmanagement/membership/$", views.group_membership, name="membership"),
|
||||||
url(r'^membership/(\w+)/remove/(\w+)/$', views.group_membership_remove,
|
url(
|
||||||
name='membership_remove'),
|
r"^groupmanagement/membership/(\w+)/$",
|
||||||
url(r'^request_add/(\w+)', views.group_request_add,
|
views.group_membership_list,
|
||||||
name='request_add'),
|
name="membership",
|
||||||
url(r'^request/accept/(\w+)', views.group_accept_request,
|
),
|
||||||
name='accept_request'),
|
url(
|
||||||
url(r'^request/reject/(\w+)', views.group_reject_request,
|
r"^groupmanagement/membership/(\w+)/audit-log/$",
|
||||||
name='reject_request'),
|
views.group_membership_audit,
|
||||||
|
name="audit_log",
|
||||||
url(r'^request_leave/(\w+)', views.group_request_leave,
|
),
|
||||||
name='request_leave'),
|
url(
|
||||||
url(r'leave_request/accept/(\w+)', views.group_leave_accept_request,
|
r"^groupmanagement/membership/(\w+)/remove/(\w+)/$",
|
||||||
name='leave_accept_request'),
|
views.group_membership_remove,
|
||||||
url(r'^leave_request/reject/(\w+)', views.group_leave_reject_request,
|
name="membership_remove",
|
||||||
name='leave_reject_request'),
|
),
|
||||||
])),
|
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",
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ def group_membership_list(request, group_id):
|
|||||||
|
|
||||||
# Check its a joinable group i.e. not corp or internal
|
# Check its a joinable group i.e. not corp or internal
|
||||||
# And the user has permission to manage it
|
# 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)
|
or not GroupManager.can_manage_group(request.user, group)
|
||||||
):
|
):
|
||||||
logger.warning(
|
logger.warning(
|
||||||
@@ -132,7 +132,7 @@ def group_membership_list(request, group_id):
|
|||||||
render_items = {'group': group, 'members': members}
|
render_items = {'group': group, 'members': members}
|
||||||
|
|
||||||
return render(
|
return render(
|
||||||
request, 'groupmanagement/groupmembers.html',
|
request, 'groupmanagement/groupmembers.html',
|
||||||
context=render_items
|
context=render_items
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -166,7 +166,7 @@ def group_membership_remove(request, group_id, user_id):
|
|||||||
except ObjectDoesNotExist:
|
except ObjectDoesNotExist:
|
||||||
messages.warning(request, _("Group does not exist"))
|
messages.warning(request, _("Group does not exist"))
|
||||||
|
|
||||||
return redirect('groupmanagement:membership_list', group_id)
|
return redirect('groupmanagement:membership', group_id)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@@ -312,18 +312,18 @@ def group_leave_reject_request(request, group_request_id):
|
|||||||
@login_required
|
@login_required
|
||||||
def groups_view(request):
|
def groups_view(request):
|
||||||
logger.debug("groups_view called by user %s" % request.user)
|
logger.debug("groups_view called by user %s" % request.user)
|
||||||
|
|
||||||
groups_qs = GroupManager.get_joinable_groups_for_user(
|
groups_qs = GroupManager.get_joinable_groups_for_user(
|
||||||
request.user, include_hidden=False
|
request.user, include_hidden=False
|
||||||
)
|
)
|
||||||
groups_qs = groups_qs.order_by('name')
|
groups_qs = groups_qs.order_by('name')
|
||||||
groups = []
|
groups = []
|
||||||
for group in groups_qs:
|
for group in groups_qs:
|
||||||
group_request = GroupRequest.objects\
|
group_request = GroupRequest.objects\
|
||||||
.filter(user=request.user)\
|
.filter(user=request.user)\
|
||||||
.filter(group=group)
|
.filter(group=group)
|
||||||
groups.append({
|
groups.append({
|
||||||
'group': group,
|
'group': group,
|
||||||
'request': group_request[0] if group_request else None
|
'request': group_request[0] if group_request else None
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -356,6 +356,9 @@ def group_request_add(request, group_id):
|
|||||||
if group.authgroup.open:
|
if group.authgroup.open:
|
||||||
logger.info("%s joining %s as is an open group" % (request.user, group))
|
logger.info("%s joining %s as is an open group" % (request.user, group))
|
||||||
request.user.groups.add(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")
|
return redirect("groupmanagement:groups")
|
||||||
req = GroupRequest.objects.filter(user=request.user, group=group)
|
req = GroupRequest.objects.filter(user=request.user, group=group)
|
||||||
if len(req) > 0:
|
if len(req) > 0:
|
||||||
@@ -389,6 +392,9 @@ def group_request_leave(request, group_id):
|
|||||||
return redirect('groupmanagement:groups')
|
return redirect('groupmanagement:groups')
|
||||||
if group.authgroup.open:
|
if group.authgroup.open:
|
||||||
logger.info("%s leaving %s as is an open group" % (request.user, group))
|
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)
|
request.user.groups.remove(group)
|
||||||
return redirect("groupmanagement:groups")
|
return redirect("groupmanagement:groups")
|
||||||
req = GroupRequest.objects.filter(user=request.user, group=group)
|
req = GroupRequest.objects.filter(user=request.user, group=group)
|
||||||
@@ -398,6 +404,9 @@ def group_request_leave(request, group_id):
|
|||||||
return redirect("groupmanagement:groups")
|
return redirect("groupmanagement:groups")
|
||||||
if getattr(settings, 'AUTO_LEAVE', False):
|
if getattr(settings, 'AUTO_LEAVE', False):
|
||||||
logger.info("%s leaving joinable group %s due to auto_leave" % (request.user, group))
|
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)
|
request.user.groups.remove(group)
|
||||||
return redirect('groupmanagement:groups')
|
return redirect('groupmanagement:groups')
|
||||||
grouprequest = GroupRequest()
|
grouprequest = GroupRequest()
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
from allianceauth.services.hooks import MenuItemHook, UrlHook
|
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from allianceauth import hooks
|
from allianceauth import hooks
|
||||||
from allianceauth.hrapplications import urls
|
from allianceauth.services.hooks import MenuItemHook, UrlHook
|
||||||
|
|
||||||
|
from . import urls
|
||||||
|
from .models import Application
|
||||||
|
|
||||||
|
|
||||||
class ApplicationsMenu(MenuItemHook):
|
class ApplicationsMenu(MenuItemHook):
|
||||||
@@ -12,6 +15,11 @@ class ApplicationsMenu(MenuItemHook):
|
|||||||
'hrapplications:index',
|
'hrapplications:index',
|
||||||
navactive=['hrapplications:'])
|
navactive=['hrapplications:'])
|
||||||
|
|
||||||
|
def render(self, request):
|
||||||
|
app_count = Application.objects.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)
|
||||||
|
|
||||||
|
|
||||||
@hooks.register('menu_item_hook')
|
@hooks.register('menu_item_hook')
|
||||||
def register_menu():
|
def register_menu():
|
||||||
|
|||||||
25
allianceauth/hrapplications/managers.py
Normal file
25
allianceauth/hrapplications/managers.py
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
from django.contrib.auth.models import User
|
||||||
|
from django.db import models
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
|
||||||
|
class ApplicationManager(models.Manager):
|
||||||
|
|
||||||
|
def pending_requests_count_for_user(self, user: User) -> Optional[int]:
|
||||||
|
"""Returns the number of pending group requests for the given user"""
|
||||||
|
if user.is_superuser:
|
||||||
|
return self.filter(approved__isnull=True).count()
|
||||||
|
elif user.has_perm("auth.human_resources"):
|
||||||
|
main_character = user.profile.main_character
|
||||||
|
if main_character:
|
||||||
|
return (
|
||||||
|
self
|
||||||
|
.select_related("form__corp")
|
||||||
|
.filter(form__corp__corporation_id=main_character.corporation_id)
|
||||||
|
.filter(approved__isnull=True)
|
||||||
|
.count()
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
return None
|
||||||
@@ -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),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -2,8 +2,9 @@ from django.contrib.auth.models import User
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
from sortedm2m.fields import SortedManyToManyField
|
from sortedm2m.fields import SortedManyToManyField
|
||||||
|
|
||||||
from allianceauth.eveonline.models import EveCharacter
|
from allianceauth.eveonline.models import EveCharacter, EveCorporationInfo
|
||||||
from allianceauth.eveonline.models import EveCorporationInfo
|
|
||||||
|
from .managers import ApplicationManager
|
||||||
|
|
||||||
|
|
||||||
class ApplicationQuestion(models.Model):
|
class ApplicationQuestion(models.Model):
|
||||||
@@ -22,6 +23,7 @@ class ApplicationChoice(models.Model):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.choice_text
|
return self.choice_text
|
||||||
|
|
||||||
|
|
||||||
class ApplicationForm(models.Model):
|
class ApplicationForm(models.Model):
|
||||||
questions = SortedManyToManyField(ApplicationQuestion)
|
questions = SortedManyToManyField(ApplicationQuestion)
|
||||||
corp = models.OneToOneField(EveCorporationInfo, on_delete=models.CASCADE)
|
corp = models.OneToOneField(EveCorporationInfo, on_delete=models.CASCADE)
|
||||||
@@ -33,11 +35,13 @@ class ApplicationForm(models.Model):
|
|||||||
class Application(models.Model):
|
class Application(models.Model):
|
||||||
form = models.ForeignKey(ApplicationForm, on_delete=models.CASCADE, related_name='applications')
|
form = models.ForeignKey(ApplicationForm, on_delete=models.CASCADE, related_name='applications')
|
||||||
user = models.ForeignKey(User, 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 = 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)
|
reviewer_character = models.ForeignKey(EveCharacter, on_delete=models.SET_NULL, blank=True, null=True)
|
||||||
created = models.DateTimeField(auto_now_add=True)
|
created = models.DateTimeField(auto_now_add=True)
|
||||||
|
|
||||||
|
objects = ApplicationManager()
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return str(self.user) + " Application To " + str(self.form)
|
return str(self.user) + " Application To " + str(self.form)
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{% extends "allianceauth/base.html" %}
|
{% extends "allianceauth/base.html" %}
|
||||||
{% load staticfiles %}
|
{% load static %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block page_title %}{% trans "Choose a Corp" %}{% endblock page_title %}
|
{% block page_title %}{% trans "Choose a Corp" %}{% endblock page_title %}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{% extends "allianceauth/base.html" %}
|
{% extends "allianceauth/base.html" %}
|
||||||
{% load staticfiles %}
|
{% load static %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block page_title %}{% trans "Apply To" %} {{ corp.corporation_name }}{% endblock page_title %}
|
{% block page_title %}{% trans "Apply To" %} {{ corp.corporation_name }}{% endblock page_title %}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{% extends "allianceauth/base.html" %}
|
{% extends "allianceauth/base.html" %}
|
||||||
{% load bootstrap %}
|
{% load bootstrap %}
|
||||||
{% load staticfiles %}
|
{% load static %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block page_title %}{% trans "HR Application Management" %}{% endblock page_title %}
|
{% block page_title %}{% trans "HR Application Management" %}{% endblock page_title %}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{% extends "allianceauth/base.html" %}
|
{% extends "allianceauth/base.html" %}
|
||||||
{% load bootstrap %}
|
{% load bootstrap %}
|
||||||
{% load staticfiles %}
|
{% load static %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block page_title %}HR Application Management{% endblock page_title %}
|
{% block page_title %}HR Application Management{% endblock page_title %}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{% extends "allianceauth/base.html" %}
|
{% extends "allianceauth/base.html" %}
|
||||||
{% load staticfiles %}
|
{% load static %}
|
||||||
{% load bootstrap %}
|
{% load bootstrap %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1,103 @@
|
|||||||
# Create your tests here.
|
from django.contrib.auth.models import User
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
from allianceauth.eveonline.models import EveCorporationInfo
|
||||||
|
from allianceauth.tests.auth_utils import AuthUtils
|
||||||
|
|
||||||
|
from .models import Application, ApplicationForm, ApplicationQuestion, ApplicationChoice
|
||||||
|
|
||||||
|
|
||||||
|
class TestApplicationManagersPendingRequestsCountForUser(TestCase):
|
||||||
|
def setUp(self) -> None:
|
||||||
|
self.corporation_1 = EveCorporationInfo.objects.create(
|
||||||
|
corporation_id=2001, corporation_name="Wayne Tech", member_count=42
|
||||||
|
)
|
||||||
|
self.corporation_2 = EveCorporationInfo.objects.create(
|
||||||
|
corporation_id=2011, corporation_name="Lex Corp", member_count=666
|
||||||
|
)
|
||||||
|
question = ApplicationQuestion.objects.create(title="Dummy Question")
|
||||||
|
ApplicationChoice.objects.create(question=question, choice_text="yes")
|
||||||
|
ApplicationChoice.objects.create(question=question, choice_text="no")
|
||||||
|
self.form_corporation_1 = ApplicationForm.objects.create(
|
||||||
|
corp=self.corporation_1
|
||||||
|
)
|
||||||
|
self.form_corporation_1.questions.add(question)
|
||||||
|
self.form_corporation_2 = ApplicationForm.objects.create(
|
||||||
|
corp=self.corporation_2
|
||||||
|
)
|
||||||
|
self.form_corporation_2.questions.add(question)
|
||||||
|
|
||||||
|
self.user_requestor = AuthUtils.create_member("Peter Parker")
|
||||||
|
|
||||||
|
self.user_manager = AuthUtils.create_member("Bruce Wayne")
|
||||||
|
AuthUtils.add_main_character_2(
|
||||||
|
self.user_manager,
|
||||||
|
self.user_manager.username,
|
||||||
|
1001,
|
||||||
|
self.corporation_1.corporation_id,
|
||||||
|
self.corporation_1.corporation_name,
|
||||||
|
)
|
||||||
|
AuthUtils.add_permission_to_user_by_name(
|
||||||
|
"auth.human_resources", self.user_manager
|
||||||
|
)
|
||||||
|
self.user_manager = User.objects.get(pk=self.user_manager.pk)
|
||||||
|
|
||||||
|
def test_no_pending_application(self):
|
||||||
|
# given manager of corporation 1 has permission
|
||||||
|
# when no application is pending for corporation 1
|
||||||
|
# return 0
|
||||||
|
self.assertEqual(
|
||||||
|
Application.objects.pending_requests_count_for_user(self.user_manager), 0
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_single_pending_application(self):
|
||||||
|
# given manager of corporation 1 has permission
|
||||||
|
# when 1 application is pending for corporation 1
|
||||||
|
# return 1
|
||||||
|
Application.objects.create(
|
||||||
|
form=self.form_corporation_1, user=self.user_requestor
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
Application.objects.pending_requests_count_for_user(self.user_manager), 1
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_user_has_no_permission(self):
|
||||||
|
# given user has no permission
|
||||||
|
# when 1 application is pending
|
||||||
|
# return None
|
||||||
|
self.assertIsNone(
|
||||||
|
Application.objects.pending_requests_count_for_user(self.user_requestor)
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_two_pending_applications_for_different_corporations_normal_manager(self):
|
||||||
|
# given manager of corporation 1 has permission
|
||||||
|
# when 1 application is pending for corporation 1
|
||||||
|
# and 1 application is pending for corporation 2
|
||||||
|
# return 1
|
||||||
|
Application.objects.create(
|
||||||
|
form=self.form_corporation_1, user=self.user_requestor
|
||||||
|
)
|
||||||
|
Application.objects.create(
|
||||||
|
form=self.form_corporation_2, user=self.user_requestor
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
Application.objects.pending_requests_count_for_user(self.user_manager), 1
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_two_pending_applications_for_different_corporations_manager_is_super(self):
|
||||||
|
# given manager of corporation 1 has permission
|
||||||
|
# when 1 application is pending for corporation 1
|
||||||
|
# and 1 application is pending for corporation 2
|
||||||
|
# return 1
|
||||||
|
Application.objects.create(
|
||||||
|
form=self.form_corporation_1, user=self.user_requestor
|
||||||
|
)
|
||||||
|
Application.objects.create(
|
||||||
|
form=self.form_corporation_2, user=self.user_requestor
|
||||||
|
)
|
||||||
|
superuser = User.objects.create_superuser(
|
||||||
|
"Superman", "superman@example.com", "password"
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
Application.objects.pending_requests_count_for_user(superuser), 2
|
||||||
|
)
|
||||||
|
|||||||
Binary file not shown.
@@ -6,16 +6,16 @@
|
|||||||
# Translators:
|
# Translators:
|
||||||
# Erik Kalkoken <erik.kalkoken@gmail.com>, 2020
|
# Erik Kalkoken <erik.kalkoken@gmail.com>, 2020
|
||||||
# Joel Falknau <ozirascal@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
|
#, fuzzy
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \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"
|
"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"
|
"Language-Team: German (https://www.transifex.com/alliance-auth/teams/107430/de/)\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
@@ -28,74 +28,74 @@ msgid "A main character is required to perform that action. Add one below."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Für diese Aktion wird ein Hauptcharacter benötigt. Bitte füge einen hinzu."
|
"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"
|
msgid "Email"
|
||||||
msgstr "E-Mail"
|
msgstr "E-Mail"
|
||||||
|
|
||||||
#: allianceauth/authentication/models.py:76
|
#: allianceauth/authentication/models.py:78
|
||||||
msgid "State Changed"
|
|
||||||
msgstr "Status geändert"
|
|
||||||
|
|
||||||
#: allianceauth/authentication/models.py:77
|
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Your user state has been changed to %(state)s"
|
msgid "State changed to: %s"
|
||||||
msgstr "Dein Nutzerstatus hat sich geändert zu %(state)s"
|
msgstr "Status geändert zu %s"
|
||||||
|
|
||||||
|
#: allianceauth/authentication/models.py:79
|
||||||
|
#, python-format
|
||||||
|
msgid "Your user's state is now: %(state)s"
|
||||||
|
msgstr "Dein Nutzerstatus ist nun %(state)s"
|
||||||
|
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:5
|
#: allianceauth/authentication/templates/authentication/dashboard.html:5
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:8
|
#: allianceauth/authentication/templates/authentication/dashboard.html:8
|
||||||
#: allianceauth/templates/allianceauth/side-menu.html:10
|
#: allianceauth/templates/allianceauth/side-menu.html:11
|
||||||
msgid "Dashboard"
|
msgid "Dashboard"
|
||||||
msgstr "Dashboard"
|
msgstr "Dashboard"
|
||||||
|
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:17
|
#: allianceauth/authentication/templates/authentication/dashboard.html:18
|
||||||
#: allianceauth/corputils/templates/corputils/corpstats.html:116
|
#, python-format
|
||||||
#: allianceauth/corputils/templates/corputils/search.html:16
|
msgid ""
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticscorpview.html:22
|
"\n"
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:83
|
" Main Character (State: %(state)s)\n"
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:128
|
" "
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:25
|
msgstr ""
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:32
|
"\n"
|
||||||
msgid "Main Character"
|
"Hauptcharakter (Status: %(state)s)"
|
||||||
msgstr "Hauptcharakter"
|
|
||||||
|
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:77
|
#: allianceauth/authentication/templates/authentication/dashboard.html:81
|
||||||
msgid "No main character set."
|
msgid "No main character set."
|
||||||
msgstr "Kein Hauptcharakter gesetzt."
|
msgstr "Kein Hauptcharakter gesetzt."
|
||||||
|
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:84
|
#: allianceauth/authentication/templates/authentication/dashboard.html:88
|
||||||
msgid "Add Character"
|
msgid "Add Character"
|
||||||
msgstr "Charakter hinzufügen"
|
msgstr "Charakter hinzufügen"
|
||||||
|
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:88
|
#: allianceauth/authentication/templates/authentication/dashboard.html:92
|
||||||
msgid "Change Main"
|
msgid "Change Main"
|
||||||
msgstr "Hauptcharakter ändern"
|
msgstr "Hauptcharakter ändern"
|
||||||
|
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:97
|
#: allianceauth/authentication/templates/authentication/dashboard.html:101
|
||||||
msgid "Group Memberships"
|
msgid "Group Memberships"
|
||||||
msgstr "Gruppen"
|
msgstr "Gruppen"
|
||||||
|
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:117
|
#: allianceauth/authentication/templates/authentication/dashboard.html:121
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticscorpview.html:23
|
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticscorpview.html:23
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:41
|
#: allianceauth/hrapplications/templates/hrapplications/view.html:41
|
||||||
msgid "Characters"
|
msgid "Characters"
|
||||||
msgstr "Charaktere"
|
msgstr "Charaktere"
|
||||||
|
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:125
|
#: allianceauth/authentication/templates/authentication/dashboard.html:129
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:73
|
#: 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/groupmanagement/templates/groupmanagement/groups.html:15
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:45
|
#: allianceauth/hrapplications/templates/hrapplications/view.html:45
|
||||||
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:34
|
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:34
|
||||||
msgid "Name"
|
msgid "Name"
|
||||||
msgstr "Name"
|
msgstr "Name"
|
||||||
|
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:126
|
#: allianceauth/authentication/templates/authentication/dashboard.html:130
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticsview.html:23
|
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticsview.html:23
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:46
|
#: allianceauth/hrapplications/templates/hrapplications/view.html:46
|
||||||
msgid "Corp"
|
msgid "Corp"
|
||||||
msgstr "Corp"
|
msgstr "Corp"
|
||||||
|
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:127
|
#: allianceauth/authentication/templates/authentication/dashboard.html:131
|
||||||
#: allianceauth/corputils/templates/corputils/corpstats.html:77
|
#: allianceauth/corputils/templates/corputils/corpstats.html:77
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:47
|
#: allianceauth/hrapplications/templates/hrapplications/view.html:47
|
||||||
msgid "Alliance"
|
msgid "Alliance"
|
||||||
@@ -168,11 +168,11 @@ msgstr ""
|
|||||||
msgid "Unable to authenticate as the selected character."
|
msgid "Unable to authenticate as the selected character."
|
||||||
msgstr "Authentifizierung mit dem ausgewählten Charakter nicht möglich."
|
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."
|
msgid "Registration token has expired."
|
||||||
msgstr "Token zur Registrierung ist abgelaufen."
|
msgstr "Token zur Registrierung ist abgelaufen."
|
||||||
|
|
||||||
#: allianceauth/authentication/views.py:200
|
#: allianceauth/authentication/views.py:206
|
||||||
msgid ""
|
msgid ""
|
||||||
"Sent confirmation email. Please follow the link to confirm your email "
|
"Sent confirmation email. Please follow the link to confirm your email "
|
||||||
"address."
|
"address."
|
||||||
@@ -180,13 +180,13 @@ msgstr ""
|
|||||||
"Bestätigungsmail gesendet. Bitte folge dem Link in der E-Mail zur "
|
"Bestätigungsmail gesendet. Bitte folge dem Link in der E-Mail zur "
|
||||||
"Bestätigung."
|
"Bestätigung."
|
||||||
|
|
||||||
#: allianceauth/authentication/views.py:205
|
#: allianceauth/authentication/views.py:211
|
||||||
msgid "Confirmed your email address. Please login to continue."
|
msgid "Confirmed your email address. Please login to continue."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Deine E-Mail Adresse wurde bestätigt. Bitte log Dich ein um fortzufahren."
|
"Deine E-Mail Adresse wurde bestätigt. Bitte log Dich ein um fortzufahren."
|
||||||
|
|
||||||
#: allianceauth/authentication/views.py:210
|
#: allianceauth/authentication/views.py:216
|
||||||
msgid "Registraion of new accounts it not allowed at this time."
|
msgid "Registration of new accounts is not allowed at this time."
|
||||||
msgstr "Registrierung von neuen Konten ist zur Zeit nicht erlaubt."
|
msgstr "Registrierung von neuen Konten ist zur Zeit nicht erlaubt."
|
||||||
|
|
||||||
#: allianceauth/corputils/auth_hooks.py:10
|
#: allianceauth/corputils/auth_hooks.py:10
|
||||||
@@ -234,16 +234,16 @@ msgstr "Letzes Update:"
|
|||||||
#: allianceauth/corputils/templates/corputils/search.html:13
|
#: allianceauth/corputils/templates/corputils/search.html:13
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html:24
|
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html:24
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:28
|
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:28
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:27
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:30
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:29
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:30
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:37
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:51
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:96
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:109
|
||||||
msgid "Character"
|
msgid "Character"
|
||||||
msgstr "Charakter"
|
msgstr "Charakter"
|
||||||
|
|
||||||
#: allianceauth/corputils/templates/corputils/corpstats.html:76
|
#: allianceauth/corputils/templates/corputils/corpstats.html:76
|
||||||
#: allianceauth/corputils/templates/corputils/search.html:14
|
#: 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:27
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:84
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:84
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:129
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:129
|
||||||
@@ -259,6 +259,16 @@ msgstr "Corporation"
|
|||||||
msgid "Killboard"
|
msgid "Killboard"
|
||||||
msgstr "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 "Hauptcharakter"
|
||||||
|
|
||||||
#: allianceauth/corputils/templates/corputils/corpstats.html:117
|
#: allianceauth/corputils/templates/corputils/corpstats.html:117
|
||||||
#: allianceauth/corputils/templates/corputils/search.html:17
|
#: allianceauth/corputils/templates/corputils/search.html:17
|
||||||
msgid "Main Corporation"
|
msgid "Main Corporation"
|
||||||
@@ -542,31 +552,35 @@ msgstr "Flottenteilnahme registriert."
|
|||||||
msgid "FAT link has expired."
|
msgid "FAT link has expired."
|
||||||
msgstr "FAT-Link ist abgelaufen."
|
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:5
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:13
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:14
|
||||||
msgid "Audit Log"
|
msgid "Audit Log"
|
||||||
msgstr "Protokoll"
|
msgstr "Protokoll"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:18
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:20
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:20
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:21
|
||||||
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:13
|
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:13
|
||||||
msgid "Back"
|
msgid "Back"
|
||||||
msgstr "Zurück"
|
msgstr "Zurück"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:25
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:28
|
||||||
msgid "Date/Time"
|
msgid "Date/Time"
|
||||||
msgstr "Datum/Uhrzeit"
|
msgstr "Datum/Uhrzeit"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:26
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:29
|
||||||
msgid "Requestor"
|
msgid "Requestor"
|
||||||
msgstr "Antragsteller"
|
msgstr "Antragsteller"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:29
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:32
|
||||||
msgid "Type"
|
msgid "Type"
|
||||||
msgstr "Typ"
|
msgstr "Typ"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:30
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:33
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:17
|
|
||||||
#: allianceauth/notifications/templates/notifications/list.html:37
|
#: allianceauth/notifications/templates/notifications/list.html:37
|
||||||
#: allianceauth/notifications/templates/notifications/list.html:69
|
#: allianceauth/notifications/templates/notifications/list.html:69
|
||||||
#: allianceauth/optimer/templates/optimer/fleetoptable.html:18
|
#: allianceauth/optimer/templates/optimer/fleetoptable.html:18
|
||||||
@@ -577,11 +591,19 @@ msgstr "Typ"
|
|||||||
msgid "Action"
|
msgid "Action"
|
||||||
msgstr "Aktion"
|
msgstr "Aktion"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:31
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:34
|
||||||
msgid "Actor"
|
msgid "Actor"
|
||||||
msgstr "Ausführender"
|
msgstr "Ausführender"
|
||||||
|
|
||||||
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:47
|
||||||
|
msgid "Removed"
|
||||||
|
msgstr "Entfernt"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:59
|
#: 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."
|
msgid "No entries found for this group."
|
||||||
msgstr "Keine Einträge für diese Gruppe gefunden."
|
msgstr "Keine Einträge für diese Gruppe gefunden."
|
||||||
|
|
||||||
@@ -589,22 +611,24 @@ msgstr "Keine Einträge für diese Gruppe gefunden."
|
|||||||
msgid "Group Members"
|
msgid "Group Members"
|
||||||
msgstr "Gruppenmitglieder"
|
msgstr "Gruppenmitglieder"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:28
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:31
|
||||||
msgid "Portrait"
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:52
|
||||||
msgstr "Portrait"
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:110
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:30
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:38
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:97
|
|
||||||
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:23
|
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:23
|
||||||
msgid "Organization"
|
msgid "Organization"
|
||||||
msgstr "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"
|
msgid "Remove from group"
|
||||||
msgstr "Aus Gruppe entfernen"
|
msgstr "Aus Gruppe entfernen"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:76
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:81
|
||||||
msgid "No group members to list."
|
msgid "No group members to list."
|
||||||
msgstr "Keine Gruppenmitglieder vorhanden."
|
msgstr "Keine Gruppenmitglieder vorhanden."
|
||||||
|
|
||||||
@@ -612,56 +636,56 @@ msgstr "Keine Gruppenmitglieder vorhanden."
|
|||||||
msgid "Groups Membership"
|
msgid "Groups Membership"
|
||||||
msgstr "Gruppenmitgliedschaft"
|
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/permissions_tool/templates/permissions_tool/overview.html:40
|
||||||
#: allianceauth/templates/allianceauth/side-menu.html:15
|
#: allianceauth/templates/allianceauth/side-menu.html:16
|
||||||
msgid "Groups"
|
msgid "Groups"
|
||||||
msgstr "Gruppen"
|
msgstr "Gruppen"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:23
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:25
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:16
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:16
|
||||||
msgid "Description"
|
msgid "Description"
|
||||||
msgstr "Beschreibung"
|
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:28
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:85
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:85
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:130
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:130
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:27
|
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:27
|
||||||
#: allianceauth/srp/templates/srp/data.html:97
|
#: allianceauth/srp/templates/srp/data.html:98
|
||||||
msgid "Status"
|
msgid "Status"
|
||||||
msgstr "Status"
|
msgstr "Status"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:25
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:27
|
||||||
msgid "Member Count"
|
msgid "Member Count"
|
||||||
msgstr "Mitgliederzahl"
|
msgstr "Mitgliederzahl"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:38
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:43
|
||||||
msgid "Hidden"
|
msgid "Hidden"
|
||||||
msgstr "Verborgen"
|
msgstr "Verborgen"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:40
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:45
|
||||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:12
|
#: allianceauth/templates/allianceauth/admin-status/overview.html:12
|
||||||
msgid "Open"
|
msgid "Open"
|
||||||
msgstr "Öffnen"
|
msgstr "Öffnen"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:42
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:47
|
||||||
msgid "Requestable"
|
msgid "Requestable"
|
||||||
msgstr "Anfragbar"
|
msgstr "Anfragbar"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:50
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:56
|
||||||
msgid "View Members"
|
msgid "View Members"
|
||||||
msgstr "Mitglieder ansehen"
|
msgstr "Mitglieder ansehen"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:53
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:60
|
||||||
msgid "Audit Members"
|
msgid "Audit Members"
|
||||||
msgstr "Mitglieder Protokoll"
|
msgstr "Mitglieder Protokoll"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:56
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:64
|
||||||
msgid "Copy Direrct Join Link"
|
msgid "Copy Direct Join Link"
|
||||||
msgstr ""
|
msgstr "Direktlink kopieren"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:68
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:75
|
||||||
msgid "No groups to list."
|
msgid "No groups to list."
|
||||||
msgstr "Keine Gruppen vorhanden."
|
msgstr "Keine Gruppen vorhanden."
|
||||||
|
|
||||||
@@ -670,19 +694,19 @@ msgstr "Keine Gruppen vorhanden."
|
|||||||
msgid "Available Groups"
|
msgid "Available Groups"
|
||||||
msgstr "Verfügbare Gruppen"
|
msgstr "Verfügbare Gruppen"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:29
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:30
|
||||||
msgid "Leave"
|
msgid "Leave"
|
||||||
msgstr "Verlassen"
|
msgstr "Verlassen"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:39
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:40
|
||||||
msgid "Join"
|
msgid "Join"
|
||||||
msgstr "Beitreten"
|
msgstr "Beitreten"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:43
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:44
|
||||||
msgid "Request"
|
msgid "Request"
|
||||||
msgstr "Anfrage"
|
msgstr "Anfrage"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:58
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:59
|
||||||
msgid "No groups available."
|
msgid "No groups available."
|
||||||
msgstr "Keine Gruppen verfügbar"
|
msgstr "Keine Gruppen verfügbar"
|
||||||
|
|
||||||
@@ -690,77 +714,72 @@ msgstr "Keine Gruppen verfügbar"
|
|||||||
msgid "Groups Management"
|
msgid "Groups Management"
|
||||||
msgstr "Gruppenverwaltung"
|
msgstr "Gruppenverwaltung"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:23
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:25
|
||||||
msgid "Join Requests"
|
msgid "Join Requests"
|
||||||
msgstr "Beitrittsgesuche"
|
msgstr "Beitrittsgesuche"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:24
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:34
|
||||||
msgid "Leave Requests"
|
msgid "Leave Requests"
|
||||||
msgstr "Austrittsgesuche"
|
msgstr "Austrittsgesuche"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:39
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:53
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:98
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:111
|
||||||
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:20
|
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:20
|
||||||
#: allianceauth/services/modules/openfire/forms.py:6
|
#: allianceauth/services/modules/openfire/forms.py:6
|
||||||
msgid "Group"
|
msgid "Group"
|
||||||
msgstr "Gruppen"
|
msgstr "Gruppen"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:71
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:84
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:130
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:142
|
||||||
msgid "Accept"
|
msgid "Accept"
|
||||||
msgstr "Akzeptieren"
|
msgstr "Akzeptieren"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:74
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:88
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:133
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:146
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:85
|
#: allianceauth/hrapplications/templates/hrapplications/view.html:85
|
||||||
msgid "Reject"
|
msgid "Reject"
|
||||||
msgstr "Ablehnen"
|
msgstr "Ablehnen"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:83
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:97
|
||||||
msgid "No group add requests."
|
msgid "No group add requests."
|
||||||
msgstr "Keine Gruppenbeitrittsanfragen."
|
msgstr "Keine Gruppenbeitrittsanfragen."
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:142
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:155
|
||||||
msgid "No group leave requests."
|
msgid "No group leave requests."
|
||||||
msgstr "Keine Gruppenaustrittsanfragen"
|
msgstr "Keine Gruppenaustrittsanfragen"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:10
|
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:9
|
||||||
msgid "Toggle navigation"
|
msgid "Toggle navigation"
|
||||||
msgstr "Toggle Navigation"
|
msgstr "Toggle Navigation"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:15
|
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:20
|
||||||
#: allianceauth/templates/allianceauth/side-menu.html:23
|
|
||||||
msgid "Group Management"
|
|
||||||
msgstr "Gruppenverwaltung"
|
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:21
|
|
||||||
msgid "Group Requests"
|
msgid "Group Requests"
|
||||||
msgstr "Gruppenanfragen"
|
msgstr "Gruppenanfragen"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:24
|
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:23
|
||||||
msgid "Group Membership"
|
msgid "Group Membership"
|
||||||
msgstr "Gruppenmitgliedschaft"
|
msgstr "Gruppenmitgliedschaft"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:166
|
#: allianceauth/groupmanagement/views.py:162
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Removed user %(user)s from group %(group)s."
|
msgid "Removed user %(user)s from group %(group)s."
|
||||||
msgstr "Benutzer %(user)s von Gruppe %(group)s entfernt."
|
msgstr "Benutzer %(user)s von Gruppe %(group)s entfernt."
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:168
|
#: allianceauth/groupmanagement/views.py:164
|
||||||
msgid "User does not exist in that group"
|
msgid "User does not exist in that group"
|
||||||
msgstr "Benutzer existiert nicht in dieser Gruppe"
|
msgstr "Benutzer existiert nicht in dieser Gruppe"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:171
|
#: allianceauth/groupmanagement/views.py:167
|
||||||
msgid "Group does not exist"
|
msgid "Group does not exist"
|
||||||
msgstr "Gruppe existiert nicht"
|
msgstr "Gruppe existiert nicht"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:198
|
#: allianceauth/groupmanagement/views.py:194
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Accepted application from %(mainchar)s to %(group)s."
|
msgid "Accepted application from %(mainchar)s to %(group)s."
|
||||||
msgstr "Beitrittsgesuch von %(mainchar)s zur Gruppe %(group)s zugestimmt."
|
msgstr "Beitrittsgesuch von %(mainchar)s zur Gruppe %(group)s zugestimmt."
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:205
|
#: allianceauth/groupmanagement/views.py:201
|
||||||
#: allianceauth/groupmanagement/views.py:238
|
#: allianceauth/groupmanagement/views.py:234
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"An unhandled error occurred while processing the application from "
|
"An unhandled error occurred while processing the application from "
|
||||||
@@ -769,18 +788,18 @@ msgstr ""
|
|||||||
"Bei der Bearbeitung des Beitrittsgesuchs von %(mainchar)s zur Gruppe "
|
"Bei der Bearbeitung des Beitrittsgesuchs von %(mainchar)s zur Gruppe "
|
||||||
"%(group)s ist ein unbehandelter Fehler aufgetreten."
|
"%(group)s ist ein unbehandelter Fehler aufgetreten."
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:231
|
#: allianceauth/groupmanagement/views.py:227
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Rejected application from %(mainchar)s to %(group)s."
|
msgid "Rejected application from %(mainchar)s to %(group)s."
|
||||||
msgstr "Beitrittsgesuch von %(mainchar)s zur Gruppe %(group)s abgelehnt."
|
msgstr "Beitrittsgesuch von %(mainchar)s zur Gruppe %(group)s abgelehnt."
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:267
|
#: allianceauth/groupmanagement/views.py:263
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Accepted application from %(mainchar)s to leave %(group)s."
|
msgid "Accepted application from %(mainchar)s to leave %(group)s."
|
||||||
msgstr "Austrittsgesuch von %(mainchar)s für Gruppe %(group)s akzeptiert."
|
msgstr "Austrittsgesuch von %(mainchar)s für Gruppe %(group)s akzeptiert."
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:273
|
#: allianceauth/groupmanagement/views.py:269
|
||||||
#: allianceauth/groupmanagement/views.py:307
|
#: allianceauth/groupmanagement/views.py:303
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"An unhandled error occurred while processing the application from "
|
"An unhandled error occurred while processing the application from "
|
||||||
@@ -789,60 +808,60 @@ msgstr ""
|
|||||||
"Bei der Bearbeitung des Austrittsgesuchs von %(mainchar)s für Gruppe "
|
"Bei der Bearbeitung des Austrittsgesuchs von %(mainchar)s für Gruppe "
|
||||||
"%(group)s ist ein unbehandelter Fehler aufgetreten."
|
"%(group)s ist ein unbehandelter Fehler aufgetreten."
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:300
|
#: allianceauth/groupmanagement/views.py:296
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Rejected application from %(mainchar)s to leave %(group)s."
|
msgid "Rejected application from %(mainchar)s to leave %(group)s."
|
||||||
msgstr "Austrittsgesuch von %(mainchar)s für Gruppe %(group)s abgelehnt."
|
msgstr "Austrittsgesuch von %(mainchar)s für Gruppe %(group)s abgelehnt."
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:346
|
#: allianceauth/groupmanagement/views.py:342
|
||||||
#: allianceauth/groupmanagement/views.py:358
|
#: allianceauth/groupmanagement/views.py:354
|
||||||
msgid "You cannot join that group"
|
msgid "You cannot join that group"
|
||||||
msgstr "Du kannst dieser Gruppe nicht beitreten"
|
msgstr "Du kannst dieser Gruppe nicht beitreten"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:352
|
#: allianceauth/groupmanagement/views.py:348
|
||||||
msgid "You are already a member of that group."
|
msgid "You are already a member of that group."
|
||||||
msgstr "Du bist bereits Mitglied dieser Gruppe."
|
msgstr "Du bist bereits Mitglied dieser Gruppe."
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:367
|
#: allianceauth/groupmanagement/views.py:363
|
||||||
msgid "You already have a pending application for that group."
|
msgid "You already have a pending application for that group."
|
||||||
msgstr "Du hast Dich bereits für diese Gruppe beworben."
|
msgstr "Du hast Dich bereits für diese Gruppe beworben."
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:370
|
#: allianceauth/groupmanagement/views.py:366
|
||||||
#: allianceauth/groupmanagement/views.py:408
|
#: allianceauth/groupmanagement/views.py:404
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:37
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:37
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:72
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:72
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:99
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:99
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:144
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:144
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:38
|
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:38
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:20
|
#: 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
|
#: allianceauth/srp/templates/srp/management.html:81
|
||||||
msgid "Pending"
|
msgid "Pending"
|
||||||
msgstr "Beantragt"
|
msgstr "Beantragt"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:376
|
#: allianceauth/groupmanagement/views.py:372
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Applied to group %(group)s."
|
msgid "Applied to group %(group)s."
|
||||||
msgstr "Beitritt zur Gruppe %(group)s beantragt."
|
msgstr "Beitritt zur Gruppe %(group)s beantragt."
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:387
|
#: allianceauth/groupmanagement/views.py:383
|
||||||
msgid "You cannot leave that group"
|
msgid "You cannot leave that group"
|
||||||
msgstr "Du kannst diese Gruppe nicht verlassen"
|
msgstr "Du kannst diese Gruppe nicht verlassen"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:392
|
#: allianceauth/groupmanagement/views.py:388
|
||||||
msgid "You are not a member of that group"
|
msgid "You are not a member of that group"
|
||||||
msgstr "Du bist kein Mitglied dieser Gruppe"
|
msgstr "Du bist kein Mitglied dieser Gruppe"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:401
|
#: allianceauth/groupmanagement/views.py:397
|
||||||
msgid "You already have a pending leave request for that group."
|
msgid "You already have a pending leave request for that group."
|
||||||
msgstr "Du hast bereits ein ausstehendes Austrittsgesuch für diese Gruppe."
|
msgstr "Du hast bereits ein ausstehendes Austrittsgesuch für diese Gruppe."
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:414
|
#: allianceauth/groupmanagement/views.py:410
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Applied to leave group %(group)s."
|
msgid "Applied to leave group %(group)s."
|
||||||
msgstr "Austrittsgesuch für Gruppe %(group)s gesendet."
|
msgstr "Austrittsgesuch für Gruppe %(group)s gesendet."
|
||||||
|
|
||||||
#: allianceauth/hrapplications/auth_hooks.py:10
|
#: allianceauth/hrapplications/auth_hooks.py:13
|
||||||
msgid "Applications"
|
msgid "Applications"
|
||||||
msgstr "Bewerbungen"
|
msgstr "Bewerbungen"
|
||||||
|
|
||||||
@@ -899,7 +918,7 @@ msgstr "Benutzername"
|
|||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:131
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:131
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:28
|
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:28
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:75
|
#: 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
|
#: allianceauth/srp/templates/srp/management.html:46
|
||||||
msgid "Actions"
|
msgid "Actions"
|
||||||
msgstr "Aktionen"
|
msgstr "Aktionen"
|
||||||
@@ -909,7 +928,7 @@ msgstr "Aktionen"
|
|||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:147
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:147
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:40
|
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:40
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:16
|
#: allianceauth/hrapplications/templates/hrapplications/view.html:16
|
||||||
#: allianceauth/srp/templates/srp/data.html:117
|
#: allianceauth/srp/templates/srp/data.html:126
|
||||||
msgid "Approved"
|
msgid "Approved"
|
||||||
msgstr "Akzeptiert"
|
msgstr "Akzeptiert"
|
||||||
|
|
||||||
@@ -917,7 +936,7 @@ msgstr "Akzeptiert"
|
|||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:104
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:104
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:149
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:149
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:42
|
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:42
|
||||||
#: allianceauth/srp/templates/srp/data.html:121
|
#: allianceauth/srp/templates/srp/data.html:130
|
||||||
msgid "Rejected"
|
msgid "Rejected"
|
||||||
msgstr "Abgelehnt"
|
msgstr "Abgelehnt"
|
||||||
|
|
||||||
@@ -1023,7 +1042,7 @@ msgstr "Ungelesen"
|
|||||||
|
|
||||||
#: allianceauth/notifications/templates/notifications/list.html:18
|
#: allianceauth/notifications/templates/notifications/list.html:18
|
||||||
msgid "Read"
|
msgid "Read"
|
||||||
msgstr "Lesen"
|
msgstr "Gelesen"
|
||||||
|
|
||||||
#: allianceauth/notifications/templates/notifications/list.html:22
|
#: allianceauth/notifications/templates/notifications/list.html:22
|
||||||
msgid "Mark All Read"
|
msgid "Mark All Read"
|
||||||
@@ -1254,7 +1273,7 @@ msgstr "Flotten Comms:"
|
|||||||
|
|
||||||
#: allianceauth/services/forms.py:9
|
#: allianceauth/services/forms.py:9
|
||||||
msgid "Fleet Type:"
|
msgid "Fleet Type:"
|
||||||
msgstr "Flottenzeit:"
|
msgstr "Flottenart:"
|
||||||
|
|
||||||
#: allianceauth/services/forms.py:10
|
#: allianceauth/services/forms.py:10
|
||||||
msgid "Ship Priorities:"
|
msgid "Ship Priorities:"
|
||||||
@@ -1300,23 +1319,54 @@ msgstr "Passwort"
|
|||||||
msgid "Password must be at least 8 characters long."
|
msgid "Password must be at least 8 characters long."
|
||||||
msgstr "Passwort muss mindestens 8 Zeichen lang sein"
|
msgstr "Passwort muss mindestens 8 Zeichen lang sein"
|
||||||
|
|
||||||
#: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:23
|
#: allianceauth/services/modules/discord/models.py:225
|
||||||
|
msgid "Discord Account Disabled"
|
||||||
|
msgstr "Discord Konto deaktiviert"
|
||||||
|
|
||||||
|
#: 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 ""
|
||||||
|
"Dein Discord Konto wurde automatisch durch Auth deaktiviert. Wenn Du glaubst"
|
||||||
|
" dies war ein Fehler, kontaktiere bitte einen Administrator."
|
||||||
|
|
||||||
|
#: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:18
|
||||||
|
msgid "Join the Discord server"
|
||||||
|
msgstr "Discord Server beitreten"
|
||||||
|
|
||||||
|
#: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:22
|
||||||
|
msgid "Leave- and rejoin the Discord Server (Reset)"
|
||||||
|
msgstr "Discord Server verlassen und wieder beitreten (Zurücksetzen)"
|
||||||
|
|
||||||
|
#: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:25
|
||||||
|
msgid "Leave the Discord server"
|
||||||
|
msgstr "Discord Server verlassen"
|
||||||
|
|
||||||
|
#: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:32
|
||||||
msgid "Link Discord Server"
|
msgid "Link Discord Server"
|
||||||
msgstr "Verbinde Discord Server"
|
msgstr "Verbinde Discord Server"
|
||||||
|
|
||||||
#: allianceauth/services/modules/discord/views.py:26
|
#: allianceauth/services/modules/discord/views.py:30
|
||||||
msgid "Deactivated Discord account."
|
msgid "Deactivated Discord account."
|
||||||
msgstr "Discord Konto deaktiviert."
|
msgstr "Discord Konto deaktiviert."
|
||||||
|
|
||||||
#: allianceauth/services/modules/discord/views.py:29
|
#: allianceauth/services/modules/discord/views.py:36
|
||||||
#: allianceauth/services/modules/discord/views.py:41
|
#: allianceauth/services/modules/discord/views.py:59
|
||||||
#: allianceauth/services/modules/discord/views.py:65
|
|
||||||
msgid "An error occurred while processing your Discord account."
|
msgid "An error occurred while processing your Discord account."
|
||||||
msgstr "Es gab einen Fehler bei der Verarbeitung Deines Discord Kontos."
|
msgstr "Es gab einen Fehler bei der Verarbeitung Deines Discord Kontos."
|
||||||
|
|
||||||
#: allianceauth/services/modules/discord/views.py:62
|
#: allianceauth/services/modules/discord/views.py:102
|
||||||
msgid "Activated Discord account."
|
msgid "Your Discord account has been successfully activated."
|
||||||
msgstr "Discord Konto aktiviert."
|
msgstr "Dein Discord Konto wurde erfolgreich aktiviert."
|
||||||
|
|
||||||
|
#: allianceauth/services/modules/discord/views.py:108
|
||||||
|
msgid ""
|
||||||
|
"An error occurred while trying to activate your Discord account. Please try "
|
||||||
|
"again."
|
||||||
|
msgstr ""
|
||||||
|
"Es gab einen Fehler während der Aktivierung Deines Discord Kontos. Bitte "
|
||||||
|
"versuche es noch einmal."
|
||||||
|
|
||||||
#: allianceauth/services/modules/discourse/views.py:37
|
#: allianceauth/services/modules/discourse/views.py:37
|
||||||
msgid "You are not authorized to access Discourse."
|
msgid "You are not authorized to access Discourse."
|
||||||
@@ -1587,7 +1637,7 @@ msgstr "Dienst"
|
|||||||
msgid "Domain"
|
msgid "Domain"
|
||||||
msgstr "Domain"
|
msgstr "Domain"
|
||||||
|
|
||||||
#: allianceauth/srp/auth_hooks.py:9
|
#: allianceauth/srp/auth_hooks.py:12
|
||||||
msgid "Ship Replacement"
|
msgid "Ship Replacement"
|
||||||
msgstr "Schiffserstattung"
|
msgstr "Schiffserstattung"
|
||||||
|
|
||||||
@@ -1601,7 +1651,7 @@ msgstr "Flottenzeit"
|
|||||||
msgid "Fleet Doctrine"
|
msgid "Fleet Doctrine"
|
||||||
msgstr "Flottendoktrin"
|
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"
|
msgid "Additional Info"
|
||||||
msgstr "Zusätzliche Info"
|
msgstr "Zusätzliche Info"
|
||||||
|
|
||||||
@@ -1630,65 +1680,65 @@ msgstr "SRP-Flotte erstellen"
|
|||||||
msgid "Give this link to the line members"
|
msgid "Give this link to the line members"
|
||||||
msgstr "Gib diesen Link an Deine Piloten weiter"
|
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"
|
msgid "SRP Fleet Data"
|
||||||
msgstr "SRP-Flotte Daten"
|
msgstr "SRP-Flotte Daten"
|
||||||
|
|
||||||
#: allianceauth/srp/templates/srp/data.html:53
|
#: allianceauth/srp/templates/srp/data.html:54
|
||||||
msgid "Mark Incomplete"
|
msgid "Mark Incomplete"
|
||||||
msgstr "Als unvollständig markieren"
|
msgstr "Als unvollständig markieren"
|
||||||
|
|
||||||
#: allianceauth/srp/templates/srp/data.html:57
|
#: allianceauth/srp/templates/srp/data.html:58
|
||||||
msgid "Mark Completed"
|
msgid "Mark Completed"
|
||||||
msgstr "Als vollständig markieren"
|
msgstr "Als vollständig markieren"
|
||||||
|
|
||||||
#: allianceauth/srp/templates/srp/data.html:69
|
#: allianceauth/srp/templates/srp/data.html:70
|
||||||
#: allianceauth/srp/templates/srp/data.html:145
|
#: allianceauth/srp/templates/srp/data.html:156
|
||||||
msgid "Total Losses:"
|
msgid "Total Losses:"
|
||||||
msgstr "Verluste insgesamt:"
|
msgstr "Verluste insgesamt:"
|
||||||
|
|
||||||
#: allianceauth/srp/templates/srp/data.html:70
|
#: allianceauth/srp/templates/srp/data.html:71
|
||||||
#: allianceauth/srp/templates/srp/data.html:146
|
#: allianceauth/srp/templates/srp/data.html:157
|
||||||
#: allianceauth/srp/templates/srp/management.html:30
|
#: allianceauth/srp/templates/srp/management.html:30
|
||||||
msgid "Total ISK Cost:"
|
msgid "Total ISK Cost:"
|
||||||
msgstr "ISK-Kosten insgesamt:"
|
msgstr "ISK-Kosten insgesamt:"
|
||||||
|
|
||||||
#: allianceauth/srp/templates/srp/data.html:78
|
#: allianceauth/srp/templates/srp/data.html:79
|
||||||
#: allianceauth/srp/templates/srp/data.html:154
|
#: allianceauth/srp/templates/srp/data.html:165
|
||||||
msgid "Are you sure you want to delete SRP requests?"
|
msgid "Are you sure you want to delete SRP requests?"
|
||||||
msgstr "Bist Du sicher das Du SRP Anfragen löschen willst?"
|
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"
|
msgid "Pilot Name"
|
||||||
msgstr "Name des Piloten"
|
msgstr "Name des Piloten"
|
||||||
|
|
||||||
#: allianceauth/srp/templates/srp/data.html:88
|
#: allianceauth/srp/templates/srp/data.html:89
|
||||||
msgid "Killboard Link"
|
msgid "Killboard Link"
|
||||||
msgstr "Killboard Link"
|
msgstr "Killboard Link"
|
||||||
|
|
||||||
#: allianceauth/srp/templates/srp/data.html:90
|
#: allianceauth/srp/templates/srp/data.html:91
|
||||||
msgid "Ship Type"
|
msgid "Ship Type"
|
||||||
msgstr "Schiffstyp"
|
msgstr "Schiffstyp"
|
||||||
|
|
||||||
#: allianceauth/srp/templates/srp/data.html:91
|
#: allianceauth/srp/templates/srp/data.html:92
|
||||||
msgid "Killboard Loss Amt"
|
msgid "Killboard Loss Amt"
|
||||||
msgstr "Summe Killboard Verluste"
|
msgstr "Summe Killboard Verluste"
|
||||||
|
|
||||||
#: allianceauth/srp/templates/srp/data.html:92
|
#: allianceauth/srp/templates/srp/data.html:93
|
||||||
msgid "SRP ISK Cost"
|
msgid "SRP ISK Cost"
|
||||||
msgstr "SRP ISK-Kosten"
|
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"
|
msgid "Click value to edit Enter to save & next ESC to cancel"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Klicke auf den Wert um diesen zu bearbeiten, Enter zum Speichern und um zum "
|
"Klicke auf den Wert um diesen zu bearbeiten, Enter zum Speichern und um zum "
|
||||||
"nächsten Wert zu springen, ESC zum Beenden."
|
"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"
|
msgid "Post Time"
|
||||||
msgstr "Veröffentlichungszeit"
|
msgstr "Veröffentlichungszeit"
|
||||||
|
|
||||||
#: allianceauth/srp/templates/srp/data.html:163
|
#: allianceauth/srp/templates/srp/data.html:174
|
||||||
msgid "No SRP requests for this fleet."
|
msgid "No SRP requests for this fleet."
|
||||||
msgstr "Keine SRP Anfragen für diese Flotte."
|
msgstr "Keine SRP Anfragen für diese Flotte."
|
||||||
|
|
||||||
@@ -1884,32 +1934,30 @@ msgid "Current"
|
|||||||
msgstr "Aktuell"
|
msgstr "Aktuell"
|
||||||
|
|
||||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:40
|
#: allianceauth/templates/allianceauth/admin-status/overview.html:40
|
||||||
msgid "Latest Major"
|
msgid "Latest Stable"
|
||||||
msgstr "Aktuellste Hauptversion"
|
msgstr "Aktuellste stabile Version"
|
||||||
|
|
||||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:46
|
#: 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"
|
msgid "Update available"
|
||||||
msgstr "Update verfügbar"
|
msgstr "Update verfügbar"
|
||||||
|
|
||||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:50
|
#: allianceauth/templates/allianceauth/admin-status/overview.html:51
|
||||||
msgid "Latest Minor"
|
msgid "Latest Pre-Release"
|
||||||
msgstr "Aktuellste Unterversion"
|
msgstr "Aktuellste Testversion"
|
||||||
|
|
||||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:60
|
#: allianceauth/templates/allianceauth/admin-status/overview.html:57
|
||||||
msgid "Latest Patch"
|
msgid "Pre-Release available"
|
||||||
msgstr "Aktuellste Patchversion"
|
msgstr "Testversion verfügbar"
|
||||||
|
|
||||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:73
|
#: allianceauth/templates/allianceauth/admin-status/overview.html:65
|
||||||
msgid "Task Queue"
|
msgid "Task Queue"
|
||||||
msgstr "Warteschlange"
|
msgstr "Warteschlange"
|
||||||
|
|
||||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:90
|
#: allianceauth/templates/allianceauth/admin-status/overview.html:82
|
||||||
msgid "Error retrieving task queue length"
|
msgid "Error retrieving task queue length"
|
||||||
msgstr "Fehler beim Ermitteln der Warteschlange."
|
msgstr "Fehler beim Ermitteln der Warteschlange."
|
||||||
|
|
||||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:92
|
#: allianceauth/templates/allianceauth/admin-status/overview.html:84
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%(tasks)s task"
|
msgid "%(tasks)s task"
|
||||||
msgid_plural "%(tasks)s tasks"
|
msgid_plural "%(tasks)s tasks"
|
||||||
@@ -2050,3 +2098,6 @@ msgstr "Neuen Timer hinzugefügt in %(system)s um %(time)s."
|
|||||||
#: allianceauth/timerboard/views.py:83
|
#: allianceauth/timerboard/views.py:83
|
||||||
msgid "Saved changes to the timer."
|
msgid "Saved changes to the timer."
|
||||||
msgstr "Änderungen am Timer gespeichert"
|
msgstr "Änderungen am Timer gespeichert"
|
||||||
|
|
||||||
|
#~ msgid "Portrait"
|
||||||
|
#~ msgstr "Portrait"
|
||||||
|
|||||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -12,7 +12,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \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"
|
"PO-Revision-Date: 2020-02-18 03:14+0000\n"
|
||||||
"Last-Translator: frank1210 <francolopez_16@hotmail.com>, 2020\n"
|
"Last-Translator: frank1210 <francolopez_16@hotmail.com>, 2020\n"
|
||||||
"Language-Team: Spanish (https://www.transifex.com/alliance-auth/teams/107430/es/)\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 ""
|
msgstr ""
|
||||||
"Un personaje principal es requerido para completar esta accion. Agregue uno"
|
"Un personaje principal es requerido para completar esta accion. Agregue uno"
|
||||||
|
|
||||||
#: allianceauth/authentication/forms.py:6
|
#: allianceauth/authentication/forms.py:5
|
||||||
msgid "Email"
|
msgid "Email"
|
||||||
msgstr "E-mail"
|
msgstr "E-mail"
|
||||||
|
|
||||||
#: allianceauth/authentication/models.py:76
|
#: allianceauth/authentication/models.py:78
|
||||||
msgid "State Changed"
|
|
||||||
msgstr "Estado Cambiado"
|
|
||||||
|
|
||||||
#: allianceauth/authentication/models.py:77
|
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Your user state has been changed to %(state)s"
|
msgid "State changed to: %s"
|
||||||
msgstr "Tu estado de usuario fue cambiado a %(state)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:5
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:8
|
#: allianceauth/authentication/templates/authentication/dashboard.html:8
|
||||||
#: allianceauth/templates/allianceauth/side-menu.html:10
|
#: allianceauth/templates/allianceauth/side-menu.html:11
|
||||||
msgid "Dashboard"
|
msgid "Dashboard"
|
||||||
msgstr "Pagina Principal"
|
msgstr "Pagina Principal"
|
||||||
|
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:17
|
#: allianceauth/authentication/templates/authentication/dashboard.html:18
|
||||||
#: allianceauth/corputils/templates/corputils/corpstats.html:116
|
#, python-format
|
||||||
#: allianceauth/corputils/templates/corputils/search.html:16
|
msgid ""
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticscorpview.html:22
|
"\n"
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:83
|
" Main Character (State: %(state)s)\n"
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:128
|
" "
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:25
|
msgstr ""
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:32
|
|
||||||
msgid "Main Character"
|
|
||||||
msgstr "Personaje Principal"
|
|
||||||
|
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:77
|
#: allianceauth/authentication/templates/authentication/dashboard.html:81
|
||||||
msgid "No main character set."
|
msgid "No main character set."
|
||||||
msgstr "No se ha seleccionado un personaje principal."
|
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"
|
msgid "Add Character"
|
||||||
msgstr "Agregar Personaje"
|
msgstr "Agregar Personaje"
|
||||||
|
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:88
|
#: allianceauth/authentication/templates/authentication/dashboard.html:92
|
||||||
msgid "Change Main"
|
msgid "Change Main"
|
||||||
msgstr "Cambiar Personaje Principal"
|
msgstr "Cambiar Personaje Principal"
|
||||||
|
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:97
|
#: allianceauth/authentication/templates/authentication/dashboard.html:101
|
||||||
msgid "Group Memberships"
|
msgid "Group Memberships"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:117
|
#: allianceauth/authentication/templates/authentication/dashboard.html:121
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticscorpview.html:23
|
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticscorpview.html:23
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:41
|
#: allianceauth/hrapplications/templates/hrapplications/view.html:41
|
||||||
msgid "Characters"
|
msgid "Characters"
|
||||||
msgstr "Personajes"
|
msgstr "Personajes"
|
||||||
|
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:125
|
#: allianceauth/authentication/templates/authentication/dashboard.html:129
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:73
|
#: 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/groupmanagement/templates/groupmanagement/groups.html:15
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:45
|
#: allianceauth/hrapplications/templates/hrapplications/view.html:45
|
||||||
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:34
|
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:34
|
||||||
msgid "Name"
|
msgid "Name"
|
||||||
msgstr "Nombre"
|
msgstr "Nombre"
|
||||||
|
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:126
|
#: allianceauth/authentication/templates/authentication/dashboard.html:130
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticsview.html:23
|
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticsview.html:23
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:46
|
#: allianceauth/hrapplications/templates/hrapplications/view.html:46
|
||||||
msgid "Corp"
|
msgid "Corp"
|
||||||
msgstr "Corporación"
|
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/corputils/templates/corputils/corpstats.html:77
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:47
|
#: allianceauth/hrapplications/templates/hrapplications/view.html:47
|
||||||
msgid "Alliance"
|
msgid "Alliance"
|
||||||
@@ -163,26 +161,26 @@ msgstr ""
|
|||||||
msgid "Unable to authenticate as the selected character."
|
msgid "Unable to authenticate as the selected character."
|
||||||
msgstr "Imposible validar con el personaje seleccionado."
|
msgstr "Imposible validar con el personaje seleccionado."
|
||||||
|
|
||||||
#: allianceauth/authentication/views.py:148
|
#: allianceauth/authentication/views.py:151
|
||||||
msgid "Registration token has expired."
|
msgid "Registration token has expired."
|
||||||
msgstr "El token de registracion expiro."
|
msgstr "El token de registracion expiro."
|
||||||
|
|
||||||
#: allianceauth/authentication/views.py:200
|
#: allianceauth/authentication/views.py:206
|
||||||
msgid ""
|
msgid ""
|
||||||
"Sent confirmation email. Please follow the link to confirm your email "
|
"Sent confirmation email. Please follow the link to confirm your email "
|
||||||
"address."
|
"address."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Confirmacion de mail enviada. Por favor siga el enlace para confirmar "
|
"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."
|
msgid "Confirmed your email address. Please login to continue."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Se ha confirmado su direccion de mail. Por favor igrese su token para "
|
"Se ha confirmado su direccion de mail. Por favor igrese su token para "
|
||||||
"continuar."
|
"continuar."
|
||||||
|
|
||||||
#: allianceauth/authentication/views.py:210
|
#: allianceauth/authentication/views.py:216
|
||||||
msgid "Registraion of new accounts it not allowed at this time."
|
msgid "Registration of new accounts is not allowed at this time."
|
||||||
msgstr "Registracion de nuevas cuentas no es permitido por el momento."
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/corputils/auth_hooks.py:10
|
#: allianceauth/corputils/auth_hooks.py:10
|
||||||
msgid "Corporation Stats"
|
msgid "Corporation Stats"
|
||||||
@@ -229,16 +227,16 @@ msgstr "Ultima Actualizacion:"
|
|||||||
#: allianceauth/corputils/templates/corputils/search.html:13
|
#: allianceauth/corputils/templates/corputils/search.html:13
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html:24
|
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html:24
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:28
|
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:28
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:27
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:30
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:29
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:30
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:37
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:51
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:96
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:109
|
||||||
msgid "Character"
|
msgid "Character"
|
||||||
msgstr "Personaje"
|
msgstr "Personaje"
|
||||||
|
|
||||||
#: allianceauth/corputils/templates/corputils/corpstats.html:76
|
#: allianceauth/corputils/templates/corputils/corpstats.html:76
|
||||||
#: allianceauth/corputils/templates/corputils/search.html:14
|
#: 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:27
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:84
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:84
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:129
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:129
|
||||||
@@ -254,6 +252,16 @@ msgstr "Corporacion"
|
|||||||
msgid "Killboard"
|
msgid "Killboard"
|
||||||
msgstr "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/corpstats.html:117
|
||||||
#: allianceauth/corputils/templates/corputils/search.html:17
|
#: allianceauth/corputils/templates/corputils/search.html:17
|
||||||
msgid "Main Corporation"
|
msgid "Main Corporation"
|
||||||
@@ -538,31 +546,35 @@ msgstr "Participacion de flota registrada."
|
|||||||
msgid "FAT link has expired."
|
msgid "FAT link has expired."
|
||||||
msgstr "Enlace de participacion expirado."
|
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:5
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:13
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:14
|
||||||
msgid "Audit Log"
|
msgid "Audit Log"
|
||||||
msgstr "Log de Auditoria"
|
msgstr "Log de Auditoria"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:18
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:20
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:20
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:21
|
||||||
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:13
|
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:13
|
||||||
msgid "Back"
|
msgid "Back"
|
||||||
msgstr "Volver"
|
msgstr "Volver"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:25
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:28
|
||||||
msgid "Date/Time"
|
msgid "Date/Time"
|
||||||
msgstr "Fecha/Hora"
|
msgstr "Fecha/Hora"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:26
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:29
|
||||||
msgid "Requestor"
|
msgid "Requestor"
|
||||||
msgstr "Solicitante"
|
msgstr "Solicitante"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:29
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:32
|
||||||
msgid "Type"
|
msgid "Type"
|
||||||
msgstr "Tipo"
|
msgstr "Tipo"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:30
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:33
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:17
|
|
||||||
#: allianceauth/notifications/templates/notifications/list.html:37
|
#: allianceauth/notifications/templates/notifications/list.html:37
|
||||||
#: allianceauth/notifications/templates/notifications/list.html:69
|
#: allianceauth/notifications/templates/notifications/list.html:69
|
||||||
#: allianceauth/optimer/templates/optimer/fleetoptable.html:18
|
#: allianceauth/optimer/templates/optimer/fleetoptable.html:18
|
||||||
@@ -573,11 +585,19 @@ msgstr "Tipo"
|
|||||||
msgid "Action"
|
msgid "Action"
|
||||||
msgstr "Accion"
|
msgstr "Accion"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:31
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:34
|
||||||
msgid "Actor"
|
msgid "Actor"
|
||||||
msgstr "Actor"
|
msgstr "Actor"
|
||||||
|
|
||||||
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:47
|
||||||
|
msgid "Removed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:59
|
#: 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."
|
msgid "No entries found for this group."
|
||||||
msgstr "No se encontraron entradas para este grupo."
|
msgstr "No se encontraron entradas para este grupo."
|
||||||
|
|
||||||
@@ -585,22 +605,24 @@ msgstr "No se encontraron entradas para este grupo."
|
|||||||
msgid "Group Members"
|
msgid "Group Members"
|
||||||
msgstr "Miembros del Grupo"
|
msgstr "Miembros del Grupo"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:28
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:31
|
||||||
msgid "Portrait"
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:52
|
||||||
msgstr "Retrato"
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:110
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:30
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:38
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:97
|
|
||||||
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:23
|
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:23
|
||||||
msgid "Organization"
|
msgid "Organization"
|
||||||
msgstr ""
|
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"
|
msgid "Remove from group"
|
||||||
msgstr "Remover del grupo"
|
msgstr "Remover del grupo"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:76
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:81
|
||||||
msgid "No group members to list."
|
msgid "No group members to list."
|
||||||
msgstr "no hay miembros para listar."
|
msgstr "no hay miembros para listar."
|
||||||
|
|
||||||
@@ -608,56 +630,56 @@ msgstr "no hay miembros para listar."
|
|||||||
msgid "Groups Membership"
|
msgid "Groups Membership"
|
||||||
msgstr "Membresia de grupos"
|
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/permissions_tool/templates/permissions_tool/overview.html:40
|
||||||
#: allianceauth/templates/allianceauth/side-menu.html:15
|
#: allianceauth/templates/allianceauth/side-menu.html:16
|
||||||
msgid "Groups"
|
msgid "Groups"
|
||||||
msgstr "Grupos"
|
msgstr "Grupos"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:23
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:25
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:16
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:16
|
||||||
msgid "Description"
|
msgid "Description"
|
||||||
msgstr "Descripcion"
|
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:28
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:85
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:85
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:130
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:130
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:27
|
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:27
|
||||||
#: allianceauth/srp/templates/srp/data.html:97
|
#: allianceauth/srp/templates/srp/data.html:98
|
||||||
msgid "Status"
|
msgid "Status"
|
||||||
msgstr "Estado"
|
msgstr "Estado"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:25
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:27
|
||||||
msgid "Member Count"
|
msgid "Member Count"
|
||||||
msgstr "Contador de miembros"
|
msgstr "Contador de miembros"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:38
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:43
|
||||||
msgid "Hidden"
|
msgid "Hidden"
|
||||||
msgstr "Escondido"
|
msgstr "Escondido"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:40
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:45
|
||||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:12
|
#: allianceauth/templates/allianceauth/admin-status/overview.html:12
|
||||||
msgid "Open"
|
msgid "Open"
|
||||||
msgstr "Abierto"
|
msgstr "Abierto"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:42
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:47
|
||||||
msgid "Requestable"
|
msgid "Requestable"
|
||||||
msgstr "Solicitable"
|
msgstr "Solicitable"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:50
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:56
|
||||||
msgid "View Members"
|
msgid "View Members"
|
||||||
msgstr "Ver Miembros"
|
msgstr "Ver Miembros"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:53
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:60
|
||||||
msgid "Audit Members"
|
msgid "Audit Members"
|
||||||
msgstr "Auditar Miembros"
|
msgstr "Auditar Miembros"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:56
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:64
|
||||||
msgid "Copy Direrct Join Link"
|
msgid "Copy Direct Join Link"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:68
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:75
|
||||||
msgid "No groups to list."
|
msgid "No groups to list."
|
||||||
msgstr "No hay grupos para listar"
|
msgstr "No hay grupos para listar"
|
||||||
|
|
||||||
@@ -666,19 +688,19 @@ msgstr "No hay grupos para listar"
|
|||||||
msgid "Available Groups"
|
msgid "Available Groups"
|
||||||
msgstr "Grupos Disponibles"
|
msgstr "Grupos Disponibles"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:29
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:30
|
||||||
msgid "Leave"
|
msgid "Leave"
|
||||||
msgstr "Dejar"
|
msgstr "Dejar"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:39
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:40
|
||||||
msgid "Join"
|
msgid "Join"
|
||||||
msgstr "Unirse"
|
msgstr "Unirse"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:43
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:44
|
||||||
msgid "Request"
|
msgid "Request"
|
||||||
msgstr "Solicitar"
|
msgstr "Solicitar"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:58
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:59
|
||||||
msgid "No groups available."
|
msgid "No groups available."
|
||||||
msgstr "No hay grupos disponibles"
|
msgstr "No hay grupos disponibles"
|
||||||
|
|
||||||
@@ -686,77 +708,72 @@ msgstr "No hay grupos disponibles"
|
|||||||
msgid "Groups Management"
|
msgid "Groups Management"
|
||||||
msgstr "Manejo de Grupos"
|
msgstr "Manejo de Grupos"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:23
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:25
|
||||||
msgid "Join Requests"
|
msgid "Join Requests"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:24
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:34
|
||||||
msgid "Leave Requests"
|
msgid "Leave Requests"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:39
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:53
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:98
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:111
|
||||||
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:20
|
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:20
|
||||||
#: allianceauth/services/modules/openfire/forms.py:6
|
#: allianceauth/services/modules/openfire/forms.py:6
|
||||||
msgid "Group"
|
msgid "Group"
|
||||||
msgstr "Grupo"
|
msgstr "Grupo"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:71
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:84
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:130
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:142
|
||||||
msgid "Accept"
|
msgid "Accept"
|
||||||
msgstr "Aceptar"
|
msgstr "Aceptar"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:74
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:88
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:133
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:146
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:85
|
#: allianceauth/hrapplications/templates/hrapplications/view.html:85
|
||||||
msgid "Reject"
|
msgid "Reject"
|
||||||
msgstr "Rechazar"
|
msgstr "Rechazar"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:83
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:97
|
||||||
msgid "No group add requests."
|
msgid "No group add requests."
|
||||||
msgstr "No hay solicitudes de ingreso."
|
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."
|
msgid "No group leave requests."
|
||||||
msgstr "No hay solicitudes paradejar el grupo."
|
msgstr "No hay solicitudes paradejar el grupo."
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:10
|
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:9
|
||||||
msgid "Toggle navigation"
|
msgid "Toggle navigation"
|
||||||
msgstr "Navegacion"
|
msgstr "Navegacion"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:15
|
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:20
|
||||||
#: allianceauth/templates/allianceauth/side-menu.html:23
|
|
||||||
msgid "Group Management"
|
|
||||||
msgstr "Manejo de Grupo"
|
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:21
|
|
||||||
msgid "Group Requests"
|
msgid "Group Requests"
|
||||||
msgstr "Solicitudes de Grupo"
|
msgstr "Solicitudes de Grupo"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:24
|
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:23
|
||||||
msgid "Group Membership"
|
msgid "Group Membership"
|
||||||
msgstr "Membresia de Grupo"
|
msgstr "Membresia de Grupo"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:166
|
#: allianceauth/groupmanagement/views.py:162
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Removed user %(user)s from group %(group)s."
|
msgid "Removed user %(user)s from group %(group)s."
|
||||||
msgstr "El usuario %(user)s fue removido del grupo %(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"
|
msgid "User does not exist in that group"
|
||||||
msgstr "El usuario no existe en ese grupos"
|
msgstr "El usuario no existe en ese grupos"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:171
|
#: allianceauth/groupmanagement/views.py:167
|
||||||
msgid "Group does not exist"
|
msgid "Group does not exist"
|
||||||
msgstr "El grupo no existe"
|
msgstr "El grupo no existe"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:198
|
#: allianceauth/groupmanagement/views.py:194
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Accepted application from %(mainchar)s to %(group)s."
|
msgid "Accepted application from %(mainchar)s to %(group)s."
|
||||||
msgstr "Solicitud aceptada de %(mainchar)s a %(group)s"
|
msgstr "Solicitud aceptada de %(mainchar)s a %(group)s"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:205
|
#: allianceauth/groupmanagement/views.py:201
|
||||||
#: allianceauth/groupmanagement/views.py:238
|
#: allianceauth/groupmanagement/views.py:234
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"An unhandled error occurred while processing the application from "
|
"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 "
|
"Ocurrio un error cuando se intento procesar la informacion de %(mainchar)s "
|
||||||
"al grupo %(group)s."
|
"al grupo %(group)s."
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:231
|
#: allianceauth/groupmanagement/views.py:227
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Rejected application from %(mainchar)s to %(group)s."
|
msgid "Rejected application from %(mainchar)s to %(group)s."
|
||||||
msgstr "Se rechazo la solicitud de %(mainchar)s al grupo %(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
|
#, python-format
|
||||||
msgid "Accepted application from %(mainchar)s to leave %(group)s."
|
msgid "Accepted application from %(mainchar)s to leave %(group)s."
|
||||||
msgstr "Se acepto la solicitud de %(mainchar)s para dejar el grupo %(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:269
|
||||||
#: allianceauth/groupmanagement/views.py:307
|
#: allianceauth/groupmanagement/views.py:303
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"An unhandled error occurred while processing the application from "
|
"An unhandled error occurred while processing the application from "
|
||||||
"%(mainchar)s to leave %(group)s."
|
"%(mainchar)s to leave %(group)s."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:300
|
#: allianceauth/groupmanagement/views.py:296
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Rejected application from %(mainchar)s to leave %(group)s."
|
msgid "Rejected application from %(mainchar)s to leave %(group)s."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Se rechazo la solicitud de %(mainchar)s para dejar el grupo %(group)s."
|
"Se rechazo la solicitud de %(mainchar)s para dejar el grupo %(group)s."
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:346
|
#: allianceauth/groupmanagement/views.py:342
|
||||||
#: allianceauth/groupmanagement/views.py:358
|
#: allianceauth/groupmanagement/views.py:354
|
||||||
msgid "You cannot join that group"
|
msgid "You cannot join that group"
|
||||||
msgstr "No puedes unirte a ese grupo"
|
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."
|
msgid "You are already a member of that group."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:367
|
#: allianceauth/groupmanagement/views.py:363
|
||||||
msgid "You already have a pending application for that group."
|
msgid "You already have a pending application for that group."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:370
|
#: allianceauth/groupmanagement/views.py:366
|
||||||
#: allianceauth/groupmanagement/views.py:408
|
#: allianceauth/groupmanagement/views.py:404
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:37
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:37
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:72
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:72
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:99
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:99
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:144
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:144
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:38
|
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:38
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:20
|
#: 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
|
#: allianceauth/srp/templates/srp/management.html:81
|
||||||
msgid "Pending"
|
msgid "Pending"
|
||||||
msgstr "Pendiente"
|
msgstr "Pendiente"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:376
|
#: allianceauth/groupmanagement/views.py:372
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Applied to group %(group)s."
|
msgid "Applied to group %(group)s."
|
||||||
msgstr "Solicitud enviada al grupo %(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"
|
msgid "You cannot leave that group"
|
||||||
msgstr "No puedes dejar el grupos"
|
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"
|
msgid "You are not a member of that group"
|
||||||
msgstr "No eres miembro de ese grupo"
|
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."
|
msgid "You already have a pending leave request for that group."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:414
|
#: allianceauth/groupmanagement/views.py:410
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Applied to leave group %(group)s."
|
msgid "Applied to leave group %(group)s."
|
||||||
msgstr "Solicitaste dejar el grupo %(group)s."
|
msgstr "Solicitaste dejar el grupo %(group)s."
|
||||||
|
|
||||||
#: allianceauth/hrapplications/auth_hooks.py:10
|
#: allianceauth/hrapplications/auth_hooks.py:13
|
||||||
msgid "Applications"
|
msgid "Applications"
|
||||||
msgstr "Solicitudes"
|
msgstr "Solicitudes"
|
||||||
|
|
||||||
@@ -894,7 +911,7 @@ msgstr "Usuario"
|
|||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:131
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:131
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:28
|
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:28
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:75
|
#: 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
|
#: allianceauth/srp/templates/srp/management.html:46
|
||||||
msgid "Actions"
|
msgid "Actions"
|
||||||
msgstr "Acciones"
|
msgstr "Acciones"
|
||||||
@@ -904,7 +921,7 @@ msgstr "Acciones"
|
|||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:147
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:147
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:40
|
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:40
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:16
|
#: allianceauth/hrapplications/templates/hrapplications/view.html:16
|
||||||
#: allianceauth/srp/templates/srp/data.html:117
|
#: allianceauth/srp/templates/srp/data.html:126
|
||||||
msgid "Approved"
|
msgid "Approved"
|
||||||
msgstr "Aprovado"
|
msgstr "Aprovado"
|
||||||
|
|
||||||
@@ -912,7 +929,7 @@ msgstr "Aprovado"
|
|||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:104
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:104
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:149
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:149
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:42
|
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:42
|
||||||
#: allianceauth/srp/templates/srp/data.html:121
|
#: allianceauth/srp/templates/srp/data.html:130
|
||||||
msgid "Rejected"
|
msgid "Rejected"
|
||||||
msgstr "Rechazado"
|
msgstr "Rechazado"
|
||||||
|
|
||||||
@@ -1295,22 +1312,49 @@ msgstr "Contraseña"
|
|||||||
msgid "Password must be at least 8 characters long."
|
msgid "Password must be at least 8 characters long."
|
||||||
msgstr "La contraseña tiene que tener 8 caracteres de largo minimo"
|
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"
|
msgid "Link Discord Server"
|
||||||
msgstr "Enlace a servidor de Discord"
|
msgstr "Enlace a servidor de Discord"
|
||||||
|
|
||||||
#: allianceauth/services/modules/discord/views.py:26
|
#: allianceauth/services/modules/discord/views.py:30
|
||||||
msgid "Deactivated Discord account."
|
msgid "Deactivated Discord account."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/services/modules/discord/views.py:29
|
#: allianceauth/services/modules/discord/views.py:36
|
||||||
#: allianceauth/services/modules/discord/views.py:41
|
#: allianceauth/services/modules/discord/views.py:59
|
||||||
#: allianceauth/services/modules/discord/views.py:65
|
|
||||||
msgid "An error occurred while processing your Discord account."
|
msgid "An error occurred while processing your Discord account."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/services/modules/discord/views.py:62
|
#: allianceauth/services/modules/discord/views.py:102
|
||||||
msgid "Activated Discord account."
|
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 ""
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/services/modules/discourse/views.py:37
|
#: allianceauth/services/modules/discourse/views.py:37
|
||||||
@@ -1575,7 +1619,7 @@ msgstr "Servicio"
|
|||||||
msgid "Domain"
|
msgid "Domain"
|
||||||
msgstr "Dominio"
|
msgstr "Dominio"
|
||||||
|
|
||||||
#: allianceauth/srp/auth_hooks.py:9
|
#: allianceauth/srp/auth_hooks.py:12
|
||||||
msgid "Ship Replacement"
|
msgid "Ship Replacement"
|
||||||
msgstr "Reemplazo de Nave"
|
msgstr "Reemplazo de Nave"
|
||||||
|
|
||||||
@@ -1589,7 +1633,7 @@ msgstr "Hora de flota"
|
|||||||
msgid "Fleet Doctrine"
|
msgid "Fleet Doctrine"
|
||||||
msgstr "Doctrina"
|
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"
|
msgid "Additional Info"
|
||||||
msgstr "Informacion Adicional"
|
msgstr "Informacion Adicional"
|
||||||
|
|
||||||
@@ -1618,63 +1662,63 @@ msgstr "Crear SRP"
|
|||||||
msgid "Give this link to the line members"
|
msgid "Give this link to the line members"
|
||||||
msgstr "Entregar este enlace a los miembros"
|
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"
|
msgid "SRP Fleet Data"
|
||||||
msgstr "Informacion de SRP de la flota"
|
msgstr "Informacion de SRP de la flota"
|
||||||
|
|
||||||
#: allianceauth/srp/templates/srp/data.html:53
|
#: allianceauth/srp/templates/srp/data.html:54
|
||||||
msgid "Mark Incomplete"
|
msgid "Mark Incomplete"
|
||||||
msgstr "Marcar como Incompleto"
|
msgstr "Marcar como Incompleto"
|
||||||
|
|
||||||
#: allianceauth/srp/templates/srp/data.html:57
|
#: allianceauth/srp/templates/srp/data.html:58
|
||||||
msgid "Mark Completed"
|
msgid "Mark Completed"
|
||||||
msgstr "Marcar como Completo"
|
msgstr "Marcar como Completo"
|
||||||
|
|
||||||
#: allianceauth/srp/templates/srp/data.html:69
|
#: allianceauth/srp/templates/srp/data.html:70
|
||||||
#: allianceauth/srp/templates/srp/data.html:145
|
#: allianceauth/srp/templates/srp/data.html:156
|
||||||
msgid "Total Losses:"
|
msgid "Total Losses:"
|
||||||
msgstr "Perdidas Totales:"
|
msgstr "Perdidas Totales:"
|
||||||
|
|
||||||
#: allianceauth/srp/templates/srp/data.html:70
|
#: allianceauth/srp/templates/srp/data.html:71
|
||||||
#: allianceauth/srp/templates/srp/data.html:146
|
#: allianceauth/srp/templates/srp/data.html:157
|
||||||
#: allianceauth/srp/templates/srp/management.html:30
|
#: allianceauth/srp/templates/srp/management.html:30
|
||||||
msgid "Total ISK Cost:"
|
msgid "Total ISK Cost:"
|
||||||
msgstr "Costo Total:"
|
msgstr "Costo Total:"
|
||||||
|
|
||||||
#: allianceauth/srp/templates/srp/data.html:78
|
#: allianceauth/srp/templates/srp/data.html:79
|
||||||
#: allianceauth/srp/templates/srp/data.html:154
|
#: allianceauth/srp/templates/srp/data.html:165
|
||||||
msgid "Are you sure you want to delete SRP requests?"
|
msgid "Are you sure you want to delete SRP requests?"
|
||||||
msgstr "Estas seguro que quiere borrar las solicitudes de SRP"
|
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"
|
msgid "Pilot Name"
|
||||||
msgstr "Nombre del Piloto"
|
msgstr "Nombre del Piloto"
|
||||||
|
|
||||||
#: allianceauth/srp/templates/srp/data.html:88
|
#: allianceauth/srp/templates/srp/data.html:89
|
||||||
msgid "Killboard Link"
|
msgid "Killboard Link"
|
||||||
msgstr "Enlace de la Muerte"
|
msgstr "Enlace de la Muerte"
|
||||||
|
|
||||||
#: allianceauth/srp/templates/srp/data.html:90
|
#: allianceauth/srp/templates/srp/data.html:91
|
||||||
msgid "Ship Type"
|
msgid "Ship Type"
|
||||||
msgstr "Tipo"
|
msgstr "Tipo"
|
||||||
|
|
||||||
#: allianceauth/srp/templates/srp/data.html:91
|
#: allianceauth/srp/templates/srp/data.html:92
|
||||||
msgid "Killboard Loss Amt"
|
msgid "Killboard Loss Amt"
|
||||||
msgstr "Monto de la perdida en ZKB"
|
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"
|
msgid "SRP ISK Cost"
|
||||||
msgstr "Costo del SRP"
|
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"
|
msgid "Click value to edit Enter to save & next ESC to cancel"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/srp/templates/srp/data.html:96
|
#: allianceauth/srp/templates/srp/data.html:97
|
||||||
msgid "Post Time"
|
msgid "Post Time"
|
||||||
msgstr "Tiempo"
|
msgstr "Tiempo"
|
||||||
|
|
||||||
#: allianceauth/srp/templates/srp/data.html:163
|
#: allianceauth/srp/templates/srp/data.html:174
|
||||||
msgid "No SRP requests for this fleet."
|
msgid "No SRP requests for this fleet."
|
||||||
msgstr "No hay solicitudes de SRP para esta flota."
|
msgstr "No hay solicitudes de SRP para esta flota."
|
||||||
|
|
||||||
@@ -1866,32 +1910,30 @@ msgid "Current"
|
|||||||
msgstr "Actual"
|
msgstr "Actual"
|
||||||
|
|
||||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:40
|
#: allianceauth/templates/allianceauth/admin-status/overview.html:40
|
||||||
msgid "Latest Major"
|
msgid "Latest Stable"
|
||||||
msgstr "Ultimo Importante"
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:46
|
#: 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"
|
msgid "Update available"
|
||||||
msgstr "Actualizacion Disponible"
|
msgstr "Actualizacion Disponible"
|
||||||
|
|
||||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:50
|
#: allianceauth/templates/allianceauth/admin-status/overview.html:51
|
||||||
msgid "Latest Minor"
|
msgid "Latest Pre-Release"
|
||||||
msgstr "Ultimo no importante"
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:60
|
#: allianceauth/templates/allianceauth/admin-status/overview.html:57
|
||||||
msgid "Latest Patch"
|
msgid "Pre-Release available"
|
||||||
msgstr "Ultimo Parche"
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:73
|
#: allianceauth/templates/allianceauth/admin-status/overview.html:65
|
||||||
msgid "Task Queue"
|
msgid "Task Queue"
|
||||||
msgstr "Cola de Tareas"
|
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"
|
msgid "Error retrieving task queue length"
|
||||||
msgstr "Error al conseguir la cola de tareas"
|
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
|
#, python-format
|
||||||
msgid "%(tasks)s task"
|
msgid "%(tasks)s task"
|
||||||
msgid_plural "%(tasks)s tasks"
|
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
|
#: allianceauth/timerboard/views.py:83
|
||||||
msgid "Saved changes to the timer."
|
msgid "Saved changes to the timer."
|
||||||
msgstr "Se guardaron los cambios en el timer."
|
msgstr "Se guardaron los cambios en el timer."
|
||||||
|
|
||||||
|
#~ msgid "Portrait"
|
||||||
|
#~ msgstr "Retrato"
|
||||||
|
|||||||
BIN
allianceauth/locale/fr_FR/LC_MESSAGES/django.mo
Normal file
BIN
allianceauth/locale/fr_FR/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
2096
allianceauth/locale/fr_FR/LC_MESSAGES/django.po
Normal file
2096
allianceauth/locale/fr_FR/LC_MESSAGES/django.po
Normal file
File diff suppressed because it is too large
Load Diff
BIN
allianceauth/locale/ja/LC_MESSAGES/django.mo
Normal file
BIN
allianceauth/locale/ja/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
2070
allianceauth/locale/ja/LC_MESSAGES/django.po
Normal file
2070
allianceauth/locale/ja/LC_MESSAGES/django.po
Normal file
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -4,19 +4,20 @@
|
|||||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||||
#
|
#
|
||||||
# Translators:
|
# Translators:
|
||||||
# Lahty <js03js70@gmail.com>, 2020
|
# None None <khd1226543@gmail.com>, 2020
|
||||||
# Kim Hyundong <khd1226543@gmail.com>, 2020
|
|
||||||
# Seowon Jung <seowon@hawaii.edu>, 2020
|
# Seowon Jung <seowon@hawaii.edu>, 2020
|
||||||
# Olgeda Choi <undead.choi@gmail.com>, 2020
|
# Olgeda Choi <undead.choi@gmail.com>, 2020
|
||||||
|
# Lahty <js03js70@gmail.com>, 2020
|
||||||
|
# Joel Falknau <ozirascal@gmail.com>, 2020
|
||||||
#
|
#
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \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"
|
"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"
|
"Language-Team: Korean (Korea) (https://www.transifex.com/alliance-auth/teams/107430/ko_KR/)\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\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."
|
msgid "A main character is required to perform that action. Add one below."
|
||||||
msgstr "해당 기능을 수행하려면 주 캐릭터가 요구됨. 아래에 하나를 추가하시오."
|
msgstr "해당 기능을 수행하려면 주 캐릭터가 요구됨. 아래에 하나를 추가하시오."
|
||||||
|
|
||||||
#: allianceauth/authentication/forms.py:6
|
#: allianceauth/authentication/forms.py:5
|
||||||
msgid "Email"
|
msgid "Email"
|
||||||
msgstr "이메일"
|
msgstr "이메일"
|
||||||
|
|
||||||
#: allianceauth/authentication/models.py:76
|
#: allianceauth/authentication/models.py:78
|
||||||
msgid "State Changed"
|
|
||||||
msgstr "상태 변경됨"
|
|
||||||
|
|
||||||
#: allianceauth/authentication/models.py:77
|
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Your user state has been changed to %(state)s"
|
msgid "State changed to: %s"
|
||||||
msgstr "사용자의 상태가 %(state)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:5
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:8
|
#: allianceauth/authentication/templates/authentication/dashboard.html:8
|
||||||
#: allianceauth/templates/allianceauth/side-menu.html:10
|
#: allianceauth/templates/allianceauth/side-menu.html:11
|
||||||
msgid "Dashboard"
|
msgid "Dashboard"
|
||||||
msgstr "대시보드"
|
msgstr "대시보드"
|
||||||
|
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:17
|
#: allianceauth/authentication/templates/authentication/dashboard.html:18
|
||||||
#: allianceauth/corputils/templates/corputils/corpstats.html:116
|
#, python-format
|
||||||
#: allianceauth/corputils/templates/corputils/search.html:16
|
msgid ""
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticscorpview.html:22
|
"\n"
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:83
|
" Main Character (State: %(state)s)\n"
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:128
|
" "
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:25
|
msgstr ""
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:32
|
"\n"
|
||||||
msgid "Main Character"
|
" 메인 캐릭터 (상태: %(state)s)\n"
|
||||||
msgstr "주 캐릭터"
|
" "
|
||||||
|
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:77
|
#: allianceauth/authentication/templates/authentication/dashboard.html:81
|
||||||
msgid "No main character set."
|
msgid "No main character set."
|
||||||
msgstr "주 캐릭터가 지정되지 않음"
|
msgstr "주 캐릭터가 지정되지 않음"
|
||||||
|
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:84
|
#: allianceauth/authentication/templates/authentication/dashboard.html:88
|
||||||
msgid "Add Character"
|
msgid "Add Character"
|
||||||
msgstr "캐릭터 추가"
|
msgstr "캐릭터 추가"
|
||||||
|
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:88
|
#: allianceauth/authentication/templates/authentication/dashboard.html:92
|
||||||
msgid "Change Main"
|
msgid "Change Main"
|
||||||
msgstr "주 캐릭터 변경"
|
msgstr "주 캐릭터 변경"
|
||||||
|
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:97
|
#: allianceauth/authentication/templates/authentication/dashboard.html:101
|
||||||
msgid "Group Memberships"
|
msgid "Group Memberships"
|
||||||
msgstr "그룹 멤버쉽"
|
msgstr "그룹 멤버쉽"
|
||||||
|
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:117
|
#: allianceauth/authentication/templates/authentication/dashboard.html:121
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticscorpview.html:23
|
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticscorpview.html:23
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:41
|
#: allianceauth/hrapplications/templates/hrapplications/view.html:41
|
||||||
msgid "Characters"
|
msgid "Characters"
|
||||||
msgstr "캐릭터"
|
msgstr "캐릭터"
|
||||||
|
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:125
|
#: allianceauth/authentication/templates/authentication/dashboard.html:129
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:73
|
#: 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/groupmanagement/templates/groupmanagement/groups.html:15
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:45
|
#: allianceauth/hrapplications/templates/hrapplications/view.html:45
|
||||||
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:34
|
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:34
|
||||||
msgid "Name"
|
msgid "Name"
|
||||||
msgstr "이름"
|
msgstr "이름"
|
||||||
|
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:126
|
#: allianceauth/authentication/templates/authentication/dashboard.html:130
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticsview.html:23
|
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticsview.html:23
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:46
|
#: allianceauth/hrapplications/templates/hrapplications/view.html:46
|
||||||
msgid "Corp"
|
msgid "Corp"
|
||||||
msgstr "콥"
|
msgstr "콥"
|
||||||
|
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:127
|
#: allianceauth/authentication/templates/authentication/dashboard.html:131
|
||||||
#: allianceauth/corputils/templates/corputils/corpstats.html:77
|
#: allianceauth/corputils/templates/corputils/corpstats.html:77
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:47
|
#: allianceauth/hrapplications/templates/hrapplications/view.html:47
|
||||||
msgid "Alliance"
|
msgid "Alliance"
|
||||||
@@ -151,33 +153,33 @@ msgstr "주 캐릭터가 %(char)s로 변경됨"
|
|||||||
#: allianceauth/authentication/views.py:89
|
#: allianceauth/authentication/views.py:89
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Added %(name)s to your account."
|
msgid "Added %(name)s to your account."
|
||||||
msgstr "%(name)s을(를) 계정에 추가함"
|
msgstr "계정에 %(name)s를 추가했습니다."
|
||||||
|
|
||||||
#: allianceauth/authentication/views.py:91
|
#: allianceauth/authentication/views.py:91
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Failed to add %(name)s to your account: they already have an account."
|
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
|
#: allianceauth/authentication/views.py:130
|
||||||
msgid "Unable to authenticate as the selected character."
|
msgid "Unable to authenticate as the selected character."
|
||||||
msgstr "선택한 캐릭터로 인증을 수행할 수 없음"
|
msgstr "선택한 캐릭터로 인증을 수행할 수 없음"
|
||||||
|
|
||||||
#: allianceauth/authentication/views.py:148
|
#: allianceauth/authentication/views.py:151
|
||||||
msgid "Registration token has expired."
|
msgid "Registration token has expired."
|
||||||
msgstr "등록토큰 만료"
|
msgstr "등록토큰 만료"
|
||||||
|
|
||||||
#: allianceauth/authentication/views.py:200
|
#: allianceauth/authentication/views.py:206
|
||||||
msgid ""
|
msgid ""
|
||||||
"Sent confirmation email. Please follow the link to confirm your email "
|
"Sent confirmation email. Please follow the link to confirm your email "
|
||||||
"address."
|
"address."
|
||||||
msgstr "확인 메일 전송됨. 다음 링크를 눌러 이메일 주소를 확인하세요."
|
msgstr "확인 메일 전송됨. 다음 링크를 눌러 이메일 주소를 확인하세요."
|
||||||
|
|
||||||
#: allianceauth/authentication/views.py:205
|
#: allianceauth/authentication/views.py:211
|
||||||
msgid "Confirmed your email address. Please login to continue."
|
msgid "Confirmed your email address. Please login to continue."
|
||||||
msgstr "이메일 주소가 확인되었습니다. 로그인 해주세요."
|
msgstr "이메일 주소가 확인되었습니다. 로그인 해주세요."
|
||||||
|
|
||||||
#: allianceauth/authentication/views.py:210
|
#: allianceauth/authentication/views.py:216
|
||||||
msgid "Registraion of new accounts it not allowed at this time."
|
msgid "Registration of new accounts is not allowed at this time."
|
||||||
msgstr "현재 새로운 계정 등록은 받지않습니다."
|
msgstr "현재 새로운 계정 등록은 받지않습니다."
|
||||||
|
|
||||||
#: allianceauth/corputils/auth_hooks.py:10
|
#: allianceauth/corputils/auth_hooks.py:10
|
||||||
@@ -225,16 +227,16 @@ msgstr "마지막 업데이트"
|
|||||||
#: allianceauth/corputils/templates/corputils/search.html:13
|
#: allianceauth/corputils/templates/corputils/search.html:13
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html:24
|
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html:24
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:28
|
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:28
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:27
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:30
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:29
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:30
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:37
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:51
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:96
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:109
|
||||||
msgid "Character"
|
msgid "Character"
|
||||||
msgstr "캐릭터"
|
msgstr "캐릭터"
|
||||||
|
|
||||||
#: allianceauth/corputils/templates/corputils/corpstats.html:76
|
#: allianceauth/corputils/templates/corputils/corpstats.html:76
|
||||||
#: allianceauth/corputils/templates/corputils/search.html:14
|
#: 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:27
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:84
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:84
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:129
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:129
|
||||||
@@ -250,6 +252,16 @@ msgstr "콥"
|
|||||||
msgid "Killboard"
|
msgid "Killboard"
|
||||||
msgstr "킬보드"
|
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/corpstats.html:117
|
||||||
#: allianceauth/corputils/templates/corputils/search.html:17
|
#: allianceauth/corputils/templates/corputils/search.html:17
|
||||||
msgid "Main Corporation"
|
msgid "Main Corporation"
|
||||||
@@ -531,31 +543,35 @@ msgstr "플릿 참여 등록됨"
|
|||||||
msgid "FAT link has expired."
|
msgid "FAT link has expired."
|
||||||
msgstr "플릿활동추적 링크 기한만료"
|
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:5
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:13
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:14
|
||||||
msgid "Audit Log"
|
msgid "Audit Log"
|
||||||
msgstr "감사 기록"
|
msgstr "감사 기록"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:18
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:20
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:20
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:21
|
||||||
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:13
|
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:13
|
||||||
msgid "Back"
|
msgid "Back"
|
||||||
msgstr "돌아가기"
|
msgstr "돌아가기"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:25
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:28
|
||||||
msgid "Date/Time"
|
msgid "Date/Time"
|
||||||
msgstr "날짜/시간"
|
msgstr "날짜/시간"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:26
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:29
|
||||||
msgid "Requestor"
|
msgid "Requestor"
|
||||||
msgstr "요청인"
|
msgstr "요청인"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:29
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:32
|
||||||
msgid "Type"
|
msgid "Type"
|
||||||
msgstr "타입"
|
msgstr "타입"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:30
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:33
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:17
|
|
||||||
#: allianceauth/notifications/templates/notifications/list.html:37
|
#: allianceauth/notifications/templates/notifications/list.html:37
|
||||||
#: allianceauth/notifications/templates/notifications/list.html:69
|
#: allianceauth/notifications/templates/notifications/list.html:69
|
||||||
#: allianceauth/optimer/templates/optimer/fleetoptable.html:18
|
#: allianceauth/optimer/templates/optimer/fleetoptable.html:18
|
||||||
@@ -566,11 +582,19 @@ msgstr "타입"
|
|||||||
msgid "Action"
|
msgid "Action"
|
||||||
msgstr "활동"
|
msgstr "활동"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:31
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:34
|
||||||
msgid "Actor"
|
msgid "Actor"
|
||||||
msgstr "활동한 사람"
|
msgstr "활동한 사람"
|
||||||
|
|
||||||
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:47
|
||||||
|
msgid "Removed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:59
|
#: 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."
|
msgid "No entries found for this group."
|
||||||
msgstr "이 그룹에는 항목 없음"
|
msgstr "이 그룹에는 항목 없음"
|
||||||
|
|
||||||
@@ -578,22 +602,24 @@ msgstr "이 그룹에는 항목 없음"
|
|||||||
msgid "Group Members"
|
msgid "Group Members"
|
||||||
msgstr "그룹 멤버"
|
msgstr "그룹 멤버"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:28
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:31
|
||||||
msgid "Portrait"
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:52
|
||||||
msgstr "포트레잇"
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:110
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:30
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:38
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:97
|
|
||||||
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:23
|
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:23
|
||||||
msgid "Organization"
|
msgid "Organization"
|
||||||
msgstr "조직"
|
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"
|
msgid "Remove from group"
|
||||||
msgstr "그룹에서 제거"
|
msgstr "그룹에서 제거"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:76
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:81
|
||||||
msgid "No group members to list."
|
msgid "No group members to list."
|
||||||
msgstr "목록에 그룹 멤버 없음"
|
msgstr "목록에 그룹 멤버 없음"
|
||||||
|
|
||||||
@@ -601,56 +627,56 @@ msgstr "목록에 그룹 멤버 없음"
|
|||||||
msgid "Groups Membership"
|
msgid "Groups Membership"
|
||||||
msgstr "그룹 멤버쉽"
|
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/permissions_tool/templates/permissions_tool/overview.html:40
|
||||||
#: allianceauth/templates/allianceauth/side-menu.html:15
|
#: allianceauth/templates/allianceauth/side-menu.html:16
|
||||||
msgid "Groups"
|
msgid "Groups"
|
||||||
msgstr "그룹"
|
msgstr "그룹"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:23
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:25
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:16
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:16
|
||||||
msgid "Description"
|
msgid "Description"
|
||||||
msgstr "설명"
|
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:28
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:85
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:85
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:130
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:130
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:27
|
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:27
|
||||||
#: allianceauth/srp/templates/srp/data.html:97
|
#: allianceauth/srp/templates/srp/data.html:98
|
||||||
msgid "Status"
|
msgid "Status"
|
||||||
msgstr "상태"
|
msgstr "상태"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:25
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:27
|
||||||
msgid "Member Count"
|
msgid "Member Count"
|
||||||
msgstr "멤버 수"
|
msgstr "멤버 수"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:38
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:43
|
||||||
msgid "Hidden"
|
msgid "Hidden"
|
||||||
msgstr "숨김"
|
msgstr "숨김"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:40
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:45
|
||||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:12
|
#: allianceauth/templates/allianceauth/admin-status/overview.html:12
|
||||||
msgid "Open"
|
msgid "Open"
|
||||||
msgstr "열기"
|
msgstr "열기"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:42
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:47
|
||||||
msgid "Requestable"
|
msgid "Requestable"
|
||||||
msgstr "요청 가능"
|
msgstr "요청 가능"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:50
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:56
|
||||||
msgid "View Members"
|
msgid "View Members"
|
||||||
msgstr "멤버 보기"
|
msgstr "멤버 보기"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:53
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:60
|
||||||
msgid "Audit Members"
|
msgid "Audit Members"
|
||||||
msgstr "멤버 검사"
|
msgstr "멤버 검사"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:56
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:64
|
||||||
msgid "Copy Direrct Join Link"
|
msgid "Copy Direct Join Link"
|
||||||
msgstr ""
|
msgstr "직접 참여 링크 복사"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:68
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:75
|
||||||
msgid "No groups to list."
|
msgid "No groups to list."
|
||||||
msgstr "목록에 그룹 없음"
|
msgstr "목록에 그룹 없음"
|
||||||
|
|
||||||
@@ -659,19 +685,19 @@ msgstr "목록에 그룹 없음"
|
|||||||
msgid "Available Groups"
|
msgid "Available Groups"
|
||||||
msgstr "사용 가능한 그룹"
|
msgstr "사용 가능한 그룹"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:29
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:30
|
||||||
msgid "Leave"
|
msgid "Leave"
|
||||||
msgstr "떠나기"
|
msgstr "떠나기"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:39
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:40
|
||||||
msgid "Join"
|
msgid "Join"
|
||||||
msgstr "참여하기"
|
msgstr "참여하기"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:43
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:44
|
||||||
msgid "Request"
|
msgid "Request"
|
||||||
msgstr "요청하기"
|
msgstr "요청하기"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:58
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:59
|
||||||
msgid "No groups available."
|
msgid "No groups available."
|
||||||
msgstr "사용 가능한 그룹 없음."
|
msgstr "사용 가능한 그룹 없음."
|
||||||
|
|
||||||
@@ -679,155 +705,150 @@ msgstr "사용 가능한 그룹 없음."
|
|||||||
msgid "Groups Management"
|
msgid "Groups Management"
|
||||||
msgstr "그룹 관리"
|
msgstr "그룹 관리"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:23
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:25
|
||||||
msgid "Join Requests"
|
msgid "Join Requests"
|
||||||
msgstr "가입 요청"
|
msgstr "가입 요청"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:24
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:34
|
||||||
msgid "Leave Requests"
|
msgid "Leave Requests"
|
||||||
msgstr "탈퇴 요청"
|
msgstr "탈퇴 요청"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:39
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:53
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:98
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:111
|
||||||
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:20
|
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:20
|
||||||
#: allianceauth/services/modules/openfire/forms.py:6
|
#: allianceauth/services/modules/openfire/forms.py:6
|
||||||
msgid "Group"
|
msgid "Group"
|
||||||
msgstr "그룹"
|
msgstr "그룹"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:71
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:84
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:130
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:142
|
||||||
msgid "Accept"
|
msgid "Accept"
|
||||||
msgstr "수락"
|
msgstr "수락"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:74
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:88
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:133
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:146
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:85
|
#: allianceauth/hrapplications/templates/hrapplications/view.html:85
|
||||||
msgid "Reject"
|
msgid "Reject"
|
||||||
msgstr "거절"
|
msgstr "거절"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:83
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:97
|
||||||
msgid "No group add requests."
|
msgid "No group add requests."
|
||||||
msgstr "가입 요청 없음"
|
msgstr "가입 요청 없음"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:142
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:155
|
||||||
msgid "No group leave requests."
|
msgid "No group leave requests."
|
||||||
msgstr "탈퇴 요청 없음"
|
msgstr "탈퇴 요청 없음"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:10
|
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:9
|
||||||
msgid "Toggle navigation"
|
msgid "Toggle navigation"
|
||||||
msgstr "네비게이션 전환"
|
msgstr "네비게이션 전환"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:15
|
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:20
|
||||||
#: allianceauth/templates/allianceauth/side-menu.html:23
|
|
||||||
msgid "Group Management"
|
|
||||||
msgstr "그룹 관리"
|
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:21
|
|
||||||
msgid "Group Requests"
|
msgid "Group Requests"
|
||||||
msgstr "그룹 요청"
|
msgstr "그룹 요청"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:24
|
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:23
|
||||||
msgid "Group Membership"
|
msgid "Group Membership"
|
||||||
msgstr "그룹 멤버쉽"
|
msgstr "그룹 멤버쉽"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:166
|
#: allianceauth/groupmanagement/views.py:162
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Removed user %(user)s from group %(group)s."
|
msgid "Removed user %(user)s from group %(group)s."
|
||||||
msgstr "유저 %(user)s이(가) %(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"
|
msgid "User does not exist in that group"
|
||||||
msgstr "유저가 해당 그룹에 존재하지 않음."
|
msgstr "유저가 해당 그룹에 존재하지 않음."
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:171
|
#: allianceauth/groupmanagement/views.py:167
|
||||||
msgid "Group does not exist"
|
msgid "Group does not exist"
|
||||||
msgstr "그룹이 존재하지 않음."
|
msgstr "그룹이 존재하지 않음."
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:198
|
#: allianceauth/groupmanagement/views.py:194
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Accepted application from %(mainchar)s to %(group)s."
|
msgid "Accepted application from %(mainchar)s to %(group)s."
|
||||||
msgstr "%(mainchar)s의 %(group)s 그룹 신청 수락"
|
msgstr "%(mainchar)s의 %(group)s 그룹 신청 수락"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:205
|
#: allianceauth/groupmanagement/views.py:201
|
||||||
#: allianceauth/groupmanagement/views.py:238
|
#: allianceauth/groupmanagement/views.py:234
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"An unhandled error occurred while processing the application from "
|
"An unhandled error occurred while processing the application from "
|
||||||
"%(mainchar)s to %(group)s."
|
"%(mainchar)s to %(group)s."
|
||||||
msgstr "%(mainchar)s의 %(group)s 그룹 신청을 처리하는 중 알 수 없는 에러 발생"
|
msgstr "%(mainchar)s의 %(group)s 그룹 신청을 처리하는 중 알 수 없는 에러 발생"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:231
|
#: allianceauth/groupmanagement/views.py:227
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Rejected application from %(mainchar)s to %(group)s."
|
msgid "Rejected application from %(mainchar)s to %(group)s."
|
||||||
msgstr "%(mainchar)s의 %(group)s 그룹 신청 거절"
|
msgstr "%(mainchar)s의 %(group)s 그룹 신청 거절"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:267
|
#: allianceauth/groupmanagement/views.py:263
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Accepted application from %(mainchar)s to leave %(group)s."
|
msgid "Accepted application from %(mainchar)s to leave %(group)s."
|
||||||
msgstr "%(mainchar)s의 %(group)s 그룹 탈퇴 수락"
|
msgstr "%(mainchar)s의 %(group)s 그룹 탈퇴 수락"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:273
|
#: allianceauth/groupmanagement/views.py:269
|
||||||
#: allianceauth/groupmanagement/views.py:307
|
#: allianceauth/groupmanagement/views.py:303
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"An unhandled error occurred while processing the application from "
|
"An unhandled error occurred while processing the application from "
|
||||||
"%(mainchar)s to leave %(group)s."
|
"%(mainchar)s to leave %(group)s."
|
||||||
msgstr "%(mainchar)s의 %(group)s 그룹 탈퇴를 처리하는 중 알 수 없는 에러 발생"
|
msgstr "%(mainchar)s의 %(group)s 그룹 탈퇴를 처리하는 중 알 수 없는 에러 발생"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:300
|
#: allianceauth/groupmanagement/views.py:296
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Rejected application from %(mainchar)s to leave %(group)s."
|
msgid "Rejected application from %(mainchar)s to leave %(group)s."
|
||||||
msgstr "%(mainchar)s의 %(group)s 그룹 탈퇴 거절"
|
msgstr "%(mainchar)s의 %(group)s 그룹 탈퇴 거절"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:346
|
#: allianceauth/groupmanagement/views.py:342
|
||||||
#: allianceauth/groupmanagement/views.py:358
|
#: allianceauth/groupmanagement/views.py:354
|
||||||
msgid "You cannot join that group"
|
msgid "You cannot join that group"
|
||||||
msgstr "해당 그룹에 참여할 수 없습니다."
|
msgstr "해당 그룹에 참여할 수 없습니다."
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:352
|
#: allianceauth/groupmanagement/views.py:348
|
||||||
msgid "You are already a member of that group."
|
msgid "You are already a member of that group."
|
||||||
msgstr "이미 해당 그룹에 가입되어 있습니다."
|
msgstr "이미 해당 그룹에 가입되어 있습니다."
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:367
|
#: allianceauth/groupmanagement/views.py:363
|
||||||
msgid "You already have a pending application for that group."
|
msgid "You already have a pending application for that group."
|
||||||
msgstr "해당 그룹에 대한 참여신청이 보류되었습니다."
|
msgstr "해당 그룹에 대한 참여신청이 보류되었습니다."
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:370
|
#: allianceauth/groupmanagement/views.py:366
|
||||||
#: allianceauth/groupmanagement/views.py:408
|
#: allianceauth/groupmanagement/views.py:404
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:37
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:37
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:72
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:72
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:99
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:99
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:144
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:144
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:38
|
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:38
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:20
|
#: 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
|
#: allianceauth/srp/templates/srp/management.html:81
|
||||||
msgid "Pending"
|
msgid "Pending"
|
||||||
msgstr "보류 중"
|
msgstr "보류 중"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:376
|
#: allianceauth/groupmanagement/views.py:372
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Applied to group %(group)s."
|
msgid "Applied to group %(group)s."
|
||||||
msgstr "%(group)s그룹에 지원하였음."
|
msgstr "%(group)s그룹에 지원하였음."
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:387
|
#: allianceauth/groupmanagement/views.py:383
|
||||||
msgid "You cannot leave that group"
|
msgid "You cannot leave that group"
|
||||||
msgstr "해당 그룹을 떠날 수 없습니다."
|
msgstr "해당 그룹을 떠날 수 없습니다."
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:392
|
#: allianceauth/groupmanagement/views.py:388
|
||||||
msgid "You are not a member of that group"
|
msgid "You are not a member of that group"
|
||||||
msgstr "해당그룹의 멤버가 아닙니다."
|
msgstr "해당그룹의 멤버가 아닙니다."
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:401
|
#: allianceauth/groupmanagement/views.py:397
|
||||||
msgid "You already have a pending leave request for that group."
|
msgid "You already have a pending leave request for that group."
|
||||||
msgstr "해당 그룹의 탈퇴 신청이 접수된 상태입니다."
|
msgstr "해당 그룹의 탈퇴 신청이 접수된 상태입니다."
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:414
|
#: allianceauth/groupmanagement/views.py:410
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Applied to leave group %(group)s."
|
msgid "Applied to leave group %(group)s."
|
||||||
msgstr "%(group)s그룹의 탈퇴가 신청됨."
|
msgstr "%(group)s그룹의 탈퇴가 신청됨."
|
||||||
|
|
||||||
#: allianceauth/hrapplications/auth_hooks.py:10
|
#: allianceauth/hrapplications/auth_hooks.py:13
|
||||||
msgid "Applications"
|
msgid "Applications"
|
||||||
msgstr "지원"
|
msgstr "지원"
|
||||||
|
|
||||||
@@ -884,7 +905,7 @@ msgstr "사용자명"
|
|||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:131
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:131
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:28
|
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:28
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:75
|
#: 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
|
#: allianceauth/srp/templates/srp/management.html:46
|
||||||
msgid "Actions"
|
msgid "Actions"
|
||||||
msgstr "활동"
|
msgstr "활동"
|
||||||
@@ -894,7 +915,7 @@ msgstr "활동"
|
|||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:147
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:147
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:40
|
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:40
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:16
|
#: allianceauth/hrapplications/templates/hrapplications/view.html:16
|
||||||
#: allianceauth/srp/templates/srp/data.html:117
|
#: allianceauth/srp/templates/srp/data.html:126
|
||||||
msgid "Approved"
|
msgid "Approved"
|
||||||
msgstr "승인"
|
msgstr "승인"
|
||||||
|
|
||||||
@@ -902,7 +923,7 @@ msgstr "승인"
|
|||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:104
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:104
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:149
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:149
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:42
|
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:42
|
||||||
#: allianceauth/srp/templates/srp/data.html:121
|
#: allianceauth/srp/templates/srp/data.html:130
|
||||||
msgid "Rejected"
|
msgid "Rejected"
|
||||||
msgstr "거절"
|
msgstr "거절"
|
||||||
|
|
||||||
@@ -1285,23 +1306,50 @@ msgstr "비밀번호"
|
|||||||
msgid "Password must be at least 8 characters long."
|
msgid "Password must be at least 8 characters long."
|
||||||
msgstr "비밀번호는 8글자 이상이어야 합니다."
|
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"
|
msgid "Link Discord Server"
|
||||||
msgstr "디스코드 서버 링크"
|
msgstr "디스코드 서버 링크"
|
||||||
|
|
||||||
#: allianceauth/services/modules/discord/views.py:26
|
#: allianceauth/services/modules/discord/views.py:30
|
||||||
msgid "Deactivated Discord account."
|
msgid "Deactivated Discord account."
|
||||||
msgstr "디스코드 계정 해제 완료"
|
msgstr "디스코드 계정 해제 완료"
|
||||||
|
|
||||||
#: allianceauth/services/modules/discord/views.py:29
|
#: allianceauth/services/modules/discord/views.py:36
|
||||||
#: allianceauth/services/modules/discord/views.py:41
|
#: allianceauth/services/modules/discord/views.py:59
|
||||||
#: allianceauth/services/modules/discord/views.py:65
|
|
||||||
msgid "An error occurred while processing your Discord account."
|
msgid "An error occurred while processing your Discord account."
|
||||||
msgstr "디스코드 계정 처리 중 오류가 발생했습니다."
|
msgstr "디스코드 계정 처리 중 오류가 발생했습니다."
|
||||||
|
|
||||||
#: allianceauth/services/modules/discord/views.py:62
|
#: allianceauth/services/modules/discord/views.py:102
|
||||||
msgid "Activated Discord account."
|
msgid "Your Discord account has been successfully activated."
|
||||||
msgstr "디스코드 계정 활성화 완료"
|
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
|
#: allianceauth/services/modules/discourse/views.py:37
|
||||||
msgid "You are not authorized to access Discourse."
|
msgid "You are not authorized to access Discourse."
|
||||||
@@ -1565,7 +1613,7 @@ msgstr "서드파티"
|
|||||||
msgid "Domain"
|
msgid "Domain"
|
||||||
msgstr "도메인"
|
msgstr "도메인"
|
||||||
|
|
||||||
#: allianceauth/srp/auth_hooks.py:9
|
#: allianceauth/srp/auth_hooks.py:12
|
||||||
msgid "Ship Replacement"
|
msgid "Ship Replacement"
|
||||||
msgstr "SRP"
|
msgstr "SRP"
|
||||||
|
|
||||||
@@ -1579,7 +1627,7 @@ msgstr "플릿 시간"
|
|||||||
msgid "Fleet Doctrine"
|
msgid "Fleet Doctrine"
|
||||||
msgstr "플릿 독트린"
|
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"
|
msgid "Additional Info"
|
||||||
msgstr "추가 기재 사항"
|
msgstr "추가 기재 사항"
|
||||||
|
|
||||||
@@ -1608,63 +1656,63 @@ msgstr "SRP 보상 플릿 생성"
|
|||||||
msgid "Give this link to the line members"
|
msgid "Give this link to the line members"
|
||||||
msgstr "이 링크를 직계 멤버들에게 전달"
|
msgstr "이 링크를 직계 멤버들에게 전달"
|
||||||
|
|
||||||
#: allianceauth/srp/templates/srp/data.html:48
|
#: allianceauth/srp/templates/srp/data.html:49
|
||||||
msgid "SRP Fleet Data"
|
msgid "SRP Fleet Data"
|
||||||
msgstr "SRP 보상 플릿 데이터"
|
msgstr "SRP 보상 플릿 데이터"
|
||||||
|
|
||||||
#: allianceauth/srp/templates/srp/data.html:53
|
#: allianceauth/srp/templates/srp/data.html:54
|
||||||
msgid "Mark Incomplete"
|
msgid "Mark Incomplete"
|
||||||
msgstr "표시 미완료"
|
msgstr "표시 미완료"
|
||||||
|
|
||||||
#: allianceauth/srp/templates/srp/data.html:57
|
#: allianceauth/srp/templates/srp/data.html:58
|
||||||
msgid "Mark Completed"
|
msgid "Mark Completed"
|
||||||
msgstr "표시 완료"
|
msgstr "표시 완료"
|
||||||
|
|
||||||
#: allianceauth/srp/templates/srp/data.html:69
|
#: allianceauth/srp/templates/srp/data.html:70
|
||||||
#: allianceauth/srp/templates/srp/data.html:145
|
#: allianceauth/srp/templates/srp/data.html:156
|
||||||
msgid "Total Losses:"
|
msgid "Total Losses:"
|
||||||
msgstr "전체 손실:"
|
msgstr "전체 손실:"
|
||||||
|
|
||||||
#: allianceauth/srp/templates/srp/data.html:70
|
#: allianceauth/srp/templates/srp/data.html:71
|
||||||
#: allianceauth/srp/templates/srp/data.html:146
|
#: allianceauth/srp/templates/srp/data.html:157
|
||||||
#: allianceauth/srp/templates/srp/management.html:30
|
#: allianceauth/srp/templates/srp/management.html:30
|
||||||
msgid "Total ISK Cost:"
|
msgid "Total ISK Cost:"
|
||||||
msgstr "전체 ISK 비용:"
|
msgstr "전체 ISK 비용:"
|
||||||
|
|
||||||
#: allianceauth/srp/templates/srp/data.html:78
|
#: allianceauth/srp/templates/srp/data.html:79
|
||||||
#: allianceauth/srp/templates/srp/data.html:154
|
#: allianceauth/srp/templates/srp/data.html:165
|
||||||
msgid "Are you sure you want to delete SRP requests?"
|
msgid "Are you sure you want to delete SRP requests?"
|
||||||
msgstr "SRP 보상 요청을 삭제하시겠습니까?"
|
msgstr "SRP 보상 요청을 삭제하시겠습니까?"
|
||||||
|
|
||||||
#: allianceauth/srp/templates/srp/data.html:87
|
#: allianceauth/srp/templates/srp/data.html:88
|
||||||
msgid "Pilot Name"
|
msgid "Pilot Name"
|
||||||
msgstr "파일럿 이름"
|
msgstr "파일럿 이름"
|
||||||
|
|
||||||
#: allianceauth/srp/templates/srp/data.html:88
|
#: allianceauth/srp/templates/srp/data.html:89
|
||||||
msgid "Killboard Link"
|
msgid "Killboard Link"
|
||||||
msgstr "킬보드 링크"
|
msgstr "킬보드 링크"
|
||||||
|
|
||||||
#: allianceauth/srp/templates/srp/data.html:90
|
#: allianceauth/srp/templates/srp/data.html:91
|
||||||
msgid "Ship Type"
|
msgid "Ship Type"
|
||||||
msgstr "함선 종류"
|
msgstr "함선 종류"
|
||||||
|
|
||||||
#: allianceauth/srp/templates/srp/data.html:91
|
#: allianceauth/srp/templates/srp/data.html:92
|
||||||
msgid "Killboard Loss Amt"
|
msgid "Killboard Loss Amt"
|
||||||
msgstr "킬보드상 손실 금액"
|
msgstr "킬보드상 손실 금액"
|
||||||
|
|
||||||
#: allianceauth/srp/templates/srp/data.html:92
|
#: allianceauth/srp/templates/srp/data.html:93
|
||||||
msgid "SRP ISK Cost"
|
msgid "SRP ISK Cost"
|
||||||
msgstr "SRP 보상 비용"
|
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"
|
msgid "Click value to edit Enter to save & next ESC to cancel"
|
||||||
msgstr "금액을 수정하려면 클릭, 저장을 하고 다음으로 가려면 엔터, 취소를 하려면 ESC를 누르세요. "
|
msgstr "금액을 수정하려면 클릭, 저장을 하고 다음으로 가려면 엔터, 취소를 하려면 ESC를 누르세요. "
|
||||||
|
|
||||||
#: allianceauth/srp/templates/srp/data.html:96
|
#: allianceauth/srp/templates/srp/data.html:97
|
||||||
msgid "Post Time"
|
msgid "Post Time"
|
||||||
msgstr "작성 시간"
|
msgstr "작성 시간"
|
||||||
|
|
||||||
#: allianceauth/srp/templates/srp/data.html:163
|
#: allianceauth/srp/templates/srp/data.html:174
|
||||||
msgid "No SRP requests for this fleet."
|
msgid "No SRP requests for this fleet."
|
||||||
msgstr "이 플릿에는 SRP 보상 요청이 없습니다."
|
msgstr "이 플릿에는 SRP 보상 요청이 없습니다."
|
||||||
|
|
||||||
@@ -1856,32 +1904,30 @@ msgid "Current"
|
|||||||
msgstr "현재"
|
msgstr "현재"
|
||||||
|
|
||||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:40
|
#: allianceauth/templates/allianceauth/admin-status/overview.html:40
|
||||||
msgid "Latest Major"
|
msgid "Latest Stable"
|
||||||
msgstr "최근 주요 사항"
|
msgstr "최신 안정화 버전"
|
||||||
|
|
||||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:46
|
#: 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"
|
msgid "Update available"
|
||||||
msgstr "업데이트 가능"
|
msgstr "업데이트 가능"
|
||||||
|
|
||||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:50
|
#: allianceauth/templates/allianceauth/admin-status/overview.html:51
|
||||||
msgid "Latest Minor"
|
msgid "Latest Pre-Release"
|
||||||
msgstr "최근 기타 사항"
|
msgstr "최신 사전 출시 버전"
|
||||||
|
|
||||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:60
|
#: allianceauth/templates/allianceauth/admin-status/overview.html:57
|
||||||
msgid "Latest Patch"
|
msgid "Pre-Release available"
|
||||||
msgstr "최근 패치"
|
msgstr "사전 출시 사용 가능"
|
||||||
|
|
||||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:73
|
#: allianceauth/templates/allianceauth/admin-status/overview.html:65
|
||||||
msgid "Task Queue"
|
msgid "Task Queue"
|
||||||
msgstr "대기 중인 할 일"
|
msgstr "대기 중인 할 일"
|
||||||
|
|
||||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:90
|
#: allianceauth/templates/allianceauth/admin-status/overview.html:82
|
||||||
msgid "Error retrieving task queue length"
|
msgid "Error retrieving task queue length"
|
||||||
msgstr "대기 중인 할 일 목록 회수 에러"
|
msgstr "대기 중인 할 일 목록 회수 에러"
|
||||||
|
|
||||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:92
|
#: allianceauth/templates/allianceauth/admin-status/overview.html:84
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%(tasks)s task"
|
msgid "%(tasks)s task"
|
||||||
msgid_plural "%(tasks)s tasks"
|
msgid_plural "%(tasks)s tasks"
|
||||||
@@ -2021,3 +2067,6 @@ msgstr "%(time)s 에 있을 %(system)s 타이머를 추가했습니다."
|
|||||||
#: allianceauth/timerboard/views.py:83
|
#: allianceauth/timerboard/views.py:83
|
||||||
msgid "Saved changes to the timer."
|
msgid "Saved changes to the timer."
|
||||||
msgstr "타이머 변경사항이 저장되었습니다."
|
msgstr "타이머 변경사항이 저장되었습니다."
|
||||||
|
|
||||||
|
#~ msgid "Portrait"
|
||||||
|
#~ msgstr "포트레잇"
|
||||||
|
|||||||
Binary file not shown.
@@ -5,15 +5,17 @@
|
|||||||
#
|
#
|
||||||
# Translators:
|
# Translators:
|
||||||
# Alexander Gess <de.alex.gess@gmail.com>, 2020
|
# Alexander Gess <de.alex.gess@gmail.com>, 2020
|
||||||
|
# Yuriy K <thedjcooltv@gmail.com>, 2020
|
||||||
|
# Андрей Зубков <and.vareba81@gmail.com>, 2020
|
||||||
#
|
#
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \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"
|
"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"
|
"Language-Team: Russian (https://www.transifex.com/alliance-auth/teams/107430/ru/)\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
@@ -25,74 +27,75 @@ msgstr ""
|
|||||||
msgid "A main character is required to perform that action. Add one below."
|
msgid "A main character is required to perform that action. Add one below."
|
||||||
msgstr "Необходимо указать основного персонажа. Добавим?"
|
msgstr "Необходимо указать основного персонажа. Добавим?"
|
||||||
|
|
||||||
#: allianceauth/authentication/forms.py:6
|
#: allianceauth/authentication/forms.py:5
|
||||||
msgid "Email"
|
msgid "Email"
|
||||||
msgstr "Email"
|
msgstr "Email"
|
||||||
|
|
||||||
#: allianceauth/authentication/models.py:76
|
#: allianceauth/authentication/models.py:78
|
||||||
msgid "State Changed"
|
|
||||||
msgstr "Состояние заменено. "
|
|
||||||
|
|
||||||
#: allianceauth/authentication/models.py:77
|
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Your user state has been changed to %(state)s"
|
msgid "State changed to: %s"
|
||||||
msgstr "Статус вашего пользователя сменен на %(state)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:5
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:8
|
#: allianceauth/authentication/templates/authentication/dashboard.html:8
|
||||||
#: allianceauth/templates/allianceauth/side-menu.html:10
|
#: allianceauth/templates/allianceauth/side-menu.html:11
|
||||||
msgid "Dashboard"
|
msgid "Dashboard"
|
||||||
msgstr "Панель показателей"
|
msgstr "Панель показателей"
|
||||||
|
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:17
|
#: allianceauth/authentication/templates/authentication/dashboard.html:18
|
||||||
#: allianceauth/corputils/templates/corputils/corpstats.html:116
|
#, python-format
|
||||||
#: allianceauth/corputils/templates/corputils/search.html:16
|
msgid ""
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticscorpview.html:22
|
"\n"
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:83
|
" Main Character (State: %(state)s)\n"
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:128
|
" "
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:25
|
msgstr ""
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:32
|
"\n"
|
||||||
msgid "Main Character"
|
" Основной персонаж (статус: %(state)s)\n"
|
||||||
msgstr "Основной персонаж"
|
" "
|
||||||
|
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:77
|
#: allianceauth/authentication/templates/authentication/dashboard.html:81
|
||||||
msgid "No main character set."
|
msgid "No main character set."
|
||||||
msgstr "Основной персонаж не установлен."
|
msgstr "Основной персонаж не установлен."
|
||||||
|
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:84
|
#: allianceauth/authentication/templates/authentication/dashboard.html:88
|
||||||
msgid "Add Character"
|
msgid "Add Character"
|
||||||
msgstr "Добавить Персонажа"
|
msgstr "Добавить Персонажа"
|
||||||
|
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:88
|
#: allianceauth/authentication/templates/authentication/dashboard.html:92
|
||||||
msgid "Change Main"
|
msgid "Change Main"
|
||||||
msgstr "Сменить основного персонажа"
|
msgstr "Сменить основного персонажа"
|
||||||
|
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:97
|
#: allianceauth/authentication/templates/authentication/dashboard.html:101
|
||||||
msgid "Group Memberships"
|
msgid "Group Memberships"
|
||||||
msgstr "Групповое участие"
|
msgstr "Роли"
|
||||||
|
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:117
|
#: allianceauth/authentication/templates/authentication/dashboard.html:121
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticscorpview.html:23
|
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticscorpview.html:23
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:41
|
#: allianceauth/hrapplications/templates/hrapplications/view.html:41
|
||||||
msgid "Characters"
|
msgid "Characters"
|
||||||
msgstr "Персонажи"
|
msgstr "Персонажи"
|
||||||
|
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:125
|
#: allianceauth/authentication/templates/authentication/dashboard.html:129
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:73
|
#: 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/groupmanagement/templates/groupmanagement/groups.html:15
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:45
|
#: allianceauth/hrapplications/templates/hrapplications/view.html:45
|
||||||
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:34
|
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:34
|
||||||
msgid "Name"
|
msgid "Name"
|
||||||
msgstr "Имя"
|
msgstr "Имя"
|
||||||
|
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:126
|
#: allianceauth/authentication/templates/authentication/dashboard.html:130
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticsview.html:23
|
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticsview.html:23
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:46
|
#: allianceauth/hrapplications/templates/hrapplications/view.html:46
|
||||||
msgid "Corp"
|
msgid "Corp"
|
||||||
msgstr "Корпорация"
|
msgstr "Корпорация"
|
||||||
|
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:127
|
#: allianceauth/authentication/templates/authentication/dashboard.html:131
|
||||||
#: allianceauth/corputils/templates/corputils/corpstats.html:77
|
#: allianceauth/corputils/templates/corputils/corpstats.html:77
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:47
|
#: allianceauth/hrapplications/templates/hrapplications/view.html:47
|
||||||
msgid "Alliance"
|
msgid "Alliance"
|
||||||
@@ -141,6 +144,7 @@ msgid ""
|
|||||||
"Cannot change main character to %(char)s: character owned by a different "
|
"Cannot change main character to %(char)s: character owned by a different "
|
||||||
"account."
|
"account."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Нельзя сменить основного персонажа на %(char)s: похоже, что Владелец не Вы. "
|
||||||
|
|
||||||
#: allianceauth/authentication/views.py:80
|
#: allianceauth/authentication/views.py:80
|
||||||
#, python-format
|
#, python-format
|
||||||
@@ -161,23 +165,23 @@ msgstr "Персонаж %(name)s уже добавлен."
|
|||||||
msgid "Unable to authenticate as the selected character."
|
msgid "Unable to authenticate as the selected character."
|
||||||
msgstr "Невозможно авторизировать этого персонажа. "
|
msgstr "Невозможно авторизировать этого персонажа. "
|
||||||
|
|
||||||
#: allianceauth/authentication/views.py:148
|
#: allianceauth/authentication/views.py:151
|
||||||
msgid "Registration token has expired."
|
msgid "Registration token has expired."
|
||||||
msgstr "Регистрационный токен просрочен."
|
msgstr "Регистрационный токен просрочен."
|
||||||
|
|
||||||
#: allianceauth/authentication/views.py:200
|
#: allianceauth/authentication/views.py:206
|
||||||
msgid ""
|
msgid ""
|
||||||
"Sent confirmation email. Please follow the link to confirm your email "
|
"Sent confirmation email. Please follow the link to confirm your email "
|
||||||
"address."
|
"address."
|
||||||
msgstr "Отправить подтверждающее письмо. Пожалуйста, подтвердите почту. "
|
msgstr "Отправить подтверждающее письмо. Пожалуйста, подтвердите почту. "
|
||||||
|
|
||||||
#: allianceauth/authentication/views.py:205
|
#: allianceauth/authentication/views.py:211
|
||||||
msgid "Confirmed your email address. Please login to continue."
|
msgid "Confirmed your email address. Please login to continue."
|
||||||
msgstr "Подтвердите Ваш email адрес. Зайти для подтверждения. "
|
msgstr "Подтвердите Ваш email адрес. Зайти для подтверждения. "
|
||||||
|
|
||||||
#: allianceauth/authentication/views.py:210
|
#: allianceauth/authentication/views.py:216
|
||||||
msgid "Registraion of new accounts it not allowed at this time."
|
msgid "Registration of new accounts is not allowed at this time."
|
||||||
msgstr "Регистрация нового аккаунта сейчас невозможна."
|
msgstr "Регистрация новых аккаунтов в настоящее время невозможна."
|
||||||
|
|
||||||
#: allianceauth/corputils/auth_hooks.py:10
|
#: allianceauth/corputils/auth_hooks.py:10
|
||||||
msgid "Corporation Stats"
|
msgid "Corporation Stats"
|
||||||
@@ -224,16 +228,16 @@ msgstr "Последнее обновление: "
|
|||||||
#: allianceauth/corputils/templates/corputils/search.html:13
|
#: allianceauth/corputils/templates/corputils/search.html:13
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html:24
|
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html:24
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:28
|
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:28
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:27
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:30
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:29
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:30
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:37
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:51
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:96
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:109
|
||||||
msgid "Character"
|
msgid "Character"
|
||||||
msgstr "Персонаж"
|
msgstr "Персонаж"
|
||||||
|
|
||||||
#: allianceauth/corputils/templates/corputils/corpstats.html:76
|
#: allianceauth/corputils/templates/corputils/corpstats.html:76
|
||||||
#: allianceauth/corputils/templates/corputils/search.html:14
|
#: 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:27
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:84
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:84
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:129
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:129
|
||||||
@@ -249,6 +253,16 @@ msgstr "Корпорация"
|
|||||||
msgid "Killboard"
|
msgid "Killboard"
|
||||||
msgstr "zKillBoard"
|
msgstr "zKillBoard"
|
||||||
|
|
||||||
|
#: 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/corpstats.html:117
|
||||||
#: allianceauth/corputils/templates/corputils/search.html:17
|
#: allianceauth/corputils/templates/corputils/search.html:17
|
||||||
msgid "Main Corporation"
|
msgid "Main Corporation"
|
||||||
@@ -314,7 +328,7 @@ msgstr "Добавить сюда"
|
|||||||
|
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/characternotexisting.html:19
|
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/characternotexisting.html:19
|
||||||
msgid "before attempting to click fleet attendance links."
|
msgid "before attempting to click fleet attendance links."
|
||||||
msgstr "перед вступлением проверте содержимое"
|
msgstr "перед вступлением проверьте содержимое"
|
||||||
|
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkformatter.html:6
|
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkformatter.html:6
|
||||||
msgid "Create Fatlink"
|
msgid "Create Fatlink"
|
||||||
@@ -536,31 +550,35 @@ msgstr "Флотовое участие зарегистрированно."
|
|||||||
msgid "FAT link has expired."
|
msgid "FAT link has expired."
|
||||||
msgstr "ФлАк ссылка устарела"
|
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:5
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:13
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:14
|
||||||
msgid "Audit Log"
|
msgid "Audit Log"
|
||||||
msgstr "Записи безопасности"
|
msgstr "Записи безопасности"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:18
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:20
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:20
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:21
|
||||||
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:13
|
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:13
|
||||||
msgid "Back"
|
msgid "Back"
|
||||||
msgstr "Назад"
|
msgstr "Назад"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:25
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:28
|
||||||
msgid "Date/Time"
|
msgid "Date/Time"
|
||||||
msgstr "Дата / Время"
|
msgstr "Дата / Время"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:26
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:29
|
||||||
msgid "Requestor"
|
msgid "Requestor"
|
||||||
msgstr "Запрос от"
|
msgstr "Запрос от"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:29
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:32
|
||||||
msgid "Type"
|
msgid "Type"
|
||||||
msgstr "Тип"
|
msgstr "Тип"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:30
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:33
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:17
|
|
||||||
#: allianceauth/notifications/templates/notifications/list.html:37
|
#: allianceauth/notifications/templates/notifications/list.html:37
|
||||||
#: allianceauth/notifications/templates/notifications/list.html:69
|
#: allianceauth/notifications/templates/notifications/list.html:69
|
||||||
#: allianceauth/optimer/templates/optimer/fleetoptable.html:18
|
#: allianceauth/optimer/templates/optimer/fleetoptable.html:18
|
||||||
@@ -571,11 +589,19 @@ msgstr "Тип"
|
|||||||
msgid "Action"
|
msgid "Action"
|
||||||
msgstr "Действие"
|
msgstr "Действие"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:31
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:34
|
||||||
msgid "Actor"
|
msgid "Actor"
|
||||||
msgstr "Исполнитель"
|
msgstr "Исполнитель"
|
||||||
|
|
||||||
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:47
|
||||||
|
msgid "Removed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:59
|
#: 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."
|
msgid "No entries found for this group."
|
||||||
msgstr "Нет вхождений в эту группу"
|
msgstr "Нет вхождений в эту группу"
|
||||||
|
|
||||||
@@ -583,22 +609,24 @@ msgstr "Нет вхождений в эту группу"
|
|||||||
msgid "Group Members"
|
msgid "Group Members"
|
||||||
msgstr "Групповые Участники"
|
msgstr "Групповые Участники"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:28
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:31
|
||||||
msgid "Portrait"
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:52
|
||||||
msgstr "Портрет"
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:110
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:30
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:38
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:97
|
|
||||||
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:23
|
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:23
|
||||||
msgid "Organization"
|
msgid "Organization"
|
||||||
msgstr "Корпорация"
|
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"
|
msgid "Remove from group"
|
||||||
msgstr "Исключить из группы"
|
msgstr "Исключить из группы"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:76
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:81
|
||||||
msgid "No group members to list."
|
msgid "No group members to list."
|
||||||
msgstr "Нет участников в группе"
|
msgstr "Нет участников в группе"
|
||||||
|
|
||||||
@@ -606,56 +634,56 @@ msgstr "Нет участников в группе"
|
|||||||
msgid "Groups Membership"
|
msgid "Groups Membership"
|
||||||
msgstr "Участники группы"
|
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/permissions_tool/templates/permissions_tool/overview.html:40
|
||||||
#: allianceauth/templates/allianceauth/side-menu.html:15
|
#: allianceauth/templates/allianceauth/side-menu.html:16
|
||||||
msgid "Groups"
|
msgid "Groups"
|
||||||
msgstr "Группы"
|
msgstr "Группы"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:23
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:25
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:16
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:16
|
||||||
msgid "Description"
|
msgid "Description"
|
||||||
msgstr "Описание"
|
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:28
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:85
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:85
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:130
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:130
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:27
|
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:27
|
||||||
#: allianceauth/srp/templates/srp/data.html:97
|
#: allianceauth/srp/templates/srp/data.html:98
|
||||||
msgid "Status"
|
msgid "Status"
|
||||||
msgstr "Статус"
|
msgstr "Статус"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:25
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:27
|
||||||
msgid "Member Count"
|
msgid "Member Count"
|
||||||
msgstr "Число участников"
|
msgstr "Число участников"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:38
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:43
|
||||||
msgid "Hidden"
|
msgid "Hidden"
|
||||||
msgstr "Скрытые"
|
msgstr "Скрытые"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:40
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:45
|
||||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:12
|
#: allianceauth/templates/allianceauth/admin-status/overview.html:12
|
||||||
msgid "Open"
|
msgid "Open"
|
||||||
msgstr "Открыть"
|
msgstr "Открыть"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:42
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:47
|
||||||
msgid "Requestable"
|
msgid "Requestable"
|
||||||
msgstr "Запрошено"
|
msgstr "Запрошено"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:50
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:56
|
||||||
msgid "View Members"
|
msgid "View Members"
|
||||||
msgstr "Посмотреть участников"
|
msgstr "Посмотреть участников"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:53
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:60
|
||||||
msgid "Audit Members"
|
msgid "Audit Members"
|
||||||
msgstr "Проверить участников"
|
msgstr "Проверить участников"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:56
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:64
|
||||||
msgid "Copy Direrct Join Link"
|
msgid "Copy Direct Join Link"
|
||||||
msgstr ""
|
msgstr "Скопировать ссылку подключения"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:68
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:75
|
||||||
msgid "No groups to list."
|
msgid "No groups to list."
|
||||||
msgstr "Нет групп в списке"
|
msgstr "Нет групп в списке"
|
||||||
|
|
||||||
@@ -664,19 +692,19 @@ msgstr "Нет групп в списке"
|
|||||||
msgid "Available Groups"
|
msgid "Available Groups"
|
||||||
msgstr "Доступные группы"
|
msgstr "Доступные группы"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:29
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:30
|
||||||
msgid "Leave"
|
msgid "Leave"
|
||||||
msgstr "Покинуть"
|
msgstr "Покинуть"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:39
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:40
|
||||||
msgid "Join"
|
msgid "Join"
|
||||||
msgstr "Присоединиться"
|
msgstr "Присоединиться"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:43
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:44
|
||||||
msgid "Request"
|
msgid "Request"
|
||||||
msgstr "Запрос"
|
msgstr "Запрос"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:58
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:59
|
||||||
msgid "No groups available."
|
msgid "No groups available."
|
||||||
msgstr "Нет доступных групп."
|
msgstr "Нет доступных групп."
|
||||||
|
|
||||||
@@ -684,77 +712,72 @@ msgstr "Нет доступных групп."
|
|||||||
msgid "Groups Management"
|
msgid "Groups Management"
|
||||||
msgstr "Управление Группами"
|
msgstr "Управление Группами"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:23
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:25
|
||||||
msgid "Join Requests"
|
msgid "Join Requests"
|
||||||
msgstr "Запрос на присоединение"
|
msgstr "Запрос на присоединение"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:24
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:34
|
||||||
msgid "Leave Requests"
|
msgid "Leave Requests"
|
||||||
msgstr "Запрос на Выход"
|
msgstr "Запрос на Выход"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:39
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:53
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:98
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:111
|
||||||
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:20
|
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:20
|
||||||
#: allianceauth/services/modules/openfire/forms.py:6
|
#: allianceauth/services/modules/openfire/forms.py:6
|
||||||
msgid "Group"
|
msgid "Group"
|
||||||
msgstr "Группа"
|
msgstr "Группа"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:71
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:84
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:130
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:142
|
||||||
msgid "Accept"
|
msgid "Accept"
|
||||||
msgstr "Принять"
|
msgstr "Принять"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:74
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:88
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:133
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:146
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:85
|
#: allianceauth/hrapplications/templates/hrapplications/view.html:85
|
||||||
msgid "Reject"
|
msgid "Reject"
|
||||||
msgstr "Сбросить"
|
msgstr "Сбросить"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:83
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:97
|
||||||
msgid "No group add requests."
|
msgid "No group add requests."
|
||||||
msgstr "Нет групповых запросов на вступление"
|
msgstr "Нет групповых запросов на вступление"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:142
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:155
|
||||||
msgid "No group leave requests."
|
msgid "No group leave requests."
|
||||||
msgstr "Нет групповых запросов на выход"
|
msgstr "Нет групповых запросов на выход"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:10
|
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:9
|
||||||
msgid "Toggle navigation"
|
msgid "Toggle navigation"
|
||||||
msgstr "Проложить маршрут"
|
msgstr "Проложить маршрут"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:15
|
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:20
|
||||||
#: allianceauth/templates/allianceauth/side-menu.html:23
|
|
||||||
msgid "Group Management"
|
|
||||||
msgstr "Управление Группой"
|
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:21
|
|
||||||
msgid "Group Requests"
|
msgid "Group Requests"
|
||||||
msgstr "Групповой запрос"
|
msgstr "Групповой запрос"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:24
|
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:23
|
||||||
msgid "Group Membership"
|
msgid "Group Membership"
|
||||||
msgstr "Групповое участие"
|
msgstr "Групповое участие"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:166
|
#: allianceauth/groupmanagement/views.py:162
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Removed user %(user)s from group %(group)s."
|
msgid "Removed user %(user)s from group %(group)s."
|
||||||
msgstr "Пользователь %(user)s исключен из %(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"
|
msgid "User does not exist in that group"
|
||||||
msgstr "Пользователь не существует в этой группе."
|
msgstr "Пользователь не существует в этой группе."
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:171
|
#: allianceauth/groupmanagement/views.py:167
|
||||||
msgid "Group does not exist"
|
msgid "Group does not exist"
|
||||||
msgstr "Группа не существует."
|
msgstr "Группа не существует."
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:198
|
#: allianceauth/groupmanagement/views.py:194
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Accepted application from %(mainchar)s to %(group)s."
|
msgid "Accepted application from %(mainchar)s to %(group)s."
|
||||||
msgstr "Запрос от %(mainchar)sв %(group)s принят."
|
msgstr "Запрос от %(mainchar)sв %(group)s принят."
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:205
|
#: allianceauth/groupmanagement/views.py:201
|
||||||
#: allianceauth/groupmanagement/views.py:238
|
#: allianceauth/groupmanagement/views.py:234
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"An unhandled error occurred while processing the application from "
|
"An unhandled error occurred while processing the application from "
|
||||||
@@ -763,78 +786,80 @@ msgstr ""
|
|||||||
"Персонаж %(mainchar)s не может быть добавлен %(group)s, из-за непредвиденной"
|
"Персонаж %(mainchar)s не может быть добавлен %(group)s, из-за непредвиденной"
|
||||||
" ошибки. "
|
" ошибки. "
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:231
|
#: allianceauth/groupmanagement/views.py:227
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Rejected application from %(mainchar)s to %(group)s."
|
msgid "Rejected application from %(mainchar)s to %(group)s."
|
||||||
msgstr "%(mainchar)s исключен из %(group)s."
|
msgstr "%(mainchar)s исключен из %(group)s."
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:267
|
#: allianceauth/groupmanagement/views.py:263
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Accepted application from %(mainchar)s to leave %(group)s."
|
msgid "Accepted application from %(mainchar)s to leave %(group)s."
|
||||||
msgstr "Утвержден выход %(mainchar)s из %(group)s. "
|
msgstr "Утвержден выход %(mainchar)s из %(group)s. "
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:273
|
#: allianceauth/groupmanagement/views.py:269
|
||||||
#: allianceauth/groupmanagement/views.py:307
|
#: allianceauth/groupmanagement/views.py:303
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"An unhandled error occurred while processing the application from "
|
"An unhandled error occurred while processing the application from "
|
||||||
"%(mainchar)s to leave %(group)s."
|
"%(mainchar)s to leave %(group)s."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Возникла ошибка во время обработки %(mainchar)s на выход из группы "
|
||||||
|
"%(group)s. Повторите позже."
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:300
|
#: allianceauth/groupmanagement/views.py:296
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Rejected application from %(mainchar)s to leave %(group)s."
|
msgid "Rejected application from %(mainchar)s to leave %(group)s."
|
||||||
msgstr "Прошение об исключении %(mainchar)s из %(group)s – отклонено. "
|
msgstr "Прошение об исключении %(mainchar)s из %(group)s – отклонено. "
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:346
|
#: allianceauth/groupmanagement/views.py:342
|
||||||
#: allianceauth/groupmanagement/views.py:358
|
#: allianceauth/groupmanagement/views.py:354
|
||||||
msgid "You cannot join that group"
|
msgid "You cannot join that group"
|
||||||
msgstr "Вы не можете вступить"
|
msgstr "Вы не можете вступить"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:352
|
#: allianceauth/groupmanagement/views.py:348
|
||||||
msgid "You are already a member of that group."
|
msgid "You are already a member of that group."
|
||||||
msgstr ""
|
msgstr "Вы уже участник этой группы."
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:367
|
#: allianceauth/groupmanagement/views.py:363
|
||||||
msgid "You already have a pending application for that group."
|
msgid "You already have a pending application for that group."
|
||||||
msgstr ""
|
msgstr "Вы уже подали заявку на вступление этой группы."
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:370
|
#: allianceauth/groupmanagement/views.py:366
|
||||||
#: allianceauth/groupmanagement/views.py:408
|
#: allianceauth/groupmanagement/views.py:404
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:37
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:37
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:72
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:72
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:99
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:99
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:144
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:144
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:38
|
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:38
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:20
|
#: 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
|
#: allianceauth/srp/templates/srp/management.html:81
|
||||||
msgid "Pending"
|
msgid "Pending"
|
||||||
msgstr "Ожидание"
|
msgstr "Ожидание"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:376
|
#: allianceauth/groupmanagement/views.py:372
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Applied to group %(group)s."
|
msgid "Applied to group %(group)s."
|
||||||
msgstr "Вступить в группу %(group)s."
|
msgstr "Вступить в группу %(group)s."
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:387
|
#: allianceauth/groupmanagement/views.py:383
|
||||||
msgid "You cannot leave that group"
|
msgid "You cannot leave that group"
|
||||||
msgstr "Вы не можете покинуть эту группу"
|
msgstr "Вы не можете покинуть эту группу"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:392
|
#: allianceauth/groupmanagement/views.py:388
|
||||||
msgid "You are not a member of that group"
|
msgid "You are not a member of that group"
|
||||||
msgstr "Вы не участник группыы"
|
msgstr "Вы не участник группыы"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:401
|
#: allianceauth/groupmanagement/views.py:397
|
||||||
msgid "You already have a pending leave request for that group."
|
msgid "You already have a pending leave request for that group."
|
||||||
msgstr ""
|
msgstr "Ваш запрос находится на рассмотрении"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/views.py:414
|
#: allianceauth/groupmanagement/views.py:410
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Applied to leave group %(group)s."
|
msgid "Applied to leave group %(group)s."
|
||||||
msgstr "Запрос на выход из группы %(group)s."
|
msgstr "Запрос на выход из группы %(group)s."
|
||||||
|
|
||||||
#: allianceauth/hrapplications/auth_hooks.py:10
|
#: allianceauth/hrapplications/auth_hooks.py:13
|
||||||
msgid "Applications"
|
msgid "Applications"
|
||||||
msgstr "Запросы"
|
msgstr "Запросы"
|
||||||
|
|
||||||
@@ -891,7 +916,7 @@ msgstr "Пользователь"
|
|||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:131
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:131
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:28
|
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:28
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:75
|
#: 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
|
#: allianceauth/srp/templates/srp/management.html:46
|
||||||
msgid "Actions"
|
msgid "Actions"
|
||||||
msgstr "Действия"
|
msgstr "Действия"
|
||||||
@@ -901,7 +926,7 @@ msgstr "Действия"
|
|||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:147
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:147
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:40
|
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:40
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:16
|
#: allianceauth/hrapplications/templates/hrapplications/view.html:16
|
||||||
#: allianceauth/srp/templates/srp/data.html:117
|
#: allianceauth/srp/templates/srp/data.html:126
|
||||||
msgid "Approved"
|
msgid "Approved"
|
||||||
msgstr "Проверено"
|
msgstr "Проверено"
|
||||||
|
|
||||||
@@ -909,7 +934,7 @@ msgstr "Проверено"
|
|||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:104
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:104
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:149
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:149
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:42
|
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:42
|
||||||
#: allianceauth/srp/templates/srp/data.html:121
|
#: allianceauth/srp/templates/srp/data.html:130
|
||||||
msgid "Rejected"
|
msgid "Rejected"
|
||||||
msgstr "Отменено "
|
msgstr "Отменено "
|
||||||
|
|
||||||
@@ -1015,7 +1040,7 @@ msgstr "Не прочитанно"
|
|||||||
|
|
||||||
#: allianceauth/notifications/templates/notifications/list.html:18
|
#: allianceauth/notifications/templates/notifications/list.html:18
|
||||||
msgid "Read"
|
msgid "Read"
|
||||||
msgstr "Прочитать"
|
msgstr "Прочитано"
|
||||||
|
|
||||||
#: allianceauth/notifications/templates/notifications/list.html:22
|
#: allianceauth/notifications/templates/notifications/list.html:22
|
||||||
msgid "Mark All Read"
|
msgid "Mark All Read"
|
||||||
@@ -1123,7 +1148,7 @@ msgstr "Таймера Флотовых операций"
|
|||||||
#: allianceauth/optimer/templates/optimer/management.html:21
|
#: allianceauth/optimer/templates/optimer/management.html:21
|
||||||
#: allianceauth/timerboard/templates/timerboard/view.html:23
|
#: allianceauth/timerboard/templates/timerboard/view.html:23
|
||||||
msgid "Current Eve Time:"
|
msgid "Current Eve Time:"
|
||||||
msgstr "ET"
|
msgstr "Текущий EVE Time:"
|
||||||
|
|
||||||
#: allianceauth/optimer/templates/optimer/management.html:27
|
#: allianceauth/optimer/templates/optimer/management.html:27
|
||||||
#: allianceauth/timerboard/templates/timerboard/view.html:189
|
#: allianceauth/timerboard/templates/timerboard/view.html:189
|
||||||
@@ -1222,15 +1247,15 @@ msgstr "Состояния"
|
|||||||
|
|
||||||
#: allianceauth/services/abstract.py:72
|
#: allianceauth/services/abstract.py:72
|
||||||
msgid "That service account already exists"
|
msgid "That service account already exists"
|
||||||
msgstr ""
|
msgstr "Этот сервис уже активирован"
|
||||||
|
|
||||||
#: allianceauth/services/abstract.py:104
|
#: allianceauth/services/abstract.py:104
|
||||||
msgid "Successfully set your {} password"
|
msgid "Successfully set your {} password"
|
||||||
msgstr ""
|
msgstr "{} Пароль успешно обновлен."
|
||||||
|
|
||||||
#: allianceauth/services/auth_hooks.py:11
|
#: allianceauth/services/auth_hooks.py:11
|
||||||
msgid "Services"
|
msgid "Services"
|
||||||
msgstr ""
|
msgstr "Подключение сервисов"
|
||||||
|
|
||||||
#: allianceauth/services/forms.py:6
|
#: allianceauth/services/forms.py:6
|
||||||
msgid "Name of Fleet:"
|
msgid "Name of Fleet:"
|
||||||
@@ -1292,37 +1317,72 @@ msgstr "Пароль"
|
|||||||
msgid "Password must be at least 8 characters long."
|
msgid "Password must be at least 8 characters long."
|
||||||
msgstr "Пароль должен быть не менее 8 символов."
|
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 "Discord персонаж отключен"
|
||||||
|
|
||||||
|
#: 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 "Подключиться к серверу Discord"
|
||||||
|
|
||||||
|
#: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:22
|
||||||
|
msgid "Leave- and rejoin the Discord Server (Reset)"
|
||||||
|
msgstr "Переподключиться к серверу Discord. "
|
||||||
|
|
||||||
|
#: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:25
|
||||||
|
msgid "Leave the Discord server"
|
||||||
|
msgstr "Покинуть Discord сервер"
|
||||||
|
|
||||||
|
#: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:32
|
||||||
msgid "Link Discord Server"
|
msgid "Link Discord Server"
|
||||||
msgstr "Ссылка на сервер Discord"
|
msgstr "Ссылка на сервер Discord"
|
||||||
|
|
||||||
#: allianceauth/services/modules/discord/views.py:26
|
#: allianceauth/services/modules/discord/views.py:30
|
||||||
msgid "Deactivated Discord account."
|
msgid "Deactivated Discord account."
|
||||||
msgstr ""
|
msgstr "Отменить доступ на Discord сервер."
|
||||||
|
|
||||||
#: allianceauth/services/modules/discord/views.py:29
|
#: allianceauth/services/modules/discord/views.py:36
|
||||||
#: allianceauth/services/modules/discord/views.py:41
|
#: allianceauth/services/modules/discord/views.py:59
|
||||||
#: allianceauth/services/modules/discord/views.py:65
|
|
||||||
msgid "An error occurred while processing your Discord account."
|
msgid "An error occurred while processing your Discord account."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Во время обработки Discord аккаунта возникла ошибка. Попробуйте чуточку "
|
||||||
|
"позднее. "
|
||||||
|
|
||||||
#: allianceauth/services/modules/discord/views.py:62
|
#: allianceauth/services/modules/discord/views.py:102
|
||||||
msgid "Activated Discord account."
|
msgid "Your Discord account has been successfully activated."
|
||||||
|
msgstr "Доступ на сервер Discord успешно получен."
|
||||||
|
|
||||||
|
#: allianceauth/services/modules/discord/views.py:108
|
||||||
|
msgid ""
|
||||||
|
"An error occurred while trying to activate your Discord account. Please try "
|
||||||
|
"again."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Во время активации Discord аккаунта возникла ошибка. Попробуйте чуточку "
|
||||||
|
"позднее. "
|
||||||
|
|
||||||
#: allianceauth/services/modules/discourse/views.py:37
|
#: allianceauth/services/modules/discourse/views.py:37
|
||||||
msgid "You are not authorized to access Discourse."
|
msgid "You are not authorized to access Discourse."
|
||||||
msgstr ""
|
msgstr "Вы не авторизованы в Discourse."
|
||||||
|
|
||||||
#: allianceauth/services/modules/discourse/views.py:42
|
#: allianceauth/services/modules/discourse/views.py:42
|
||||||
msgid "You must have a main character set to access Discourse."
|
msgid "You must have a main character set to access Discourse."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Для авторизации Discourse, необходимо получить авторизацию Вашим основным "
|
||||||
|
"аккаунтом."
|
||||||
|
|
||||||
#: allianceauth/services/modules/discourse/views.py:52
|
#: allianceauth/services/modules/discourse/views.py:52
|
||||||
msgid ""
|
msgid ""
|
||||||
"No SSO payload or signature. Please contact support if this problem "
|
"No SSO payload or signature. Please contact support if this problem "
|
||||||
"persists."
|
"persists."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Отсуствует связь SSO. Если ошибка повторяется - свяжитесь с тех. поддержкой."
|
||||||
|
" "
|
||||||
|
|
||||||
#: allianceauth/services/modules/discourse/views.py:62
|
#: allianceauth/services/modules/discourse/views.py:62
|
||||||
#: allianceauth/services/modules/discourse/views.py:70
|
#: allianceauth/services/modules/discourse/views.py:70
|
||||||
@@ -1354,7 +1414,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: allianceauth/services/modules/openfire/auth_hooks.py:26
|
#: allianceauth/services/modules/openfire/auth_hooks.py:26
|
||||||
msgid "Jabber"
|
msgid "Jabber"
|
||||||
msgstr ""
|
msgstr "Jabber"
|
||||||
|
|
||||||
#: allianceauth/services/modules/openfire/auth_hooks.py:78
|
#: allianceauth/services/modules/openfire/auth_hooks.py:78
|
||||||
#: allianceauth/services/modules/openfire/templates/services/openfire/broadcast.html:6
|
#: allianceauth/services/modules/openfire/templates/services/openfire/broadcast.html:6
|
||||||
@@ -1380,50 +1440,50 @@ msgstr "Бродкаст"
|
|||||||
|
|
||||||
#: allianceauth/services/modules/openfire/views.py:35
|
#: allianceauth/services/modules/openfire/views.py:35
|
||||||
msgid "Activated jabber account."
|
msgid "Activated jabber account."
|
||||||
msgstr ""
|
msgstr "Активировать доступ в jabber."
|
||||||
|
|
||||||
#: allianceauth/services/modules/openfire/views.py:44
|
#: allianceauth/services/modules/openfire/views.py:44
|
||||||
#: allianceauth/services/modules/openfire/views.py:57
|
#: allianceauth/services/modules/openfire/views.py:57
|
||||||
#: allianceauth/services/modules/openfire/views.py:78
|
#: allianceauth/services/modules/openfire/views.py:78
|
||||||
#: allianceauth/services/modules/openfire/views.py:151
|
#: allianceauth/services/modules/openfire/views.py:151
|
||||||
msgid "An error occurred while processing your jabber account."
|
msgid "An error occurred while processing your jabber account."
|
||||||
msgstr ""
|
msgstr "Возникла ошибка во время активации jabber'а ."
|
||||||
|
|
||||||
#: allianceauth/services/modules/openfire/views.py:70
|
#: allianceauth/services/modules/openfire/views.py:70
|
||||||
msgid "Reset jabber password."
|
msgid "Reset jabber password."
|
||||||
msgstr ""
|
msgstr "Сбросить jabber пароль."
|
||||||
|
|
||||||
#: allianceauth/services/modules/openfire/views.py:119
|
#: allianceauth/services/modules/openfire/views.py:119
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Sent jabber broadcast to %s"
|
msgid "Sent jabber broadcast to %s"
|
||||||
msgstr ""
|
msgstr "Отправить Бродкаст %s"
|
||||||
|
|
||||||
#: allianceauth/services/modules/openfire/views.py:148
|
#: allianceauth/services/modules/openfire/views.py:148
|
||||||
msgid "Set jabber password."
|
msgid "Set jabber password."
|
||||||
msgstr ""
|
msgstr "Установить jabber пароль."
|
||||||
|
|
||||||
#: allianceauth/services/modules/phpbb3/views.py:34
|
#: allianceauth/services/modules/phpbb3/views.py:34
|
||||||
msgid "Activated forum account."
|
msgid "Activated forum account."
|
||||||
msgstr ""
|
msgstr "Допустить на Форум."
|
||||||
|
|
||||||
#: allianceauth/services/modules/phpbb3/views.py:43
|
#: allianceauth/services/modules/phpbb3/views.py:43
|
||||||
#: allianceauth/services/modules/phpbb3/views.py:57
|
#: allianceauth/services/modules/phpbb3/views.py:57
|
||||||
#: allianceauth/services/modules/phpbb3/views.py:80
|
#: allianceauth/services/modules/phpbb3/views.py:80
|
||||||
#: allianceauth/services/modules/phpbb3/views.py:103
|
#: allianceauth/services/modules/phpbb3/views.py:103
|
||||||
msgid "An error occurred while processing your forum account."
|
msgid "An error occurred while processing your forum account."
|
||||||
msgstr ""
|
msgstr "Во время обработки Форумного аккаунта, возникла ошибка."
|
||||||
|
|
||||||
#: allianceauth/services/modules/phpbb3/views.py:54
|
#: allianceauth/services/modules/phpbb3/views.py:54
|
||||||
msgid "Deactivated forum account."
|
msgid "Deactivated forum account."
|
||||||
msgstr ""
|
msgstr "Отменить доступ на Форум. "
|
||||||
|
|
||||||
#: allianceauth/services/modules/phpbb3/views.py:71
|
#: allianceauth/services/modules/phpbb3/views.py:71
|
||||||
msgid "Reset forum password."
|
msgid "Reset forum password."
|
||||||
msgstr ""
|
msgstr "Сбросить пароль на Форум."
|
||||||
|
|
||||||
#: allianceauth/services/modules/phpbb3/views.py:100
|
#: allianceauth/services/modules/phpbb3/views.py:100
|
||||||
msgid "Set forum password."
|
msgid "Set forum password."
|
||||||
msgstr ""
|
msgstr "Установить пароль на Форум."
|
||||||
|
|
||||||
#: allianceauth/services/modules/smf/views.py:34
|
#: allianceauth/services/modules/smf/views.py:34
|
||||||
msgid "Activated SMF account."
|
msgid "Activated SMF account."
|
||||||
@@ -1473,21 +1533,21 @@ msgstr "Продолжить"
|
|||||||
|
|
||||||
#: allianceauth/services/modules/teamspeak3/views.py:34
|
#: allianceauth/services/modules/teamspeak3/views.py:34
|
||||||
msgid "Activated TeamSpeak3 account."
|
msgid "Activated TeamSpeak3 account."
|
||||||
msgstr ""
|
msgstr "Активировать аккаунт TeamSpeak3."
|
||||||
|
|
||||||
#: allianceauth/services/modules/teamspeak3/views.py:37
|
#: allianceauth/services/modules/teamspeak3/views.py:37
|
||||||
#: allianceauth/services/modules/teamspeak3/views.py:74
|
#: allianceauth/services/modules/teamspeak3/views.py:74
|
||||||
#: allianceauth/services/modules/teamspeak3/views.py:100
|
#: allianceauth/services/modules/teamspeak3/views.py:100
|
||||||
msgid "An error occurred while processing your TeamSpeak3 account."
|
msgid "An error occurred while processing your TeamSpeak3 account."
|
||||||
msgstr ""
|
msgstr "Во время активации TeamSpeak3 возникла ошибка, попробуйте позже."
|
||||||
|
|
||||||
#: allianceauth/services/modules/teamspeak3/views.py:71
|
#: allianceauth/services/modules/teamspeak3/views.py:71
|
||||||
msgid "Deactivated TeamSpeak3 account."
|
msgid "Deactivated TeamSpeak3 account."
|
||||||
msgstr ""
|
msgstr "Отключить TeamSpeak3 аккаунт."
|
||||||
|
|
||||||
#: allianceauth/services/modules/teamspeak3/views.py:97
|
#: allianceauth/services/modules/teamspeak3/views.py:97
|
||||||
msgid "Reset TeamSpeak3 permission key."
|
msgid "Reset TeamSpeak3 permission key."
|
||||||
msgstr ""
|
msgstr "Сбросить TeamSpeak3 ключ доступа."
|
||||||
|
|
||||||
#: allianceauth/services/modules/xenforo/views.py:30
|
#: allianceauth/services/modules/xenforo/views.py:30
|
||||||
msgid "Activated XenForo account."
|
msgid "Activated XenForo account."
|
||||||
@@ -1572,9 +1632,9 @@ msgstr "Сервис"
|
|||||||
msgid "Domain"
|
msgid "Domain"
|
||||||
msgstr "Домен"
|
msgstr "Домен"
|
||||||
|
|
||||||
#: allianceauth/srp/auth_hooks.py:9
|
#: allianceauth/srp/auth_hooks.py:12
|
||||||
msgid "Ship Replacement"
|
msgid "Ship Replacement"
|
||||||
msgstr "Замена корабля"
|
msgstr "Компенсация корабля"
|
||||||
|
|
||||||
#: allianceauth/srp/form.py:7
|
#: allianceauth/srp/form.py:7
|
||||||
#: allianceauth/srp/templates/srp/management.html:38
|
#: allianceauth/srp/templates/srp/management.html:38
|
||||||
@@ -1586,7 +1646,7 @@ msgstr "Флотовое время"
|
|||||||
msgid "Fleet Doctrine"
|
msgid "Fleet Doctrine"
|
||||||
msgstr "Флотовая Доктрина"
|
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"
|
msgid "Additional Info"
|
||||||
msgstr "Дополнительная информация"
|
msgstr "Дополнительная информация"
|
||||||
|
|
||||||
@@ -1615,63 +1675,63 @@ msgstr "Создать SRP Флот"
|
|||||||
msgid "Give this link to the line members"
|
msgid "Give this link to the line members"
|
||||||
msgstr "Поделиться ссылкой с рядовыми участниками"
|
msgstr "Поделиться ссылкой с рядовыми участниками"
|
||||||
|
|
||||||
#: allianceauth/srp/templates/srp/data.html:48
|
#: allianceauth/srp/templates/srp/data.html:49
|
||||||
msgid "SRP Fleet Data"
|
msgid "SRP Fleet Data"
|
||||||
msgstr "SRP данные флота"
|
msgstr "SRP данные флота"
|
||||||
|
|
||||||
#: allianceauth/srp/templates/srp/data.html:53
|
#: allianceauth/srp/templates/srp/data.html:54
|
||||||
msgid "Mark Incomplete"
|
msgid "Mark Incomplete"
|
||||||
msgstr "Пометить незаконченным"
|
msgstr "Пометить незаконченным"
|
||||||
|
|
||||||
#: allianceauth/srp/templates/srp/data.html:57
|
#: allianceauth/srp/templates/srp/data.html:58
|
||||||
msgid "Mark Completed"
|
msgid "Mark Completed"
|
||||||
msgstr "Пометить законченным"
|
msgstr "Пометить законченным"
|
||||||
|
|
||||||
#: allianceauth/srp/templates/srp/data.html:69
|
#: allianceauth/srp/templates/srp/data.html:70
|
||||||
#: allianceauth/srp/templates/srp/data.html:145
|
#: allianceauth/srp/templates/srp/data.html:156
|
||||||
msgid "Total Losses:"
|
msgid "Total Losses:"
|
||||||
msgstr "Суммарные потери:"
|
msgstr "Суммарные потери:"
|
||||||
|
|
||||||
#: allianceauth/srp/templates/srp/data.html:70
|
#: allianceauth/srp/templates/srp/data.html:71
|
||||||
#: allianceauth/srp/templates/srp/data.html:146
|
#: allianceauth/srp/templates/srp/data.html:157
|
||||||
#: allianceauth/srp/templates/srp/management.html:30
|
#: allianceauth/srp/templates/srp/management.html:30
|
||||||
msgid "Total ISK Cost:"
|
msgid "Total ISK Cost:"
|
||||||
msgstr "Оценочная стоимость (ISK):"
|
msgstr "Оценочная стоимость (ISK):"
|
||||||
|
|
||||||
#: allianceauth/srp/templates/srp/data.html:78
|
#: allianceauth/srp/templates/srp/data.html:79
|
||||||
#: allianceauth/srp/templates/srp/data.html:154
|
#: allianceauth/srp/templates/srp/data.html:165
|
||||||
msgid "Are you sure you want to delete SRP requests?"
|
msgid "Are you sure you want to delete SRP requests?"
|
||||||
msgstr "Вы уверенны что хотите удалить запрос на SRP?"
|
msgstr "Вы уверенны что хотите удалить запрос на SRP?"
|
||||||
|
|
||||||
#: allianceauth/srp/templates/srp/data.html:87
|
#: allianceauth/srp/templates/srp/data.html:88
|
||||||
msgid "Pilot Name"
|
msgid "Pilot Name"
|
||||||
msgstr "Имя Пилота"
|
msgstr "Имя Пилота"
|
||||||
|
|
||||||
#: allianceauth/srp/templates/srp/data.html:88
|
#: allianceauth/srp/templates/srp/data.html:89
|
||||||
msgid "Killboard Link"
|
msgid "Killboard Link"
|
||||||
msgstr "zKillBoard ссылка"
|
msgstr "zKillBoard ссылка"
|
||||||
|
|
||||||
#: allianceauth/srp/templates/srp/data.html:90
|
#: allianceauth/srp/templates/srp/data.html:91
|
||||||
msgid "Ship Type"
|
msgid "Ship Type"
|
||||||
msgstr "Тип корабля"
|
msgstr "Тип корабля"
|
||||||
|
|
||||||
#: allianceauth/srp/templates/srp/data.html:91
|
#: allianceauth/srp/templates/srp/data.html:92
|
||||||
msgid "Killboard Loss Amt"
|
msgid "Killboard Loss Amt"
|
||||||
msgstr "потерь по zKillBoard на данный момент"
|
msgstr "потерь по zKillBoard на данный момент"
|
||||||
|
|
||||||
#: allianceauth/srp/templates/srp/data.html:92
|
#: allianceauth/srp/templates/srp/data.html:93
|
||||||
msgid "SRP ISK Cost"
|
msgid "SRP ISK Cost"
|
||||||
msgstr "SRP ISK Стоимость"
|
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"
|
msgid "Click value to edit Enter to save & next ESC to cancel"
|
||||||
msgstr "Нажмите на значение для редактирования и ESC для отмены"
|
msgstr "Нажмите на значение для редактирования и ESC для отмены"
|
||||||
|
|
||||||
#: allianceauth/srp/templates/srp/data.html:96
|
#: allianceauth/srp/templates/srp/data.html:97
|
||||||
msgid "Post Time"
|
msgid "Post Time"
|
||||||
msgstr "Опубликованно"
|
msgstr "Опубликованно"
|
||||||
|
|
||||||
#: allianceauth/srp/templates/srp/data.html:163
|
#: allianceauth/srp/templates/srp/data.html:174
|
||||||
msgid "No SRP requests for this fleet."
|
msgid "No SRP requests for this fleet."
|
||||||
msgstr "SRP запросы отсутствуют"
|
msgstr "SRP запросы отсутствуют"
|
||||||
|
|
||||||
@@ -1866,32 +1926,30 @@ msgid "Current"
|
|||||||
msgstr "Текущий"
|
msgstr "Текущий"
|
||||||
|
|
||||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:40
|
#: allianceauth/templates/allianceauth/admin-status/overview.html:40
|
||||||
msgid "Latest Major"
|
msgid "Latest Stable"
|
||||||
msgstr "Последняя версия"
|
msgstr "Стабильная Версия"
|
||||||
|
|
||||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:46
|
#: 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"
|
msgid "Update available"
|
||||||
msgstr "Доступно обновление"
|
msgstr "Доступно обновление"
|
||||||
|
|
||||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:50
|
#: allianceauth/templates/allianceauth/admin-status/overview.html:51
|
||||||
msgid "Latest Minor"
|
msgid "Latest Pre-Release"
|
||||||
msgstr "Последняя версия"
|
msgstr "Предрелизная Версия"
|
||||||
|
|
||||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:60
|
#: allianceauth/templates/allianceauth/admin-status/overview.html:57
|
||||||
msgid "Latest Patch"
|
msgid "Pre-Release available"
|
||||||
msgstr "Последние исправления"
|
msgstr "Предрелизная Версия"
|
||||||
|
|
||||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:73
|
#: allianceauth/templates/allianceauth/admin-status/overview.html:65
|
||||||
msgid "Task Queue"
|
msgid "Task Queue"
|
||||||
msgstr "Список задач"
|
msgstr "Список задач"
|
||||||
|
|
||||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:90
|
#: allianceauth/templates/allianceauth/admin-status/overview.html:82
|
||||||
msgid "Error retrieving task queue length"
|
msgid "Error retrieving task queue length"
|
||||||
msgstr "Ошибка при получении списка задач. "
|
msgstr "Ошибка при получении списка задач. "
|
||||||
|
|
||||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:92
|
#: allianceauth/templates/allianceauth/admin-status/overview.html:84
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%(tasks)s task"
|
msgid "%(tasks)s task"
|
||||||
msgid_plural "%(tasks)s tasks"
|
msgid_plural "%(tasks)s tasks"
|
||||||
@@ -1925,14 +1983,14 @@ msgstr "Прочие"
|
|||||||
#: allianceauth/timerboard/templates/timerboard/view.html:220
|
#: allianceauth/timerboard/templates/timerboard/view.html:220
|
||||||
#: allianceauth/timerboard/templates/timerboard/view.html:388
|
#: allianceauth/timerboard/templates/timerboard/view.html:388
|
||||||
msgid "Friendly"
|
msgid "Friendly"
|
||||||
msgstr "Дружествен"
|
msgstr "Дружественный"
|
||||||
|
|
||||||
#: allianceauth/timerboard/form.py:55
|
#: allianceauth/timerboard/form.py:55
|
||||||
#: allianceauth/timerboard/templates/timerboard/view.html:53
|
#: allianceauth/timerboard/templates/timerboard/view.html:53
|
||||||
#: allianceauth/timerboard/templates/timerboard/view.html:215
|
#: allianceauth/timerboard/templates/timerboard/view.html:215
|
||||||
#: allianceauth/timerboard/templates/timerboard/view.html:383
|
#: allianceauth/timerboard/templates/timerboard/view.html:383
|
||||||
msgid "Hostile"
|
msgid "Hostile"
|
||||||
msgstr "Заложник"
|
msgstr "Вражеский"
|
||||||
|
|
||||||
#: allianceauth/timerboard/form.py:56
|
#: allianceauth/timerboard/form.py:56
|
||||||
#: allianceauth/timerboard/templates/timerboard/view.html:63
|
#: allianceauth/timerboard/templates/timerboard/view.html:63
|
||||||
@@ -2034,3 +2092,6 @@ msgstr "Добавлен таймер в %(system)s на %(time)s."
|
|||||||
#: allianceauth/timerboard/views.py:83
|
#: allianceauth/timerboard/views.py:83
|
||||||
msgid "Saved changes to the timer."
|
msgid "Saved changes to the timer."
|
||||||
msgstr "Изменения сохранены"
|
msgstr "Изменения сохранены"
|
||||||
|
|
||||||
|
#~ msgid "Portrait"
|
||||||
|
#~ msgstr "Портрет"
|
||||||
|
|||||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -1,22 +1,9 @@
|
|||||||
default_app_config = 'allianceauth.notifications.apps.NotificationsConfig'
|
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
|
from .models import Notification
|
||||||
if Notification.objects.filter(user=user).count() > MAX_NOTIFICATIONS:
|
Notification.objects.notify_user(user, title, message, level)
|
||||||
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)
|
|
||||||
|
|||||||
@@ -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}
|
|
||||||
101
allianceauth/notifications/managers.py
Normal file
101
allianceauth/notifications/managers.py
Normal 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}'
|
||||||
@@ -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),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -1,11 +1,19 @@
|
|||||||
|
import logging
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
import logging
|
|
||||||
|
from .managers import NotificationManager
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class Notification(models.Model):
|
class Notification(models.Model):
|
||||||
|
"""Notification to a user within Auth"""
|
||||||
|
|
||||||
|
NOTIFICATIONS_MAX_PER_USER_DEFAULT = 50
|
||||||
|
NOTIFICATIONS_REFRESH_TIME_DEFAULT = 30
|
||||||
|
|
||||||
LEVEL_CHOICES = (
|
LEVEL_CHOICES = (
|
||||||
('danger', 'CRITICAL'),
|
('danger', 'CRITICAL'),
|
||||||
('danger', 'ERROR'),
|
('danger', 'ERROR'),
|
||||||
@@ -18,19 +26,41 @@ class Notification(models.Model):
|
|||||||
level = models.CharField(choices=LEVEL_CHOICES, max_length=10)
|
level = models.CharField(choices=LEVEL_CHOICES, max_length=10)
|
||||||
title = models.CharField(max_length=254)
|
title = models.CharField(max_length=254)
|
||||||
message = models.TextField()
|
message = models.TextField()
|
||||||
timestamp = models.DateTimeField(auto_now_add=True)
|
timestamp = models.DateTimeField(auto_now_add=True, db_index=True)
|
||||||
viewed = models.BooleanField(default=False)
|
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)
|
logger.info("Marking notification as viewed: %s" % self)
|
||||||
self.viewed = True
|
self.viewed = True
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
def __str__(self):
|
def set_level(self, level_name: str) -> None:
|
||||||
return "%s: %s" % (self.user, self.title)
|
"""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 = new_level
|
||||||
self.level = [item[0] for item in self.LEVEL_CHOICES if item[1] == level][0]
|
self.save()
|
||||||
|
|
||||||
class Meta:
|
|
||||||
ordering = ['-timestamp']
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{% extends "allianceauth/base.html" %}
|
{% extends "allianceauth/base.html" %}
|
||||||
{% load staticfiles %}
|
{% load static %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block page_title %}{% trans "Notifications" %}{% endblock %}
|
{% block page_title %}{% trans "Notifications" %}{% endblock %}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{% extends "allianceauth/base.html" %}
|
{% extends "allianceauth/base.html" %}
|
||||||
{% load staticfiles %}
|
{% load static %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block page_title %}{% trans "View Notification" %}{% endblock page_title %}
|
{% block page_title %}{% trans "View Notification" %}{% endblock page_title %}
|
||||||
|
|||||||
@@ -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
|
||||||
28
allianceauth/notifications/tests/test_init.py
Normal file
28
allianceauth/notifications/tests/test_init.py
Normal 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)
|
||||||
206
allianceauth/notifications/tests/test_managers.py
Normal file
206
allianceauth/notifications/tests/test_managers.py
Normal 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)
|
||||||
|
)
|
||||||
73
allianceauth/notifications/tests/test_models.py
Normal file
73
allianceauth/notifications/tests/test_models.py
Normal 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')
|
||||||
@@ -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
|
|
||||||
86
allianceauth/notifications/tests/test_templatetags.py
Normal file
86
allianceauth/notifications/tests/test_templatetags.py
Normal 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)
|
||||||
49
allianceauth/notifications/tests/test_views.py
Normal file
49
allianceauth/notifications/tests/test_views.py
Normal 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)
|
||||||
@@ -9,4 +9,9 @@ urlpatterns = [
|
|||||||
url(r'^notifications/delete_all_read/$', views.delete_all_read, name='delete_all_read'),
|
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/$', views.notification_list, name='list'),
|
||||||
url(r'^notifications/(\w+)/$', views.notification_view, name='view'),
|
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'
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
from django.shortcuts import render, get_object_or_404, redirect
|
import logging
|
||||||
from .models import Notification
|
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.http import JsonResponse
|
||||||
import logging
|
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__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -11,9 +14,15 @@ logger = logging.getLogger(__name__)
|
|||||||
@login_required
|
@login_required
|
||||||
def notification_list(request):
|
def notification_list(request):
|
||||||
logger.debug("notification_list called by user %s" % request.user)
|
logger.debug("notification_list called by user %s" % request.user)
|
||||||
new_notifs = Notification.objects.filter(user=request.user).filter(viewed=False)
|
notifications_qs = Notification.objects.filter(user=request.user).order_by("-timestamp")
|
||||||
old_notifs = Notification.objects.filter(user=request.user).filter(viewed=True)
|
new_notifs = notifications_qs.filter(viewed=False)
|
||||||
logger.debug("User %s has %s unread and %s read notifications" % (request.user, len(new_notifs), len(old_notifs)))
|
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 = {
|
context = {
|
||||||
'read': old_notifs,
|
'read': old_notifs,
|
||||||
'unread': new_notifs,
|
'unread': new_notifs,
|
||||||
@@ -23,39 +32,53 @@ def notification_list(request):
|
|||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def notification_view(request, notif_id):
|
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)
|
notif = get_object_or_404(Notification, pk=notif_id)
|
||||||
if notif.user == request.user:
|
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}
|
context = {'notif': notif}
|
||||||
notif.view()
|
notif.mark_viewed()
|
||||||
return render(request, 'notifications/view.html', context)
|
return render(request, 'notifications/view.html', context)
|
||||||
else:
|
else:
|
||||||
logger.warn(
|
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.'))
|
messages.error(request, _('You are not authorized to view that notification.'))
|
||||||
return redirect('notifications:list')
|
return redirect('notifications:list')
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def remove_notification(request, notif_id):
|
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)
|
notif = get_object_or_404(Notification, pk=notif_id)
|
||||||
if notif.user == request.user:
|
if notif.user == request.user:
|
||||||
if Notification.objects.filter(id=notif_id).exists():
|
if Notification.objects.filter(id=notif_id).exists():
|
||||||
notif.delete()
|
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.'))
|
messages.success(request, _('Deleted notification.'))
|
||||||
else:
|
else:
|
||||||
logger.error(
|
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.'))
|
messages.error(request, _('Failed to locate notification.'))
|
||||||
return redirect('notifications:list')
|
return redirect('notifications:list')
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def mark_all_read(request):
|
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)
|
Notification.objects.filter(user=request.user).update(viewed=True)
|
||||||
messages.success(request, _('Marked all notifications as read.'))
|
messages.success(request, _('Marked all notifications as read.'))
|
||||||
return redirect('notifications:list')
|
return redirect('notifications:list')
|
||||||
@@ -63,7 +86,17 @@ def mark_all_read(request):
|
|||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def delete_all_read(request):
|
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()
|
Notification.objects.filter(user=request.user).filter(viewed=True).delete()
|
||||||
messages.success(request, _('Deleted all read notifications.'))
|
messages.success(request, _('Deleted all read notifications.'))
|
||||||
return redirect('notifications:list')
|
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)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{% extends "allianceauth/base.html" %}
|
{% extends "allianceauth/base.html" %}
|
||||||
{% load bootstrap %}
|
{% load bootstrap %}
|
||||||
{% load staticfiles %}
|
{% load static %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% get_current_language as LANGUAGE_CODE %}
|
{% get_current_language as LANGUAGE_CODE %}
|
||||||
|
|
||||||
@@ -36,9 +36,15 @@
|
|||||||
{% block extra_script %}
|
{% block extra_script %}
|
||||||
|
|
||||||
$('#id_start').datetimepicker({
|
$('#id_start').datetimepicker({
|
||||||
lang: '{{ LANGUAGE_CODE }}',
|
setlocale: '{{ LANGUAGE_CODE }}',
|
||||||
maskInput: true,
|
{% if NIGHT_MODE %}
|
||||||
format: 'Y-m-d H:i',minDate:0
|
theme: 'dark',
|
||||||
|
{% else %}
|
||||||
|
theme: 'default',
|
||||||
|
{% endif %}
|
||||||
|
mask: true,
|
||||||
|
format: 'Y-m-d H:i',
|
||||||
|
minDate: 0
|
||||||
});
|
});
|
||||||
|
|
||||||
{% endblock extra_script %}
|
{% endblock extra_script %}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{% extends "allianceauth/base.html" %}
|
{% extends "allianceauth/base.html" %}
|
||||||
{% load staticfiles %}
|
{% load static %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% get_current_language as LANGUAGE_CODE %}
|
{% get_current_language as LANGUAGE_CODE %}
|
||||||
|
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
|
|
||||||
{% include 'bundles/moment-js.html' with locale=True %}
|
{% include 'bundles/moment-js.html' with locale=True %}
|
||||||
<script src="{% static 'js/timers.js' %}"></script>
|
<script src="{% static 'js/timers.js' %}"></script>
|
||||||
<script type="text/javascript">
|
<script type="application/javascript">
|
||||||
// Data
|
// Data
|
||||||
var timers = [
|
var timers = [
|
||||||
{% for op in optimer %}
|
{% for op in optimer %}
|
||||||
@@ -53,7 +53,7 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
];
|
];
|
||||||
</script>
|
</script>
|
||||||
<script type="text/javascript">
|
<script type="application/javascript">
|
||||||
|
|
||||||
timedUpdate();
|
timedUpdate();
|
||||||
setAllLocalTimes();
|
setAllLocalTimes();
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{% extends "allianceauth/base.html" %}
|
{% extends "allianceauth/base.html" %}
|
||||||
{% load bootstrap %}
|
{% load bootstrap %}
|
||||||
{% load staticfiles %}
|
{% load static %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% get_current_language as LANGUAGE_CODE %}
|
{% get_current_language as LANGUAGE_CODE %}
|
||||||
|
|
||||||
@@ -44,9 +44,15 @@
|
|||||||
{% block extra_script %}
|
{% block extra_script %}
|
||||||
|
|
||||||
$('#id_start').datetimepicker({
|
$('#id_start').datetimepicker({
|
||||||
lang: '{{ LANGUAGE_CODE }}',
|
setlocale: '{{ LANGUAGE_CODE }}',
|
||||||
maskInput: true,
|
{% if NIGHT_MODE %}
|
||||||
format: 'Y-m-d H:i',minDate:0
|
theme: 'dark',
|
||||||
|
{% else %}
|
||||||
|
theme: 'default',
|
||||||
|
{% endif %}
|
||||||
|
mask: true,
|
||||||
|
format: 'Y-m-d H:i',
|
||||||
|
minDate: 0
|
||||||
});
|
});
|
||||||
|
|
||||||
{% endblock extra_script %}
|
{% endblock extra_script %}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{% extends "allianceauth/base.html" %}
|
{% extends "allianceauth/base.html" %}
|
||||||
{% load bootstrap %}
|
{% load bootstrap %}
|
||||||
{% load staticfiles %}
|
{% load static %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block page_title %}{{ permission.permission.codename }} - {% trans "Permissions Audit" %}{% endblock page_title %}
|
{% block page_title %}{{ permission.permission.codename }} - {% trans "Permissions Audit" %}{% endblock page_title %}
|
||||||
@@ -47,7 +47,7 @@
|
|||||||
|
|
||||||
{% block extra_javascript %}
|
{% block extra_javascript %}
|
||||||
{% include 'bundles/datatables-js.html' %}
|
{% include 'bundles/datatables-js.html' %}
|
||||||
<script type="text/javascript" src="{% static 'js/filterDropDown/filterDropDown.min.js' %}"></script>
|
<script type="application/javascript" src="{% static 'js/filterDropDown/filterDropDown.min.js' %}"></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block extra_css %}
|
{% block extra_css %}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{% extends "allianceauth/base.html" %}
|
{% extends "allianceauth/base.html" %}
|
||||||
{% load bootstrap %}
|
{% load bootstrap %}
|
||||||
{% load staticfiles %}
|
{% load static %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block page_title %}{% trans "Permissions Overview" %}{% endblock page_title %}
|
{% block page_title %}{% trans "Permissions Overview" %}{% endblock page_title %}
|
||||||
@@ -80,7 +80,7 @@
|
|||||||
|
|
||||||
{% block extra_javascript %}
|
{% block extra_javascript %}
|
||||||
{% include 'bundles/datatables-js.html' %}
|
{% include 'bundles/datatables-js.html' %}
|
||||||
<script type="text/javascript" src="{% static 'js/filterDropDown/filterDropDown.min.js' %}"></script>
|
<script type="application/javascript" src="{% static 'js/filterDropDown/filterDropDown.min.js' %}"></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block extra_css %}
|
{% block extra_css %}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import os
|
import os
|
||||||
from celery import Celery
|
from celery import Celery
|
||||||
|
from celery.app import trace
|
||||||
|
|
||||||
# set the default Django settings module for the 'celery' program.
|
# set the default Django settings module for the 'celery' program.
|
||||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', '{{ project_name }}.settings.local')
|
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.
|
# Load task modules from all registered Django app configs.
|
||||||
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
|
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"
|
||||||
|
|||||||
@@ -64,12 +64,12 @@ BASE_DIR = os.path.dirname(PROJECT_DIR)
|
|||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
'django.middleware.security.SecurityMiddleware',
|
'django.middleware.security.SecurityMiddleware',
|
||||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||||
|
'django.middleware.locale.LocaleMiddleware',
|
||||||
'django.middleware.common.CommonMiddleware',
|
'django.middleware.common.CommonMiddleware',
|
||||||
'django.middleware.csrf.CsrfViewMiddleware',
|
'django.middleware.csrf.CsrfViewMiddleware',
|
||||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||||
'django.contrib.messages.middleware.MessageMiddleware',
|
'django.contrib.messages.middleware.MessageMiddleware',
|
||||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||||
'django.middleware.locale.LocaleMiddleware',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
ROOT_URLCONF = 'allianceauth.urls'
|
ROOT_URLCONF = 'allianceauth.urls'
|
||||||
@@ -86,6 +86,8 @@ LANGUAGES = (
|
|||||||
('zh-hans', ugettext('Chinese Simplified')),
|
('zh-hans', ugettext('Chinese Simplified')),
|
||||||
('ru', ugettext('Russian')),
|
('ru', ugettext('Russian')),
|
||||||
('ko', ugettext('Korean')),
|
('ko', ugettext('Korean')),
|
||||||
|
('fr', ugettext('French')),
|
||||||
|
('ja', ugettext('Japanese')),
|
||||||
)
|
)
|
||||||
|
|
||||||
TEMPLATES = [
|
TEMPLATES = [
|
||||||
@@ -102,8 +104,7 @@ TEMPLATES = [
|
|||||||
'django.template.context_processors.i18n',
|
'django.template.context_processors.i18n',
|
||||||
'django.template.context_processors.media',
|
'django.template.context_processors.media',
|
||||||
'django.template.context_processors.static',
|
'django.template.context_processors.static',
|
||||||
'django.template.context_processors.tz',
|
'django.template.context_processors.tz',
|
||||||
'allianceauth.notifications.context_processors.user_notification_count',
|
|
||||||
'allianceauth.context_processors.auth_settings',
|
'allianceauth.context_processors.auth_settings',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -138,6 +139,8 @@ AUTHENTICATION_BACKENDS = ['allianceauth.authentication.backends.StateBackend',
|
|||||||
|
|
||||||
LANGUAGE_CODE = 'en-us'
|
LANGUAGE_CODE = 'en-us'
|
||||||
|
|
||||||
|
LANGUAGE_COOKIE_AGE = 1209600
|
||||||
|
|
||||||
TIME_ZONE = 'UTC'
|
TIME_ZONE = 'UTC'
|
||||||
|
|
||||||
USE_I18N = True
|
USE_I18N = True
|
||||||
@@ -169,6 +172,8 @@ CACHES = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SESSION_ENGINE = "django.contrib.sessions.backends.cached_db"
|
||||||
|
|
||||||
DEBUG = True
|
DEBUG = True
|
||||||
ALLOWED_HOSTS = ['*']
|
ALLOWED_HOSTS = ['*']
|
||||||
DATABASES = {
|
DATABASES = {
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ DATABASES['default'] = {
|
|||||||
ESI_SSO_CLIENT_ID = ''
|
ESI_SSO_CLIENT_ID = ''
|
||||||
ESI_SSO_CLIENT_SECRET = ''
|
ESI_SSO_CLIENT_SECRET = ''
|
||||||
ESI_SSO_CALLBACK_URL = ''
|
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.
|
# 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.
|
# It's recommended to use a free service like SparkPost or Elastic Email to send email.
|
||||||
|
|||||||
@@ -139,6 +139,11 @@ class MenuItemHook:
|
|||||||
self.url_name = url_name
|
self.url_name = url_name
|
||||||
self.template = 'public/menuitem.html'
|
self.template = 'public/menuitem.html'
|
||||||
self.order = order if order is not None else 9999
|
self.order = order if order is not None else 9999
|
||||||
|
|
||||||
|
# count is an integer shown next to the menu item as badge when count != None
|
||||||
|
# apps need to set the count in their child class, e.g. in render() method
|
||||||
|
self.count = None
|
||||||
|
|
||||||
navactive = navactive or []
|
navactive = navactive or []
|
||||||
navactive.append(url_name)
|
navactive.append(url_name)
|
||||||
self.navactive = navactive
|
self.navactive = navactive
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ from ..utils import clean_setting
|
|||||||
|
|
||||||
# Base URL for all API calls. Must end with /.
|
# Base URL for all API calls. Must end with /.
|
||||||
DISCORD_API_BASE_URL = clean_setting(
|
DISCORD_API_BASE_URL = clean_setting(
|
||||||
'DISCORD_API_BASE_URL', 'https://discordapp.com/api/'
|
'DISCORD_API_BASE_URL', 'https://discord.com/api/'
|
||||||
)
|
)
|
||||||
|
|
||||||
# Low level connecttimeout for requests to the Discord API in seconds
|
# Low level connecttimeout for requests to the Discord API in seconds
|
||||||
@@ -18,23 +18,23 @@ DISCORD_API_TIMEOUT_READ = clean_setting(
|
|||||||
|
|
||||||
# Base authorization URL for Discord Oauth
|
# Base authorization URL for Discord Oauth
|
||||||
DISCORD_OAUTH_BASE_URL = clean_setting(
|
DISCORD_OAUTH_BASE_URL = clean_setting(
|
||||||
'DISCORD_OAUTH_BASE_URL', 'https://discordapp.com/api/oauth2/authorize'
|
'DISCORD_OAUTH_BASE_URL', 'https://discord.com/api/oauth2/authorize'
|
||||||
)
|
)
|
||||||
|
|
||||||
# Base authorization URL for Discord Oauth
|
# Base authorization URL for Discord Oauth
|
||||||
DISCORD_OAUTH_TOKEN_URL = clean_setting(
|
DISCORD_OAUTH_TOKEN_URL = clean_setting(
|
||||||
'DISCORD_OAUTH_TOKEN_URL', 'https://discordapp.com/api/oauth2/token'
|
'DISCORD_OAUTH_TOKEN_URL', 'https://discord.com/api/oauth2/token'
|
||||||
)
|
)
|
||||||
|
|
||||||
# How long the Discord guild names retrieved from the server are
|
# How long the Discord guild names retrieved from the server are
|
||||||
# caches locally in milliseconds.
|
# caches locally in seconds.
|
||||||
DISCORD_GUILD_NAME_CACHE_MAX_AGE = clean_setting(
|
DISCORD_GUILD_NAME_CACHE_MAX_AGE = clean_setting(
|
||||||
'DISCORD_GUILD_NAME_CACHE_MAX_AGE', 3600 * 1 * 1000
|
'DISCORD_GUILD_NAME_CACHE_MAX_AGE', 3600 * 24
|
||||||
)
|
)
|
||||||
|
|
||||||
# How long Discord roles retrieved from the server are caches locally in milliseconds.
|
# How long Discord roles retrieved from the server are caches locally in seconds.
|
||||||
DISCORD_ROLES_CACHE_MAX_AGE = clean_setting(
|
DISCORD_ROLES_CACHE_MAX_AGE = clean_setting(
|
||||||
'DISCORD_ROLES_CACHE_MAX_AGE', 3600 * 1 * 1000
|
'DISCORD_ROLES_CACHE_MAX_AGE', 3600 * 1
|
||||||
)
|
)
|
||||||
|
|
||||||
# Turns off creation of new roles. In case the rate limit for creating roles is
|
# Turns off creation of new roles. In case the rate limit for creating roles is
|
||||||
|
|||||||
@@ -180,12 +180,19 @@ class DiscordClient:
|
|||||||
r = self._api_request(method='get', route=route)
|
r = self._api_request(method='get', route=route)
|
||||||
return r.json()
|
return r.json()
|
||||||
|
|
||||||
def guild_name(self, guild_id: int) -> str:
|
def guild_name(self, guild_id: int, use_cache: bool = True) -> str:
|
||||||
"""returns the name of this guild (cached)
|
"""returns the name of this guild (cached)
|
||||||
or an empty string if something went wrong
|
or an empty string if something went wrong
|
||||||
|
|
||||||
|
Params:
|
||||||
|
- guild_id: ID of current guild
|
||||||
|
- use_cache: When set to False will force an API call to get the server name
|
||||||
"""
|
"""
|
||||||
key_name = self._guild_name_cache_key(guild_id)
|
key_name = self._guild_name_cache_key(guild_id)
|
||||||
guild_name = self._redis_decode(self._redis.get(key_name))
|
if use_cache:
|
||||||
|
guild_name = self._redis_decode(self._redis.get(key_name))
|
||||||
|
else:
|
||||||
|
guild_name = None
|
||||||
if not guild_name:
|
if not guild_name:
|
||||||
guild_infos = self.guild_infos(guild_id)
|
guild_infos = self.guild_infos(guild_id)
|
||||||
if 'name' in guild_infos:
|
if 'name' in guild_infos:
|
||||||
@@ -193,7 +200,7 @@ class DiscordClient:
|
|||||||
self._redis.set(
|
self._redis.set(
|
||||||
name=key_name,
|
name=key_name,
|
||||||
value=guild_name,
|
value=guild_name,
|
||||||
px=DISCORD_GUILD_NAME_CACHE_MAX_AGE
|
ex=DISCORD_GUILD_NAME_CACHE_MAX_AGE
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
guild_name = ''
|
guild_name = ''
|
||||||
@@ -230,7 +237,7 @@ class DiscordClient:
|
|||||||
self._redis.set(
|
self._redis.set(
|
||||||
name=cache_key,
|
name=cache_key,
|
||||||
value=json.dumps(roles),
|
value=json.dumps(roles),
|
||||||
px=DISCORD_ROLES_CACHE_MAX_AGE
|
ex=DISCORD_ROLES_CACHE_MAX_AGE
|
||||||
)
|
)
|
||||||
return roles
|
return roles
|
||||||
|
|
||||||
@@ -274,6 +281,11 @@ class DiscordClient:
|
|||||||
gen_key = cls._generate_hash(f'{guild_id}')
|
gen_key = cls._generate_hash(f'{guild_id}')
|
||||||
return f'{cls._KEYPREFIX_GUILD_ROLES}__{gen_key}'
|
return f'{cls._KEYPREFIX_GUILD_ROLES}__{gen_key}'
|
||||||
|
|
||||||
|
def match_role_from_name(self, guild_id: int, role_name: str) -> dict:
|
||||||
|
"""returns Discord role matching the given name or an empty dict"""
|
||||||
|
guild_roles = DiscordRoles(self.guild_roles(guild_id))
|
||||||
|
return guild_roles.role_by_name(role_name)
|
||||||
|
|
||||||
def match_or_create_roles_from_names(self, guild_id: int, role_names: list) -> list:
|
def match_or_create_roles_from_names(self, guild_id: int, role_names: list) -> list:
|
||||||
"""returns Discord roles matching the given names
|
"""returns Discord roles matching the given names
|
||||||
|
|
||||||
@@ -281,6 +293,7 @@ class DiscordClient:
|
|||||||
|
|
||||||
Will try to match with existing roles names
|
Will try to match with existing roles names
|
||||||
Non-existing roles will be created, then created flag will be True
|
Non-existing roles will be created, then created flag will be True
|
||||||
|
|
||||||
Params:
|
Params:
|
||||||
- guild_id: ID of guild
|
- guild_id: ID of guild
|
||||||
- role_names: list of name strings each defining a role
|
- role_names: list of name strings each defining a role
|
||||||
@@ -311,6 +324,7 @@ class DiscordClient:
|
|||||||
|
|
||||||
Will try to match with existing roles names
|
Will try to match with existing roles names
|
||||||
Non-existing roles will be created, then created flag will be True
|
Non-existing roles will be created, then created flag will be True
|
||||||
|
|
||||||
Params:
|
Params:
|
||||||
- guild_id: ID of guild
|
- guild_id: ID of guild
|
||||||
- role_name: strings defining name of a role
|
- role_name: strings defining name of a role
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ logger = set_logger_to_file(
|
|||||||
)
|
)
|
||||||
|
|
||||||
MODULE_PATH = 'allianceauth.services.modules.discord.discord_client.client'
|
MODULE_PATH = 'allianceauth.services.modules.discord.discord_client.client'
|
||||||
API_BASE_URL = 'https://discordapp.com/api/'
|
API_BASE_URL = 'https://discord.com/api/'
|
||||||
|
|
||||||
TEST_RETRY_AFTER = 3000
|
TEST_RETRY_AFTER = 3000
|
||||||
|
|
||||||
@@ -280,6 +280,8 @@ class TestGuildGetName(TestCase):
|
|||||||
client = DiscordClient2(TEST_BOT_TOKEN, my_mock_redis)
|
client = DiscordClient2(TEST_BOT_TOKEN, my_mock_redis)
|
||||||
result = client.guild_name(TEST_GUILD_ID)
|
result = client.guild_name(TEST_GUILD_ID)
|
||||||
self.assertEqual(result, guild_name)
|
self.assertEqual(result, guild_name)
|
||||||
|
self.assertTrue(my_mock_redis.get.called)
|
||||||
|
self.assertFalse(my_mock_redis.set.called)
|
||||||
|
|
||||||
@patch(MODULE_PATH + '.DiscordClient.guild_infos')
|
@patch(MODULE_PATH + '.DiscordClient.guild_infos')
|
||||||
def test_fetches_from_server_if_not_found_in_cache_and_stores_in_cache(
|
def test_fetches_from_server_if_not_found_in_cache_and_stores_in_cache(
|
||||||
@@ -291,6 +293,20 @@ class TestGuildGetName(TestCase):
|
|||||||
client = DiscordClient2(TEST_BOT_TOKEN, my_mock_redis)
|
client = DiscordClient2(TEST_BOT_TOKEN, my_mock_redis)
|
||||||
result = client.guild_name(TEST_GUILD_ID)
|
result = client.guild_name(TEST_GUILD_ID)
|
||||||
self.assertEqual(result, guild_name)
|
self.assertEqual(result, guild_name)
|
||||||
|
self.assertTrue(my_mock_redis.get.called)
|
||||||
|
self.assertTrue(my_mock_redis.set.called)
|
||||||
|
|
||||||
|
@patch(MODULE_PATH + '.DiscordClient.guild_infos')
|
||||||
|
def test_fetches_from_server_if_asked_to_ignore_cache_and_stores_in_cache(
|
||||||
|
self, mock_guild_get_infos
|
||||||
|
):
|
||||||
|
guild_name = 'Omega'
|
||||||
|
my_mock_redis = MagicMock(**{'get.return_value': False})
|
||||||
|
mock_guild_get_infos.return_value = {'id': TEST_GUILD_ID, 'name': guild_name}
|
||||||
|
client = DiscordClient2(TEST_BOT_TOKEN, my_mock_redis)
|
||||||
|
result = client.guild_name(TEST_GUILD_ID, use_cache=False)
|
||||||
|
self.assertFalse(my_mock_redis.get.called)
|
||||||
|
self.assertEqual(result, guild_name)
|
||||||
self.assertTrue(my_mock_redis.set.called)
|
self.assertTrue(my_mock_redis.set.called)
|
||||||
|
|
||||||
@patch(MODULE_PATH + '.DiscordClient.guild_infos')
|
@patch(MODULE_PATH + '.DiscordClient.guild_infos')
|
||||||
@@ -302,6 +318,7 @@ class TestGuildGetName(TestCase):
|
|||||||
client = DiscordClient2(TEST_BOT_TOKEN, my_mock_redis)
|
client = DiscordClient2(TEST_BOT_TOKEN, my_mock_redis)
|
||||||
result = client.guild_name(TEST_GUILD_ID)
|
result = client.guild_name(TEST_GUILD_ID)
|
||||||
self.assertEqual(result, '')
|
self.assertEqual(result, '')
|
||||||
|
self.assertTrue(my_mock_redis.get.called)
|
||||||
self.assertFalse(my_mock_redis.set.called)
|
self.assertFalse(my_mock_redis.set.called)
|
||||||
|
|
||||||
|
|
||||||
@@ -844,9 +861,45 @@ class TestGuildMemberRemoveRole(TestCase):
|
|||||||
self.assertFalse(result)
|
self.assertFalse(result)
|
||||||
|
|
||||||
|
|
||||||
|
class TestMatchGuildRolesToName(TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.url = f'{API_BASE_URL}guilds/{TEST_GUILD_ID}/roles'
|
||||||
|
|
||||||
|
@requests_mock.Mocker()
|
||||||
|
def test_return_role_if_known(self, requests_mocker):
|
||||||
|
my_mock_redis = MagicMock(**{
|
||||||
|
'get.return_value': None,
|
||||||
|
'pttl.return_value': -1,
|
||||||
|
})
|
||||||
|
requests_mocker.get(
|
||||||
|
url=self.url,
|
||||||
|
request_headers=DEFAULT_REQUEST_HEADERS,
|
||||||
|
json=ALL_ROLES
|
||||||
|
)
|
||||||
|
client = DiscordClient2(TEST_BOT_TOKEN, my_mock_redis)
|
||||||
|
result = client.match_role_from_name(TEST_GUILD_ID, "alpha")
|
||||||
|
self.assertDictEqual(result, ROLE_ALPHA)
|
||||||
|
|
||||||
|
@requests_mock.Mocker()
|
||||||
|
def test_return_empty_dict_if_not_known(self, requests_mocker):
|
||||||
|
my_mock_redis = MagicMock(**{
|
||||||
|
'get.return_value': None,
|
||||||
|
'pttl.return_value': -1,
|
||||||
|
})
|
||||||
|
requests_mocker.get(
|
||||||
|
url=self.url,
|
||||||
|
request_headers=DEFAULT_REQUEST_HEADERS,
|
||||||
|
json=ALL_ROLES
|
||||||
|
)
|
||||||
|
client = DiscordClient2(TEST_BOT_TOKEN, my_mock_redis)
|
||||||
|
result = client.match_role_from_name(TEST_GUILD_ID, "unknown")
|
||||||
|
self.assertDictEqual(result, dict())
|
||||||
|
|
||||||
|
|
||||||
@patch(MODULE_PATH + '.DiscordClient.create_guild_role')
|
@patch(MODULE_PATH + '.DiscordClient.create_guild_role')
|
||||||
@patch(MODULE_PATH + '.DiscordClient.guild_roles')
|
@patch(MODULE_PATH + '.DiscordClient.guild_roles')
|
||||||
class TestMatchGuildRolesToName(TestCase):
|
class TestMatchOrCreateGuildRolesToName(TestCase):
|
||||||
|
|
||||||
def test_return_role_if_known(
|
def test_return_role_if_known(
|
||||||
self, mock_guild_get_roles, mock_guild_create_role,
|
self, mock_guild_get_roles, mock_guild_create_role,
|
||||||
@@ -896,7 +949,7 @@ class TestMatchGuildRolesToName(TestCase):
|
|||||||
|
|
||||||
@patch(MODULE_PATH + '.DiscordClient.create_guild_role')
|
@patch(MODULE_PATH + '.DiscordClient.create_guild_role')
|
||||||
@patch(MODULE_PATH + '.DiscordClient.guild_roles')
|
@patch(MODULE_PATH + '.DiscordClient.guild_roles')
|
||||||
class TestMatchGuildRolesToNames(TestCase):
|
class TestMatchOrCreateGuildRolesToNames(TestCase):
|
||||||
|
|
||||||
def test_return_roles_if_known(
|
def test_return_roles_if_known(
|
||||||
self, mock_guild_get_roles, mock_guild_create_role,
|
self, mock_guild_get_roles, mock_guild_create_role,
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ from urllib.parse import urlencode
|
|||||||
from requests_oauthlib import OAuth2Session
|
from requests_oauthlib import OAuth2Session
|
||||||
from requests.exceptions import HTTPError
|
from requests.exceptions import HTTPError
|
||||||
|
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User, Group
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.timezone import now
|
from django.utils.timezone import now
|
||||||
|
|
||||||
@@ -19,7 +19,8 @@ from .app_settings import (
|
|||||||
DISCORD_GUILD_ID,
|
DISCORD_GUILD_ID,
|
||||||
DISCORD_SYNC_NAMES
|
DISCORD_SYNC_NAMES
|
||||||
)
|
)
|
||||||
from .discord_client import DiscordClient, DiscordApiBackoff
|
from .discord_client import DiscordClient
|
||||||
|
from .discord_client.exceptions import DiscordClientException, DiscordApiBackoff
|
||||||
from .discord_client.helpers import match_or_create_roles_from_names
|
from .discord_client.helpers import match_or_create_roles_from_names
|
||||||
from .utils import LoggerAddTag
|
from .utils import LoggerAddTag
|
||||||
|
|
||||||
@@ -149,7 +150,7 @@ class DiscordUserManager(models.Manager):
|
|||||||
return self.filter(user=user).select_related('user').exists()
|
return self.filter(user=user).select_related('user').exists()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def generate_bot_add_url(cls):
|
def generate_bot_add_url(cls) -> str:
|
||||||
params = urlencode({
|
params = urlencode({
|
||||||
'client_id': DISCORD_APP_ID,
|
'client_id': DISCORD_APP_ID,
|
||||||
'scope': 'bot',
|
'scope': 'bot',
|
||||||
@@ -159,7 +160,7 @@ class DiscordUserManager(models.Manager):
|
|||||||
return f'{DiscordClient.OAUTH_BASE_URL}?{params}'
|
return f'{DiscordClient.OAUTH_BASE_URL}?{params}'
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def generate_oauth_redirect_url(cls):
|
def generate_oauth_redirect_url(cls) -> str:
|
||||||
oauth = OAuth2Session(
|
oauth = OAuth2Session(
|
||||||
DISCORD_APP_ID, redirect_uri=DISCORD_CALLBACK_URL, scope=cls.SCOPES
|
DISCORD_APP_ID, redirect_uri=DISCORD_CALLBACK_URL, scope=cls.SCOPES
|
||||||
)
|
)
|
||||||
@@ -178,18 +179,38 @@ class DiscordUserManager(models.Manager):
|
|||||||
return token['access_token']
|
return token['access_token']
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def server_name(cls):
|
def server_name(cls, use_cache: bool = True) -> str:
|
||||||
"""returns the name of the current Discord server
|
"""returns the name of the current Discord server
|
||||||
or an empty string if the name could not be retrieved
|
or an empty string if the name could not be retrieved
|
||||||
|
|
||||||
|
Params:
|
||||||
|
- use_cache: When set False will force an API call to get the server name
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
server_name = cls._bot_client().guild_name(DISCORD_GUILD_ID)
|
server_name = cls._bot_client().guild_name(
|
||||||
except HTTPError:
|
guild_id=DISCORD_GUILD_ID, use_cache=use_cache
|
||||||
|
)
|
||||||
|
except (HTTPError, DiscordClientException):
|
||||||
|
server_name = ""
|
||||||
|
except Exception:
|
||||||
|
logger.warning(
|
||||||
|
"Unexpected error when trying to retrieve the server name from Discord",
|
||||||
|
exc_info=True
|
||||||
|
)
|
||||||
server_name = ""
|
server_name = ""
|
||||||
|
|
||||||
return server_name
|
return server_name
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def group_to_role(cls, group: Group) -> dict:
|
||||||
|
"""returns the Discord role matching the given Django group by name
|
||||||
|
or an empty dict() if no matching role exist
|
||||||
|
"""
|
||||||
|
return cls._bot_client().match_role_from_name(
|
||||||
|
guild_id=DISCORD_GUILD_ID, role_name=group.name
|
||||||
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _bot_client(is_rate_limited: bool = True):
|
def _bot_client(is_rate_limited: bool = True) -> DiscordClient:
|
||||||
"""returns a bot client for access to the Discord API"""
|
"""returns a bot client for access to the Discord API"""
|
||||||
return DiscordClient(DISCORD_BOT_TOKEN, is_rate_limited=is_rate_limited)
|
return DiscordClient(DISCORD_BOT_TOKEN, is_rate_limited=is_rate_limited)
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user