mirror of
https://gitlab.com/allianceauth/allianceauth.git
synced 2026-02-04 14:16:21 +01:00
Compare commits
140 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
10bd77d761 | ||
|
|
192d286cf2 | ||
|
|
8ab9d2d5ad | ||
|
|
3630812b92 | ||
|
|
2f320bc256 | ||
|
|
45b8d42b8e | ||
|
|
bd2d19f867 | ||
|
|
0be404baca | ||
|
|
e6cee9ac83 | ||
|
|
5a2c9243c4 | ||
|
|
fecd748198 | ||
|
|
85351b2c66 | ||
|
|
8b3e5b6462 | ||
|
|
93af920b8f | ||
|
|
b1248d9845 | ||
|
|
c86abef07d | ||
|
|
17ad5dfe33 | ||
|
|
e1843fe1f1 | ||
|
|
256a21f058 | ||
|
|
1473259e41 | ||
|
|
e935b91e93 | ||
|
|
07258a6914 | ||
|
|
cb35808508 | ||
|
|
937d656227 | ||
|
|
d173a59441 | ||
|
|
75a3adb2c9 | ||
|
|
148e208476 | ||
|
|
8f59f2549a | ||
|
|
630400fee4 | ||
|
|
1ec6929e91 | ||
|
|
8c6bdd8ae2 | ||
|
|
e04138bced | ||
|
|
db5ad85811 | ||
|
|
5b44fd376d | ||
|
|
0036e8b280 | ||
|
|
ea2b5bfecf | ||
|
|
aa7495fa60 | ||
|
|
162ec1bd86 | ||
|
|
2668884008 | ||
|
|
abdc3f3485 | ||
|
|
911f21ee7c | ||
|
|
2387c40254 | ||
|
|
76e18a79b3 | ||
|
|
9725c9c947 | ||
|
|
247ed7cc64 | ||
|
|
2fd2af793e | ||
|
|
3fc36b9ce1 | ||
|
|
c12fd2d7bc | ||
|
|
7fe1ba2fb2 | ||
|
|
ab7eb3e5df | ||
|
|
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 |
@@ -1,54 +1,94 @@
|
||||
stages:
|
||||
- gitlab
|
||||
- test
|
||||
- deploy
|
||||
|
||||
before_script:
|
||||
- apt-get update && apt-get install redis-server -y
|
||||
- redis-server --daemonize yes
|
||||
- redis-cli ping
|
||||
- python -V
|
||||
- pip install wheel tox
|
||||
include:
|
||||
- template: Dependency-Scanning.gitlab-ci.yml
|
||||
- template: Security/SAST.gitlab-ci.yml
|
||||
|
||||
test-3.6-core:
|
||||
image: python:3.6-buster
|
||||
script:
|
||||
- tox -e py36-core
|
||||
before_script:
|
||||
- apt-get update && apt-get install redis-server -y
|
||||
- redis-server --daemonize yes
|
||||
- python -V
|
||||
- pip install wheel tox
|
||||
|
||||
sast:
|
||||
stage: gitlab
|
||||
before_script: []
|
||||
|
||||
dependency_scanning:
|
||||
stage: gitlab
|
||||
before_script:
|
||||
- apt-get update && apt-get install redis-server libmariadbclient-dev -y
|
||||
- redis-server --daemonize yes
|
||||
- python -V
|
||||
- pip install wheel tox
|
||||
|
||||
test-3.7-core:
|
||||
image: python:3.7-buster
|
||||
script:
|
||||
- tox -e py37-core
|
||||
artifacts:
|
||||
when: always
|
||||
reports:
|
||||
cobertura: coverage.xml
|
||||
|
||||
test-3.8-core:
|
||||
image: python:3.8-buster
|
||||
script:
|
||||
- tox -e py38-core
|
||||
artifacts:
|
||||
when: always
|
||||
reports:
|
||||
cobertura: coverage.xml
|
||||
|
||||
test-3.6-all:
|
||||
image: python:3.6-buster
|
||||
test-3.9-core:
|
||||
image: python:3.9-buster
|
||||
script:
|
||||
- tox -e py36-all
|
||||
- tox -e py39-core
|
||||
artifacts:
|
||||
when: always
|
||||
reports:
|
||||
cobertura: coverage.xml
|
||||
|
||||
test-3.7-all:
|
||||
image: python:3.7-buster
|
||||
script:
|
||||
- tox -e py37-all
|
||||
artifacts:
|
||||
when: always
|
||||
reports:
|
||||
cobertura: coverage.xml
|
||||
|
||||
test-3.8-all:
|
||||
image: python:3.8-buster
|
||||
script:
|
||||
- tox -e py38-all
|
||||
artifacts:
|
||||
when: always
|
||||
reports:
|
||||
cobertura: coverage.xml
|
||||
|
||||
test-3.9-all:
|
||||
image: python:3.9-buster
|
||||
script:
|
||||
- tox -e py39-all
|
||||
artifacts:
|
||||
when: always
|
||||
reports:
|
||||
cobertura: coverage.xml
|
||||
|
||||
deploy_production:
|
||||
stage: deploy
|
||||
image: python:3.6-stretch
|
||||
image: python:3.9-buster
|
||||
|
||||
before_script:
|
||||
- pip install twine
|
||||
- pip install twine wheel
|
||||
|
||||
script:
|
||||
- python setup.py sdist
|
||||
- python setup.py sdist bdist_wheel
|
||||
- twine upload dist/*
|
||||
|
||||
rules:
|
||||
- if: $CI_COMMIT_TAG
|
||||
- if: $CI_COMMIT_TAG
|
||||
@@ -18,10 +18,6 @@ formats: all
|
||||
|
||||
# Optionally set the version of Python and requirements required to build your docs
|
||||
python:
|
||||
version: 3.7
|
||||
install:
|
||||
- method: pip
|
||||
path: .
|
||||
extra_requirements:
|
||||
- testing
|
||||
system_packages: true
|
||||
version: 3.7
|
||||
install:
|
||||
- requirements: docs/requirements.txt
|
||||
@@ -1,7 +1,7 @@
|
||||
# This will make sure the app is always imported when
|
||||
# Django starts so that shared_task will use this app.
|
||||
|
||||
__version__ = '2.8.0a1'
|
||||
__version__ = '2.9.0a2'
|
||||
__title__ = 'Alliance Auth'
|
||||
__url__ = 'https://gitlab.com/allianceauth/allianceauth'
|
||||
NAME = '%s v%s' % (__title__, __version__)
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
from django.conf import settings
|
||||
|
||||
from django.contrib import admin
|
||||
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
|
||||
from django.contrib.auth.models import User as BaseUser, \
|
||||
Permission as BasePermission, Group
|
||||
from django.db.models import Q, F
|
||||
from django.db.models import Count, Q
|
||||
from allianceauth.services.hooks import ServicesHook
|
||||
from django.db.models.signals import pre_save, post_save, pre_delete, \
|
||||
post_delete, m2m_changed
|
||||
@@ -24,11 +22,6 @@ from allianceauth.eveonline.tasks import update_character
|
||||
from .app_settings import AUTHENTICATION_ADMIN_USERS_MAX_GROUPS, \
|
||||
AUTHENTICATION_ADMIN_USERS_MAX_CHARS
|
||||
|
||||
if 'allianceauth.eveonline.autogroups' in settings.INSTALLED_APPS:
|
||||
_has_auto_groups = True
|
||||
else:
|
||||
_has_auto_groups = False
|
||||
|
||||
|
||||
def make_service_hooks_update_groups_action(service):
|
||||
"""
|
||||
@@ -91,8 +84,7 @@ class UserProfileInline(admin.StackedInline):
|
||||
if request.user.is_superuser:
|
||||
query |= Q(userprofile__isnull=True)
|
||||
else:
|
||||
query |= Q(character_ownership__user=obj)
|
||||
qs = EveCharacter.objects.filter(query)
|
||||
query |= Q(character_ownership__user=obj)
|
||||
formset = super().get_formset(request, obj=obj, **kwargs)
|
||||
|
||||
def get_kwargs(self, index):
|
||||
@@ -100,7 +92,7 @@ class UserProfileInline(admin.StackedInline):
|
||||
formset.get_form_kwargs = get_kwargs
|
||||
return formset
|
||||
|
||||
def has_add_permission(self, request):
|
||||
def has_add_permission(self, request, obj=None):
|
||||
return False
|
||||
|
||||
def has_delete_permission(self, request, obj=None):
|
||||
@@ -121,6 +113,8 @@ def user_profile_pic(obj):
|
||||
)
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
user_profile_pic.short_description = ''
|
||||
|
||||
|
||||
@@ -152,6 +146,7 @@ def user_username(obj):
|
||||
user_obj.username,
|
||||
)
|
||||
|
||||
|
||||
user_username.short_description = 'user / main'
|
||||
user_username.admin_order_field = 'username'
|
||||
|
||||
@@ -168,7 +163,8 @@ def user_main_organization(obj):
|
||||
else:
|
||||
corporation = user_obj.profile.main_character.corporation_name
|
||||
if user_obj.profile.main_character.alliance_id:
|
||||
result = format_html('{}<br>{}',
|
||||
result = format_html(
|
||||
'{}<br>{}',
|
||||
corporation,
|
||||
user_obj.profile.main_character.alliance_name
|
||||
)
|
||||
@@ -176,6 +172,7 @@ def user_main_organization(obj):
|
||||
result = corporation
|
||||
return result
|
||||
|
||||
|
||||
user_main_organization.short_description = 'Corporation / Alliance (Main)'
|
||||
user_main_organization.admin_order_field = \
|
||||
'profile__main_character__corporation_name'
|
||||
@@ -205,13 +202,13 @@ class MainCorporationsFilter(admin.SimpleListFilter):
|
||||
return qs.all()
|
||||
else:
|
||||
if qs.model == User:
|
||||
return qs\
|
||||
.filter(profile__main_character__corporation_id=\
|
||||
self.value())
|
||||
return qs.filter(
|
||||
profile__main_character__corporation_id=self.value()
|
||||
)
|
||||
else:
|
||||
return qs\
|
||||
.filter(user__profile__main_character__corporation_id=\
|
||||
self.value())
|
||||
return qs.filter(
|
||||
user__profile__main_character__corporation_id=self.value()
|
||||
)
|
||||
|
||||
|
||||
class MainAllianceFilter(admin.SimpleListFilter):
|
||||
@@ -239,12 +236,11 @@ class MainAllianceFilter(admin.SimpleListFilter):
|
||||
return qs.all()
|
||||
else:
|
||||
if qs.model == User:
|
||||
return qs\
|
||||
.filter(profile__main_character__alliance_id=self.value())
|
||||
return qs.filter(profile__main_character__alliance_id=self.value())
|
||||
else:
|
||||
return qs\
|
||||
.filter(user__profile__main_character__alliance_id=\
|
||||
self.value())
|
||||
return qs.filter(
|
||||
user__profile__main_character__alliance_id=self.value()
|
||||
)
|
||||
|
||||
|
||||
def update_main_character_model(modeladmin, request, queryset):
|
||||
@@ -259,6 +255,7 @@ def update_main_character_model(modeladmin, request, queryset):
|
||||
'Update from ESI started for {} characters'.format(tasks_count)
|
||||
)
|
||||
|
||||
|
||||
update_main_character_model.short_description = \
|
||||
'Update main character model from ESI'
|
||||
|
||||
@@ -267,32 +264,16 @@ class UserAdmin(BaseUserAdmin):
|
||||
"""Extending Django's UserAdmin model
|
||||
|
||||
Behavior of groups and characters columns can be configured via settings
|
||||
|
||||
"""
|
||||
|
||||
class Media:
|
||||
css = {
|
||||
"all": ("authentication/css/admin.css",)
|
||||
}
|
||||
|
||||
class RealGroupsFilter(admin.SimpleListFilter):
|
||||
"""Custom filter to get groups w/o Autogroups"""
|
||||
title = 'group'
|
||||
parameter_name = 'group_id__exact'
|
||||
|
||||
def lookups(self, request, model_admin):
|
||||
qs = Group.objects.all().order_by(Lower('name'))
|
||||
if _has_auto_groups:
|
||||
qs = qs\
|
||||
.filter(managedalliancegroup__isnull=True)\
|
||||
.filter(managedcorpgroup__isnull=True)
|
||||
return tuple([(x.pk, x.name) for x in qs])
|
||||
|
||||
def queryset(self, request, queryset):
|
||||
if self.value() is None:
|
||||
return queryset.all()
|
||||
else:
|
||||
return queryset.filter(groups__pk=self.value())
|
||||
|
||||
def get_queryset(self, request):
|
||||
qs = super().get_queryset(request)
|
||||
return qs.prefetch_related("character_ownerships__character", "groups")
|
||||
|
||||
def get_actions(self, request):
|
||||
actions = super(BaseUserAdmin, self).get_actions(request)
|
||||
@@ -341,11 +322,9 @@ class UserAdmin(BaseUserAdmin):
|
||||
return result
|
||||
|
||||
inlines = BaseUserAdmin.inlines + [UserProfileInline]
|
||||
|
||||
ordering = ('username', )
|
||||
list_select_related = True
|
||||
show_full_result_count = True
|
||||
|
||||
ordering = ('username', )
|
||||
list_select_related = ('profile__state', 'profile__main_character')
|
||||
show_full_result_count = True
|
||||
list_display = (
|
||||
user_profile_pic,
|
||||
user_username,
|
||||
@@ -358,10 +337,9 @@ class UserAdmin(BaseUserAdmin):
|
||||
'_role'
|
||||
)
|
||||
list_display_links = None
|
||||
|
||||
list_filter = (
|
||||
'profile__state',
|
||||
RealGroupsFilter,
|
||||
'groups',
|
||||
MainCorporationsFilter,
|
||||
MainAllianceFilter,
|
||||
'is_active',
|
||||
@@ -375,41 +353,25 @@ class UserAdmin(BaseUserAdmin):
|
||||
)
|
||||
|
||||
def _characters(self, obj):
|
||||
my_characters = [
|
||||
x.character.character_name
|
||||
for x in CharacterOwnership.objects\
|
||||
.filter(user=obj)\
|
||||
.order_by('character__character_name')\
|
||||
.select_related()
|
||||
]
|
||||
character_ownerships = list(obj.character_ownerships.all())
|
||||
characters = [obj.character.character_name for obj in character_ownerships]
|
||||
return self._list_2_html_w_tooltips(
|
||||
my_characters,
|
||||
sorted(characters),
|
||||
AUTHENTICATION_ADMIN_USERS_MAX_CHARS
|
||||
)
|
||||
|
||||
_characters.short_description = 'characters'
|
||||
|
||||
|
||||
def _state(self, obj):
|
||||
return obj.profile.state.name
|
||||
|
||||
_state.short_description = 'state'
|
||||
_state.admin_order_field = 'profile__state'
|
||||
|
||||
def _groups(self, obj):
|
||||
if not _has_auto_groups:
|
||||
my_groups = [x.name for x in obj.groups.order_by('name')]
|
||||
else:
|
||||
my_groups = [
|
||||
x.name for x in obj.groups\
|
||||
.filter(managedalliancegroup__isnull=True)\
|
||||
.filter(managedcorpgroup__isnull=True)\
|
||||
.order_by('name')
|
||||
]
|
||||
|
||||
def _groups(self, obj):
|
||||
my_groups = sorted([group.name for group in list(obj.groups.all())])
|
||||
return self._list_2_html_w_tooltips(
|
||||
my_groups,
|
||||
AUTHENTICATION_ADMIN_USERS_MAX_GROUPS
|
||||
my_groups, AUTHENTICATION_ADMIN_USERS_MAX_GROUPS
|
||||
)
|
||||
|
||||
_groups.short_description = 'groups'
|
||||
@@ -446,9 +408,14 @@ class StateAdmin(admin.ModelAdmin):
|
||||
list_select_related = True
|
||||
list_display = ('name', 'priority', '_user_count')
|
||||
|
||||
def get_queryset(self, request):
|
||||
qs = super().get_queryset(request)
|
||||
return qs.annotate(user_count=Count("userprofile__id"))
|
||||
|
||||
def _user_count(self, obj):
|
||||
return obj.userprofile_set.all().count()
|
||||
return obj.user_count
|
||||
_user_count.short_description = 'Users'
|
||||
_user_count.admin_order_field = 'user_count'
|
||||
|
||||
fieldsets = (
|
||||
(None, {
|
||||
@@ -504,7 +471,8 @@ class BaseOwnershipAdmin(admin.ModelAdmin):
|
||||
"all": ("authentication/css/admin.css",)
|
||||
}
|
||||
|
||||
list_select_related = True
|
||||
list_select_related = (
|
||||
'user__profile__state', 'user__profile__main_character', 'character')
|
||||
list_display = (
|
||||
user_profile_pic,
|
||||
user_username,
|
||||
@@ -542,6 +510,7 @@ class CharacterOwnershipAdmin(BaseOwnershipAdmin):
|
||||
class PermissionAdmin(admin.ModelAdmin):
|
||||
actions = None
|
||||
readonly_fields = [field.name for field in BasePermission._meta.fields]
|
||||
search_fields = ('codename', )
|
||||
list_display = ('admin_name', 'name', 'codename', 'content_type')
|
||||
list_filter = ('content_type__app_label',)
|
||||
|
||||
@@ -549,7 +518,7 @@ class PermissionAdmin(admin.ModelAdmin):
|
||||
def admin_name(obj):
|
||||
return str(obj)
|
||||
|
||||
def has_add_permission(self, request):
|
||||
def has_add_permission(self, request, obj=None):
|
||||
return False
|
||||
|
||||
def has_delete_permission(self, request, obj=None):
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
from django import forms
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
|
||||
from allianceauth.authentication.models import User
|
||||
class RegistrationForm(forms.Form):
|
||||
email = forms.EmailField(label=_('Email'), max_length=254, required=True)
|
||||
|
||||
class _meta:
|
||||
model = User
|
||||
|
||||
@@ -10,5 +10,5 @@ urlpatterns = [
|
||||
url(r'^register/$', views.RegistrationView.as_view(), name='registration_register'),
|
||||
url(r'^register/complete/$', views.registration_complete, name='registration_complete'),
|
||||
url(r'^register/closed/$', views.registration_closed, name='registration_disallowed'),
|
||||
url(r'', include('registration.auth_urls')),
|
||||
url(r'', include('django.contrib.auth.urls')),
|
||||
]
|
||||
@@ -1,5 +1,5 @@
|
||||
{% extends "allianceauth/base.html" %}
|
||||
{% load staticfiles %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block page_title %}{% trans "Dashboard" %}{% endblock %}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{% load staticfiles %}
|
||||
{% extends 'public/base.html' %}
|
||||
{% load static %}
|
||||
{% load bootstrap %}
|
||||
{% load i18n %}
|
||||
{% extends 'public/base.html' %}
|
||||
{% block page_title %}Registration{% endblock %}
|
||||
{% block extra_include %}
|
||||
{% include 'bundles/bootstrap-css.html' %}
|
||||
|
||||
@@ -10,9 +10,10 @@ def get_admin_change_view_url(obj: object) -> str:
|
||||
args=(obj.pk,)
|
||||
)
|
||||
|
||||
|
||||
def get_admin_search_url(ModelClass: type) -> str:
|
||||
"""returns URL to search URL for model of given object"""
|
||||
return '{}{}/'.format(
|
||||
reverse('admin:app_list', args=(ModelClass._meta.app_label,)),
|
||||
ModelClass.__name__.lower()
|
||||
)
|
||||
)
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
from urllib.parse import quote
|
||||
from unittest.mock import patch, MagicMock
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib import admin
|
||||
from django.contrib.admin.sites import AdminSite
|
||||
from django.contrib.auth.models import User as BaseUser, Group
|
||||
from django.contrib.auth.models import Group
|
||||
from django.test import TestCase, RequestFactory, Client
|
||||
|
||||
from allianceauth.authentication.models import (
|
||||
@@ -18,8 +16,7 @@ from allianceauth.tests.auth_utils import AuthUtils
|
||||
|
||||
from ..admin import (
|
||||
BaseUserAdmin,
|
||||
CharacterOwnershipAdmin,
|
||||
PermissionAdmin,
|
||||
CharacterOwnershipAdmin,
|
||||
StateAdmin,
|
||||
MainCorporationsFilter,
|
||||
MainAllianceFilter,
|
||||
@@ -35,11 +32,6 @@ from ..admin import (
|
||||
)
|
||||
from . import get_admin_change_view_url, get_admin_search_url
|
||||
|
||||
if 'allianceauth.eveonline.autogroups' in settings.INSTALLED_APPS:
|
||||
_has_auto_groups = True
|
||||
from allianceauth.eveonline.autogroups.models import AutogroupsConfig
|
||||
else:
|
||||
_has_auto_groups = False
|
||||
|
||||
MODULE_PATH = 'allianceauth.authentication.admin'
|
||||
|
||||
@@ -48,6 +40,7 @@ class MockRequest(object):
|
||||
def __init__(self, user=None):
|
||||
self.user = user
|
||||
|
||||
|
||||
class TestCaseWithTestData(TestCase):
|
||||
|
||||
@classmethod
|
||||
@@ -279,6 +272,7 @@ class TestStateAdmin(TestCaseWithTestData):
|
||||
expected = 200
|
||||
self.assertEqual(response.status_code, expected)
|
||||
|
||||
|
||||
class TestUserAdmin(TestCaseWithTestData):
|
||||
|
||||
def setUp(self):
|
||||
@@ -287,24 +281,12 @@ class TestUserAdmin(TestCaseWithTestData):
|
||||
model=User, admin_site=AdminSite()
|
||||
)
|
||||
self.character_1 = self.user_1.character_ownerships.first().character
|
||||
|
||||
def _create_autogroups(self):
|
||||
"""create autogroups for corps and alliances"""
|
||||
if _has_auto_groups:
|
||||
autogroups_config = AutogroupsConfig(
|
||||
corp_groups = True,
|
||||
alliance_groups = True
|
||||
)
|
||||
autogroups_config.save()
|
||||
for state in State.objects.all():
|
||||
autogroups_config.states.add(state)
|
||||
autogroups_config.update_corp_group_membership(self.user_1)
|
||||
|
||||
# column rendering
|
||||
|
||||
|
||||
def test_user_profile_pic_u1(self):
|
||||
expected = ('<img src="https://images.evetech.net/characters/1001/'
|
||||
'portrait?size=32" class="img-circle">')
|
||||
expected = (
|
||||
'<img src="https://images.evetech.net/characters/1001/'
|
||||
'portrait?size=32" class="img-circle">'
|
||||
)
|
||||
self.assertEqual(user_profile_pic(self.user_1), expected)
|
||||
|
||||
def test_user_profile_pic_u3(self):
|
||||
@@ -351,37 +333,17 @@ class TestUserAdmin(TestCaseWithTestData):
|
||||
result = self.modeladmin._characters(self.user_3)
|
||||
self.assertEqual(result, expected)
|
||||
|
||||
def test_groups_u1(self):
|
||||
self._create_autogroups()
|
||||
def test_groups_u1(self):
|
||||
expected = 'Group 1'
|
||||
result = self.modeladmin._groups(self.user_1)
|
||||
self.assertEqual(result, expected)
|
||||
|
||||
def test_groups_u2(self):
|
||||
self._create_autogroups()
|
||||
def test_groups_u2(self):
|
||||
expected = 'Group 2'
|
||||
result = self.modeladmin._groups(self.user_2)
|
||||
self.assertEqual(result, expected)
|
||||
|
||||
def test_groups_u3(self):
|
||||
self._create_autogroups()
|
||||
result = self.modeladmin._groups(self.user_3)
|
||||
self.assertIsNone(result)
|
||||
|
||||
@patch(MODULE_PATH + '._has_auto_groups', False)
|
||||
def test_groups_u1_no_autogroups(self):
|
||||
expected = 'Group 1'
|
||||
result = self.modeladmin._groups(self.user_1)
|
||||
self.assertEqual(result, expected)
|
||||
|
||||
@patch(MODULE_PATH + '._has_auto_groups', False)
|
||||
def test_groups_u2_no_autogroups(self):
|
||||
expected = 'Group 2'
|
||||
result = self.modeladmin._groups(self.user_2)
|
||||
self.assertEqual(result, expected)
|
||||
|
||||
@patch(MODULE_PATH + '._has_auto_groups', False)
|
||||
def test_groups_u3_no_autogroups(self):
|
||||
def test_groups_u3(self):
|
||||
result = self.modeladmin._groups(self.user_3)
|
||||
self.assertIsNone(result)
|
||||
|
||||
@@ -413,8 +375,10 @@ class TestUserAdmin(TestCaseWithTestData):
|
||||
|
||||
def test_list_2_html_w_tooltips_w_cutoff(self):
|
||||
items = ['one', 'two', 'three']
|
||||
expected = ('<span data-tooltip="one, two, three" '
|
||||
'class="tooltip">one, two, (...)</span>')
|
||||
expected = (
|
||||
'<span data-tooltip="one, two, three" '
|
||||
'class="tooltip">one, two, (...)</span>'
|
||||
)
|
||||
result = self.modeladmin._list_2_html_w_tooltips(items, 2)
|
||||
self.assertEqual(expected, result)
|
||||
|
||||
@@ -439,63 +403,7 @@ class TestUserAdmin(TestCaseWithTestData):
|
||||
self.assertTrue(mock_message_user.called)
|
||||
|
||||
# filters
|
||||
|
||||
def test_filter_real_groups_with_autogroups(self):
|
||||
|
||||
class UserAdminTest(BaseUserAdmin):
|
||||
list_filter = (UserAdmin.RealGroupsFilter,)
|
||||
|
||||
self._create_autogroups()
|
||||
my_modeladmin = UserAdminTest(User, AdminSite())
|
||||
|
||||
# Make sure the lookups are correct
|
||||
request = self.factory.get('/')
|
||||
request.user = self.user_1
|
||||
changelist = my_modeladmin.get_changelist_instance(request)
|
||||
filters = changelist.get_filters(request)
|
||||
filterspec = filters[0][0]
|
||||
expected = [
|
||||
(self.group_1.pk, self.group_1.name),
|
||||
(self.group_2.pk, self.group_2.name),
|
||||
]
|
||||
self.assertEqual(filterspec.lookup_choices, expected)
|
||||
|
||||
# Make sure the correct queryset is returned
|
||||
request = self.factory.get('/', {'group_id__exact': self.group_1.pk})
|
||||
request.user = self.user_1
|
||||
changelist = my_modeladmin.get_changelist_instance(request)
|
||||
queryset = changelist.get_queryset(request)
|
||||
expected = User.objects.filter(groups__in=[self.group_1])
|
||||
self.assertSetEqual(set(queryset), set(expected))
|
||||
|
||||
@patch(MODULE_PATH + '._has_auto_groups', False)
|
||||
def test_filter_real_groups_no_autogroups(self):
|
||||
|
||||
class UserAdminTest(BaseUserAdmin):
|
||||
list_filter = (UserAdmin.RealGroupsFilter,)
|
||||
|
||||
my_modeladmin = UserAdminTest(User, AdminSite())
|
||||
|
||||
# Make sure the lookups are correct
|
||||
request = self.factory.get('/')
|
||||
request.user = self.user_1
|
||||
changelist = my_modeladmin.get_changelist_instance(request)
|
||||
filters = changelist.get_filters(request)
|
||||
filterspec = filters[0][0]
|
||||
expected = [
|
||||
(self.group_1.pk, self.group_1.name),
|
||||
(self.group_2.pk, self.group_2.name),
|
||||
]
|
||||
self.assertEqual(filterspec.lookup_choices, expected)
|
||||
|
||||
# Make sure the correct queryset is returned
|
||||
request = self.factory.get('/', {'group_id__exact': self.group_1.pk})
|
||||
request.user = self.user_1
|
||||
changelist = my_modeladmin.get_changelist_instance(request)
|
||||
queryset = changelist.get_queryset(request)
|
||||
expected = User.objects.filter(groups__in=[self.group_1])
|
||||
self.assertSetEqual(set(queryset), set(expected))
|
||||
|
||||
|
||||
def test_filter_main_corporations(self):
|
||||
|
||||
class UserAdminTest(BaseUserAdmin):
|
||||
@@ -603,7 +511,6 @@ class TestMakeServicesHooksActions(TestCaseWithTestData):
|
||||
def sync_nicknames_bulk(self, user):
|
||||
pass
|
||||
|
||||
|
||||
def test_service_has_update_groups_only(self):
|
||||
service = self.MyServicesHookTypeA()
|
||||
mock_service = MagicMock(spec=service)
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
from math import ceil
|
||||
from unittest.mock import patch
|
||||
|
||||
from requests import RequestException
|
||||
import requests_mock
|
||||
from packaging.version import Version as Pep440Version
|
||||
|
||||
from django.core.cache import cache
|
||||
from django.test import TestCase
|
||||
|
||||
from allianceauth.templatetags.admin_status import (
|
||||
@@ -12,8 +12,7 @@ from allianceauth.templatetags.admin_status import (
|
||||
_fetch_list_from_gitlab,
|
||||
_current_notifications,
|
||||
_current_version_summary,
|
||||
_fetch_notification_issues_from_gitlab,
|
||||
_fetch_tags_from_gitlab,
|
||||
_fetch_notification_issues_from_gitlab,
|
||||
_latests_versions
|
||||
)
|
||||
|
||||
@@ -103,35 +102,51 @@ class TestStatusOverviewTag(TestCase):
|
||||
|
||||
class TestNotifications(TestCase):
|
||||
|
||||
def setUp(self) -> None:
|
||||
cache.clear()
|
||||
|
||||
@requests_mock.mock()
|
||||
def test_fetch_notification_issues_from_gitlab(self, requests_mocker):
|
||||
# given
|
||||
url = (
|
||||
'https://gitlab.com/api/v4/projects/allianceauth%2Fallianceauth/issues'
|
||||
'?labels=announcement'
|
||||
)
|
||||
requests_mocker.get(url, json=GITHUB_NOTIFICATION_ISSUES)
|
||||
# when
|
||||
result = _fetch_notification_issues_from_gitlab()
|
||||
# then
|
||||
self.assertEqual(result, GITHUB_NOTIFICATION_ISSUES)
|
||||
|
||||
@patch(MODULE_PATH + '.admin_status.cache')
|
||||
def test_current_notifications_normal(self, mock_cache):
|
||||
# given
|
||||
mock_cache.get_or_set.return_value = GITHUB_NOTIFICATION_ISSUES
|
||||
|
||||
# when
|
||||
result = _current_notifications()
|
||||
# then
|
||||
self.assertEqual(result['notifications'], GITHUB_NOTIFICATION_ISSUES[:5])
|
||||
|
||||
@patch(MODULE_PATH + '.admin_status.cache')
|
||||
def test_current_notifications_failed(self, mock_cache):
|
||||
mock_cache.get_or_set.side_effect = RequestException
|
||||
|
||||
@requests_mock.mock()
|
||||
def test_current_notifications_failed(self, requests_mocker):
|
||||
# given
|
||||
url = (
|
||||
'https://gitlab.com/api/v4/projects/allianceauth%2Fallianceauth/issues'
|
||||
'?labels=announcement'
|
||||
)
|
||||
requests_mocker.get(url, status_code=404)
|
||||
# when
|
||||
result = _current_notifications()
|
||||
# then
|
||||
self.assertEqual(result['notifications'], list())
|
||||
|
||||
@patch(MODULE_PATH + '.admin_status.cache')
|
||||
def test_current_notifications_is_none(self, mock_cache):
|
||||
# given
|
||||
mock_cache.get_or_set.return_value = None
|
||||
|
||||
# when
|
||||
result = _current_notifications()
|
||||
# then
|
||||
self.assertEqual(result['notifications'], list())
|
||||
|
||||
|
||||
@@ -143,12 +158,17 @@ class TestCeleryQueueLength(TestCase):
|
||||
|
||||
class TestVersionTags(TestCase):
|
||||
|
||||
def setUp(self) -> None:
|
||||
cache.clear()
|
||||
|
||||
@patch(MODULE_PATH + '.admin_status.__version__', TEST_VERSION)
|
||||
@patch(MODULE_PATH + '.admin_status.cache')
|
||||
def test_current_version_info_normal(self, mock_cache):
|
||||
def test_current_version_info_normal(self, mock_cache):
|
||||
# given
|
||||
mock_cache.get_or_set.return_value = GITHUB_TAGS
|
||||
|
||||
# when
|
||||
result = _current_version_summary()
|
||||
# then
|
||||
self.assertTrue(result['latest_major'])
|
||||
self.assertTrue(result['latest_minor'])
|
||||
self.assertTrue(result['latest_patch'])
|
||||
@@ -158,32 +178,41 @@ class TestVersionTags(TestCase):
|
||||
self.assertEqual(result['latest_beta_version'], '2.4.6a1')
|
||||
|
||||
@patch(MODULE_PATH + '.admin_status.__version__', TEST_VERSION)
|
||||
@patch(MODULE_PATH + '.admin_status.cache')
|
||||
def test_current_version_info_failed(self, mock_cache):
|
||||
mock_cache.get_or_set.side_effect = RequestException
|
||||
|
||||
expected = {}
|
||||
@requests_mock.mock()
|
||||
def test_current_version_info_failed(self, requests_mocker):
|
||||
# given
|
||||
url = (
|
||||
'https://gitlab.com/api/v4/projects/allianceauth%2Fallianceauth'
|
||||
'/repository/tags'
|
||||
)
|
||||
requests_mocker.get(url, status_code=500)
|
||||
# when
|
||||
result = _current_version_summary()
|
||||
self.assertEqual(result, expected)
|
||||
# then
|
||||
self.assertEqual(result, {})
|
||||
|
||||
@requests_mock.mock()
|
||||
def test_fetch_tags_from_gitlab(self, requests_mocker):
|
||||
# given
|
||||
url = (
|
||||
'https://gitlab.com/api/v4/projects/allianceauth%2Fallianceauth'
|
||||
'/repository/tags'
|
||||
)
|
||||
requests_mocker.get(url, json=GITHUB_TAGS)
|
||||
result = _fetch_tags_from_gitlab()
|
||||
self.assertEqual(result, GITHUB_TAGS)
|
||||
# when
|
||||
result = _current_version_summary()
|
||||
# then
|
||||
self.assertTrue(result)
|
||||
|
||||
@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 = {}
|
||||
# given
|
||||
mock_cache.get_or_set.return_value = None
|
||||
# when
|
||||
result = _current_version_summary()
|
||||
self.assertEqual(result, expected)
|
||||
# then
|
||||
self.assertEqual(result, {})
|
||||
|
||||
|
||||
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.models import User
|
||||
from django.core import signing
|
||||
from django.urls import reverse
|
||||
from django.http import JsonResponse
|
||||
from django.shortcuts import redirect, render
|
||||
from django.urls import reverse, reverse_lazy
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from allianceauth.eveonline.models import EveCharacter
|
||||
from esi.decorators import token_required
|
||||
from esi.models import Token
|
||||
|
||||
from registration.backends.hmac.views import (
|
||||
from django_registration.backends.activation.views import (
|
||||
RegistrationView as BaseRegistrationView,
|
||||
ActivationView as BaseActivationView,
|
||||
REGISTRATION_SALT
|
||||
)
|
||||
from registration.signals import user_registered
|
||||
from django_registration.signals import user_registered
|
||||
|
||||
from .models import CharacterOwnership
|
||||
from .forms import RegistrationForm
|
||||
@@ -134,11 +135,14 @@ def sso_login(request, token):
|
||||
# Step 2
|
||||
class RegistrationView(BaseRegistrationView):
|
||||
form_class = RegistrationForm
|
||||
success_url = 'authentication:dashboard'
|
||||
template_name = "public/register.html"
|
||||
email_body_template = "registration/activation_email.txt"
|
||||
email_subject_template = "registration/activation_email_subject.txt"
|
||||
success_url = reverse_lazy('registration_complete')
|
||||
|
||||
def get_success_url(self, user):
|
||||
if not getattr(settings, 'REGISTRATION_VERIFY_EMAIL', True):
|
||||
return 'authentication:dashboard', (), {}
|
||||
return reverse_lazy('authentication:dashboard')
|
||||
return super().get_success_url(user)
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
@@ -176,6 +180,9 @@ class RegistrationView(BaseRegistrationView):
|
||||
|
||||
# Step 3
|
||||
class ActivationView(BaseActivationView):
|
||||
template_name = "registration/activate.html"
|
||||
success_url = reverse_lazy('registration_activation_complete')
|
||||
|
||||
def validate_key(self, activation_key):
|
||||
try:
|
||||
dump = signing.loads(activation_key, salt=REGISTRATION_SALT,
|
||||
@@ -207,5 +214,5 @@ def activation_complete(request):
|
||||
|
||||
|
||||
def registration_closed(request):
|
||||
messages.error(request, _('Registraion of new accounts it not allowed at this time.'))
|
||||
messages.error(request, _('Registration of new accounts is not allowed at this time.'))
|
||||
return redirect('authentication:login')
|
||||
|
||||
@@ -96,24 +96,62 @@ class EveAllianceForm(EveEntityForm):
|
||||
|
||||
@admin.register(EveCorporationInfo)
|
||||
class EveCorporationInfoAdmin(admin.ModelAdmin):
|
||||
search_fields = ['corporation_name']
|
||||
list_display = ('corporation_name', 'alliance')
|
||||
list_select_related = ('alliance',)
|
||||
list_filter = (('alliance', admin.RelatedOnlyFieldListFilter),)
|
||||
ordering = ('corporation_name',)
|
||||
|
||||
def has_change_permission(self, request, obj=None):
|
||||
return False
|
||||
|
||||
def get_form(self, request, obj=None, **kwargs):
|
||||
if not obj or not obj.pk:
|
||||
return EveCorporationForm
|
||||
return super(EveCorporationInfoAdmin, self).get_form(request, obj=obj, **kwargs)
|
||||
return super().get_form(request, obj=obj, **kwargs)
|
||||
|
||||
|
||||
@admin.register(EveAllianceInfo)
|
||||
class EveAllianceInfoAdmin(admin.ModelAdmin):
|
||||
search_fields = ['alliance_name']
|
||||
list_display = ('alliance_name',)
|
||||
ordering = ('alliance_name',)
|
||||
|
||||
def has_change_permission(self, request, obj=None):
|
||||
return False
|
||||
|
||||
def get_form(self, request, obj=None, **kwargs):
|
||||
if not obj or not obj.pk:
|
||||
return EveAllianceForm
|
||||
return super(EveAllianceInfoAdmin, self).get_form(request, obj=obj, **kwargs)
|
||||
return super().get_form(request, obj=obj, **kwargs)
|
||||
|
||||
|
||||
@admin.register(EveCharacter)
|
||||
class EveCharacterAdmin(admin.ModelAdmin):
|
||||
search_fields = ['character_name', 'corporation_name', 'alliance_name', 'character_ownership__user__username']
|
||||
list_display = ('character_name', 'corporation_name', 'alliance_name', 'user', 'main_character')
|
||||
search_fields = [
|
||||
'character_name',
|
||||
'corporation_name',
|
||||
'alliance_name',
|
||||
'character_ownership__user__username'
|
||||
]
|
||||
list_display = (
|
||||
'character_name', 'corporation_name', 'alliance_name', 'user', 'main_character'
|
||||
)
|
||||
list_select_related = (
|
||||
'character_ownership', 'character_ownership__user__profile__main_character'
|
||||
)
|
||||
list_filter = (
|
||||
'corporation_name',
|
||||
'alliance_name',
|
||||
(
|
||||
'character_ownership__user__profile__main_character',
|
||||
admin.RelatedOnlyFieldListFilter
|
||||
),
|
||||
)
|
||||
ordering = ('character_name', )
|
||||
|
||||
def has_change_permission(self, request, obj=None):
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def user(obj):
|
||||
|
||||
@@ -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_ticker = models.CharField(max_length=254)
|
||||
member_count = models.IntegerField()
|
||||
ceo_id = models.PositiveIntegerField(blank=True, null=True, default=None)
|
||||
alliance = models.ForeignKey(
|
||||
EveAllianceInfo, blank=True, null=True, on_delete=models.SET_NULL
|
||||
)
|
||||
@@ -89,10 +90,16 @@ class EveCorporationInfo(models.Model):
|
||||
objects = EveCorporationManager()
|
||||
provider = EveCorporationProviderManager()
|
||||
|
||||
class Meta:
|
||||
indexes = [
|
||||
models.Index(fields=['ceo_id',]),
|
||||
]
|
||||
|
||||
def update_corporation(self, corp: providers.Corporation = None):
|
||||
if corp is None:
|
||||
corp = self.provider.get_corporation(self.corporation_id)
|
||||
self.member_count = corp.members
|
||||
self.ceo_id = corp.ceo_id
|
||||
try:
|
||||
self.alliance = EveAllianceInfo.objects.get(alliance_id=corp.alliance_id)
|
||||
except EveAllianceInfo.DoesNotExist:
|
||||
|
||||
@@ -7,6 +7,8 @@ from jsonschema.exceptions import RefResolutionError
|
||||
from django.conf import settings
|
||||
from esi.clients import esi_client_factory
|
||||
|
||||
from allianceauth import __version__
|
||||
|
||||
|
||||
SWAGGER_SPEC_PATH = os.path.join(os.path.dirname(
|
||||
os.path.abspath(__file__)), 'swagger.json'
|
||||
@@ -166,7 +168,7 @@ class EveSwaggerProvider(EveProvider):
|
||||
else:
|
||||
try:
|
||||
self._client = esi_client_factory(
|
||||
token=token, spec_file=SWAGGER_SPEC_PATH
|
||||
token=token, spec_file=SWAGGER_SPEC_PATH, app_info_text=("allianceauth v" + __version__)
|
||||
)
|
||||
except (HTTPError, RefResolutionError):
|
||||
logger.exception(
|
||||
@@ -182,7 +184,7 @@ class EveSwaggerProvider(EveProvider):
|
||||
def client(self):
|
||||
if self._client is None:
|
||||
self._client = esi_client_factory(
|
||||
token=self._token, spec_file=SWAGGER_SPEC_PATH
|
||||
token=self._token, spec_file=SWAGGER_SPEC_PATH, app_info_text=("allianceauth v" + __version__)
|
||||
)
|
||||
return self._client
|
||||
|
||||
|
||||
@@ -592,3 +592,12 @@ class TestEveSwaggerProvider(TestCase):
|
||||
self.assertTrue(mock_esi_client_factory.called)
|
||||
self.assertIsNotNone(my_provider._client)
|
||||
self.assertEqual(my_client, 'my_client')
|
||||
|
||||
@patch(MODULE_PATH + '.__version__', '1.0.0')
|
||||
def test_user_agent_header(self):
|
||||
my_provider = EveSwaggerProvider()
|
||||
my_client = my_provider.client
|
||||
operation = my_client.Status.get_status()
|
||||
self.assertEqual(
|
||||
operation.future.request.headers['User-Agent'], 'allianceauth v1.0.0'
|
||||
)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% extends "allianceauth/base.html" %}
|
||||
{% load bootstrap %}
|
||||
{% load staticfiles %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block page_title %}{% trans "Create Fatlink" %}{% endblock page_title %}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% extends "allianceauth/base.html" %}
|
||||
{% load bootstrap %}
|
||||
{% load staticfiles %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
{% block page_title %}{% trans "Fatlink view" %}{% endblock page_title %}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% extends "allianceauth/base.html" %}
|
||||
{% load bootstrap %}
|
||||
{% load staticfiles %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block page_title %}{% trans "Personal fatlink statistics" %}{% endblock page_title %}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% extends "allianceauth/base.html" %}
|
||||
{% load bootstrap %}
|
||||
{% load staticfiles %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block page_title %}{% trans "Personal fatlink statistics" %}{% endblock page_title %}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% extends "allianceauth/base.html" %}
|
||||
{% load bootstrap %}
|
||||
{% load staticfiles %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block page_title %}{% trans "Fatlink Corp Statistics" %}{% endblock page_title %}
|
||||
@@ -42,6 +42,7 @@
|
||||
</div>
|
||||
{% endblock content %}
|
||||
{% block extra_script %}
|
||||
$(document).ready(function(){
|
||||
$("[rel=tooltip]").tooltip();
|
||||
$(document).ready(function () {
|
||||
$("[rel=tooltip]").tooltip();
|
||||
});
|
||||
{% endblock extra_script %}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% extends "allianceauth/base.html" %}
|
||||
{% load bootstrap %}
|
||||
{% load staticfiles %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block page_title %}{% trans "Fatlink statistics" %}{% endblock page_title %}
|
||||
@@ -44,6 +44,7 @@
|
||||
</div>
|
||||
{% endblock content %}
|
||||
{% block extra_script %}
|
||||
$(document).ready(function(){
|
||||
$("[rel=tooltip]").tooltip();
|
||||
$(document).ready(function () {
|
||||
$("[rel=tooltip]").tooltip();
|
||||
});
|
||||
{% endblock extra_script %}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% extends "allianceauth/base.html" %}
|
||||
{% load bootstrap %}
|
||||
{% load staticfiles %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block page_title %}{% trans "Fatlink view" %}{% endblock page_title %}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
from django.conf import settings
|
||||
|
||||
from django.apps import apps
|
||||
from django.contrib import admin
|
||||
from django.contrib.auth.models import Group as BaseGroup, User
|
||||
from django.db.models import Count
|
||||
@@ -10,9 +9,8 @@ from django.dispatch import receiver
|
||||
|
||||
from .models import AuthGroup
|
||||
from .models import GroupRequest
|
||||
from . import signals
|
||||
|
||||
if 'allianceauth.eveonline.autogroups' in settings.INSTALLED_APPS:
|
||||
if 'eve_autogroups' in apps.app_configs:
|
||||
_has_auto_groups = True
|
||||
else:
|
||||
_has_auto_groups = False
|
||||
@@ -41,7 +39,7 @@ class AuthGroupInlineAdmin(admin.StackedInline):
|
||||
kwargs["queryset"] = Group.objects.order_by(Lower('name'))
|
||||
return super().formfield_for_manytomany(db_field, request, **kwargs)
|
||||
|
||||
def has_add_permission(self, request):
|
||||
def has_add_permission(self, request, obj=None):
|
||||
return False
|
||||
|
||||
def has_delete_permission(self, request, obj=None):
|
||||
@@ -97,9 +95,10 @@ class HasLeaderFilter(admin.SimpleListFilter):
|
||||
else:
|
||||
return queryset
|
||||
|
||||
|
||||
class GroupAdmin(admin.ModelAdmin):
|
||||
list_select_related = True
|
||||
ordering = ('name', )
|
||||
list_select_related = ('authgroup',)
|
||||
ordering = ('name',)
|
||||
list_display = (
|
||||
'name',
|
||||
'_description',
|
||||
@@ -118,9 +117,12 @@ class GroupAdmin(admin.ModelAdmin):
|
||||
list_filter.append(HasLeaderFilter)
|
||||
|
||||
search_fields = ('name', 'authgroup__description')
|
||||
|
||||
|
||||
def get_queryset(self, request):
|
||||
qs = super().get_queryset(request)
|
||||
if _has_auto_groups:
|
||||
qs = qs.prefetch_related('managedalliancegroup_set', 'managedcorpgroup_set')
|
||||
qs = qs.prefetch_related('authgroup__group_leaders')
|
||||
qs = qs.annotate(
|
||||
member_count=Count('user', distinct=True),
|
||||
)
|
||||
@@ -173,13 +175,29 @@ class Group(BaseGroup):
|
||||
verbose_name = BaseGroup._meta.verbose_name
|
||||
verbose_name_plural = BaseGroup._meta.verbose_name_plural
|
||||
|
||||
|
||||
try:
|
||||
admin.site.unregister(BaseGroup)
|
||||
finally:
|
||||
admin.site.register(Group, GroupAdmin)
|
||||
|
||||
|
||||
admin.site.register(GroupRequest)
|
||||
@admin.register(GroupRequest)
|
||||
class GroupRequestAdmin(admin.ModelAdmin):
|
||||
search_fields = ('user__username', )
|
||||
list_display = ('id', 'group', 'user', '_leave_request', 'status')
|
||||
list_filter = (
|
||||
('group', admin.RelatedOnlyFieldListFilter),
|
||||
('user', admin.RelatedOnlyFieldListFilter),
|
||||
'leave_request',
|
||||
'status'
|
||||
)
|
||||
|
||||
def _leave_request(self, obj) -> True:
|
||||
return obj.leave_request
|
||||
|
||||
_leave_request.short_description = 'is leave request'
|
||||
_leave_request.boolean = True
|
||||
|
||||
|
||||
@receiver(pre_save, sender=Group)
|
||||
|
||||
@@ -5,3 +5,6 @@ class GroupManagementConfig(AppConfig):
|
||||
name = 'allianceauth.groupmanagement'
|
||||
label = 'groupmanagement'
|
||||
verbose_name = 'Group Management'
|
||||
|
||||
def ready(self):
|
||||
from . import signals # noqa: F401
|
||||
|
||||
@@ -9,29 +9,35 @@ from .managers import GroupManager
|
||||
|
||||
class GroupManagementMenuItem(MenuItemHook):
|
||||
""" This class ensures only authorized users will see the menu entry """
|
||||
|
||||
def __init__(self):
|
||||
# setup menu entry for sidebar
|
||||
MenuItemHook.__init__(
|
||||
self,
|
||||
text=_('Group Management'),
|
||||
classes='fas fa-users-cog fa-fw',
|
||||
url_name='groupmanagement:management',
|
||||
text=_("Group Management"),
|
||||
classes="fas fa-users-cog fa-fw",
|
||||
url_name="groupmanagement:management",
|
||||
order=50,
|
||||
navactive=['groupmanagement:management']
|
||||
navactive=[
|
||||
"groupmanagement:management", # group requests view
|
||||
"groupmanagement:membership", # group membership view
|
||||
"groupmanagement:audit_log", # group audit log view
|
||||
],
|
||||
)
|
||||
|
||||
def render(self, request):
|
||||
if GroupManager.can_manage_groups(request.user):
|
||||
self.count = GroupManager.pending_requests_count_for_user(request.user)
|
||||
app_count = GroupManager.pending_requests_count_for_user(request.user)
|
||||
self.count = app_count if app_count and app_count > 0 else None
|
||||
return MenuItemHook.render(self, request)
|
||||
return ''
|
||||
return ""
|
||||
|
||||
|
||||
@hooks.register('menu_item_hook')
|
||||
@hooks.register("menu_item_hook")
|
||||
def register_menu():
|
||||
return GroupManagementMenuItem()
|
||||
|
||||
|
||||
@hooks.register('url_hook')
|
||||
@hooks.register("url_hook")
|
||||
def register_urls():
|
||||
return UrlHook(urls, 'group', r'^group/')
|
||||
return UrlHook(urls, "group", r"^groups/")
|
||||
|
||||
@@ -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,
|
||||
),
|
||||
),
|
||||
]
|
||||
@@ -25,7 +25,7 @@ class GroupRequest(models.Model):
|
||||
|
||||
|
||||
class RequestLog(models.Model):
|
||||
request_type = models.NullBooleanField(default=0)
|
||||
request_type = models.BooleanField(null=True)
|
||||
group = models.ForeignKey(Group, on_delete=models.CASCADE)
|
||||
request_info = models.CharField(max_length=254)
|
||||
action = models.BooleanField(default=0)
|
||||
@@ -107,7 +107,7 @@ class AuthGroup(models.Model):
|
||||
help_text="States listed here will have the ability to join this group provided "
|
||||
"they have the proper permissions.")
|
||||
|
||||
description = models.CharField(max_length=512, blank=True, help_text="Description of the group shown to users.")
|
||||
description = models.TextField(max_length=512, blank=True, help_text="Short description <i>(max. 512 characters)</i> of the group shown to users.")
|
||||
|
||||
def __str__(self):
|
||||
return self.group.name
|
||||
|
||||
@@ -1,16 +1,22 @@
|
||||
from allianceauth.authentication.signals import state_changed
|
||||
from .managers import GroupManager
|
||||
from .models import Group
|
||||
from django.dispatch import receiver
|
||||
import logging
|
||||
from django.dispatch import receiver
|
||||
from allianceauth.authentication.signals import state_changed
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@receiver(state_changed)
|
||||
def check_groups_on_state_change(sender, user, state, **kwargs):
|
||||
logger.debug("Updating auth groups for {}".format(user))
|
||||
visible_groups = GroupManager.get_joinable_groups(state)
|
||||
visible_groups = visible_groups | Group.objects.select_related('authgroup').filter(authgroup__internal=True)
|
||||
groups = user.groups.all()
|
||||
for g in groups:
|
||||
if g not in visible_groups:
|
||||
user.groups.remove(g)
|
||||
logger.debug(
|
||||
"Checking group memberships for %s based on new state %s" % (user, state)
|
||||
)
|
||||
state_groups = (
|
||||
user.groups.select_related("authgroup").exclude(authgroup__states=None)
|
||||
)
|
||||
for group in state_groups:
|
||||
if not group.authgroup.states.filter(id=state.id).exists():
|
||||
logger.info(
|
||||
"Removing user %s from group %s due to missing state" % (user, group)
|
||||
)
|
||||
user.groups.remove(group)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{% extends "allianceauth/base.html" %}
|
||||
{% load staticfiles %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block page_title %}{{ group }} {% trans "Audit Log" %}{% endblock page_title %}
|
||||
@@ -8,58 +8,65 @@
|
||||
<div class="col-lg-12">
|
||||
<br>
|
||||
{% include 'groupmanagement/menu.html' %}
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
{{ group }} - {% trans 'Audit Log' %}
|
||||
{{ group }} - {% trans "Audit Log" %}
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<p>
|
||||
|
||||
<div class="panel-body">
|
||||
<p>
|
||||
<a class="btn btn-default" href="{% url 'groupmanagement:membership' %}" role="button">
|
||||
{% trans "Back" %}
|
||||
</a>
|
||||
</p>
|
||||
</p>
|
||||
|
||||
{% if entries %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped" id="log-entries">
|
||||
<thead>
|
||||
<th class="text-center" scope="col">{% trans "Date/Time" %}</th>
|
||||
<th class="text-center" scope="col">{% trans "Requestor" %}</th>
|
||||
<th class="text-center" scope="col">{% trans "Character" %}</th>
|
||||
<th class="text-center" scope="col">{% trans "Corporation" %}</th>
|
||||
<th class="text-center" scope="col">{% trans "Type" %}</th>
|
||||
<th class="text-center" scope="col">{% trans "Action" %}</th>
|
||||
<th class="text-center" scope="col">{% trans "Actor" %}</th>
|
||||
<th scope="col">{% trans "Date/Time" %}</th>
|
||||
<th scope="col">{% trans "Requestor" %}</th>
|
||||
<th scope="col">{% trans "Character" %}</th>
|
||||
<th scope="col">{% trans "Corporation" %}</th>
|
||||
<th scope="col">{% trans "Type" %}</th>
|
||||
<th scope="col">{% trans "Action" %}</th>
|
||||
<th scope="col">{% trans "Actor" %}</th>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{% for entry in entries %}
|
||||
<tr>
|
||||
<td class="text-center">{{ entry.date|date:"Y-M-d, H:i" }}</td>
|
||||
<td class="text-center">{{ entry.requestor }}</td>
|
||||
<td class="text-center">{{ entry.req_char }}</td>
|
||||
<td class="text-center">{{ entry.req_char.corporation_name }}</td>
|
||||
<td class="text-center">{{ entry.type_to_str }}</td>
|
||||
<td>{{ entry.date|date:"Y-M-d, H:i" }}</td>
|
||||
<td>{{ entry.requestor }}</td>
|
||||
<td>{{ entry.req_char }}</td>
|
||||
<td>{{ entry.req_char.corporation_name }}</td>
|
||||
<td>{{ entry.type_to_str }}</td>
|
||||
|
||||
{% if entry.request_type is None %}
|
||||
<td class="text-center"> Removed</td>
|
||||
<td>{% trans "Removed" %}</td>
|
||||
{% else %}
|
||||
<td class="text-center">{{ entry.action_to_str }}</td>
|
||||
<td>{{ entry.action_to_str }}</td>
|
||||
{% endif %}
|
||||
<td class="text-center">{{ entry.request_actor }}</td>
|
||||
|
||||
<td>{{ entry.request_actor }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p class="text-muted">
|
||||
All times displayed are EVE/UTC.
|
||||
{% trans "All times displayed are EVE/UTC." %}
|
||||
</p>
|
||||
</div>
|
||||
{% else %}
|
||||
{% else %}
|
||||
<div class="clearfix"></div>
|
||||
<br>
|
||||
<div class="alert alert-warning text-center">
|
||||
<div class="alert alert-warning text-center">
|
||||
{% trans "No entries found for this group." %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -75,31 +82,30 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_script %}
|
||||
$.fn.dataTable.moment = function(format, locale) {
|
||||
let types = $.fn.dataTable.ext.type;
|
||||
|
||||
$.fn.dataTable.moment = function ( format, locale ) {
|
||||
var types = $.fn.dataTable.ext.type;
|
||||
|
||||
// Add type detection
|
||||
types.detect.unshift( function ( d ) {
|
||||
return moment( d, format, locale, true ).isValid() ?
|
||||
types.detect.unshift(function(d) {
|
||||
return moment(d, format, locale, true).isValid() ?
|
||||
'moment-'+format :
|
||||
null;
|
||||
} );
|
||||
|
||||
});
|
||||
|
||||
// Add sorting method - use an integer for the sorting
|
||||
types.order[ 'moment-'+format+'-pre' ] = function ( d ) {
|
||||
return moment( d, format, locale, true ).unix();
|
||||
types.order[ 'moment-'+format+'-pre' ] = function(d) {
|
||||
return moment(d, format, locale, true).unix();
|
||||
};
|
||||
};
|
||||
|
||||
$(document).ready(function(){
|
||||
$.fn.dataTable.moment( 'YYYY-MMM-D, HH:mm' );
|
||||
$.fn.dataTable.moment('YYYY-MMM-D, HH:mm');
|
||||
|
||||
$('#log-entries').DataTable({
|
||||
order: [[ 0, 'desc' ], [ 1, 'asc' ] ],
|
||||
order: [[0, 'desc'], [1, 'asc']],
|
||||
filterDropDown:
|
||||
{
|
||||
columns: [
|
||||
columns: [
|
||||
{
|
||||
idx: 1
|
||||
},
|
||||
@@ -124,4 +130,3 @@
|
||||
});
|
||||
});
|
||||
{% endblock %}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{% extends "allianceauth/base.html" %}
|
||||
{% load staticfiles %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
{% load evelinks %}
|
||||
|
||||
@@ -9,38 +9,35 @@
|
||||
<div class="col-lg-12">
|
||||
<br>
|
||||
{% include 'groupmanagement/menu.html' %}
|
||||
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
{{ group.name }} - {% trans 'Members' %}
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<p>
|
||||
|
||||
<div class="panel-body">
|
||||
<p>
|
||||
<a class="btn btn-default" href="{% url 'groupmanagement:membership' %}" role="button">
|
||||
{% trans "Back" %}
|
||||
</a>
|
||||
</p>
|
||||
{% if group.user_set %}
|
||||
</p>
|
||||
|
||||
{% if group.user_set %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-aa" id="tab_group_members">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-right">{% trans "Portrait" %}</th>
|
||||
<th class="text-center">{% trans "Character" %}</th>
|
||||
<th class="text-center">{% trans "Organization" %}</th>
|
||||
<th class="text-center"></th>
|
||||
<tr>
|
||||
<th>{% trans "Character" %}</th>
|
||||
<th>{% trans "Organization" %}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{% for member in members %}
|
||||
<tr>
|
||||
<td class="text-right">
|
||||
{% if member.is_leader %}
|
||||
<i class="fas fa-star"></i>
|
||||
{% endif %}
|
||||
<img src="{{ member.main_char|character_portrait_url:32 }}" class="img-circle">
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<tr>
|
||||
<td>
|
||||
<img src="{{ member.main_char|character_portrait_url:32 }}" class="img-circle" style="margin-right: 1rem;">
|
||||
{% if member.main_char %}
|
||||
<a href="{{ member.main_char|evewho_character_url }}" target="_blank">
|
||||
{{ member.main_char.character_name }}
|
||||
@@ -48,28 +45,36 @@
|
||||
{% else %}
|
||||
{{ member.user.username }}
|
||||
{% endif %}
|
||||
|
||||
{% if member.is_leader %}
|
||||
<i class="fas fa-star" title="{% trans "Group leader" %}" style="margin-left: 1rem;"></i>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="text-center">
|
||||
|
||||
<td>
|
||||
{% if member.main_char %}
|
||||
<a href="{{ member.main_char|dotlan_corporation_url }}" target="_blank">
|
||||
{{ member.main_char.corporation_name }}
|
||||
</a><br>
|
||||
{{ member.main_char.alliance_name|default_if_none:"" }}
|
||||
{% else %}
|
||||
(unknown)
|
||||
{% trans "(unknown)" %}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<a href="{% url 'groupmanagement:membership_remove' group.id member.user.id %}" class="btn btn-danger"
|
||||
title="{% trans "Remove from group" %}">
|
||||
<i class="glyphicon glyphicon-remove"></i>
|
||||
</td>
|
||||
|
||||
<td class="text-right">
|
||||
<a href="{% url 'groupmanagement:membership_remove' group.id member.user.id %}" class="btn btn-danger" title="{% trans "Remove from group" %}">
|
||||
<i class="glyphicon glyphicon-remove"></i>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<p class="text-muted"><i class="fas fa-star"></i>: Group leader</p>
|
||||
|
||||
<p class="text-muted">
|
||||
<i class="fas fa-star"></i>: {% trans "Group leader" %}
|
||||
</p>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="alert alert-warning text-center">
|
||||
@@ -77,7 +82,7 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{% endblock content %}
|
||||
@@ -93,10 +98,13 @@
|
||||
{% block extra_script %}
|
||||
$(document).ready(function(){
|
||||
$('#tab_group_members').DataTable({
|
||||
order: [ [ 1, "asc" ] ],
|
||||
order: [[0, "asc"]],
|
||||
columnDefs: [
|
||||
{ "sortable": false, "targets": [0, 3] },
|
||||
{
|
||||
"sortable": false,
|
||||
"targets": [2]
|
||||
},
|
||||
]
|
||||
});
|
||||
});
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{% extends "allianceauth/base.html" %}
|
||||
{% load staticfiles %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block page_title %}{% trans "Groups Membership" %}{% endblock page_title %}
|
||||
@@ -9,31 +9,36 @@
|
||||
<div class="col-lg-12">
|
||||
<br>
|
||||
{% include 'groupmanagement/menu.html' %}
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
{% trans "Groups" %}
|
||||
</div>
|
||||
|
||||
<div class="panel-body">
|
||||
{% if groups %}
|
||||
{% if groups %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-aa">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-center">{% trans "Name" %}</th>
|
||||
<th class="text-center">{% trans "Description" %}</th>
|
||||
<th class="text-center">{% trans "Status" %}</th>
|
||||
<th class="text-center">{% trans "Member Count" %}</th>
|
||||
<th class="text-center"></th>
|
||||
<th>{% trans "Name" %}</th>
|
||||
<th>{% trans "Description" %}</th>
|
||||
<th>{% trans "Status" %}</th>
|
||||
<th style="white-space: nowrap;">{% trans "Member Count" %}</th>
|
||||
<th style="min-width: 170px;"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{% for group in groups %}
|
||||
<tr>
|
||||
<td class="text-center">
|
||||
<a href="{% url 'groupmanagement:membership_list' group.id %}">{{ group.name }}</a>
|
||||
<td>
|
||||
<a href="{% url 'groupmanagement:membership' group.id %}">{{ group.name }}</a>
|
||||
</td>
|
||||
<td class="text-center">{{ group.authgroup.description }}</td>
|
||||
<td class="text-center">
|
||||
|
||||
<td>{{ group.authgroup.description|linebreaks|urlize }}</td>
|
||||
|
||||
<td>
|
||||
{% if group.authgroup.hidden %}
|
||||
<span class="label label-info">{% trans "Hidden" %}</span>
|
||||
{% elif group.authgroup.open %}
|
||||
@@ -42,21 +47,23 @@
|
||||
<span class="label label-default">{% trans "Requestable" %}</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="text-center">
|
||||
|
||||
<td class="text-right">
|
||||
{{ group.num_members }}
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<a href="{% url 'groupmanagement:membership_list' group.id %}" class="btn btn-primary"
|
||||
title="{% trans "View Members" %}">
|
||||
<i class="glyphicon glyphicon-eye-open"></i>
|
||||
|
||||
<td class="text-right">
|
||||
<a href="{% url 'groupmanagement:membership' group.id %}" class="btn btn-primary" title="{% trans "View Members" %}">
|
||||
<i class="glyphicon glyphicon-eye-open"></i>
|
||||
</a>
|
||||
|
||||
<a href="{% url "groupmanagement:audit_log" group.id %}" class="btn btn-info" title="{% trans "Audit Members" %}">
|
||||
<i class="glyphicon glyphicon-list-alt"></i>
|
||||
</a>
|
||||
|
||||
<a id="clipboard-copy" data-clipboard-text="{{ request.scheme }}://{{request.get_host}}{% url 'groupmanagement:request_add' group.id %}" class="btn btn-warning" title="{% trans "Copy Direct Join Link" %}">
|
||||
<i class="glyphicon glyphicon-copy"></i>
|
||||
</a>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
@@ -72,9 +79,11 @@
|
||||
</div>
|
||||
</div>
|
||||
{% endblock content %}
|
||||
{% block extra_javascript %}
|
||||
|
||||
{% block extra_javascript %}
|
||||
{% include 'bundles/clipboard-js.html' %}
|
||||
<script>
|
||||
new ClipboardJS('#clipboard-copy');
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
<script>
|
||||
new ClipboardJS('#clipboard-copy');
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
{% extends "allianceauth/base.html" %}
|
||||
{% load staticfiles %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block page_title %}{% trans "Available Groups" %}{% endblock page_title %}
|
||||
{% block extra_css %}{% endblock extra_css %}
|
||||
url
|
||||
|
||||
{% block content %}
|
||||
<div class="col-lg-12">
|
||||
<h1 class="page-header text-center">{% trans "Available Groups" %}</h1>
|
||||
@@ -12,17 +12,18 @@ url
|
||||
<table class="table table-aa">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-center">{% trans "Name" %}</th>
|
||||
<th class="text-center">{% trans "Description" %}</th>
|
||||
<th class="text-center">{% trans "Action" %}</th>
|
||||
<th>{% trans "Name" %}</th>
|
||||
<th>{% trans "Description" %}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{% for g in groups %}
|
||||
<tr>
|
||||
<td class="text-center">{{ g.group.name }}</td>
|
||||
<td class="text-center">{{ g.group.authgroup.description|urlize }}</td>
|
||||
<td class="text-center">
|
||||
<td>{{ g.group.name }}</td>
|
||||
<td>{{ g.group.authgroup.description|linebreaks|urlize }}</td>
|
||||
<td class="text-right">
|
||||
{% if g.group in user.groups.all %}
|
||||
{% if not g.request %}
|
||||
<a href="{% url 'groupmanagement:request_leave' g.group.id %}" class="btn btn-danger">
|
||||
@@ -59,5 +60,4 @@ url
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% endblock content %}
|
||||
|
||||
@@ -1,28 +1,29 @@
|
||||
{% extends "allianceauth/base.html" %}
|
||||
{% load staticfiles %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
{% load evelinks %}
|
||||
|
||||
{% block page_title %}{% trans "Groups Management" %}{% endblock page_title %}
|
||||
{% block extra_css %}
|
||||
<style>
|
||||
.nav-tabs>li.active>a {
|
||||
background-color: #ECF0F1 !important;
|
||||
color: #2C3E50;
|
||||
}
|
||||
</style>
|
||||
|
||||
{% block extra_css %}
|
||||
<style>
|
||||
.nav-tabs > li.active > a {
|
||||
background-color: rgb(236, 240, 241) !important;
|
||||
color: rgb(44, 62, 80);
|
||||
}
|
||||
</style>
|
||||
{% endblock extra_css %}
|
||||
|
||||
{% block content %}
|
||||
<div class="col-lg-12">
|
||||
<br>
|
||||
{% include 'groupmanagement/menu.html' %}
|
||||
|
||||
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="active">
|
||||
<a data-toggle="tab" href="#add">
|
||||
{% trans "Join Requests" %}
|
||||
{% trans "Join Requests" %}
|
||||
|
||||
{% if acceptrequests %}
|
||||
<span class="badge">{{ acceptrequests|length }}</span>
|
||||
{% endif %}
|
||||
@@ -31,133 +32,131 @@
|
||||
<li>
|
||||
<a data-toggle="tab" href="#leave">
|
||||
{% trans "Leave Requests" %}
|
||||
|
||||
{% if leaverequests %}
|
||||
<span class="badge">{{ leaverequests|length }}</span>
|
||||
{% endif %}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="tab-content">
|
||||
|
||||
<div id="add" class="tab-pane fade in active panel panel-default">
|
||||
<div class="panel-body">
|
||||
{% if acceptrequests %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-aa">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-center"></th>
|
||||
<th class="text-center">{% trans "Character" %}</th>
|
||||
<th class="text-center">{% trans "Organization" %}</th>
|
||||
<th class="text-center">{% trans "Group" %}</th>
|
||||
<th class="text-center"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for acceptrequest in acceptrequests %}
|
||||
<tr>
|
||||
<td class="text-right">
|
||||
<img src="{{ acceptrequest.main_char|character_portrait_url:32 }}" class="img-circle">
|
||||
</td>
|
||||
<td class="text-center">
|
||||
{% if acceptrequest.main_char %}
|
||||
<a href="{{ acceptrequest.main_char|evewho_character_url }}" target="_blank">
|
||||
{{ acceptrequest.main_char.character_name }}
|
||||
</a>
|
||||
{% else %}
|
||||
{{ acceptrequest.user.username }}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="text-center">
|
||||
{% if acceptrequest.main_char %}
|
||||
<a href="{{ acceptrequest.main_char|dotlan_corporation_url }}" target="_blank">
|
||||
{{ acceptrequest.main_char.corporation_name }}
|
||||
</a><br>
|
||||
{{ acceptrequest.main_char.alliance_name|default_if_none:"" }}
|
||||
{% else %}
|
||||
(unknown)
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="text-center">{{ acceptrequest.group.name }}</td>
|
||||
<td class="text-center">
|
||||
<a href="{% url 'groupmanagement:accept_request' acceptrequest.id %}" class="btn btn-success">
|
||||
{% trans "Accept" %}
|
||||
</a>
|
||||
<a href="{% url 'groupmanagement:reject_request' acceptrequest.id %}" class="btn btn-danger">
|
||||
{% trans "Reject" %}
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="panel panel-default panel-tabs-aa">
|
||||
<div class="panel-body">
|
||||
<div class="tab-content">
|
||||
|
||||
<div id="add" class="tab-pane active">
|
||||
{% if acceptrequests %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-aa">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "Character" %}</th>
|
||||
<th>{% trans "Organization" %}</th>
|
||||
<th>{% trans "Group" %}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{% for acceptrequest in acceptrequests %}
|
||||
<tr>
|
||||
<td>
|
||||
<img src="{{ acceptrequest.main_char|character_portrait_url:32 }}" class="img-circle" style="margin-right: 1rem;">
|
||||
{% if acceptrequest.main_char %}
|
||||
<a href="{{ acceptrequest.main_char|evewho_character_url }}" target="_blank">
|
||||
{{ acceptrequest.main_char.character_name }}
|
||||
</a>
|
||||
{% else %}
|
||||
{{ acceptrequest.user.username }}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if acceptrequest.main_char %}
|
||||
<a href="{{ acceptrequest.main_char|dotlan_corporation_url }}" target="_blank">
|
||||
{{ acceptrequest.main_char.corporation_name }}
|
||||
</a><br>
|
||||
{{ acceptrequest.main_char.alliance_name|default_if_none:"" }}
|
||||
{% else %}
|
||||
{% trans "(unknown)" %}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>{{ acceptrequest.group.name }}</td>
|
||||
<td class="text-right">
|
||||
<a href="{% url 'groupmanagement:accept_request' acceptrequest.id %}" class="btn btn-success">
|
||||
{% trans "Accept" %}
|
||||
</a>
|
||||
|
||||
<a href="{% url 'groupmanagement:reject_request' acceptrequest.id %}" class="btn btn-danger">
|
||||
{% trans "Reject" %}
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="alert alert-warning text-center">{% trans "No group add requests." %}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div id="leave" class="tab-pane">
|
||||
{% if leaverequests %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-aa">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "Character" %}</th>
|
||||
<th>{% trans "Organization" %}</th>
|
||||
<th>{% trans "Group" %}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{% for leaverequest in leaverequests %}
|
||||
<tr>
|
||||
<td>
|
||||
<img src="{{ leaverequest.main_char|character_portrait_url:32 }}" class="img-circle" style="margin-right: 1rem;">
|
||||
{% if leaverequest.main_char %}
|
||||
<a href="{{ leaverequest.main_char|evewho_character_url }}" target="_blank">
|
||||
{{ leaverequest.main_char.character_name }}
|
||||
</a>
|
||||
{% else %}
|
||||
{{ leaverequest.user.username }}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if leaverequest.main_char %}
|
||||
<a href="{{ leaverequest.main_char|dotlan_corporation_url }}" target="_blank">
|
||||
{{ leaverequest.main_char.corporation_name }}
|
||||
</a><br>
|
||||
{{ leaverequest.main_char.alliance_name|default_if_none:"" }}
|
||||
{% else %}
|
||||
{% trans "(unknown)" %}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>{{ leaverequest.group.name }}</td>
|
||||
<td class="text-right">
|
||||
<a href="{% url 'groupmanagement:leave_accept_request' leaverequest.id %}" class="btn btn-success">
|
||||
{% trans "Accept" %}
|
||||
</a>
|
||||
|
||||
<a href="{% url 'groupmanagement:leave_reject_request' leaverequest.id %}" class="btn btn-danger">
|
||||
{% trans "Reject" %}
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="alert alert-warning text-center">{% trans "No group leave requests." %}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="alert alert-warning text-center">{% trans "No group add requests." %}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="leave" class="tab-pane fade panel panel-default">
|
||||
<div class="panel-body">
|
||||
{% if leaverequests %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-aa">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-center"></th>
|
||||
<th class="text-center">{% trans "Character" %}</th>
|
||||
<th class="text-center">{% trans "Organization" %}</th>
|
||||
<th class="text-center">{% trans "Group" %}</th>
|
||||
<th class="text-center"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for leaverequest in leaverequests %}
|
||||
<tr>
|
||||
<td class="text-right">
|
||||
<img src="{{ leaverequest.main_char|character_portrait_url:32 }}" class="img-circle">
|
||||
</td>
|
||||
<td class="text-center">
|
||||
{% if leaverequest.main_char %}
|
||||
<a href="{{ leaverequest.main_char|evewho_character_url }}" target="_blank">
|
||||
{{ leaverequest.main_char.character_name }}
|
||||
</a>
|
||||
{% else %}
|
||||
{{ leaverequest.user.username }}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="text-center">
|
||||
{% if leaverequest.main_char %}
|
||||
<a href="{{ leaverequest.main_char|dotlan_corporation_url }}" target="_blank">
|
||||
{{ leaverequest.main_char.corporation_name }}
|
||||
</a><br>
|
||||
{{ leaverequest.main_char.alliance_name|default_if_none:"" }}
|
||||
{% else %}
|
||||
(unknown)
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="text-center">{{ leaverequest.group.name }}</td>
|
||||
<td class="text-center">
|
||||
<a href="{% url 'groupmanagement:leave_accept_request' leaverequest.id %}" class="btn btn-success">
|
||||
{% trans "Accept" %}
|
||||
</a>
|
||||
<a href="{% url 'groupmanagement:leave_reject_request' leaverequest.id %}" class="btn btn-danger">
|
||||
{% trans "Reject" %}
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="alert alert-warning text-center">{% trans "No group leave requests." %}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{% endblock content %}
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
{% load staticfiles %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
{% load navactive %}
|
||||
|
||||
<nav class="navbar navbar-default">
|
||||
<div class="container-fluid">
|
||||
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
|
||||
<span class="sr-only">{% trans "Toggle navigation" %}</span>
|
||||
@@ -12,7 +11,7 @@
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="">{% trans "Group Management" %}</a>
|
||||
<a class="navbar-brand" href="{% url 'groupmanagement:management' %}">{% trans "Group Management" %}</a>
|
||||
</div>
|
||||
|
||||
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
|
||||
@@ -20,11 +19,10 @@
|
||||
<li class="{% navactive request 'groupmanagement:management' %}">
|
||||
<a href="{% url 'groupmanagement:management' %}">{% trans "Group Requests" %}</a>
|
||||
</li>
|
||||
<li class="{% renavactive request '^/group/membership/' %}">
|
||||
<li class="{% navactive request 'groupmanagement:membership groupmanagement:audit_log' %}">
|
||||
<a href="{% url 'groupmanagement:membership' %}">{% trans "Group Membership" %}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
@@ -1,61 +1,100 @@
|
||||
from unittest import mock
|
||||
|
||||
from django.test import TestCase
|
||||
from django.contrib.auth.models import User, Group
|
||||
|
||||
from allianceauth.eveonline.models import EveCorporationInfo, EveAllianceInfo
|
||||
from allianceauth.eveonline.models import EveCorporationInfo
|
||||
from allianceauth.eveonline.autogroups.models import AutogroupsConfig
|
||||
from allianceauth.tests.auth_utils import AuthUtils
|
||||
|
||||
from ..signals import check_groups_on_state_change
|
||||
|
||||
|
||||
class GroupManagementStateTestCase(TestCase):
|
||||
class TestCheckGroupsOnStateChange(TestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
cls.user = AuthUtils.create_user('test')
|
||||
AuthUtils.add_main_character(
|
||||
cls.user, 'test character', '1', corp_id='2', corp_name='test_corp', corp_ticker='TEST', alliance_id='3', alliance_name='TEST'
|
||||
cls.character = AuthUtils.add_main_character_2(
|
||||
cls.user, 'test character', 1001, corp_id=2001, corp_name='test corp 1', corp_ticker='TEST'
|
||||
)
|
||||
cls.user.profile.refresh_from_db()
|
||||
cls.alliance = EveAllianceInfo.objects.create(
|
||||
alliance_id='3', alliance_name='test alliance', alliance_ticker='TEST', executor_corp_id='2'
|
||||
cls.user.profile.refresh_from_db()
|
||||
cls.corp_1 = EveCorporationInfo.objects.create(
|
||||
corporation_id=2001, corporation_name='test corp 1', corporation_ticker='C1', member_count=1
|
||||
)
|
||||
cls.corp = EveCorporationInfo.objects.create(
|
||||
corporation_id='2', corporation_name='test corp', corporation_ticker='TEST', alliance=cls.alliance, member_count=1
|
||||
cls.corp_2 = EveCorporationInfo.objects.create(
|
||||
corporation_id=2002, corporation_name='test corp 2', corporation_ticker='C2', member_count=1
|
||||
)
|
||||
cls.state_group = Group.objects.create(name='state_group')
|
||||
cls.open_group = Group.objects.create(name='open_group')
|
||||
cls.state = AuthUtils.create_state('test state', 500)
|
||||
cls.state_group.authgroup.states.add(cls.state)
|
||||
cls.state_group.authgroup.internal = False
|
||||
cls.state_group.save()
|
||||
|
||||
cls.guest_state = AuthUtils.get_guest_state()
|
||||
cls.test_state_1 = AuthUtils.create_state('test_state_1', 500)
|
||||
cls.test_state_2 = AuthUtils.create_state('test_state_2', 600)
|
||||
|
||||
def setUp(self):
|
||||
self.user.refresh_from_db()
|
||||
self.state.refresh_from_db()
|
||||
self.user.refresh_from_db()
|
||||
|
||||
def _refresh_user(self):
|
||||
self.user = User.objects.get(pk=self.user.pk)
|
||||
|
||||
def _refresh_test_group(self):
|
||||
self.state_group = Group.objects.get(pk=self.state_group.pk)
|
||||
|
||||
|
||||
def test_drop_state_group(self):
|
||||
self.user.groups.add(self.open_group)
|
||||
self.user.groups.add(self.state_group)
|
||||
self.assertEqual(self.user.profile.state.name, "Guest")
|
||||
|
||||
self.state.member_corporations.add(self.corp)
|
||||
"""
|
||||
given user is member of: state group, normal group and auto group
|
||||
when user looses state
|
||||
then user is automatically kicked from state group
|
||||
and remains member of normal group and auto group
|
||||
"""
|
||||
# setup
|
||||
state_group = Group.objects.create(name='state_group')
|
||||
state_group.authgroup.states.add(self.test_state_1)
|
||||
state_group.authgroup.internal = False
|
||||
state_group.save()
|
||||
normal_group = Group.objects.create(name='normal_group')
|
||||
normal_group.authgroup.internal = False
|
||||
normal_group.save()
|
||||
internal_group = Group.objects.create(name='internal_group')
|
||||
autogroup_config = AutogroupsConfig.objects.create(corp_groups=True)
|
||||
autogroup_config.states.add(self.test_state_1)
|
||||
autogroup_config.states.add(self.guest_state)
|
||||
auto_group = autogroup_config.corp_managed_groups.first()
|
||||
internal_state_group = Group.objects.create(name='internal_state_group')
|
||||
internal_state_group.authgroup.states.add(self.test_state_1)
|
||||
self.test_state_1.member_corporations.add(self.corp_1)
|
||||
self.user.groups.add(normal_group)
|
||||
self.user.groups.add(internal_group)
|
||||
self.user.groups.add(state_group)
|
||||
self.user.groups.add(internal_state_group)
|
||||
|
||||
# user changes state back to guest
|
||||
self.test_state_1.member_corporations.clear()
|
||||
|
||||
# assert
|
||||
self._refresh_user()
|
||||
self.assertEqual(self.user.profile.state, self.state)
|
||||
self.assertEqual(self.user.profile.state, self.guest_state)
|
||||
groups = self.user.groups.all()
|
||||
self.assertIn(self.state_group, groups) #keeps group
|
||||
self.assertIn(self.open_group, groups) #public group unafected
|
||||
self.assertNotIn(state_group, groups) # looses state group
|
||||
self.assertNotIn(internal_state_group, groups) # looses state group
|
||||
self.assertIn(normal_group, groups) # normal group unafected
|
||||
self.assertIn(internal_group, groups) # internal group unafected
|
||||
self.assertIn(auto_group, groups) # auto group unafected
|
||||
|
||||
self.state.member_corporations.clear()
|
||||
def test_change_to_other_state(self):
|
||||
"""
|
||||
given a state group with 2 allowed states
|
||||
when user changes from one state to the other
|
||||
then user remains member of that group
|
||||
"""
|
||||
# setup
|
||||
state_group = Group.objects.create(name='state_group')
|
||||
state_group.authgroup.states.add(self.test_state_1)
|
||||
state_group.authgroup.states.add(self.test_state_2)
|
||||
|
||||
self.test_state_1.member_corporations.add(self.corp_1)
|
||||
self.test_state_2.member_corporations.add(self.corp_2)
|
||||
self.user.groups.add(state_group)
|
||||
|
||||
# user changes state back to guest
|
||||
self.character.corporation_id = 2002
|
||||
self.character.corporation_name = "test corp 2"
|
||||
self.character.save()
|
||||
|
||||
# assert
|
||||
self._refresh_user()
|
||||
self.assertEqual(self.user.profile.state.name, "Guest")
|
||||
groups = self.user.groups.all()
|
||||
self.assertNotIn(self.state_group, groups) #looses group
|
||||
self.assertIn(self.open_group, groups) #public group unafected
|
||||
self.assertEqual(self.user.profile.state, self.test_state_2)
|
||||
groups = self.user.groups.all()
|
||||
self.assertIn(state_group, groups)
|
||||
|
||||
@@ -1,29 +1,52 @@
|
||||
from . import views
|
||||
|
||||
from django.conf.urls import url
|
||||
app_name = 'groupmanagement'
|
||||
|
||||
app_name = "groupmanagement"
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^groups/', views.groups_view, name='groups'),
|
||||
url(r'^management/', views.group_management,
|
||||
name='management'),
|
||||
url(r'^membership/$', views.group_membership,
|
||||
name='membership'),
|
||||
url(r'^membership/(\w+)/$', views.group_membership_list,
|
||||
name='membership_list'),
|
||||
url(r'^membership/(\w+)/audit/$', views.group_membership_audit, name="audit_log"),
|
||||
url(r'^membership/(\w+)/remove/(\w+)/$', views.group_membership_remove,
|
||||
name='membership_remove'),
|
||||
url(r'^request_add/(\w+)', views.group_request_add,
|
||||
name='request_add'),
|
||||
url(r'^request/accept/(\w+)', views.group_accept_request,
|
||||
name='accept_request'),
|
||||
url(r'^request/reject/(\w+)', views.group_reject_request,
|
||||
name='reject_request'),
|
||||
url(r'^request_leave/(\w+)', views.group_request_leave,
|
||||
name='request_leave'),
|
||||
url(r'leave_request/accept/(\w+)', views.group_leave_accept_request,
|
||||
name='leave_accept_request'),
|
||||
url(r'^leave_request/reject/(\w+)', views.group_leave_reject_request,
|
||||
name='leave_reject_request'),
|
||||
# groups
|
||||
url(r"^groups/$", views.groups_view, name="groups"),
|
||||
url(r"^group/request/join/(\w+)/$", views.group_request_add, name="request_add"),
|
||||
url(
|
||||
r"^group/request/leave/(\w+)/$", views.group_request_leave, name="request_leave"
|
||||
),
|
||||
# group management
|
||||
url(r"^groupmanagement/requests/$", views.group_management, name="management"),
|
||||
url(r"^groupmanagement/membership/$", views.group_membership, name="membership"),
|
||||
url(
|
||||
r"^groupmanagement/membership/(\w+)/$",
|
||||
views.group_membership_list,
|
||||
name="membership",
|
||||
),
|
||||
url(
|
||||
r"^groupmanagement/membership/(\w+)/audit-log/$",
|
||||
views.group_membership_audit,
|
||||
name="audit_log",
|
||||
),
|
||||
url(
|
||||
r"^groupmanagement/membership/(\w+)/remove/(\w+)/$",
|
||||
views.group_membership_remove,
|
||||
name="membership_remove",
|
||||
),
|
||||
url(
|
||||
r"^groupmanagement/request/join/accept/(\w+)/$",
|
||||
views.group_accept_request,
|
||||
name="accept_request",
|
||||
),
|
||||
url(
|
||||
r"^groupmanagement/request/join/reject/(\w+)/$",
|
||||
views.group_reject_request,
|
||||
name="reject_request",
|
||||
),
|
||||
url(
|
||||
r"^groupmanagement/request/leave/accept/(\w+)/$",
|
||||
views.group_leave_accept_request,
|
||||
name="leave_accept_request",
|
||||
),
|
||||
url(
|
||||
r"^groupmanagement/request/leave/reject/(\w+)/$",
|
||||
views.group_leave_reject_request,
|
||||
name="leave_reject_request",
|
||||
),
|
||||
]
|
||||
|
||||
@@ -103,7 +103,7 @@ def group_membership_list(request, group_id):
|
||||
|
||||
# Check its a joinable group i.e. not corp or internal
|
||||
# And the user has permission to manage it
|
||||
if (not GroupManager.check_internal_group(group)
|
||||
if (not GroupManager.check_internal_group(group)
|
||||
or not GroupManager.can_manage_group(request.user, group)
|
||||
):
|
||||
logger.warning(
|
||||
@@ -132,7 +132,7 @@ def group_membership_list(request, group_id):
|
||||
render_items = {'group': group, 'members': members}
|
||||
|
||||
return render(
|
||||
request, 'groupmanagement/groupmembers.html',
|
||||
request, 'groupmanagement/groupmembers.html',
|
||||
context=render_items
|
||||
)
|
||||
|
||||
@@ -166,7 +166,7 @@ def group_membership_remove(request, group_id, user_id):
|
||||
except ObjectDoesNotExist:
|
||||
messages.warning(request, _("Group does not exist"))
|
||||
|
||||
return redirect('groupmanagement:membership_list', group_id)
|
||||
return redirect('groupmanagement:membership', group_id)
|
||||
|
||||
|
||||
@login_required
|
||||
@@ -312,18 +312,18 @@ def group_leave_reject_request(request, group_request_id):
|
||||
@login_required
|
||||
def groups_view(request):
|
||||
logger.debug("groups_view called by user %s" % request.user)
|
||||
|
||||
|
||||
groups_qs = GroupManager.get_joinable_groups_for_user(
|
||||
request.user, include_hidden=False
|
||||
)
|
||||
groups_qs = groups_qs.order_by('name')
|
||||
groups = []
|
||||
for group in groups_qs:
|
||||
for group in groups_qs:
|
||||
group_request = GroupRequest.objects\
|
||||
.filter(user=request.user)\
|
||||
.filter(group=group)
|
||||
groups.append({
|
||||
'group': group,
|
||||
'group': group,
|
||||
'request': group_request[0] if group_request else None
|
||||
})
|
||||
|
||||
@@ -356,6 +356,9 @@ def group_request_add(request, group_id):
|
||||
if group.authgroup.open:
|
||||
logger.info("%s joining %s as is an open group" % (request.user, group))
|
||||
request.user.groups.add(group)
|
||||
request_info = request.user.username + ":" + group.name
|
||||
log = RequestLog(request_type=False, group=group, request_info=request_info, action=1, request_actor=request.user)
|
||||
log.save()
|
||||
return redirect("groupmanagement:groups")
|
||||
req = GroupRequest.objects.filter(user=request.user, group=group)
|
||||
if len(req) > 0:
|
||||
@@ -389,6 +392,9 @@ def group_request_leave(request, group_id):
|
||||
return redirect('groupmanagement:groups')
|
||||
if group.authgroup.open:
|
||||
logger.info("%s leaving %s as is an open group" % (request.user, group))
|
||||
request_info = request.user.username + ":" + group.name
|
||||
log = RequestLog(request_type=True, group=group, request_info=request_info, action=1, request_actor=request.user)
|
||||
log.save()
|
||||
request.user.groups.remove(group)
|
||||
return redirect("groupmanagement:groups")
|
||||
req = GroupRequest.objects.filter(user=request.user, group=group)
|
||||
@@ -398,6 +404,9 @@ def group_request_leave(request, group_id):
|
||||
return redirect("groupmanagement:groups")
|
||||
if getattr(settings, 'AUTO_LEAVE', False):
|
||||
logger.info("%s leaving joinable group %s due to auto_leave" % (request.user, group))
|
||||
request_info = request.user.username + ":" + group.name
|
||||
log = RequestLog(request_type=True, group=group, request_info=request_info, action=1, request_actor=request.user)
|
||||
log.save()
|
||||
request.user.groups.remove(group)
|
||||
return redirect('groupmanagement:groups')
|
||||
grouprequest = GroupRequest()
|
||||
|
||||
@@ -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),
|
||||
),
|
||||
]
|
||||
@@ -35,7 +35,7 @@ class ApplicationForm(models.Model):
|
||||
class Application(models.Model):
|
||||
form = models.ForeignKey(ApplicationForm, on_delete=models.CASCADE, related_name='applications')
|
||||
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='applications')
|
||||
approved = models.NullBooleanField(blank=True, null=True, default=None)
|
||||
approved = models.BooleanField(blank=True, null=True, default=None)
|
||||
reviewer = models.ForeignKey(User, on_delete=models.SET_NULL, blank=True, null=True)
|
||||
reviewer_character = models.ForeignKey(EveCharacter, on_delete=models.SET_NULL, blank=True, null=True)
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{% extends "allianceauth/base.html" %}
|
||||
{% load staticfiles %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block page_title %}{% trans "Choose a Corp" %}{% endblock page_title %}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{% extends "allianceauth/base.html" %}
|
||||
{% load staticfiles %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block page_title %}{% trans "Apply To" %} {{ corp.corporation_name }}{% endblock page_title %}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% extends "allianceauth/base.html" %}
|
||||
{% load bootstrap %}
|
||||
{% load staticfiles %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block page_title %}{% trans "HR Application Management" %}{% endblock page_title %}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% extends "allianceauth/base.html" %}
|
||||
{% load bootstrap %}
|
||||
{% load staticfiles %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block page_title %}HR Application Management{% endblock page_title %}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{% extends "allianceauth/base.html" %}
|
||||
{% load staticfiles %}
|
||||
{% load static %}
|
||||
{% load bootstrap %}
|
||||
{% load i18n %}
|
||||
|
||||
|
||||
Binary file not shown.
@@ -6,16 +6,16 @@
|
||||
# Translators:
|
||||
# Erik Kalkoken <erik.kalkoken@gmail.com>, 2020
|
||||
# Joel Falknau <ozirascal@gmail.com>, 2020
|
||||
# Rounon Dax <rounon.dax@terra-nanotech.de>, 2020
|
||||
# Peter Pfeufer <rounon.dax@terra-nanotech.de>, 2020
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-07-29 04:56+0000\n"
|
||||
"POT-Creation-Date: 2020-11-20 05:33+0000\n"
|
||||
"PO-Revision-Date: 2020-02-18 03:14+0000\n"
|
||||
"Last-Translator: Rounon Dax <rounon.dax@terra-nanotech.de>, 2020\n"
|
||||
"Last-Translator: Peter Pfeufer <rounon.dax@terra-nanotech.de>, 2020\n"
|
||||
"Language-Team: German (https://www.transifex.com/alliance-auth/teams/107430/de/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@@ -28,7 +28,7 @@ msgid "A main character is required to perform that action. Add one below."
|
||||
msgstr ""
|
||||
"Für diese Aktion wird ein Hauptcharacter benötigt. Bitte füge einen hinzu."
|
||||
|
||||
#: allianceauth/authentication/forms.py:6
|
||||
#: allianceauth/authentication/forms.py:5
|
||||
msgid "Email"
|
||||
msgstr "E-Mail"
|
||||
|
||||
@@ -44,7 +44,7 @@ msgstr "Dein Nutzerstatus ist nun %(state)s"
|
||||
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:5
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:8
|
||||
#: allianceauth/templates/allianceauth/side-menu.html:12
|
||||
#: allianceauth/templates/allianceauth/side-menu.html:11
|
||||
msgid "Dashboard"
|
||||
msgstr "Dashboard"
|
||||
|
||||
@@ -82,7 +82,7 @@ msgstr "Charaktere"
|
||||
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:129
|
||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:73
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:22
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:24
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:15
|
||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:45
|
||||
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:34
|
||||
@@ -168,11 +168,11 @@ msgstr ""
|
||||
msgid "Unable to authenticate as the selected character."
|
||||
msgstr "Authentifizierung mit dem ausgewählten Charakter nicht möglich."
|
||||
|
||||
#: allianceauth/authentication/views.py:148
|
||||
#: allianceauth/authentication/views.py:151
|
||||
msgid "Registration token has expired."
|
||||
msgstr "Token zur Registrierung ist abgelaufen."
|
||||
|
||||
#: allianceauth/authentication/views.py:200
|
||||
#: allianceauth/authentication/views.py:206
|
||||
msgid ""
|
||||
"Sent confirmation email. Please follow the link to confirm your email "
|
||||
"address."
|
||||
@@ -180,13 +180,13 @@ msgstr ""
|
||||
"Bestätigungsmail gesendet. Bitte folge dem Link in der E-Mail zur "
|
||||
"Bestätigung."
|
||||
|
||||
#: allianceauth/authentication/views.py:205
|
||||
#: allianceauth/authentication/views.py:211
|
||||
msgid "Confirmed your email address. Please login to continue."
|
||||
msgstr ""
|
||||
"Deine E-Mail Adresse wurde bestätigt. Bitte log Dich ein um fortzufahren."
|
||||
|
||||
#: allianceauth/authentication/views.py:210
|
||||
msgid "Registraion of new accounts it not allowed at this time."
|
||||
#: allianceauth/authentication/views.py:216
|
||||
msgid "Registration of new accounts is not allowed at this time."
|
||||
msgstr "Registrierung von neuen Konten ist zur Zeit nicht erlaubt."
|
||||
|
||||
#: allianceauth/corputils/auth_hooks.py:10
|
||||
@@ -234,16 +234,16 @@ msgstr "Letzes Update:"
|
||||
#: allianceauth/corputils/templates/corputils/search.html:13
|
||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html:24
|
||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:28
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:27
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:29
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:30
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:30
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:51
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:110
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:109
|
||||
msgid "Character"
|
||||
msgstr "Charakter"
|
||||
|
||||
#: allianceauth/corputils/templates/corputils/corpstats.html:76
|
||||
#: allianceauth/corputils/templates/corputils/search.html:14
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:28
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:31
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:27
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:84
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:129
|
||||
@@ -552,31 +552,35 @@ msgstr "Flottenteilnahme registriert."
|
||||
msgid "FAT link has expired."
|
||||
msgstr "FAT-Link ist abgelaufen."
|
||||
|
||||
#: allianceauth/groupmanagement/auth_hooks.py:17
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:14
|
||||
msgid "Group Management"
|
||||
msgstr "Gruppenverwaltung"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:5
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:13
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:14
|
||||
msgid "Audit Log"
|
||||
msgstr "Protokoll"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:18
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:20
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:20
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:21
|
||||
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:13
|
||||
msgid "Back"
|
||||
msgstr "Zurück"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:25
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:28
|
||||
msgid "Date/Time"
|
||||
msgstr "Datum/Uhrzeit"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:26
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:29
|
||||
msgid "Requestor"
|
||||
msgstr "Antragsteller"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:29
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:32
|
||||
msgid "Type"
|
||||
msgstr "Typ"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:30
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:17
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:33
|
||||
#: allianceauth/notifications/templates/notifications/list.html:37
|
||||
#: allianceauth/notifications/templates/notifications/list.html:69
|
||||
#: allianceauth/optimer/templates/optimer/fleetoptable.html:18
|
||||
@@ -587,11 +591,19 @@ msgstr "Typ"
|
||||
msgid "Action"
|
||||
msgstr "Aktion"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:31
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:34
|
||||
msgid "Actor"
|
||||
msgstr "Ausführender"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:47
|
||||
msgid "Removed"
|
||||
msgstr "Entfernt"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:59
|
||||
msgid "All times displayed are EVE/UTC."
|
||||
msgstr "Alle angezeigten Zeiten sind EVE/UTC"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:66
|
||||
msgid "No entries found for this group."
|
||||
msgstr "Keine Einträge für diese Gruppe gefunden."
|
||||
|
||||
@@ -599,22 +611,24 @@ msgstr "Keine Einträge für diese Gruppe gefunden."
|
||||
msgid "Group Members"
|
||||
msgstr "Gruppenmitglieder"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:28
|
||||
msgid "Portrait"
|
||||
msgstr "Portrait"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:30
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:31
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:52
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:111
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:110
|
||||
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:23
|
||||
msgid "Organization"
|
||||
msgstr "Organization"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:64
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:61
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:78
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:136
|
||||
msgid "(unknown)"
|
||||
msgstr "(unbekannt)"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:66
|
||||
msgid "Remove from group"
|
||||
msgstr "Aus Gruppe entfernen"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:76
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:81
|
||||
msgid "No group members to list."
|
||||
msgstr "Keine Gruppenmitglieder vorhanden."
|
||||
|
||||
@@ -622,56 +636,56 @@ msgstr "Keine Gruppenmitglieder vorhanden."
|
||||
msgid "Groups Membership"
|
||||
msgstr "Gruppenmitgliedschaft"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:14
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:15
|
||||
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:40
|
||||
#: allianceauth/templates/allianceauth/side-menu.html:17
|
||||
#: allianceauth/templates/allianceauth/side-menu.html:16
|
||||
msgid "Groups"
|
||||
msgstr "Gruppen"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:23
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:25
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:16
|
||||
msgid "Description"
|
||||
msgstr "Beschreibung"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:24
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:26
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:28
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:85
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:130
|
||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:27
|
||||
#: allianceauth/srp/templates/srp/data.html:97
|
||||
#: allianceauth/srp/templates/srp/data.html:98
|
||||
msgid "Status"
|
||||
msgstr "Status"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:25
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:27
|
||||
msgid "Member Count"
|
||||
msgstr "Mitgliederzahl"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:38
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:43
|
||||
msgid "Hidden"
|
||||
msgstr "Verborgen"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:40
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:45
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:12
|
||||
msgid "Open"
|
||||
msgstr "Öffnen"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:42
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:47
|
||||
msgid "Requestable"
|
||||
msgstr "Anfragbar"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:50
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:56
|
||||
msgid "View Members"
|
||||
msgstr "Mitglieder ansehen"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:53
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:60
|
||||
msgid "Audit Members"
|
||||
msgstr "Mitglieder Protokoll"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:56
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:64
|
||||
msgid "Copy Direct Join Link"
|
||||
msgstr "Direktlink kopieren"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:68
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:75
|
||||
msgid "No groups to list."
|
||||
msgstr "Keine Gruppen vorhanden."
|
||||
|
||||
@@ -680,19 +694,19 @@ msgstr "Keine Gruppen vorhanden."
|
||||
msgid "Available Groups"
|
||||
msgstr "Verfügbare Gruppen"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:29
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:30
|
||||
msgid "Leave"
|
||||
msgstr "Verlassen"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:39
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:40
|
||||
msgid "Join"
|
||||
msgstr "Beitreten"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:43
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:44
|
||||
msgid "Request"
|
||||
msgstr "Anfrage"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:58
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:59
|
||||
msgid "No groups available."
|
||||
msgstr "Keine Gruppen verfügbar"
|
||||
|
||||
@@ -704,24 +718,24 @@ msgstr "Gruppenverwaltung"
|
||||
msgid "Join Requests"
|
||||
msgstr "Beitrittsgesuche"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:33
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:34
|
||||
msgid "Leave Requests"
|
||||
msgstr "Austrittsgesuche"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:53
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:112
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:111
|
||||
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:20
|
||||
#: allianceauth/services/modules/openfire/forms.py:6
|
||||
msgid "Group"
|
||||
msgstr "Gruppen"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:85
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:144
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:84
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:142
|
||||
msgid "Accept"
|
||||
msgstr "Akzeptieren"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:88
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:147
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:146
|
||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:85
|
||||
msgid "Reject"
|
||||
msgstr "Ablehnen"
|
||||
@@ -730,24 +744,19 @@ msgstr "Ablehnen"
|
||||
msgid "No group add requests."
|
||||
msgstr "Keine Gruppenbeitrittsanfragen."
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:156
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:155
|
||||
msgid "No group leave requests."
|
||||
msgstr "Keine Gruppenaustrittsanfragen"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:10
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:9
|
||||
msgid "Toggle navigation"
|
||||
msgstr "Toggle Navigation"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:15
|
||||
#: allianceauth/templates/allianceauth/side-menu.html:25
|
||||
msgid "Group Management"
|
||||
msgstr "Gruppenverwaltung"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:21
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:20
|
||||
msgid "Group Requests"
|
||||
msgstr "Gruppenanfragen"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:24
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:23
|
||||
msgid "Group Membership"
|
||||
msgstr "Gruppenmitgliedschaft"
|
||||
|
||||
@@ -825,7 +834,7 @@ msgstr "Du hast Dich bereits für diese Gruppe beworben."
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:144
|
||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:38
|
||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:20
|
||||
#: allianceauth/srp/templates/srp/data.html:125
|
||||
#: allianceauth/srp/templates/srp/data.html:134
|
||||
#: allianceauth/srp/templates/srp/management.html:81
|
||||
msgid "Pending"
|
||||
msgstr "Beantragt"
|
||||
@@ -852,7 +861,7 @@ msgstr "Du hast bereits ein ausstehendes Austrittsgesuch für diese Gruppe."
|
||||
msgid "Applied to leave group %(group)s."
|
||||
msgstr "Austrittsgesuch für Gruppe %(group)s gesendet."
|
||||
|
||||
#: allianceauth/hrapplications/auth_hooks.py:10
|
||||
#: allianceauth/hrapplications/auth_hooks.py:13
|
||||
msgid "Applications"
|
||||
msgstr "Bewerbungen"
|
||||
|
||||
@@ -909,7 +918,7 @@ msgstr "Benutzername"
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:131
|
||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:28
|
||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:75
|
||||
#: allianceauth/srp/templates/srp/data.html:99
|
||||
#: allianceauth/srp/templates/srp/data.html:100
|
||||
#: allianceauth/srp/templates/srp/management.html:46
|
||||
msgid "Actions"
|
||||
msgstr "Aktionen"
|
||||
@@ -919,7 +928,7 @@ msgstr "Aktionen"
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:147
|
||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:40
|
||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:16
|
||||
#: allianceauth/srp/templates/srp/data.html:117
|
||||
#: allianceauth/srp/templates/srp/data.html:126
|
||||
msgid "Approved"
|
||||
msgstr "Akzeptiert"
|
||||
|
||||
@@ -927,7 +936,7 @@ msgstr "Akzeptiert"
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:104
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:149
|
||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:42
|
||||
#: allianceauth/srp/templates/srp/data.html:121
|
||||
#: allianceauth/srp/templates/srp/data.html:130
|
||||
msgid "Rejected"
|
||||
msgstr "Abgelehnt"
|
||||
|
||||
@@ -1033,7 +1042,7 @@ msgstr "Ungelesen"
|
||||
|
||||
#: allianceauth/notifications/templates/notifications/list.html:18
|
||||
msgid "Read"
|
||||
msgstr "Lesen"
|
||||
msgstr "Gelesen"
|
||||
|
||||
#: allianceauth/notifications/templates/notifications/list.html:22
|
||||
msgid "Mark All Read"
|
||||
@@ -1264,7 +1273,7 @@ msgstr "Flotten Comms:"
|
||||
|
||||
#: allianceauth/services/forms.py:9
|
||||
msgid "Fleet Type:"
|
||||
msgstr "Flottenzeit:"
|
||||
msgstr "Flottenart:"
|
||||
|
||||
#: allianceauth/services/forms.py:10
|
||||
msgid "Ship Priorities:"
|
||||
@@ -1310,13 +1319,13 @@ msgstr "Passwort"
|
||||
msgid "Password must be at least 8 characters long."
|
||||
msgstr "Passwort muss mindestens 8 Zeichen lang sein"
|
||||
|
||||
#: allianceauth/services/modules/discord/models.py:224
|
||||
#: allianceauth/services/modules/discord/models.py:225
|
||||
msgid "Discord Account Disabled"
|
||||
msgstr "Discord Konto deaktiviert"
|
||||
|
||||
#: allianceauth/services/modules/discord/models.py:226
|
||||
#: allianceauth/services/modules/discord/models.py:227
|
||||
msgid ""
|
||||
"Your Discord account was disabeled automatically by Auth. If you think this "
|
||||
"Your Discord account was disabled automatically by Auth. If you think this "
|
||||
"was a mistake, please contact an admin."
|
||||
msgstr ""
|
||||
"Dein Discord Konto wurde automatisch durch Auth deaktiviert. Wenn Du glaubst"
|
||||
@@ -1628,7 +1637,7 @@ msgstr "Dienst"
|
||||
msgid "Domain"
|
||||
msgstr "Domain"
|
||||
|
||||
#: allianceauth/srp/auth_hooks.py:9
|
||||
#: allianceauth/srp/auth_hooks.py:12
|
||||
msgid "Ship Replacement"
|
||||
msgstr "Schiffserstattung"
|
||||
|
||||
@@ -1642,7 +1651,7 @@ msgstr "Flottenzeit"
|
||||
msgid "Fleet Doctrine"
|
||||
msgstr "Flottendoktrin"
|
||||
|
||||
#: allianceauth/srp/form.py:12 allianceauth/srp/templates/srp/data.html:89
|
||||
#: allianceauth/srp/form.py:12 allianceauth/srp/templates/srp/data.html:90
|
||||
msgid "Additional Info"
|
||||
msgstr "Zusätzliche Info"
|
||||
|
||||
@@ -1671,65 +1680,65 @@ msgstr "SRP-Flotte erstellen"
|
||||
msgid "Give this link to the line members"
|
||||
msgstr "Gib diesen Link an Deine Piloten weiter"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:48
|
||||
#: allianceauth/srp/templates/srp/data.html:49
|
||||
msgid "SRP Fleet Data"
|
||||
msgstr "SRP-Flotte Daten"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:53
|
||||
#: allianceauth/srp/templates/srp/data.html:54
|
||||
msgid "Mark Incomplete"
|
||||
msgstr "Als unvollständig markieren"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:57
|
||||
#: allianceauth/srp/templates/srp/data.html:58
|
||||
msgid "Mark Completed"
|
||||
msgstr "Als vollständig markieren"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:69
|
||||
#: allianceauth/srp/templates/srp/data.html:145
|
||||
#: allianceauth/srp/templates/srp/data.html:70
|
||||
#: allianceauth/srp/templates/srp/data.html:156
|
||||
msgid "Total Losses:"
|
||||
msgstr "Verluste insgesamt:"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:70
|
||||
#: allianceauth/srp/templates/srp/data.html:146
|
||||
#: allianceauth/srp/templates/srp/data.html:71
|
||||
#: allianceauth/srp/templates/srp/data.html:157
|
||||
#: allianceauth/srp/templates/srp/management.html:30
|
||||
msgid "Total ISK Cost:"
|
||||
msgstr "ISK-Kosten insgesamt:"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:78
|
||||
#: allianceauth/srp/templates/srp/data.html:154
|
||||
#: allianceauth/srp/templates/srp/data.html:79
|
||||
#: allianceauth/srp/templates/srp/data.html:165
|
||||
msgid "Are you sure you want to delete SRP requests?"
|
||||
msgstr "Bist Du sicher das Du SRP Anfragen löschen willst?"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:87
|
||||
#: allianceauth/srp/templates/srp/data.html:88
|
||||
msgid "Pilot Name"
|
||||
msgstr "Name des Piloten"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:88
|
||||
#: allianceauth/srp/templates/srp/data.html:89
|
||||
msgid "Killboard Link"
|
||||
msgstr "Killboard Link"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:90
|
||||
#: allianceauth/srp/templates/srp/data.html:91
|
||||
msgid "Ship Type"
|
||||
msgstr "Schiffstyp"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:91
|
||||
#: allianceauth/srp/templates/srp/data.html:92
|
||||
msgid "Killboard Loss Amt"
|
||||
msgstr "Summe Killboard Verluste"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:92
|
||||
#: allianceauth/srp/templates/srp/data.html:93
|
||||
msgid "SRP ISK Cost"
|
||||
msgstr "SRP ISK-Kosten"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:93
|
||||
#: allianceauth/srp/templates/srp/data.html:94
|
||||
msgid "Click value to edit Enter to save & next ESC to cancel"
|
||||
msgstr ""
|
||||
"Klicke auf den Wert um diesen zu bearbeiten, Enter zum Speichern und um zum "
|
||||
"nächsten Wert zu springen, ESC zum Beenden."
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:96
|
||||
#: allianceauth/srp/templates/srp/data.html:97
|
||||
msgid "Post Time"
|
||||
msgstr "Veröffentlichungszeit"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:163
|
||||
#: allianceauth/srp/templates/srp/data.html:174
|
||||
msgid "No SRP requests for this fleet."
|
||||
msgstr "Keine SRP Anfragen für diese Flotte."
|
||||
|
||||
@@ -2089,3 +2098,6 @@ msgstr "Neuen Timer hinzugefügt in %(system)s um %(time)s."
|
||||
#: allianceauth/timerboard/views.py:83
|
||||
msgid "Saved changes to the timer."
|
||||
msgstr "Änderungen am Timer gespeichert"
|
||||
|
||||
#~ msgid "Portrait"
|
||||
#~ msgstr "Portrait"
|
||||
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -12,7 +12,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-05-08 00:57+0000\n"
|
||||
"POT-Creation-Date: 2020-11-20 05:33+0000\n"
|
||||
"PO-Revision-Date: 2020-02-18 03:14+0000\n"
|
||||
"Last-Translator: frank1210 <francolopez_16@hotmail.com>, 2020\n"
|
||||
"Language-Team: Spanish (https://www.transifex.com/alliance-auth/teams/107430/es/)\n"
|
||||
@@ -27,74 +27,72 @@ msgid "A main character is required to perform that action. Add one below."
|
||||
msgstr ""
|
||||
"Un personaje principal es requerido para completar esta accion. Agregue uno"
|
||||
|
||||
#: allianceauth/authentication/forms.py:6
|
||||
#: allianceauth/authentication/forms.py:5
|
||||
msgid "Email"
|
||||
msgstr "E-mail"
|
||||
|
||||
#: allianceauth/authentication/models.py:76
|
||||
msgid "State Changed"
|
||||
msgstr "Estado Cambiado"
|
||||
|
||||
#: allianceauth/authentication/models.py:77
|
||||
#: allianceauth/authentication/models.py:78
|
||||
#, python-format
|
||||
msgid "Your user state has been changed to %(state)s"
|
||||
msgstr "Tu estado de usuario fue cambiado a %(state)s"
|
||||
msgid "State changed to: %s"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/authentication/models.py:79
|
||||
#, python-format
|
||||
msgid "Your user's state is now: %(state)s"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:5
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:8
|
||||
#: allianceauth/templates/allianceauth/side-menu.html:10
|
||||
#: allianceauth/templates/allianceauth/side-menu.html:11
|
||||
msgid "Dashboard"
|
||||
msgstr "Pagina Principal"
|
||||
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:17
|
||||
#: allianceauth/corputils/templates/corputils/corpstats.html:116
|
||||
#: allianceauth/corputils/templates/corputils/search.html:16
|
||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticscorpview.html:22
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:83
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:128
|
||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:25
|
||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:32
|
||||
msgid "Main Character"
|
||||
msgstr "Personaje Principal"
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:18
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\n"
|
||||
" Main Character (State: %(state)s)\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:77
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:81
|
||||
msgid "No main character set."
|
||||
msgstr "No se ha seleccionado un personaje principal."
|
||||
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:84
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:88
|
||||
msgid "Add Character"
|
||||
msgstr "Agregar Personaje"
|
||||
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:88
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:92
|
||||
msgid "Change Main"
|
||||
msgstr "Cambiar Personaje Principal"
|
||||
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:97
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:101
|
||||
msgid "Group Memberships"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:117
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:121
|
||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticscorpview.html:23
|
||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:41
|
||||
msgid "Characters"
|
||||
msgstr "Personajes"
|
||||
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:125
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:129
|
||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:73
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:22
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:24
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:15
|
||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:45
|
||||
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:34
|
||||
msgid "Name"
|
||||
msgstr "Nombre"
|
||||
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:126
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:130
|
||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticsview.html:23
|
||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:46
|
||||
msgid "Corp"
|
||||
msgstr "Corporación"
|
||||
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:127
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:131
|
||||
#: allianceauth/corputils/templates/corputils/corpstats.html:77
|
||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:47
|
||||
msgid "Alliance"
|
||||
@@ -163,26 +161,26 @@ msgstr ""
|
||||
msgid "Unable to authenticate as the selected character."
|
||||
msgstr "Imposible validar con el personaje seleccionado."
|
||||
|
||||
#: allianceauth/authentication/views.py:148
|
||||
#: allianceauth/authentication/views.py:151
|
||||
msgid "Registration token has expired."
|
||||
msgstr "El token de registracion expiro."
|
||||
|
||||
#: allianceauth/authentication/views.py:200
|
||||
#: allianceauth/authentication/views.py:206
|
||||
msgid ""
|
||||
"Sent confirmation email. Please follow the link to confirm your email "
|
||||
"address."
|
||||
msgstr ""
|
||||
"Confirmacion de mail enviada. Por favor siga el enlace para confirmar "
|
||||
|
||||
#: allianceauth/authentication/views.py:205
|
||||
#: allianceauth/authentication/views.py:211
|
||||
msgid "Confirmed your email address. Please login to continue."
|
||||
msgstr ""
|
||||
"Se ha confirmado su direccion de mail. Por favor igrese su token para "
|
||||
"continuar."
|
||||
|
||||
#: allianceauth/authentication/views.py:210
|
||||
msgid "Registraion of new accounts it not allowed at this time."
|
||||
msgstr "Registracion de nuevas cuentas no es permitido por el momento."
|
||||
#: allianceauth/authentication/views.py:216
|
||||
msgid "Registration of new accounts is not allowed at this time."
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/corputils/auth_hooks.py:10
|
||||
msgid "Corporation Stats"
|
||||
@@ -229,16 +227,16 @@ msgstr "Ultima Actualizacion:"
|
||||
#: allianceauth/corputils/templates/corputils/search.html:13
|
||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html:24
|
||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:28
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:27
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:29
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:37
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:96
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:30
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:30
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:51
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:109
|
||||
msgid "Character"
|
||||
msgstr "Personaje"
|
||||
|
||||
#: allianceauth/corputils/templates/corputils/corpstats.html:76
|
||||
#: allianceauth/corputils/templates/corputils/search.html:14
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:28
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:31
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:27
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:84
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:129
|
||||
@@ -254,6 +252,16 @@ msgstr "Corporacion"
|
||||
msgid "Killboard"
|
||||
msgstr "Killboard"
|
||||
|
||||
#: allianceauth/corputils/templates/corputils/corpstats.html:116
|
||||
#: allianceauth/corputils/templates/corputils/search.html:16
|
||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticscorpview.html:22
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:83
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:128
|
||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:25
|
||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:32
|
||||
msgid "Main Character"
|
||||
msgstr "Personaje Principal"
|
||||
|
||||
#: allianceauth/corputils/templates/corputils/corpstats.html:117
|
||||
#: allianceauth/corputils/templates/corputils/search.html:17
|
||||
msgid "Main Corporation"
|
||||
@@ -538,31 +546,35 @@ msgstr "Participacion de flota registrada."
|
||||
msgid "FAT link has expired."
|
||||
msgstr "Enlace de participacion expirado."
|
||||
|
||||
#: allianceauth/groupmanagement/auth_hooks.py:17
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:14
|
||||
msgid "Group Management"
|
||||
msgstr "Manejo de Grupo"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:5
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:13
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:14
|
||||
msgid "Audit Log"
|
||||
msgstr "Log de Auditoria"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:18
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:20
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:20
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:21
|
||||
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:13
|
||||
msgid "Back"
|
||||
msgstr "Volver"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:25
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:28
|
||||
msgid "Date/Time"
|
||||
msgstr "Fecha/Hora"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:26
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:29
|
||||
msgid "Requestor"
|
||||
msgstr "Solicitante"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:29
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:32
|
||||
msgid "Type"
|
||||
msgstr "Tipo"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:30
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:17
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:33
|
||||
#: allianceauth/notifications/templates/notifications/list.html:37
|
||||
#: allianceauth/notifications/templates/notifications/list.html:69
|
||||
#: allianceauth/optimer/templates/optimer/fleetoptable.html:18
|
||||
@@ -573,11 +585,19 @@ msgstr "Tipo"
|
||||
msgid "Action"
|
||||
msgstr "Accion"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:31
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:34
|
||||
msgid "Actor"
|
||||
msgstr "Actor"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:47
|
||||
msgid "Removed"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:59
|
||||
msgid "All times displayed are EVE/UTC."
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:66
|
||||
msgid "No entries found for this group."
|
||||
msgstr "No se encontraron entradas para este grupo."
|
||||
|
||||
@@ -585,22 +605,24 @@ msgstr "No se encontraron entradas para este grupo."
|
||||
msgid "Group Members"
|
||||
msgstr "Miembros del Grupo"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:28
|
||||
msgid "Portrait"
|
||||
msgstr "Retrato"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:30
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:38
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:97
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:31
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:52
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:110
|
||||
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:23
|
||||
msgid "Organization"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:64
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:61
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:78
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:136
|
||||
msgid "(unknown)"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:66
|
||||
msgid "Remove from group"
|
||||
msgstr "Remover del grupo"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:76
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:81
|
||||
msgid "No group members to list."
|
||||
msgstr "no hay miembros para listar."
|
||||
|
||||
@@ -608,56 +630,56 @@ msgstr "no hay miembros para listar."
|
||||
msgid "Groups Membership"
|
||||
msgstr "Membresia de grupos"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:14
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:15
|
||||
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:40
|
||||
#: allianceauth/templates/allianceauth/side-menu.html:15
|
||||
#: allianceauth/templates/allianceauth/side-menu.html:16
|
||||
msgid "Groups"
|
||||
msgstr "Grupos"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:23
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:25
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:16
|
||||
msgid "Description"
|
||||
msgstr "Descripcion"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:24
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:26
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:28
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:85
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:130
|
||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:27
|
||||
#: allianceauth/srp/templates/srp/data.html:97
|
||||
#: allianceauth/srp/templates/srp/data.html:98
|
||||
msgid "Status"
|
||||
msgstr "Estado"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:25
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:27
|
||||
msgid "Member Count"
|
||||
msgstr "Contador de miembros"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:38
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:43
|
||||
msgid "Hidden"
|
||||
msgstr "Escondido"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:40
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:45
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:12
|
||||
msgid "Open"
|
||||
msgstr "Abierto"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:42
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:47
|
||||
msgid "Requestable"
|
||||
msgstr "Solicitable"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:50
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:56
|
||||
msgid "View Members"
|
||||
msgstr "Ver Miembros"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:53
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:60
|
||||
msgid "Audit Members"
|
||||
msgstr "Auditar Miembros"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:56
|
||||
msgid "Copy Direrct Join Link"
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:64
|
||||
msgid "Copy Direct Join Link"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:68
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:75
|
||||
msgid "No groups to list."
|
||||
msgstr "No hay grupos para listar"
|
||||
|
||||
@@ -666,19 +688,19 @@ msgstr "No hay grupos para listar"
|
||||
msgid "Available Groups"
|
||||
msgstr "Grupos Disponibles"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:29
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:30
|
||||
msgid "Leave"
|
||||
msgstr "Dejar"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:39
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:40
|
||||
msgid "Join"
|
||||
msgstr "Unirse"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:43
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:44
|
||||
msgid "Request"
|
||||
msgstr "Solicitar"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:58
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:59
|
||||
msgid "No groups available."
|
||||
msgstr "No hay grupos disponibles"
|
||||
|
||||
@@ -686,77 +708,72 @@ msgstr "No hay grupos disponibles"
|
||||
msgid "Groups Management"
|
||||
msgstr "Manejo de Grupos"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:23
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:25
|
||||
msgid "Join Requests"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:24
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:34
|
||||
msgid "Leave Requests"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:39
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:98
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:53
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:111
|
||||
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:20
|
||||
#: allianceauth/services/modules/openfire/forms.py:6
|
||||
msgid "Group"
|
||||
msgstr "Grupo"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:71
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:130
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:84
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:142
|
||||
msgid "Accept"
|
||||
msgstr "Aceptar"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:74
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:133
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:88
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:146
|
||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:85
|
||||
msgid "Reject"
|
||||
msgstr "Rechazar"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:83
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:97
|
||||
msgid "No group add requests."
|
||||
msgstr "No hay solicitudes de ingreso."
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:142
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:155
|
||||
msgid "No group leave requests."
|
||||
msgstr "No hay solicitudes paradejar el grupo."
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:10
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:9
|
||||
msgid "Toggle navigation"
|
||||
msgstr "Navegacion"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:15
|
||||
#: allianceauth/templates/allianceauth/side-menu.html:23
|
||||
msgid "Group Management"
|
||||
msgstr "Manejo de Grupo"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:21
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:20
|
||||
msgid "Group Requests"
|
||||
msgstr "Solicitudes de Grupo"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:24
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:23
|
||||
msgid "Group Membership"
|
||||
msgstr "Membresia de Grupo"
|
||||
|
||||
#: allianceauth/groupmanagement/views.py:166
|
||||
#: allianceauth/groupmanagement/views.py:162
|
||||
#, python-format
|
||||
msgid "Removed user %(user)s from group %(group)s."
|
||||
msgstr "El usuario %(user)s fue removido del grupo %(group)s"
|
||||
|
||||
#: allianceauth/groupmanagement/views.py:168
|
||||
#: allianceauth/groupmanagement/views.py:164
|
||||
msgid "User does not exist in that group"
|
||||
msgstr "El usuario no existe en ese grupos"
|
||||
|
||||
#: allianceauth/groupmanagement/views.py:171
|
||||
#: allianceauth/groupmanagement/views.py:167
|
||||
msgid "Group does not exist"
|
||||
msgstr "El grupo no existe"
|
||||
|
||||
#: allianceauth/groupmanagement/views.py:198
|
||||
#: allianceauth/groupmanagement/views.py:194
|
||||
#, python-format
|
||||
msgid "Accepted application from %(mainchar)s to %(group)s."
|
||||
msgstr "Solicitud aceptada de %(mainchar)s a %(group)s"
|
||||
|
||||
#: allianceauth/groupmanagement/views.py:205
|
||||
#: allianceauth/groupmanagement/views.py:238
|
||||
#: allianceauth/groupmanagement/views.py:201
|
||||
#: allianceauth/groupmanagement/views.py:234
|
||||
#, python-format
|
||||
msgid ""
|
||||
"An unhandled error occurred while processing the application from "
|
||||
@@ -765,79 +782,79 @@ msgstr ""
|
||||
"Ocurrio un error cuando se intento procesar la informacion de %(mainchar)s "
|
||||
"al grupo %(group)s."
|
||||
|
||||
#: allianceauth/groupmanagement/views.py:231
|
||||
#: allianceauth/groupmanagement/views.py:227
|
||||
#, python-format
|
||||
msgid "Rejected application from %(mainchar)s to %(group)s."
|
||||
msgstr "Se rechazo la solicitud de %(mainchar)s al grupo %(group)s."
|
||||
|
||||
#: allianceauth/groupmanagement/views.py:267
|
||||
#: allianceauth/groupmanagement/views.py:263
|
||||
#, python-format
|
||||
msgid "Accepted application from %(mainchar)s to leave %(group)s."
|
||||
msgstr "Se acepto la solicitud de %(mainchar)s para dejar el grupo %(group)s."
|
||||
|
||||
#: allianceauth/groupmanagement/views.py:273
|
||||
#: allianceauth/groupmanagement/views.py:307
|
||||
#: allianceauth/groupmanagement/views.py:269
|
||||
#: allianceauth/groupmanagement/views.py:303
|
||||
#, python-format
|
||||
msgid ""
|
||||
"An unhandled error occurred while processing the application from "
|
||||
"%(mainchar)s to leave %(group)s."
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/groupmanagement/views.py:300
|
||||
#: allianceauth/groupmanagement/views.py:296
|
||||
#, python-format
|
||||
msgid "Rejected application from %(mainchar)s to leave %(group)s."
|
||||
msgstr ""
|
||||
"Se rechazo la solicitud de %(mainchar)s para dejar el grupo %(group)s."
|
||||
|
||||
#: allianceauth/groupmanagement/views.py:346
|
||||
#: allianceauth/groupmanagement/views.py:358
|
||||
#: allianceauth/groupmanagement/views.py:342
|
||||
#: allianceauth/groupmanagement/views.py:354
|
||||
msgid "You cannot join that group"
|
||||
msgstr "No puedes unirte a ese grupo"
|
||||
|
||||
#: allianceauth/groupmanagement/views.py:352
|
||||
#: allianceauth/groupmanagement/views.py:348
|
||||
msgid "You are already a member of that group."
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/groupmanagement/views.py:367
|
||||
#: allianceauth/groupmanagement/views.py:363
|
||||
msgid "You already have a pending application for that group."
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/groupmanagement/views.py:370
|
||||
#: allianceauth/groupmanagement/views.py:408
|
||||
#: allianceauth/groupmanagement/views.py:366
|
||||
#: allianceauth/groupmanagement/views.py:404
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:37
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:72
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:99
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:144
|
||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:38
|
||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:20
|
||||
#: allianceauth/srp/templates/srp/data.html:125
|
||||
#: allianceauth/srp/templates/srp/data.html:134
|
||||
#: allianceauth/srp/templates/srp/management.html:81
|
||||
msgid "Pending"
|
||||
msgstr "Pendiente"
|
||||
|
||||
#: allianceauth/groupmanagement/views.py:376
|
||||
#: allianceauth/groupmanagement/views.py:372
|
||||
#, python-format
|
||||
msgid "Applied to group %(group)s."
|
||||
msgstr "Solicitud enviada al grupo %(group)s."
|
||||
|
||||
#: allianceauth/groupmanagement/views.py:387
|
||||
#: allianceauth/groupmanagement/views.py:383
|
||||
msgid "You cannot leave that group"
|
||||
msgstr "No puedes dejar el grupos"
|
||||
|
||||
#: allianceauth/groupmanagement/views.py:392
|
||||
#: allianceauth/groupmanagement/views.py:388
|
||||
msgid "You are not a member of that group"
|
||||
msgstr "No eres miembro de ese grupo"
|
||||
|
||||
#: allianceauth/groupmanagement/views.py:401
|
||||
#: allianceauth/groupmanagement/views.py:397
|
||||
msgid "You already have a pending leave request for that group."
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/groupmanagement/views.py:414
|
||||
#: allianceauth/groupmanagement/views.py:410
|
||||
#, python-format
|
||||
msgid "Applied to leave group %(group)s."
|
||||
msgstr "Solicitaste dejar el grupo %(group)s."
|
||||
|
||||
#: allianceauth/hrapplications/auth_hooks.py:10
|
||||
#: allianceauth/hrapplications/auth_hooks.py:13
|
||||
msgid "Applications"
|
||||
msgstr "Solicitudes"
|
||||
|
||||
@@ -894,7 +911,7 @@ msgstr "Usuario"
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:131
|
||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:28
|
||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:75
|
||||
#: allianceauth/srp/templates/srp/data.html:99
|
||||
#: allianceauth/srp/templates/srp/data.html:100
|
||||
#: allianceauth/srp/templates/srp/management.html:46
|
||||
msgid "Actions"
|
||||
msgstr "Acciones"
|
||||
@@ -904,7 +921,7 @@ msgstr "Acciones"
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:147
|
||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:40
|
||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:16
|
||||
#: allianceauth/srp/templates/srp/data.html:117
|
||||
#: allianceauth/srp/templates/srp/data.html:126
|
||||
msgid "Approved"
|
||||
msgstr "Aprovado"
|
||||
|
||||
@@ -912,7 +929,7 @@ msgstr "Aprovado"
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:104
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:149
|
||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:42
|
||||
#: allianceauth/srp/templates/srp/data.html:121
|
||||
#: allianceauth/srp/templates/srp/data.html:130
|
||||
msgid "Rejected"
|
||||
msgstr "Rechazado"
|
||||
|
||||
@@ -1295,22 +1312,49 @@ msgstr "Contraseña"
|
||||
msgid "Password must be at least 8 characters long."
|
||||
msgstr "La contraseña tiene que tener 8 caracteres de largo minimo"
|
||||
|
||||
#: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:23
|
||||
#: allianceauth/services/modules/discord/models.py:225
|
||||
msgid "Discord Account Disabled"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/services/modules/discord/models.py:227
|
||||
msgid ""
|
||||
"Your Discord account was disabled automatically by Auth. If you think this "
|
||||
"was a mistake, please contact an admin."
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:18
|
||||
msgid "Join the Discord server"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:22
|
||||
msgid "Leave- and rejoin the Discord Server (Reset)"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:25
|
||||
msgid "Leave the Discord server"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:32
|
||||
msgid "Link Discord Server"
|
||||
msgstr "Enlace a servidor de Discord"
|
||||
|
||||
#: allianceauth/services/modules/discord/views.py:26
|
||||
#: allianceauth/services/modules/discord/views.py:30
|
||||
msgid "Deactivated Discord account."
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/services/modules/discord/views.py:29
|
||||
#: allianceauth/services/modules/discord/views.py:41
|
||||
#: allianceauth/services/modules/discord/views.py:65
|
||||
#: allianceauth/services/modules/discord/views.py:36
|
||||
#: allianceauth/services/modules/discord/views.py:59
|
||||
msgid "An error occurred while processing your Discord account."
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/services/modules/discord/views.py:62
|
||||
msgid "Activated Discord account."
|
||||
#: allianceauth/services/modules/discord/views.py:102
|
||||
msgid "Your Discord account has been successfully activated."
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/services/modules/discord/views.py:108
|
||||
msgid ""
|
||||
"An error occurred while trying to activate your Discord account. Please try "
|
||||
"again."
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/services/modules/discourse/views.py:37
|
||||
@@ -1575,7 +1619,7 @@ msgstr "Servicio"
|
||||
msgid "Domain"
|
||||
msgstr "Dominio"
|
||||
|
||||
#: allianceauth/srp/auth_hooks.py:9
|
||||
#: allianceauth/srp/auth_hooks.py:12
|
||||
msgid "Ship Replacement"
|
||||
msgstr "Reemplazo de Nave"
|
||||
|
||||
@@ -1589,7 +1633,7 @@ msgstr "Hora de flota"
|
||||
msgid "Fleet Doctrine"
|
||||
msgstr "Doctrina"
|
||||
|
||||
#: allianceauth/srp/form.py:12 allianceauth/srp/templates/srp/data.html:89
|
||||
#: allianceauth/srp/form.py:12 allianceauth/srp/templates/srp/data.html:90
|
||||
msgid "Additional Info"
|
||||
msgstr "Informacion Adicional"
|
||||
|
||||
@@ -1618,63 +1662,63 @@ msgstr "Crear SRP"
|
||||
msgid "Give this link to the line members"
|
||||
msgstr "Entregar este enlace a los miembros"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:48
|
||||
#: allianceauth/srp/templates/srp/data.html:49
|
||||
msgid "SRP Fleet Data"
|
||||
msgstr "Informacion de SRP de la flota"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:53
|
||||
#: allianceauth/srp/templates/srp/data.html:54
|
||||
msgid "Mark Incomplete"
|
||||
msgstr "Marcar como Incompleto"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:57
|
||||
#: allianceauth/srp/templates/srp/data.html:58
|
||||
msgid "Mark Completed"
|
||||
msgstr "Marcar como Completo"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:69
|
||||
#: allianceauth/srp/templates/srp/data.html:145
|
||||
#: allianceauth/srp/templates/srp/data.html:70
|
||||
#: allianceauth/srp/templates/srp/data.html:156
|
||||
msgid "Total Losses:"
|
||||
msgstr "Perdidas Totales:"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:70
|
||||
#: allianceauth/srp/templates/srp/data.html:146
|
||||
#: allianceauth/srp/templates/srp/data.html:71
|
||||
#: allianceauth/srp/templates/srp/data.html:157
|
||||
#: allianceauth/srp/templates/srp/management.html:30
|
||||
msgid "Total ISK Cost:"
|
||||
msgstr "Costo Total:"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:78
|
||||
#: allianceauth/srp/templates/srp/data.html:154
|
||||
#: allianceauth/srp/templates/srp/data.html:79
|
||||
#: allianceauth/srp/templates/srp/data.html:165
|
||||
msgid "Are you sure you want to delete SRP requests?"
|
||||
msgstr "Estas seguro que quiere borrar las solicitudes de SRP"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:87
|
||||
#: allianceauth/srp/templates/srp/data.html:88
|
||||
msgid "Pilot Name"
|
||||
msgstr "Nombre del Piloto"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:88
|
||||
#: allianceauth/srp/templates/srp/data.html:89
|
||||
msgid "Killboard Link"
|
||||
msgstr "Enlace de la Muerte"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:90
|
||||
#: allianceauth/srp/templates/srp/data.html:91
|
||||
msgid "Ship Type"
|
||||
msgstr "Tipo"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:91
|
||||
#: allianceauth/srp/templates/srp/data.html:92
|
||||
msgid "Killboard Loss Amt"
|
||||
msgstr "Monto de la perdida en ZKB"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:92
|
||||
#: allianceauth/srp/templates/srp/data.html:93
|
||||
msgid "SRP ISK Cost"
|
||||
msgstr "Costo del SRP"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:93
|
||||
#: allianceauth/srp/templates/srp/data.html:94
|
||||
msgid "Click value to edit Enter to save & next ESC to cancel"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:96
|
||||
#: allianceauth/srp/templates/srp/data.html:97
|
||||
msgid "Post Time"
|
||||
msgstr "Tiempo"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:163
|
||||
#: allianceauth/srp/templates/srp/data.html:174
|
||||
msgid "No SRP requests for this fleet."
|
||||
msgstr "No hay solicitudes de SRP para esta flota."
|
||||
|
||||
@@ -1866,32 +1910,30 @@ msgid "Current"
|
||||
msgstr "Actual"
|
||||
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:40
|
||||
msgid "Latest Major"
|
||||
msgstr "Ultimo Importante"
|
||||
msgid "Latest Stable"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:46
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:56
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:66
|
||||
msgid "Update available"
|
||||
msgstr "Actualizacion Disponible"
|
||||
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:50
|
||||
msgid "Latest Minor"
|
||||
msgstr "Ultimo no importante"
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:51
|
||||
msgid "Latest Pre-Release"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:60
|
||||
msgid "Latest Patch"
|
||||
msgstr "Ultimo Parche"
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:57
|
||||
msgid "Pre-Release available"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:73
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:65
|
||||
msgid "Task Queue"
|
||||
msgstr "Cola de Tareas"
|
||||
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:90
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:82
|
||||
msgid "Error retrieving task queue length"
|
||||
msgstr "Error al conseguir la cola de tareas"
|
||||
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:92
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:84
|
||||
#, python-format
|
||||
msgid "%(tasks)s task"
|
||||
msgid_plural "%(tasks)s tasks"
|
||||
@@ -2032,3 +2074,6 @@ msgstr "Se agrego un nuevo timer en %(system)s a las %(time)s."
|
||||
#: allianceauth/timerboard/views.py:83
|
||||
msgid "Saved changes to the timer."
|
||||
msgstr "Se guardaron los cambios en el timer."
|
||||
|
||||
#~ msgid "Portrait"
|
||||
#~ msgstr "Retrato"
|
||||
|
||||
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.
|
||||
#
|
||||
# Translators:
|
||||
# Lahty <js03js70@gmail.com>, 2020
|
||||
# Kim Hyundong <khd1226543@gmail.com>, 2020
|
||||
# None None <khd1226543@gmail.com>, 2020
|
||||
# Seowon Jung <seowon@hawaii.edu>, 2020
|
||||
# Olgeda Choi <undead.choi@gmail.com>, 2020
|
||||
# Lahty <js03js70@gmail.com>, 2020
|
||||
# Joel Falknau <ozirascal@gmail.com>, 2020
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-05-08 00:57+0000\n"
|
||||
"POT-Creation-Date: 2020-11-20 05:33+0000\n"
|
||||
"PO-Revision-Date: 2020-02-18 03:14+0000\n"
|
||||
"Last-Translator: Olgeda Choi <undead.choi@gmail.com>, 2020\n"
|
||||
"Last-Translator: Joel Falknau <ozirascal@gmail.com>, 2020\n"
|
||||
"Language-Team: Korean (Korea) (https://www.transifex.com/alliance-auth/teams/107430/ko_KR/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@@ -28,74 +29,75 @@ msgstr ""
|
||||
msgid "A main character is required to perform that action. Add one below."
|
||||
msgstr "해당 기능을 수행하려면 주 캐릭터가 요구됨. 아래에 하나를 추가하시오."
|
||||
|
||||
#: allianceauth/authentication/forms.py:6
|
||||
#: allianceauth/authentication/forms.py:5
|
||||
msgid "Email"
|
||||
msgstr "이메일"
|
||||
|
||||
#: allianceauth/authentication/models.py:76
|
||||
msgid "State Changed"
|
||||
msgstr "상태 변경됨"
|
||||
|
||||
#: allianceauth/authentication/models.py:77
|
||||
#: allianceauth/authentication/models.py:78
|
||||
#, python-format
|
||||
msgid "Your user state has been changed to %(state)s"
|
||||
msgstr "사용자의 상태가 %(state)s변경됨"
|
||||
msgid "State changed to: %s"
|
||||
msgstr "상태가 %s로 변경됐습니다."
|
||||
|
||||
#: allianceauth/authentication/models.py:79
|
||||
#, python-format
|
||||
msgid "Your user's state is now: %(state)s"
|
||||
msgstr "사용자의 상태는 %(state)s입니다."
|
||||
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:5
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:8
|
||||
#: allianceauth/templates/allianceauth/side-menu.html:10
|
||||
#: allianceauth/templates/allianceauth/side-menu.html:11
|
||||
msgid "Dashboard"
|
||||
msgstr "대시보드"
|
||||
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:17
|
||||
#: allianceauth/corputils/templates/corputils/corpstats.html:116
|
||||
#: allianceauth/corputils/templates/corputils/search.html:16
|
||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticscorpview.html:22
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:83
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:128
|
||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:25
|
||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:32
|
||||
msgid "Main Character"
|
||||
msgstr "주 캐릭터"
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:18
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\n"
|
||||
" Main Character (State: %(state)s)\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
" 메인 캐릭터 (상태: %(state)s)\n"
|
||||
" "
|
||||
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:77
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:81
|
||||
msgid "No main character set."
|
||||
msgstr "주 캐릭터가 지정되지 않음"
|
||||
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:84
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:88
|
||||
msgid "Add Character"
|
||||
msgstr "캐릭터 추가"
|
||||
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:88
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:92
|
||||
msgid "Change Main"
|
||||
msgstr "주 캐릭터 변경"
|
||||
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:97
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:101
|
||||
msgid "Group Memberships"
|
||||
msgstr "그룹 멤버쉽"
|
||||
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:117
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:121
|
||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticscorpview.html:23
|
||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:41
|
||||
msgid "Characters"
|
||||
msgstr "캐릭터"
|
||||
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:125
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:129
|
||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:73
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:22
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:24
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:15
|
||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:45
|
||||
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:34
|
||||
msgid "Name"
|
||||
msgstr "이름"
|
||||
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:126
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:130
|
||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticsview.html:23
|
||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:46
|
||||
msgid "Corp"
|
||||
msgstr "콥"
|
||||
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:127
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:131
|
||||
#: allianceauth/corputils/templates/corputils/corpstats.html:77
|
||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:47
|
||||
msgid "Alliance"
|
||||
@@ -151,33 +153,33 @@ msgstr "주 캐릭터가 %(char)s로 변경됨"
|
||||
#: allianceauth/authentication/views.py:89
|
||||
#, python-format
|
||||
msgid "Added %(name)s to your account."
|
||||
msgstr "%(name)s을(를) 계정에 추가함"
|
||||
msgstr "계정에 %(name)s를 추가했습니다."
|
||||
|
||||
#: allianceauth/authentication/views.py:91
|
||||
#, python-format
|
||||
msgid "Failed to add %(name)s to your account: they already have an account."
|
||||
msgstr "%(name)s을(를) 계정에 추가하는데 실패함. 이미 추가되어있음."
|
||||
msgstr "계정에 %(name)s를 추가하지 못했습니다. 이미 추가된 계정입니다."
|
||||
|
||||
#: allianceauth/authentication/views.py:130
|
||||
msgid "Unable to authenticate as the selected character."
|
||||
msgstr "선택한 캐릭터로 인증을 수행할 수 없음"
|
||||
|
||||
#: allianceauth/authentication/views.py:148
|
||||
#: allianceauth/authentication/views.py:151
|
||||
msgid "Registration token has expired."
|
||||
msgstr "등록토큰 만료"
|
||||
|
||||
#: allianceauth/authentication/views.py:200
|
||||
#: allianceauth/authentication/views.py:206
|
||||
msgid ""
|
||||
"Sent confirmation email. Please follow the link to confirm your email "
|
||||
"address."
|
||||
msgstr "확인 메일 전송됨. 다음 링크를 눌러 이메일 주소를 확인하세요."
|
||||
|
||||
#: allianceauth/authentication/views.py:205
|
||||
#: allianceauth/authentication/views.py:211
|
||||
msgid "Confirmed your email address. Please login to continue."
|
||||
msgstr "이메일 주소가 확인되었습니다. 로그인 해주세요."
|
||||
|
||||
#: allianceauth/authentication/views.py:210
|
||||
msgid "Registraion of new accounts it not allowed at this time."
|
||||
#: allianceauth/authentication/views.py:216
|
||||
msgid "Registration of new accounts is not allowed at this time."
|
||||
msgstr "현재 새로운 계정 등록은 받지않습니다."
|
||||
|
||||
#: allianceauth/corputils/auth_hooks.py:10
|
||||
@@ -225,16 +227,16 @@ msgstr "마지막 업데이트"
|
||||
#: allianceauth/corputils/templates/corputils/search.html:13
|
||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html:24
|
||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:28
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:27
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:29
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:37
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:96
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:30
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:30
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:51
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:109
|
||||
msgid "Character"
|
||||
msgstr "캐릭터"
|
||||
|
||||
#: allianceauth/corputils/templates/corputils/corpstats.html:76
|
||||
#: allianceauth/corputils/templates/corputils/search.html:14
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:28
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:31
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:27
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:84
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:129
|
||||
@@ -250,6 +252,16 @@ msgstr "콥"
|
||||
msgid "Killboard"
|
||||
msgstr "킬보드"
|
||||
|
||||
#: allianceauth/corputils/templates/corputils/corpstats.html:116
|
||||
#: allianceauth/corputils/templates/corputils/search.html:16
|
||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticscorpview.html:22
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:83
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:128
|
||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:25
|
||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:32
|
||||
msgid "Main Character"
|
||||
msgstr "주 캐릭터"
|
||||
|
||||
#: allianceauth/corputils/templates/corputils/corpstats.html:117
|
||||
#: allianceauth/corputils/templates/corputils/search.html:17
|
||||
msgid "Main Corporation"
|
||||
@@ -531,31 +543,35 @@ msgstr "플릿 참여 등록됨"
|
||||
msgid "FAT link has expired."
|
||||
msgstr "플릿활동추적 링크 기한만료"
|
||||
|
||||
#: allianceauth/groupmanagement/auth_hooks.py:17
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:14
|
||||
msgid "Group Management"
|
||||
msgstr "그룹 관리"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:5
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:13
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:14
|
||||
msgid "Audit Log"
|
||||
msgstr "감사 기록"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:18
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:20
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:20
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:21
|
||||
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:13
|
||||
msgid "Back"
|
||||
msgstr "돌아가기"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:25
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:28
|
||||
msgid "Date/Time"
|
||||
msgstr "날짜/시간"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:26
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:29
|
||||
msgid "Requestor"
|
||||
msgstr "요청인"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:29
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:32
|
||||
msgid "Type"
|
||||
msgstr "타입"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:30
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:17
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:33
|
||||
#: allianceauth/notifications/templates/notifications/list.html:37
|
||||
#: allianceauth/notifications/templates/notifications/list.html:69
|
||||
#: allianceauth/optimer/templates/optimer/fleetoptable.html:18
|
||||
@@ -566,11 +582,19 @@ msgstr "타입"
|
||||
msgid "Action"
|
||||
msgstr "활동"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:31
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:34
|
||||
msgid "Actor"
|
||||
msgstr "활동한 사람"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:47
|
||||
msgid "Removed"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:59
|
||||
msgid "All times displayed are EVE/UTC."
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:66
|
||||
msgid "No entries found for this group."
|
||||
msgstr "이 그룹에는 항목 없음"
|
||||
|
||||
@@ -578,22 +602,24 @@ msgstr "이 그룹에는 항목 없음"
|
||||
msgid "Group Members"
|
||||
msgstr "그룹 멤버"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:28
|
||||
msgid "Portrait"
|
||||
msgstr "포트레잇"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:30
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:38
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:97
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:31
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:52
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:110
|
||||
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:23
|
||||
msgid "Organization"
|
||||
msgstr "조직"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:64
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:61
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:78
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:136
|
||||
msgid "(unknown)"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:66
|
||||
msgid "Remove from group"
|
||||
msgstr "그룹에서 제거"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:76
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:81
|
||||
msgid "No group members to list."
|
||||
msgstr "목록에 그룹 멤버 없음"
|
||||
|
||||
@@ -601,56 +627,56 @@ msgstr "목록에 그룹 멤버 없음"
|
||||
msgid "Groups Membership"
|
||||
msgstr "그룹 멤버쉽"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:14
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:15
|
||||
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:40
|
||||
#: allianceauth/templates/allianceauth/side-menu.html:15
|
||||
#: allianceauth/templates/allianceauth/side-menu.html:16
|
||||
msgid "Groups"
|
||||
msgstr "그룹"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:23
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:25
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:16
|
||||
msgid "Description"
|
||||
msgstr "설명"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:24
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:26
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:28
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:85
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:130
|
||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:27
|
||||
#: allianceauth/srp/templates/srp/data.html:97
|
||||
#: allianceauth/srp/templates/srp/data.html:98
|
||||
msgid "Status"
|
||||
msgstr "상태"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:25
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:27
|
||||
msgid "Member Count"
|
||||
msgstr "멤버 수"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:38
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:43
|
||||
msgid "Hidden"
|
||||
msgstr "숨김"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:40
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:45
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:12
|
||||
msgid "Open"
|
||||
msgstr "열기"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:42
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:47
|
||||
msgid "Requestable"
|
||||
msgstr "요청 가능"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:50
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:56
|
||||
msgid "View Members"
|
||||
msgstr "멤버 보기"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:53
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:60
|
||||
msgid "Audit Members"
|
||||
msgstr "멤버 검사"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:56
|
||||
msgid "Copy Direrct Join Link"
|
||||
msgstr ""
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:64
|
||||
msgid "Copy Direct Join Link"
|
||||
msgstr "직접 참여 링크 복사"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:68
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:75
|
||||
msgid "No groups to list."
|
||||
msgstr "목록에 그룹 없음"
|
||||
|
||||
@@ -659,19 +685,19 @@ msgstr "목록에 그룹 없음"
|
||||
msgid "Available Groups"
|
||||
msgstr "사용 가능한 그룹"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:29
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:30
|
||||
msgid "Leave"
|
||||
msgstr "떠나기"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:39
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:40
|
||||
msgid "Join"
|
||||
msgstr "참여하기"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:43
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:44
|
||||
msgid "Request"
|
||||
msgstr "요청하기"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:58
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:59
|
||||
msgid "No groups available."
|
||||
msgstr "사용 가능한 그룹 없음."
|
||||
|
||||
@@ -679,155 +705,150 @@ msgstr "사용 가능한 그룹 없음."
|
||||
msgid "Groups Management"
|
||||
msgstr "그룹 관리"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:23
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:25
|
||||
msgid "Join Requests"
|
||||
msgstr "가입 요청"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:24
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:34
|
||||
msgid "Leave Requests"
|
||||
msgstr "탈퇴 요청"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:39
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:98
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:53
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:111
|
||||
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:20
|
||||
#: allianceauth/services/modules/openfire/forms.py:6
|
||||
msgid "Group"
|
||||
msgstr "그룹"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:71
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:130
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:84
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:142
|
||||
msgid "Accept"
|
||||
msgstr "수락"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:74
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:133
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:88
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:146
|
||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:85
|
||||
msgid "Reject"
|
||||
msgstr "거절"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:83
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:97
|
||||
msgid "No group add requests."
|
||||
msgstr "가입 요청 없음"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:142
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:155
|
||||
msgid "No group leave requests."
|
||||
msgstr "탈퇴 요청 없음"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:10
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:9
|
||||
msgid "Toggle navigation"
|
||||
msgstr "네비게이션 전환"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:15
|
||||
#: allianceauth/templates/allianceauth/side-menu.html:23
|
||||
msgid "Group Management"
|
||||
msgstr "그룹 관리"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:21
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:20
|
||||
msgid "Group Requests"
|
||||
msgstr "그룹 요청"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:24
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:23
|
||||
msgid "Group Membership"
|
||||
msgstr "그룹 멤버쉽"
|
||||
|
||||
#: allianceauth/groupmanagement/views.py:166
|
||||
#: allianceauth/groupmanagement/views.py:162
|
||||
#, python-format
|
||||
msgid "Removed user %(user)s from group %(group)s."
|
||||
msgstr "유저 %(user)s이(가) %(group)s에서 제거됨."
|
||||
|
||||
#: allianceauth/groupmanagement/views.py:168
|
||||
#: allianceauth/groupmanagement/views.py:164
|
||||
msgid "User does not exist in that group"
|
||||
msgstr "유저가 해당 그룹에 존재하지 않음."
|
||||
|
||||
#: allianceauth/groupmanagement/views.py:171
|
||||
#: allianceauth/groupmanagement/views.py:167
|
||||
msgid "Group does not exist"
|
||||
msgstr "그룹이 존재하지 않음."
|
||||
|
||||
#: allianceauth/groupmanagement/views.py:198
|
||||
#: allianceauth/groupmanagement/views.py:194
|
||||
#, python-format
|
||||
msgid "Accepted application from %(mainchar)s to %(group)s."
|
||||
msgstr "%(mainchar)s의 %(group)s 그룹 신청 수락"
|
||||
|
||||
#: allianceauth/groupmanagement/views.py:205
|
||||
#: allianceauth/groupmanagement/views.py:238
|
||||
#: allianceauth/groupmanagement/views.py:201
|
||||
#: allianceauth/groupmanagement/views.py:234
|
||||
#, python-format
|
||||
msgid ""
|
||||
"An unhandled error occurred while processing the application from "
|
||||
"%(mainchar)s to %(group)s."
|
||||
msgstr "%(mainchar)s의 %(group)s 그룹 신청을 처리하는 중 알 수 없는 에러 발생"
|
||||
|
||||
#: allianceauth/groupmanagement/views.py:231
|
||||
#: allianceauth/groupmanagement/views.py:227
|
||||
#, python-format
|
||||
msgid "Rejected application from %(mainchar)s to %(group)s."
|
||||
msgstr "%(mainchar)s의 %(group)s 그룹 신청 거절"
|
||||
|
||||
#: allianceauth/groupmanagement/views.py:267
|
||||
#: allianceauth/groupmanagement/views.py:263
|
||||
#, python-format
|
||||
msgid "Accepted application from %(mainchar)s to leave %(group)s."
|
||||
msgstr "%(mainchar)s의 %(group)s 그룹 탈퇴 수락"
|
||||
|
||||
#: allianceauth/groupmanagement/views.py:273
|
||||
#: allianceauth/groupmanagement/views.py:307
|
||||
#: allianceauth/groupmanagement/views.py:269
|
||||
#: allianceauth/groupmanagement/views.py:303
|
||||
#, python-format
|
||||
msgid ""
|
||||
"An unhandled error occurred while processing the application from "
|
||||
"%(mainchar)s to leave %(group)s."
|
||||
msgstr "%(mainchar)s의 %(group)s 그룹 탈퇴를 처리하는 중 알 수 없는 에러 발생"
|
||||
|
||||
#: allianceauth/groupmanagement/views.py:300
|
||||
#: allianceauth/groupmanagement/views.py:296
|
||||
#, python-format
|
||||
msgid "Rejected application from %(mainchar)s to leave %(group)s."
|
||||
msgstr "%(mainchar)s의 %(group)s 그룹 탈퇴 거절"
|
||||
|
||||
#: allianceauth/groupmanagement/views.py:346
|
||||
#: allianceauth/groupmanagement/views.py:358
|
||||
#: allianceauth/groupmanagement/views.py:342
|
||||
#: allianceauth/groupmanagement/views.py:354
|
||||
msgid "You cannot join that group"
|
||||
msgstr "해당 그룹에 참여할 수 없습니다."
|
||||
|
||||
#: allianceauth/groupmanagement/views.py:352
|
||||
#: allianceauth/groupmanagement/views.py:348
|
||||
msgid "You are already a member of that group."
|
||||
msgstr "이미 해당 그룹에 가입되어 있습니다."
|
||||
|
||||
#: allianceauth/groupmanagement/views.py:367
|
||||
#: allianceauth/groupmanagement/views.py:363
|
||||
msgid "You already have a pending application for that group."
|
||||
msgstr "해당 그룹에 대한 참여신청이 보류되었습니다."
|
||||
|
||||
#: allianceauth/groupmanagement/views.py:370
|
||||
#: allianceauth/groupmanagement/views.py:408
|
||||
#: allianceauth/groupmanagement/views.py:366
|
||||
#: allianceauth/groupmanagement/views.py:404
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:37
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:72
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:99
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:144
|
||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:38
|
||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:20
|
||||
#: allianceauth/srp/templates/srp/data.html:125
|
||||
#: allianceauth/srp/templates/srp/data.html:134
|
||||
#: allianceauth/srp/templates/srp/management.html:81
|
||||
msgid "Pending"
|
||||
msgstr "보류 중"
|
||||
|
||||
#: allianceauth/groupmanagement/views.py:376
|
||||
#: allianceauth/groupmanagement/views.py:372
|
||||
#, python-format
|
||||
msgid "Applied to group %(group)s."
|
||||
msgstr "%(group)s그룹에 지원하였음."
|
||||
|
||||
#: allianceauth/groupmanagement/views.py:387
|
||||
#: allianceauth/groupmanagement/views.py:383
|
||||
msgid "You cannot leave that group"
|
||||
msgstr "해당 그룹을 떠날 수 없습니다."
|
||||
|
||||
#: allianceauth/groupmanagement/views.py:392
|
||||
#: allianceauth/groupmanagement/views.py:388
|
||||
msgid "You are not a member of that group"
|
||||
msgstr "해당그룹의 멤버가 아닙니다."
|
||||
|
||||
#: allianceauth/groupmanagement/views.py:401
|
||||
#: allianceauth/groupmanagement/views.py:397
|
||||
msgid "You already have a pending leave request for that group."
|
||||
msgstr "해당 그룹의 탈퇴 신청이 접수된 상태입니다."
|
||||
|
||||
#: allianceauth/groupmanagement/views.py:414
|
||||
#: allianceauth/groupmanagement/views.py:410
|
||||
#, python-format
|
||||
msgid "Applied to leave group %(group)s."
|
||||
msgstr "%(group)s그룹의 탈퇴가 신청됨."
|
||||
|
||||
#: allianceauth/hrapplications/auth_hooks.py:10
|
||||
#: allianceauth/hrapplications/auth_hooks.py:13
|
||||
msgid "Applications"
|
||||
msgstr "지원"
|
||||
|
||||
@@ -884,7 +905,7 @@ msgstr "사용자명"
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:131
|
||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:28
|
||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:75
|
||||
#: allianceauth/srp/templates/srp/data.html:99
|
||||
#: allianceauth/srp/templates/srp/data.html:100
|
||||
#: allianceauth/srp/templates/srp/management.html:46
|
||||
msgid "Actions"
|
||||
msgstr "활동"
|
||||
@@ -894,7 +915,7 @@ msgstr "활동"
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:147
|
||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:40
|
||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:16
|
||||
#: allianceauth/srp/templates/srp/data.html:117
|
||||
#: allianceauth/srp/templates/srp/data.html:126
|
||||
msgid "Approved"
|
||||
msgstr "승인"
|
||||
|
||||
@@ -902,7 +923,7 @@ msgstr "승인"
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:104
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:149
|
||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:42
|
||||
#: allianceauth/srp/templates/srp/data.html:121
|
||||
#: allianceauth/srp/templates/srp/data.html:130
|
||||
msgid "Rejected"
|
||||
msgstr "거절"
|
||||
|
||||
@@ -1285,23 +1306,50 @@ msgstr "비밀번호"
|
||||
msgid "Password must be at least 8 characters long."
|
||||
msgstr "비밀번호는 8글자 이상이어야 합니다."
|
||||
|
||||
#: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:23
|
||||
#: allianceauth/services/modules/discord/models.py:225
|
||||
msgid "Discord Account Disabled"
|
||||
msgstr "디스코드 계정 비활성화"
|
||||
|
||||
#: allianceauth/services/modules/discord/models.py:227
|
||||
msgid ""
|
||||
"Your Discord account was disabled automatically by Auth. If you think this "
|
||||
"was a mistake, please contact an admin."
|
||||
msgstr "Auth에 의해 자동으로 디스코드 계정이 비활성화됐습니다. 원치 않는 사항일 경우, 관리자에게 문의해 주세요."
|
||||
|
||||
#: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:18
|
||||
msgid "Join the Discord server"
|
||||
msgstr "디스코드 서버 입장"
|
||||
|
||||
#: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:22
|
||||
msgid "Leave- and rejoin the Discord Server (Reset)"
|
||||
msgstr "디스코드 서버를 나가고 다시 입장하기 (리셋)"
|
||||
|
||||
#: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:25
|
||||
msgid "Leave the Discord server"
|
||||
msgstr "디스코드 서버 나가기"
|
||||
|
||||
#: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:32
|
||||
msgid "Link Discord Server"
|
||||
msgstr "디스코드 서버 링크"
|
||||
|
||||
#: allianceauth/services/modules/discord/views.py:26
|
||||
#: allianceauth/services/modules/discord/views.py:30
|
||||
msgid "Deactivated Discord account."
|
||||
msgstr "디스코드 계정 해제 완료"
|
||||
|
||||
#: allianceauth/services/modules/discord/views.py:29
|
||||
#: allianceauth/services/modules/discord/views.py:41
|
||||
#: allianceauth/services/modules/discord/views.py:65
|
||||
#: allianceauth/services/modules/discord/views.py:36
|
||||
#: allianceauth/services/modules/discord/views.py:59
|
||||
msgid "An error occurred while processing your Discord account."
|
||||
msgstr "디스코드 계정 처리 중 오류가 발생했습니다."
|
||||
|
||||
#: allianceauth/services/modules/discord/views.py:62
|
||||
msgid "Activated Discord account."
|
||||
msgstr "디스코드 계정 활성화 완료"
|
||||
#: allianceauth/services/modules/discord/views.py:102
|
||||
msgid "Your Discord account has been successfully activated."
|
||||
msgstr "디스코드 계정과 성공적으로 연동됐습니다."
|
||||
|
||||
#: allianceauth/services/modules/discord/views.py:108
|
||||
msgid ""
|
||||
"An error occurred while trying to activate your Discord account. Please try "
|
||||
"again."
|
||||
msgstr "디스코드 계정 연동 중 오류가 발생했습니다. 다시 시도해 주세요."
|
||||
|
||||
#: allianceauth/services/modules/discourse/views.py:37
|
||||
msgid "You are not authorized to access Discourse."
|
||||
@@ -1565,7 +1613,7 @@ msgstr "서드파티"
|
||||
msgid "Domain"
|
||||
msgstr "도메인"
|
||||
|
||||
#: allianceauth/srp/auth_hooks.py:9
|
||||
#: allianceauth/srp/auth_hooks.py:12
|
||||
msgid "Ship Replacement"
|
||||
msgstr "SRP"
|
||||
|
||||
@@ -1579,7 +1627,7 @@ msgstr "플릿 시간"
|
||||
msgid "Fleet Doctrine"
|
||||
msgstr "플릿 독트린"
|
||||
|
||||
#: allianceauth/srp/form.py:12 allianceauth/srp/templates/srp/data.html:89
|
||||
#: allianceauth/srp/form.py:12 allianceauth/srp/templates/srp/data.html:90
|
||||
msgid "Additional Info"
|
||||
msgstr "추가 기재 사항"
|
||||
|
||||
@@ -1608,63 +1656,63 @@ msgstr "SRP 보상 플릿 생성"
|
||||
msgid "Give this link to the line members"
|
||||
msgstr "이 링크를 직계 멤버들에게 전달"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:48
|
||||
#: allianceauth/srp/templates/srp/data.html:49
|
||||
msgid "SRP Fleet Data"
|
||||
msgstr "SRP 보상 플릿 데이터"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:53
|
||||
#: allianceauth/srp/templates/srp/data.html:54
|
||||
msgid "Mark Incomplete"
|
||||
msgstr "표시 미완료"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:57
|
||||
#: allianceauth/srp/templates/srp/data.html:58
|
||||
msgid "Mark Completed"
|
||||
msgstr "표시 완료"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:69
|
||||
#: allianceauth/srp/templates/srp/data.html:145
|
||||
#: allianceauth/srp/templates/srp/data.html:70
|
||||
#: allianceauth/srp/templates/srp/data.html:156
|
||||
msgid "Total Losses:"
|
||||
msgstr "전체 손실:"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:70
|
||||
#: allianceauth/srp/templates/srp/data.html:146
|
||||
#: allianceauth/srp/templates/srp/data.html:71
|
||||
#: allianceauth/srp/templates/srp/data.html:157
|
||||
#: allianceauth/srp/templates/srp/management.html:30
|
||||
msgid "Total ISK Cost:"
|
||||
msgstr "전체 ISK 비용:"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:78
|
||||
#: allianceauth/srp/templates/srp/data.html:154
|
||||
#: allianceauth/srp/templates/srp/data.html:79
|
||||
#: allianceauth/srp/templates/srp/data.html:165
|
||||
msgid "Are you sure you want to delete SRP requests?"
|
||||
msgstr "SRP 보상 요청을 삭제하시겠습니까?"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:87
|
||||
#: allianceauth/srp/templates/srp/data.html:88
|
||||
msgid "Pilot Name"
|
||||
msgstr "파일럿 이름"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:88
|
||||
#: allianceauth/srp/templates/srp/data.html:89
|
||||
msgid "Killboard Link"
|
||||
msgstr "킬보드 링크"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:90
|
||||
#: allianceauth/srp/templates/srp/data.html:91
|
||||
msgid "Ship Type"
|
||||
msgstr "함선 종류"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:91
|
||||
#: allianceauth/srp/templates/srp/data.html:92
|
||||
msgid "Killboard Loss Amt"
|
||||
msgstr "킬보드상 손실 금액"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:92
|
||||
#: allianceauth/srp/templates/srp/data.html:93
|
||||
msgid "SRP ISK Cost"
|
||||
msgstr "SRP 보상 비용"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:93
|
||||
#: allianceauth/srp/templates/srp/data.html:94
|
||||
msgid "Click value to edit Enter to save & next ESC to cancel"
|
||||
msgstr "금액을 수정하려면 클릭, 저장을 하고 다음으로 가려면 엔터, 취소를 하려면 ESC를 누르세요. "
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:96
|
||||
#: allianceauth/srp/templates/srp/data.html:97
|
||||
msgid "Post Time"
|
||||
msgstr "작성 시간"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:163
|
||||
#: allianceauth/srp/templates/srp/data.html:174
|
||||
msgid "No SRP requests for this fleet."
|
||||
msgstr "이 플릿에는 SRP 보상 요청이 없습니다."
|
||||
|
||||
@@ -1856,32 +1904,30 @@ msgid "Current"
|
||||
msgstr "현재"
|
||||
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:40
|
||||
msgid "Latest Major"
|
||||
msgstr "최근 주요 사항"
|
||||
msgid "Latest Stable"
|
||||
msgstr "최신 안정화 버전"
|
||||
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:46
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:56
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:66
|
||||
msgid "Update available"
|
||||
msgstr "업데이트 가능"
|
||||
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:50
|
||||
msgid "Latest Minor"
|
||||
msgstr "최근 기타 사항"
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:51
|
||||
msgid "Latest Pre-Release"
|
||||
msgstr "최신 사전 출시 버전"
|
||||
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:60
|
||||
msgid "Latest Patch"
|
||||
msgstr "최근 패치"
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:57
|
||||
msgid "Pre-Release available"
|
||||
msgstr "사전 출시 사용 가능"
|
||||
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:73
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:65
|
||||
msgid "Task Queue"
|
||||
msgstr "대기 중인 할 일"
|
||||
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:90
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:82
|
||||
msgid "Error retrieving task queue length"
|
||||
msgstr "대기 중인 할 일 목록 회수 에러"
|
||||
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:92
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:84
|
||||
#, python-format
|
||||
msgid "%(tasks)s task"
|
||||
msgid_plural "%(tasks)s tasks"
|
||||
@@ -2021,3 +2067,6 @@ msgstr "%(time)s 에 있을 %(system)s 타이머를 추가했습니다."
|
||||
#: allianceauth/timerboard/views.py:83
|
||||
msgid "Saved changes to the timer."
|
||||
msgstr "타이머 변경사항이 저장되었습니다."
|
||||
|
||||
#~ msgid "Portrait"
|
||||
#~ msgstr "포트레잇"
|
||||
|
||||
Binary file not shown.
@@ -5,15 +5,17 @@
|
||||
#
|
||||
# Translators:
|
||||
# Alexander Gess <de.alex.gess@gmail.com>, 2020
|
||||
# Yuriy K <thedjcooltv@gmail.com>, 2020
|
||||
# Андрей Зубков <and.vareba81@gmail.com>, 2020
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-07-29 04:56+0000\n"
|
||||
"POT-Creation-Date: 2020-11-20 05:33+0000\n"
|
||||
"PO-Revision-Date: 2020-02-18 03:14+0000\n"
|
||||
"Last-Translator: Alexander Gess <de.alex.gess@gmail.com>, 2020\n"
|
||||
"Last-Translator: Андрей Зубков <and.vareba81@gmail.com>, 2020\n"
|
||||
"Language-Team: Russian (https://www.transifex.com/alliance-auth/teams/107430/ru/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@@ -25,7 +27,7 @@ msgstr ""
|
||||
msgid "A main character is required to perform that action. Add one below."
|
||||
msgstr "Необходимо указать основного персонажа. Добавим?"
|
||||
|
||||
#: allianceauth/authentication/forms.py:6
|
||||
#: allianceauth/authentication/forms.py:5
|
||||
msgid "Email"
|
||||
msgstr "Email"
|
||||
|
||||
@@ -41,7 +43,7 @@ msgstr "Статус пилота: %(state)s"
|
||||
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:5
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:8
|
||||
#: allianceauth/templates/allianceauth/side-menu.html:12
|
||||
#: allianceauth/templates/allianceauth/side-menu.html:11
|
||||
msgid "Dashboard"
|
||||
msgstr "Панель показателей"
|
||||
|
||||
@@ -70,7 +72,7 @@ msgstr "Сменить основного персонажа"
|
||||
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:101
|
||||
msgid "Group Memberships"
|
||||
msgstr "Групповое участие"
|
||||
msgstr "Роли"
|
||||
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:121
|
||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticscorpview.html:23
|
||||
@@ -80,7 +82,7 @@ msgstr "Персонажи"
|
||||
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:129
|
||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:73
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:22
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:24
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:15
|
||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:45
|
||||
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:34
|
||||
@@ -163,23 +165,23 @@ msgstr "Персонаж %(name)s уже добавлен."
|
||||
msgid "Unable to authenticate as the selected character."
|
||||
msgstr "Невозможно авторизировать этого персонажа. "
|
||||
|
||||
#: allianceauth/authentication/views.py:148
|
||||
#: allianceauth/authentication/views.py:151
|
||||
msgid "Registration token has expired."
|
||||
msgstr "Регистрационный токен просрочен."
|
||||
|
||||
#: allianceauth/authentication/views.py:200
|
||||
#: allianceauth/authentication/views.py:206
|
||||
msgid ""
|
||||
"Sent confirmation email. Please follow the link to confirm your email "
|
||||
"address."
|
||||
msgstr "Отправить подтверждающее письмо. Пожалуйста, подтвердите почту. "
|
||||
|
||||
#: allianceauth/authentication/views.py:205
|
||||
#: allianceauth/authentication/views.py:211
|
||||
msgid "Confirmed your email address. Please login to continue."
|
||||
msgstr "Подтвердите Ваш email адрес. Зайти для подтверждения. "
|
||||
|
||||
#: allianceauth/authentication/views.py:210
|
||||
msgid "Registraion of new accounts it not allowed at this time."
|
||||
msgstr "Регистрация нового аккаунта сейчас невозможна."
|
||||
#: allianceauth/authentication/views.py:216
|
||||
msgid "Registration of new accounts is not allowed at this time."
|
||||
msgstr "Регистрация новых аккаунтов в настоящее время невозможна."
|
||||
|
||||
#: allianceauth/corputils/auth_hooks.py:10
|
||||
msgid "Corporation Stats"
|
||||
@@ -226,16 +228,16 @@ msgstr "Последнее обновление: "
|
||||
#: allianceauth/corputils/templates/corputils/search.html:13
|
||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html:24
|
||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:28
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:27
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:29
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:30
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:30
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:51
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:110
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:109
|
||||
msgid "Character"
|
||||
msgstr "Персонаж"
|
||||
|
||||
#: allianceauth/corputils/templates/corputils/corpstats.html:76
|
||||
#: allianceauth/corputils/templates/corputils/search.html:14
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:28
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:31
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:27
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:84
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:129
|
||||
@@ -326,7 +328,7 @@ msgstr "Добавить сюда"
|
||||
|
||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/characternotexisting.html:19
|
||||
msgid "before attempting to click fleet attendance links."
|
||||
msgstr "перед вступлением проверте содержимое"
|
||||
msgstr "перед вступлением проверьте содержимое"
|
||||
|
||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkformatter.html:6
|
||||
msgid "Create Fatlink"
|
||||
@@ -548,31 +550,35 @@ msgstr "Флотовое участие зарегистрированно."
|
||||
msgid "FAT link has expired."
|
||||
msgstr "ФлАк ссылка устарела"
|
||||
|
||||
#: allianceauth/groupmanagement/auth_hooks.py:17
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:14
|
||||
msgid "Group Management"
|
||||
msgstr "Управление Группой"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:5
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:13
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:14
|
||||
msgid "Audit Log"
|
||||
msgstr "Записи безопасности"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:18
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:20
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:20
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:21
|
||||
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:13
|
||||
msgid "Back"
|
||||
msgstr "Назад"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:25
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:28
|
||||
msgid "Date/Time"
|
||||
msgstr "Дата / Время"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:26
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:29
|
||||
msgid "Requestor"
|
||||
msgstr "Запрос от"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:29
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:32
|
||||
msgid "Type"
|
||||
msgstr "Тип"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:30
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:17
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:33
|
||||
#: allianceauth/notifications/templates/notifications/list.html:37
|
||||
#: allianceauth/notifications/templates/notifications/list.html:69
|
||||
#: allianceauth/optimer/templates/optimer/fleetoptable.html:18
|
||||
@@ -583,11 +589,19 @@ msgstr "Тип"
|
||||
msgid "Action"
|
||||
msgstr "Действие"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:31
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:34
|
||||
msgid "Actor"
|
||||
msgstr "Исполнитель"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:47
|
||||
msgid "Removed"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:59
|
||||
msgid "All times displayed are EVE/UTC."
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:66
|
||||
msgid "No entries found for this group."
|
||||
msgstr "Нет вхождений в эту группу"
|
||||
|
||||
@@ -595,22 +609,24 @@ msgstr "Нет вхождений в эту группу"
|
||||
msgid "Group Members"
|
||||
msgstr "Групповые Участники"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:28
|
||||
msgid "Portrait"
|
||||
msgstr "Портрет"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:30
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:31
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:52
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:111
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:110
|
||||
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:23
|
||||
msgid "Organization"
|
||||
msgstr "Корпорация"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:64
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:61
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:78
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:136
|
||||
msgid "(unknown)"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:66
|
||||
msgid "Remove from group"
|
||||
msgstr "Исключить из группы"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:76
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:81
|
||||
msgid "No group members to list."
|
||||
msgstr "Нет участников в группе"
|
||||
|
||||
@@ -618,56 +634,56 @@ msgstr "Нет участников в группе"
|
||||
msgid "Groups Membership"
|
||||
msgstr "Участники группы"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:14
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:15
|
||||
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:40
|
||||
#: allianceauth/templates/allianceauth/side-menu.html:17
|
||||
#: allianceauth/templates/allianceauth/side-menu.html:16
|
||||
msgid "Groups"
|
||||
msgstr "Группы"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:23
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:25
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:16
|
||||
msgid "Description"
|
||||
msgstr "Описание"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:24
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:26
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:28
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:85
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:130
|
||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:27
|
||||
#: allianceauth/srp/templates/srp/data.html:97
|
||||
#: allianceauth/srp/templates/srp/data.html:98
|
||||
msgid "Status"
|
||||
msgstr "Статус"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:25
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:27
|
||||
msgid "Member Count"
|
||||
msgstr "Число участников"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:38
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:43
|
||||
msgid "Hidden"
|
||||
msgstr "Скрытые"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:40
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:45
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:12
|
||||
msgid "Open"
|
||||
msgstr "Открыть"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:42
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:47
|
||||
msgid "Requestable"
|
||||
msgstr "Запрошено"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:50
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:56
|
||||
msgid "View Members"
|
||||
msgstr "Посмотреть участников"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:53
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:60
|
||||
msgid "Audit Members"
|
||||
msgstr "Проверить участников"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:56
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:64
|
||||
msgid "Copy Direct Join Link"
|
||||
msgstr "Скопировать ссылку подключения"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:68
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:75
|
||||
msgid "No groups to list."
|
||||
msgstr "Нет групп в списке"
|
||||
|
||||
@@ -676,19 +692,19 @@ msgstr "Нет групп в списке"
|
||||
msgid "Available Groups"
|
||||
msgstr "Доступные группы"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:29
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:30
|
||||
msgid "Leave"
|
||||
msgstr "Покинуть"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:39
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:40
|
||||
msgid "Join"
|
||||
msgstr "Присоединиться"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:43
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:44
|
||||
msgid "Request"
|
||||
msgstr "Запрос"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:58
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:59
|
||||
msgid "No groups available."
|
||||
msgstr "Нет доступных групп."
|
||||
|
||||
@@ -700,24 +716,24 @@ msgstr "Управление Группами"
|
||||
msgid "Join Requests"
|
||||
msgstr "Запрос на присоединение"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:33
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:34
|
||||
msgid "Leave Requests"
|
||||
msgstr "Запрос на Выход"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:53
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:112
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:111
|
||||
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:20
|
||||
#: allianceauth/services/modules/openfire/forms.py:6
|
||||
msgid "Group"
|
||||
msgstr "Группа"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:85
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:144
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:84
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:142
|
||||
msgid "Accept"
|
||||
msgstr "Принять"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:88
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:147
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:146
|
||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:85
|
||||
msgid "Reject"
|
||||
msgstr "Сбросить"
|
||||
@@ -726,24 +742,19 @@ msgstr "Сбросить"
|
||||
msgid "No group add requests."
|
||||
msgstr "Нет групповых запросов на вступление"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:156
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:155
|
||||
msgid "No group leave requests."
|
||||
msgstr "Нет групповых запросов на выход"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:10
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:9
|
||||
msgid "Toggle navigation"
|
||||
msgstr "Проложить маршрут"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:15
|
||||
#: allianceauth/templates/allianceauth/side-menu.html:25
|
||||
msgid "Group Management"
|
||||
msgstr "Управление Группой"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:21
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:20
|
||||
msgid "Group Requests"
|
||||
msgstr "Групповой запрос"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:24
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:23
|
||||
msgid "Group Membership"
|
||||
msgstr "Групповое участие"
|
||||
|
||||
@@ -821,7 +832,7 @@ msgstr "Вы уже подали заявку на вступление этой
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:144
|
||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:38
|
||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:20
|
||||
#: allianceauth/srp/templates/srp/data.html:125
|
||||
#: allianceauth/srp/templates/srp/data.html:134
|
||||
#: allianceauth/srp/templates/srp/management.html:81
|
||||
msgid "Pending"
|
||||
msgstr "Ожидание"
|
||||
@@ -848,7 +859,7 @@ msgstr "Ваш запрос находится на рассмотрении"
|
||||
msgid "Applied to leave group %(group)s."
|
||||
msgstr "Запрос на выход из группы %(group)s."
|
||||
|
||||
#: allianceauth/hrapplications/auth_hooks.py:10
|
||||
#: allianceauth/hrapplications/auth_hooks.py:13
|
||||
msgid "Applications"
|
||||
msgstr "Запросы"
|
||||
|
||||
@@ -905,7 +916,7 @@ msgstr "Пользователь"
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:131
|
||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:28
|
||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:75
|
||||
#: allianceauth/srp/templates/srp/data.html:99
|
||||
#: allianceauth/srp/templates/srp/data.html:100
|
||||
#: allianceauth/srp/templates/srp/management.html:46
|
||||
msgid "Actions"
|
||||
msgstr "Действия"
|
||||
@@ -915,7 +926,7 @@ msgstr "Действия"
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:147
|
||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:40
|
||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:16
|
||||
#: allianceauth/srp/templates/srp/data.html:117
|
||||
#: allianceauth/srp/templates/srp/data.html:126
|
||||
msgid "Approved"
|
||||
msgstr "Проверено"
|
||||
|
||||
@@ -923,7 +934,7 @@ msgstr "Проверено"
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:104
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:149
|
||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:42
|
||||
#: allianceauth/srp/templates/srp/data.html:121
|
||||
#: allianceauth/srp/templates/srp/data.html:130
|
||||
msgid "Rejected"
|
||||
msgstr "Отменено "
|
||||
|
||||
@@ -1029,7 +1040,7 @@ msgstr "Не прочитанно"
|
||||
|
||||
#: allianceauth/notifications/templates/notifications/list.html:18
|
||||
msgid "Read"
|
||||
msgstr "Прочитать"
|
||||
msgstr "Прочитано"
|
||||
|
||||
#: allianceauth/notifications/templates/notifications/list.html:22
|
||||
msgid "Mark All Read"
|
||||
@@ -1137,7 +1148,7 @@ msgstr "Таймера Флотовых операций"
|
||||
#: allianceauth/optimer/templates/optimer/management.html:21
|
||||
#: allianceauth/timerboard/templates/timerboard/view.html:23
|
||||
msgid "Current Eve Time:"
|
||||
msgstr "ET"
|
||||
msgstr "Текущий EVE Time:"
|
||||
|
||||
#: allianceauth/optimer/templates/optimer/management.html:27
|
||||
#: allianceauth/timerboard/templates/timerboard/view.html:189
|
||||
@@ -1244,7 +1255,7 @@ msgstr "{} Пароль успешно обновлен."
|
||||
|
||||
#: allianceauth/services/auth_hooks.py:11
|
||||
msgid "Services"
|
||||
msgstr "Сервисные услуги"
|
||||
msgstr "Подключение сервисов"
|
||||
|
||||
#: allianceauth/services/forms.py:6
|
||||
msgid "Name of Fleet:"
|
||||
@@ -1306,17 +1317,15 @@ msgstr "Пароль"
|
||||
msgid "Password must be at least 8 characters long."
|
||||
msgstr "Пароль должен быть не менее 8 символов."
|
||||
|
||||
#: allianceauth/services/modules/discord/models.py:224
|
||||
#: allianceauth/services/modules/discord/models.py:225
|
||||
msgid "Discord Account Disabled"
|
||||
msgstr "Discord персонаж отключен"
|
||||
|
||||
#: allianceauth/services/modules/discord/models.py:226
|
||||
#: allianceauth/services/modules/discord/models.py:227
|
||||
msgid ""
|
||||
"Your Discord account was disabeled automatically by Auth. If you think this "
|
||||
"Your Discord account was disabled automatically by Auth. If you think this "
|
||||
"was a mistake, please contact an admin."
|
||||
msgstr ""
|
||||
"Ваш доступ на сервер Discord был отменен. Если Вы считаете что по ошибке, "
|
||||
"пожалуйста, свяжитесь с СЕО."
|
||||
|
||||
#: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:18
|
||||
msgid "Join the Discord server"
|
||||
@@ -1623,9 +1632,9 @@ msgstr "Сервис"
|
||||
msgid "Domain"
|
||||
msgstr "Домен"
|
||||
|
||||
#: allianceauth/srp/auth_hooks.py:9
|
||||
#: allianceauth/srp/auth_hooks.py:12
|
||||
msgid "Ship Replacement"
|
||||
msgstr "Замена корабля"
|
||||
msgstr "Компенсация корабля"
|
||||
|
||||
#: allianceauth/srp/form.py:7
|
||||
#: allianceauth/srp/templates/srp/management.html:38
|
||||
@@ -1637,7 +1646,7 @@ msgstr "Флотовое время"
|
||||
msgid "Fleet Doctrine"
|
||||
msgstr "Флотовая Доктрина"
|
||||
|
||||
#: allianceauth/srp/form.py:12 allianceauth/srp/templates/srp/data.html:89
|
||||
#: allianceauth/srp/form.py:12 allianceauth/srp/templates/srp/data.html:90
|
||||
msgid "Additional Info"
|
||||
msgstr "Дополнительная информация"
|
||||
|
||||
@@ -1666,63 +1675,63 @@ msgstr "Создать SRP Флот"
|
||||
msgid "Give this link to the line members"
|
||||
msgstr "Поделиться ссылкой с рядовыми участниками"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:48
|
||||
#: allianceauth/srp/templates/srp/data.html:49
|
||||
msgid "SRP Fleet Data"
|
||||
msgstr "SRP данные флота"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:53
|
||||
#: allianceauth/srp/templates/srp/data.html:54
|
||||
msgid "Mark Incomplete"
|
||||
msgstr "Пометить незаконченным"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:57
|
||||
#: allianceauth/srp/templates/srp/data.html:58
|
||||
msgid "Mark Completed"
|
||||
msgstr "Пометить законченным"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:69
|
||||
#: allianceauth/srp/templates/srp/data.html:145
|
||||
#: allianceauth/srp/templates/srp/data.html:70
|
||||
#: allianceauth/srp/templates/srp/data.html:156
|
||||
msgid "Total Losses:"
|
||||
msgstr "Суммарные потери:"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:70
|
||||
#: allianceauth/srp/templates/srp/data.html:146
|
||||
#: allianceauth/srp/templates/srp/data.html:71
|
||||
#: allianceauth/srp/templates/srp/data.html:157
|
||||
#: allianceauth/srp/templates/srp/management.html:30
|
||||
msgid "Total ISK Cost:"
|
||||
msgstr "Оценочная стоимость (ISK):"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:78
|
||||
#: allianceauth/srp/templates/srp/data.html:154
|
||||
#: allianceauth/srp/templates/srp/data.html:79
|
||||
#: allianceauth/srp/templates/srp/data.html:165
|
||||
msgid "Are you sure you want to delete SRP requests?"
|
||||
msgstr "Вы уверенны что хотите удалить запрос на SRP?"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:87
|
||||
#: allianceauth/srp/templates/srp/data.html:88
|
||||
msgid "Pilot Name"
|
||||
msgstr "Имя Пилота"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:88
|
||||
#: allianceauth/srp/templates/srp/data.html:89
|
||||
msgid "Killboard Link"
|
||||
msgstr "zKillBoard ссылка"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:90
|
||||
#: allianceauth/srp/templates/srp/data.html:91
|
||||
msgid "Ship Type"
|
||||
msgstr "Тип корабля"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:91
|
||||
#: allianceauth/srp/templates/srp/data.html:92
|
||||
msgid "Killboard Loss Amt"
|
||||
msgstr "потерь по zKillBoard на данный момент"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:92
|
||||
#: allianceauth/srp/templates/srp/data.html:93
|
||||
msgid "SRP ISK Cost"
|
||||
msgstr "SRP ISK Стоимость"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:93
|
||||
#: allianceauth/srp/templates/srp/data.html:94
|
||||
msgid "Click value to edit Enter to save & next ESC to cancel"
|
||||
msgstr "Нажмите на значение для редактирования и ESC для отмены"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:96
|
||||
#: allianceauth/srp/templates/srp/data.html:97
|
||||
msgid "Post Time"
|
||||
msgstr "Опубликованно"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:163
|
||||
#: allianceauth/srp/templates/srp/data.html:174
|
||||
msgid "No SRP requests for this fleet."
|
||||
msgstr "SRP запросы отсутствуют"
|
||||
|
||||
@@ -1974,14 +1983,14 @@ msgstr "Прочие"
|
||||
#: allianceauth/timerboard/templates/timerboard/view.html:220
|
||||
#: allianceauth/timerboard/templates/timerboard/view.html:388
|
||||
msgid "Friendly"
|
||||
msgstr "Дружествен"
|
||||
msgstr "Дружественный"
|
||||
|
||||
#: allianceauth/timerboard/form.py:55
|
||||
#: allianceauth/timerboard/templates/timerboard/view.html:53
|
||||
#: allianceauth/timerboard/templates/timerboard/view.html:215
|
||||
#: allianceauth/timerboard/templates/timerboard/view.html:383
|
||||
msgid "Hostile"
|
||||
msgstr "Заложник"
|
||||
msgstr "Вражеский"
|
||||
|
||||
#: allianceauth/timerboard/form.py:56
|
||||
#: allianceauth/timerboard/templates/timerboard/view.html:63
|
||||
@@ -2083,3 +2092,6 @@ msgstr "Добавлен таймер в %(system)s на %(time)s."
|
||||
#: allianceauth/timerboard/views.py:83
|
||||
msgid "Saved changes to the timer."
|
||||
msgstr "Изменения сохранены"
|
||||
|
||||
#~ msgid "Portrait"
|
||||
#~ msgstr "Портрет"
|
||||
|
||||
Binary file not shown.
@@ -13,7 +13,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-07-29 03:24+0000\n"
|
||||
"POT-Creation-Date: 2020-11-20 05:33+0000\n"
|
||||
"PO-Revision-Date: 2020-02-18 03:14+0000\n"
|
||||
"Last-Translator: Aaron BuBu <351793078@qq.com>, 2020\n"
|
||||
"Language-Team: Chinese Simplified (https://www.transifex.com/alliance-auth/teams/107430/zh-Hans/)\n"
|
||||
@@ -27,7 +27,7 @@ msgstr ""
|
||||
msgid "A main character is required to perform that action. Add one below."
|
||||
msgstr "只有主要角色才能执行这个操作。在下面添加一个"
|
||||
|
||||
#: allianceauth/authentication/forms.py:6
|
||||
#: allianceauth/authentication/forms.py:5
|
||||
msgid "Email"
|
||||
msgstr "电子邮箱"
|
||||
|
||||
@@ -43,7 +43,7 @@ msgstr ""
|
||||
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:5
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:8
|
||||
#: allianceauth/templates/allianceauth/side-menu.html:12
|
||||
#: allianceauth/templates/allianceauth/side-menu.html:11
|
||||
msgid "Dashboard"
|
||||
msgstr "账户总览"
|
||||
|
||||
@@ -79,7 +79,7 @@ msgstr "角色"
|
||||
|
||||
#: allianceauth/authentication/templates/authentication/dashboard.html:129
|
||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:73
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:22
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:24
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:15
|
||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:45
|
||||
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:34
|
||||
@@ -159,23 +159,23 @@ msgstr "添加%(name)s到您的账户失败:他们已经在一个账户中了"
|
||||
msgid "Unable to authenticate as the selected character."
|
||||
msgstr "无法作为选定的角色进行身份验证"
|
||||
|
||||
#: allianceauth/authentication/views.py:148
|
||||
#: allianceauth/authentication/views.py:151
|
||||
msgid "Registration token has expired."
|
||||
msgstr "注册令牌过期。"
|
||||
|
||||
#: allianceauth/authentication/views.py:200
|
||||
#: allianceauth/authentication/views.py:206
|
||||
msgid ""
|
||||
"Sent confirmation email. Please follow the link to confirm your email "
|
||||
"address."
|
||||
msgstr "已经发送了确认邮件。请按照链接确定您的电邮地址"
|
||||
|
||||
#: allianceauth/authentication/views.py:205
|
||||
#: allianceauth/authentication/views.py:211
|
||||
msgid "Confirmed your email address. Please login to continue."
|
||||
msgstr "已确认您的电邮地址。请登录以继续"
|
||||
|
||||
#: allianceauth/authentication/views.py:210
|
||||
msgid "Registraion of new accounts it not allowed at this time."
|
||||
msgstr "现在不允许注册新账户。"
|
||||
#: allianceauth/authentication/views.py:216
|
||||
msgid "Registration of new accounts is not allowed at this time."
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/corputils/auth_hooks.py:10
|
||||
msgid "Corporation Stats"
|
||||
@@ -222,16 +222,16 @@ msgstr "最后一次更新"
|
||||
#: allianceauth/corputils/templates/corputils/search.html:13
|
||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html:24
|
||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:28
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:27
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:29
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:30
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:30
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:51
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:110
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:109
|
||||
msgid "Character"
|
||||
msgstr "角色"
|
||||
|
||||
#: allianceauth/corputils/templates/corputils/corpstats.html:76
|
||||
#: allianceauth/corputils/templates/corputils/search.html:14
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:28
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:31
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:27
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:84
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:129
|
||||
@@ -538,31 +538,35 @@ msgstr "成功注册舰队PAP"
|
||||
msgid "FAT link has expired."
|
||||
msgstr "PAP链接已过期"
|
||||
|
||||
#: allianceauth/groupmanagement/auth_hooks.py:17
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:14
|
||||
msgid "Group Management"
|
||||
msgstr "用户组管理"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:5
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:13
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:14
|
||||
msgid "Audit Log"
|
||||
msgstr "审计日志"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:18
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:20
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:20
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:21
|
||||
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:13
|
||||
msgid "Back"
|
||||
msgstr "返回"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:25
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:28
|
||||
msgid "Date/Time"
|
||||
msgstr "日期/时间"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:26
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:29
|
||||
msgid "Requestor"
|
||||
msgstr "申请人"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:29
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:32
|
||||
msgid "Type"
|
||||
msgstr "类型"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:30
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:17
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:33
|
||||
#: allianceauth/notifications/templates/notifications/list.html:37
|
||||
#: allianceauth/notifications/templates/notifications/list.html:69
|
||||
#: allianceauth/optimer/templates/optimer/fleetoptable.html:18
|
||||
@@ -573,11 +577,19 @@ msgstr "类型"
|
||||
msgid "Action"
|
||||
msgstr "操作"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:31
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:34
|
||||
msgid "Actor"
|
||||
msgstr "操作者"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:47
|
||||
msgid "Removed"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:59
|
||||
msgid "All times displayed are EVE/UTC."
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:66
|
||||
msgid "No entries found for this group."
|
||||
msgstr "这一用户组下面没有任何条目呀"
|
||||
|
||||
@@ -585,22 +597,24 @@ msgstr "这一用户组下面没有任何条目呀"
|
||||
msgid "Group Members"
|
||||
msgstr "群组成员"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:28
|
||||
msgid "Portrait"
|
||||
msgstr "人物头像"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:30
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:31
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:52
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:111
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:110
|
||||
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:23
|
||||
msgid "Organization"
|
||||
msgstr "组织"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:64
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:61
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:78
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:136
|
||||
msgid "(unknown)"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:66
|
||||
msgid "Remove from group"
|
||||
msgstr "从用户组中移除"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:76
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:81
|
||||
msgid "No group members to list."
|
||||
msgstr "用户组里没人呀,你叫我怎么列"
|
||||
|
||||
@@ -608,56 +622,56 @@ msgstr "用户组里没人呀,你叫我怎么列"
|
||||
msgid "Groups Membership"
|
||||
msgstr "用户组成员"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:14
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:15
|
||||
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:40
|
||||
#: allianceauth/templates/allianceauth/side-menu.html:17
|
||||
#: allianceauth/templates/allianceauth/side-menu.html:16
|
||||
msgid "Groups"
|
||||
msgstr "群组"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:23
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:25
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:16
|
||||
msgid "Description"
|
||||
msgstr "描述"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:24
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:26
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:28
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:85
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:130
|
||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:27
|
||||
#: allianceauth/srp/templates/srp/data.html:97
|
||||
#: allianceauth/srp/templates/srp/data.html:98
|
||||
msgid "Status"
|
||||
msgstr "状态"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:25
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:27
|
||||
msgid "Member Count"
|
||||
msgstr "成员数量"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:38
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:43
|
||||
msgid "Hidden"
|
||||
msgstr "已隐藏"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:40
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:45
|
||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:12
|
||||
msgid "Open"
|
||||
msgstr "公开"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:42
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:47
|
||||
msgid "Requestable"
|
||||
msgstr "可申请"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:50
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:56
|
||||
msgid "View Members"
|
||||
msgstr "查看成员"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:53
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:60
|
||||
msgid "Audit Members"
|
||||
msgstr "编辑成员"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:56
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:64
|
||||
msgid "Copy Direct Join Link"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:68
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:75
|
||||
msgid "No groups to list."
|
||||
msgstr "无可用组"
|
||||
|
||||
@@ -666,19 +680,19 @@ msgstr "无可用组"
|
||||
msgid "Available Groups"
|
||||
msgstr "可用组"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:29
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:30
|
||||
msgid "Leave"
|
||||
msgstr "离开"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:39
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:40
|
||||
msgid "Join"
|
||||
msgstr "加入"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:43
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:44
|
||||
msgid "Request"
|
||||
msgstr "申请"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:58
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:59
|
||||
msgid "No groups available."
|
||||
msgstr "没有可用用户组"
|
||||
|
||||
@@ -690,24 +704,24 @@ msgstr "用户组管理"
|
||||
msgid "Join Requests"
|
||||
msgstr "入组的请求"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:33
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:34
|
||||
msgid "Leave Requests"
|
||||
msgstr "离组的请求"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:53
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:112
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:111
|
||||
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:20
|
||||
#: allianceauth/services/modules/openfire/forms.py:6
|
||||
msgid "Group"
|
||||
msgstr "用户组"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:85
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:144
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:84
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:142
|
||||
msgid "Accept"
|
||||
msgstr "接受"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:88
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:147
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:146
|
||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:85
|
||||
msgid "Reject"
|
||||
msgstr "拒绝"
|
||||
@@ -716,24 +730,19 @@ msgstr "拒绝"
|
||||
msgid "No group add requests."
|
||||
msgstr "没有加入用户组的请求,小老弟你是不是摇不到人"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:156
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:155
|
||||
msgid "No group leave requests."
|
||||
msgstr "没有离开用户组的请求,小老弟你人缘可以啊?"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:10
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:9
|
||||
msgid "Toggle navigation"
|
||||
msgstr "打开导航栏"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:15
|
||||
#: allianceauth/templates/allianceauth/side-menu.html:25
|
||||
msgid "Group Management"
|
||||
msgstr "用户组管理"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:21
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:20
|
||||
msgid "Group Requests"
|
||||
msgstr "用户组请求"
|
||||
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:24
|
||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:23
|
||||
msgid "Group Membership"
|
||||
msgstr "用户组成员"
|
||||
|
||||
@@ -807,7 +816,7 @@ msgstr "你已经有了该组的未决申请"
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:144
|
||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:38
|
||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:20
|
||||
#: allianceauth/srp/templates/srp/data.html:125
|
||||
#: allianceauth/srp/templates/srp/data.html:134
|
||||
#: allianceauth/srp/templates/srp/management.html:81
|
||||
msgid "Pending"
|
||||
msgstr "待定"
|
||||
@@ -834,7 +843,7 @@ msgstr "你已经有了该组的未决离开请求"
|
||||
msgid "Applied to leave group %(group)s."
|
||||
msgstr "已经离开群组%(group)s"
|
||||
|
||||
#: allianceauth/hrapplications/auth_hooks.py:10
|
||||
#: allianceauth/hrapplications/auth_hooks.py:13
|
||||
msgid "Applications"
|
||||
msgstr "申请"
|
||||
|
||||
@@ -891,7 +900,7 @@ msgstr "用户名"
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:131
|
||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:28
|
||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:75
|
||||
#: allianceauth/srp/templates/srp/data.html:99
|
||||
#: allianceauth/srp/templates/srp/data.html:100
|
||||
#: allianceauth/srp/templates/srp/management.html:46
|
||||
msgid "Actions"
|
||||
msgstr "操作"
|
||||
@@ -901,7 +910,7 @@ msgstr "操作"
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:147
|
||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:40
|
||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:16
|
||||
#: allianceauth/srp/templates/srp/data.html:117
|
||||
#: allianceauth/srp/templates/srp/data.html:126
|
||||
msgid "Approved"
|
||||
msgstr "通过"
|
||||
|
||||
@@ -909,7 +918,7 @@ msgstr "通过"
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:104
|
||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:149
|
||||
#: allianceauth/hrapplications/templates/hrapplications/searchview.html:42
|
||||
#: allianceauth/srp/templates/srp/data.html:121
|
||||
#: allianceauth/srp/templates/srp/data.html:130
|
||||
msgid "Rejected"
|
||||
msgstr "拒绝"
|
||||
|
||||
@@ -1292,13 +1301,13 @@ msgstr "密码"
|
||||
msgid "Password must be at least 8 characters long."
|
||||
msgstr "密码至少要有8个字符啊,你也太不注重安全啦"
|
||||
|
||||
#: allianceauth/services/modules/discord/models.py:224
|
||||
#: allianceauth/services/modules/discord/models.py:225
|
||||
msgid "Discord Account Disabled"
|
||||
msgstr ""
|
||||
|
||||
#: allianceauth/services/modules/discord/models.py:226
|
||||
#: allianceauth/services/modules/discord/models.py:227
|
||||
msgid ""
|
||||
"Your Discord account was disabeled automatically by Auth. If you think this "
|
||||
"Your Discord account was disabled automatically by Auth. If you think this "
|
||||
"was a mistake, please contact an admin."
|
||||
msgstr ""
|
||||
|
||||
@@ -1599,7 +1608,7 @@ msgstr "服务"
|
||||
msgid "Domain"
|
||||
msgstr "域名"
|
||||
|
||||
#: allianceauth/srp/auth_hooks.py:9
|
||||
#: allianceauth/srp/auth_hooks.py:12
|
||||
msgid "Ship Replacement"
|
||||
msgstr "补损"
|
||||
|
||||
@@ -1613,7 +1622,7 @@ msgstr "集结时间"
|
||||
msgid "Fleet Doctrine"
|
||||
msgstr "舰队船型"
|
||||
|
||||
#: allianceauth/srp/form.py:12 allianceauth/srp/templates/srp/data.html:89
|
||||
#: allianceauth/srp/form.py:12 allianceauth/srp/templates/srp/data.html:90
|
||||
msgid "Additional Info"
|
||||
msgstr "其他信息"
|
||||
|
||||
@@ -1642,63 +1651,63 @@ msgstr "创建补损舰队"
|
||||
msgid "Give this link to the line members"
|
||||
msgstr "把这个链接发送给火力狗们"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:48
|
||||
#: allianceauth/srp/templates/srp/data.html:49
|
||||
msgid "SRP Fleet Data"
|
||||
msgstr "舰队补损信息"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:53
|
||||
#: allianceauth/srp/templates/srp/data.html:54
|
||||
msgid "Mark Incomplete"
|
||||
msgstr "标记为未完成"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:57
|
||||
#: allianceauth/srp/templates/srp/data.html:58
|
||||
msgid "Mark Completed"
|
||||
msgstr "标记为已完成"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:69
|
||||
#: allianceauth/srp/templates/srp/data.html:145
|
||||
#: allianceauth/srp/templates/srp/data.html:70
|
||||
#: allianceauth/srp/templates/srp/data.html:156
|
||||
msgid "Total Losses:"
|
||||
msgstr "损失总额:"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:70
|
||||
#: allianceauth/srp/templates/srp/data.html:146
|
||||
#: allianceauth/srp/templates/srp/data.html:71
|
||||
#: allianceauth/srp/templates/srp/data.html:157
|
||||
#: allianceauth/srp/templates/srp/management.html:30
|
||||
msgid "Total ISK Cost:"
|
||||
msgstr "ISK花费总额:"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:78
|
||||
#: allianceauth/srp/templates/srp/data.html:154
|
||||
#: allianceauth/srp/templates/srp/data.html:79
|
||||
#: allianceauth/srp/templates/srp/data.html:165
|
||||
msgid "Are you sure you want to delete SRP requests?"
|
||||
msgstr "老哥,你确定要删了补损请求么?"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:87
|
||||
#: allianceauth/srp/templates/srp/data.html:88
|
||||
msgid "Pilot Name"
|
||||
msgstr "玩家ID"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:88
|
||||
#: allianceauth/srp/templates/srp/data.html:89
|
||||
msgid "Killboard Link"
|
||||
msgstr "KB网链接"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:90
|
||||
#: allianceauth/srp/templates/srp/data.html:91
|
||||
msgid "Ship Type"
|
||||
msgstr "船型"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:91
|
||||
#: allianceauth/srp/templates/srp/data.html:92
|
||||
msgid "Killboard Loss Amt"
|
||||
msgstr "KB网总损失"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:92
|
||||
#: allianceauth/srp/templates/srp/data.html:93
|
||||
msgid "SRP ISK Cost"
|
||||
msgstr "补损ISK花费"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:93
|
||||
#: allianceauth/srp/templates/srp/data.html:94
|
||||
msgid "Click value to edit Enter to save & next ESC to cancel"
|
||||
msgstr "点击数值就可以编辑啦,按回车确认,按ESC取消"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:96
|
||||
#: allianceauth/srp/templates/srp/data.html:97
|
||||
msgid "Post Time"
|
||||
msgstr "发布时间"
|
||||
|
||||
#: allianceauth/srp/templates/srp/data.html:163
|
||||
#: allianceauth/srp/templates/srp/data.html:174
|
||||
msgid "No SRP requests for this fleet."
|
||||
msgstr "这次起队没有补损请求!大捷"
|
||||
|
||||
@@ -2052,3 +2061,6 @@ msgstr "已经把%(system)s星系里%(time)s的时间节点设置好了!CTA!
|
||||
#: allianceauth/timerboard/views.py:83
|
||||
msgid "Saved changes to the timer."
|
||||
msgstr "保存至新的计划表"
|
||||
|
||||
#~ msgid "Portrait"
|
||||
#~ msgstr "人物头像"
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
default_app_config = 'allianceauth.notifications.apps.NotificationsConfig'
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
MAX_NOTIFICATIONS = 50
|
||||
|
||||
|
||||
def notify(user, title, message=None, level='info'):
|
||||
def notify(
|
||||
user: object, title: str, message: str = None, level: str = 'info'
|
||||
) -> None:
|
||||
"""Sends a new notification to user. Convenience function to manager pendant."""
|
||||
from .models import Notification
|
||||
if Notification.objects.filter(user=user).count() > MAX_NOTIFICATIONS:
|
||||
for n in Notification.objects.filter(user=user)[MAX_NOTIFICATIONS-1:]:
|
||||
n.delete()
|
||||
notif = Notification()
|
||||
notif.user = user
|
||||
notif.title = title
|
||||
if not message:
|
||||
message = title
|
||||
notif.message = message
|
||||
notif.level = level
|
||||
notif.save()
|
||||
logger.info("Created notification %s" % notif)
|
||||
Notification.objects.notify_user(user, title, message, level)
|
||||
|
||||
@@ -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.contrib.auth.models import User
|
||||
import logging
|
||||
|
||||
from .managers import NotificationManager
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Notification(models.Model):
|
||||
"""Notification to a user within Auth"""
|
||||
|
||||
NOTIFICATIONS_MAX_PER_USER_DEFAULT = 50
|
||||
NOTIFICATIONS_REFRESH_TIME_DEFAULT = 30
|
||||
|
||||
LEVEL_CHOICES = (
|
||||
('danger', 'CRITICAL'),
|
||||
('danger', 'ERROR'),
|
||||
@@ -18,19 +26,41 @@ class Notification(models.Model):
|
||||
level = models.CharField(choices=LEVEL_CHOICES, max_length=10)
|
||||
title = models.CharField(max_length=254)
|
||||
message = models.TextField()
|
||||
timestamp = models.DateTimeField(auto_now_add=True)
|
||||
viewed = models.BooleanField(default=False)
|
||||
timestamp = models.DateTimeField(auto_now_add=True, db_index=True)
|
||||
viewed = models.BooleanField(default=False, db_index=True)
|
||||
|
||||
def view(self):
|
||||
objects = NotificationManager()
|
||||
|
||||
def __str__(self) -> str:
|
||||
return "%s: %s" % (self.user, self.title)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
# overriden save to ensure cache is invaidated on very call
|
||||
super().save(*args, **kwargs)
|
||||
Notification.objects.invalidate_user_notification_cache(self.user.pk)
|
||||
|
||||
def delete(self, *args, **kwargs):
|
||||
# overriden delete to ensure cache is invaidated on very call
|
||||
super().delete(*args, **kwargs)
|
||||
Notification.objects.invalidate_user_notification_cache(self.user.pk)
|
||||
|
||||
def mark_viewed(self) -> None:
|
||||
"""mark notification as viewed"""
|
||||
logger.info("Marking notification as viewed: %s" % self)
|
||||
self.viewed = True
|
||||
self.save()
|
||||
|
||||
def __str__(self):
|
||||
return "%s: %s" % (self.user, self.title)
|
||||
def set_level(self, level_name: str) -> None:
|
||||
"""set notification level according to level name, e.g. 'CRITICAL'
|
||||
|
||||
raised exception on invalid level names
|
||||
"""
|
||||
try:
|
||||
new_level = [
|
||||
item[0] for item in self.LEVEL_CHOICES if item[1] == level_name
|
||||
][0]
|
||||
except IndexError:
|
||||
raise ValueError('Invalid level name: %s' % level_name)
|
||||
|
||||
def set_level(self, level):
|
||||
self.level = [item[0] for item in self.LEVEL_CHOICES if item[1] == level][0]
|
||||
|
||||
class Meta:
|
||||
ordering = ['-timestamp']
|
||||
self.level = new_level
|
||||
self.save()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{% extends "allianceauth/base.html" %}
|
||||
{% load staticfiles %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block page_title %}{% trans "Notifications" %}{% endblock %}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{% extends "allianceauth/base.html" %}
|
||||
{% load staticfiles %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block page_title %}{% trans "View Notification" %}{% endblock page_title %}
|
||||
|
||||
0
allianceauth/notifications/templatetags/__init__.py
Normal file
0
allianceauth/notifications/templatetags/__init__.py
Normal file
@@ -0,0 +1,41 @@
|
||||
"""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', Notification.NOTIFICATIONS_REFRESH_TIME_DEFAULT)
|
||||
if (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/$', views.notification_list, name='list'),
|
||||
url(r'^notifications/(\w+)/$', views.notification_view, name='view'),
|
||||
url(
|
||||
r'^user_notifications_count/(?P<user_pk>\d+)/$',
|
||||
views.user_notifications_count,
|
||||
name='user_notifications_count'
|
||||
),
|
||||
]
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
from django.shortcuts import render, get_object_or_404, redirect
|
||||
from .models import Notification
|
||||
import logging
|
||||
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.contrib import messages
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
import logging
|
||||
from django.http import JsonResponse
|
||||
from django.shortcuts import render, get_object_or_404, redirect
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from .models import Notification
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -11,9 +14,15 @@ logger = logging.getLogger(__name__)
|
||||
@login_required
|
||||
def notification_list(request):
|
||||
logger.debug("notification_list called by user %s" % request.user)
|
||||
new_notifs = Notification.objects.filter(user=request.user).filter(viewed=False)
|
||||
old_notifs = Notification.objects.filter(user=request.user).filter(viewed=True)
|
||||
logger.debug("User %s has %s unread and %s read notifications" % (request.user, len(new_notifs), len(old_notifs)))
|
||||
notifications_qs = Notification.objects.filter(user=request.user).order_by("-timestamp")
|
||||
new_notifs = notifications_qs.filter(viewed=False)
|
||||
old_notifs = notifications_qs.filter(viewed=True)
|
||||
logger.debug(
|
||||
"User %s has %s unread and %s read notifications",
|
||||
request.user,
|
||||
len(new_notifs),
|
||||
len(old_notifs)
|
||||
)
|
||||
context = {
|
||||
'read': old_notifs,
|
||||
'unread': new_notifs,
|
||||
@@ -23,39 +32,53 @@ def notification_list(request):
|
||||
|
||||
@login_required
|
||||
def notification_view(request, notif_id):
|
||||
logger.debug("notification_view called by user %s for notif_id %s" % (request.user, notif_id))
|
||||
logger.debug(
|
||||
"notification_view called by user %s for notif_id %s",
|
||||
request.user,
|
||||
notif_id
|
||||
)
|
||||
notif = get_object_or_404(Notification, pk=notif_id)
|
||||
if notif.user == request.user:
|
||||
logger.debug("Providing notification for user %s" % request.user)
|
||||
logger.debug("Providing notification for user %s", request.user)
|
||||
context = {'notif': notif}
|
||||
notif.view()
|
||||
notif.mark_viewed()
|
||||
return render(request, 'notifications/view.html', context)
|
||||
else:
|
||||
logger.warn(
|
||||
"User %s not authorized to view notif_id %s belonging to user %s" % (request.user, notif_id, notif.user))
|
||||
"User %s not authorized to view notif_id %s belonging to user %s",
|
||||
request.user,
|
||||
notif_id, notif.user
|
||||
)
|
||||
messages.error(request, _('You are not authorized to view that notification.'))
|
||||
return redirect('notifications:list')
|
||||
|
||||
|
||||
@login_required
|
||||
def remove_notification(request, notif_id):
|
||||
logger.debug("remove notification called by user %s for notif_id %s" % (request.user, notif_id))
|
||||
logger.debug(
|
||||
"remove notification called by user %s for notif_id %s",
|
||||
request.user,
|
||||
notif_id
|
||||
)
|
||||
notif = get_object_or_404(Notification, pk=notif_id)
|
||||
if notif.user == request.user:
|
||||
if Notification.objects.filter(id=notif_id).exists():
|
||||
notif.delete()
|
||||
logger.info("Deleting notif id %s by user %s" % (notif_id, request.user))
|
||||
logger.info("Deleting notif id %s by user %s", notif_id, request.user)
|
||||
messages.success(request, _('Deleted notification.'))
|
||||
else:
|
||||
logger.error(
|
||||
"Unable to delete notif id %s for user %s - notif matching id not found." % (notif_id, request.user))
|
||||
"Unable to delete notif id %s for user %s - notif matching id not found.",
|
||||
notif_id,
|
||||
request.user
|
||||
)
|
||||
messages.error(request, _('Failed to locate notification.'))
|
||||
return redirect('notifications:list')
|
||||
|
||||
|
||||
@login_required
|
||||
def mark_all_read(request):
|
||||
logger.debug('mark all notifications read called by user %s' % request.user)
|
||||
logger.debug('mark all notifications read called by user %s', request.user)
|
||||
Notification.objects.filter(user=request.user).update(viewed=True)
|
||||
messages.success(request, _('Marked all notifications as read.'))
|
||||
return redirect('notifications:list')
|
||||
@@ -63,7 +86,17 @@ def mark_all_read(request):
|
||||
|
||||
@login_required
|
||||
def delete_all_read(request):
|
||||
logger.debug('delete all read notifications called by user %s' % request.user)
|
||||
logger.debug('delete all read notifications called by user %s', request.user)
|
||||
Notification.objects.filter(user=request.user).filter(viewed=True).delete()
|
||||
messages.success(request, _('Deleted all read notifications.'))
|
||||
return redirect('notifications:list')
|
||||
|
||||
|
||||
def user_notifications_count(request, user_pk: int):
|
||||
"""returns to notifications count for the give user as JSON
|
||||
|
||||
This view is public and does not require login
|
||||
"""
|
||||
unread_count = Notification.objects.user_unread_count(user_pk)
|
||||
data = {'unread_count': unread_count}
|
||||
return JsonResponse(data, safe=False)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% extends "allianceauth/base.html" %}
|
||||
{% load bootstrap %}
|
||||
{% load staticfiles %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
{% get_current_language as LANGUAGE_CODE %}
|
||||
|
||||
@@ -34,17 +34,15 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_script %}
|
||||
|
||||
$('#id_start').datetimepicker({
|
||||
setlocale: '{{ LANGUAGE_CODE }}',
|
||||
{% if NIGHT_MODE %}
|
||||
theme: 'dark',
|
||||
{% else %}
|
||||
theme: 'default',
|
||||
{% endif %}
|
||||
mask: true,
|
||||
format: 'Y-m-d H:i',
|
||||
minDate: 0
|
||||
setlocale: '{{ LANGUAGE_CODE }}',
|
||||
{% if NIGHT_MODE %}
|
||||
theme: 'dark',
|
||||
{% else %}
|
||||
theme: 'default',
|
||||
{% endif %}
|
||||
mask: true,
|
||||
format: 'Y-m-d H:i',
|
||||
minDate: 0
|
||||
});
|
||||
|
||||
{% endblock extra_script %}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{% extends "allianceauth/base.html" %}
|
||||
{% load staticfiles %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
{% get_current_language as LANGUAGE_CODE %}
|
||||
|
||||
@@ -41,9 +41,10 @@
|
||||
|
||||
{% include 'bundles/moment-js.html' with locale=True %}
|
||||
<script src="{% static 'js/timers.js' %}"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
// Data
|
||||
var timers = [
|
||||
let timers = [
|
||||
{% for op in optimer %}
|
||||
{
|
||||
'id': {{ op.id }},
|
||||
@@ -52,67 +53,66 @@
|
||||
},
|
||||
{% endfor %}
|
||||
];
|
||||
</script>
|
||||
<script type="application/javascript">
|
||||
|
||||
timedUpdate();
|
||||
setAllLocalTimes();
|
||||
|
||||
// Start timed updates
|
||||
setInterval(timedUpdate, 1000);
|
||||
|
||||
function timedUpdate() {
|
||||
updateClock();
|
||||
updateAllTimers();
|
||||
}
|
||||
|
||||
function updateAllTimers () {
|
||||
var l = timers.length;
|
||||
for (var i=0; i < l; ++i) {
|
||||
if (timers[i].expired) continue;
|
||||
updateTimer(timers[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a timer
|
||||
* @param timer Timer information
|
||||
* @param timer.start Date of the timer
|
||||
* @param timer.id Id number of the timer
|
||||
* @param timer.expired
|
||||
*/
|
||||
function updateTimer(timer) {
|
||||
let updateTimer = function (timer) {
|
||||
if (timer.start.isAfter(Date.now())) {
|
||||
var duration = moment.duration(timer.start - moment(), 'milliseconds');
|
||||
let duration = moment.duration(timer.start - moment(), 'milliseconds');
|
||||
|
||||
document.getElementById("countdown" + timer.id).innerHTML = getDurationString(duration);
|
||||
} else {
|
||||
timer.expired = true;
|
||||
|
||||
document.getElementById("countdown" + timer.id).innerHTML = "";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let updateAllTimers = function () {
|
||||
let l = timers.length;
|
||||
|
||||
/**
|
||||
* Set all local time fields
|
||||
*/
|
||||
function setAllLocalTimes() {
|
||||
var l = timers.length;
|
||||
for (var i=0; i < l; ++i) {
|
||||
setLocalTime(timers[i]);
|
||||
if (timers[i].expired) continue;
|
||||
|
||||
updateTimer(timers[i]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the local time info for the timer
|
||||
* @param timer Timer information
|
||||
* @param timer.start Date of the timer
|
||||
* @param timer.id Id number of the timer
|
||||
*/
|
||||
function setLocalTime(timer) {
|
||||
let setLocalTime = function (timer) {
|
||||
document.getElementById("localtime" + timer.id).innerHTML = timer.start.format("ddd @ LT");
|
||||
}
|
||||
};
|
||||
|
||||
function updateClock() {
|
||||
/**
|
||||
* Set all local time fields
|
||||
*/
|
||||
let setAllLocalTimes = function () {
|
||||
let l = timers.length;
|
||||
|
||||
for (var i=0; i < l; ++i) {
|
||||
setLocalTime(timers[i]);
|
||||
}
|
||||
};
|
||||
|
||||
let updateClock = function () {
|
||||
document.getElementById("current-time").innerHTML = getCurrentEveTimeString();
|
||||
}
|
||||
};
|
||||
|
||||
let timedUpdate = function () {
|
||||
updateClock();
|
||||
updateAllTimers();
|
||||
};
|
||||
|
||||
// Set initial values
|
||||
setAllLocalTimes();
|
||||
timedUpdate();
|
||||
|
||||
// Start timed updates
|
||||
setInterval(timedUpdate, 1000);
|
||||
</script>
|
||||
{% endblock content %}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% extends "allianceauth/base.html" %}
|
||||
{% load bootstrap %}
|
||||
{% load staticfiles %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
{% get_current_language as LANGUAGE_CODE %}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% extends "allianceauth/base.html" %}
|
||||
{% load bootstrap %}
|
||||
{% load staticfiles %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block page_title %}{{ permission.permission.codename }} - {% trans "Permissions Audit" %}{% endblock page_title %}
|
||||
@@ -24,7 +24,7 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for user in permission.users %}
|
||||
{% for user in permission.users %}
|
||||
{% include 'permissions_tool/audit_row.html' with type="User" name="Permission granted directlty" %}
|
||||
{% endfor %}
|
||||
{% for group in permission.groups %}
|
||||
@@ -35,13 +35,13 @@
|
||||
{% for state in permission.states %}
|
||||
{% for profile in state.userprofile_set.all %}
|
||||
{% with profile.user as user %}
|
||||
{% include 'permissions_tool/audit_row.html' with type="State" name=state%}
|
||||
{% include 'permissions_tool/audit_row.html' with type="State" name=state%}
|
||||
{% endwith %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock content %}
|
||||
|
||||
@@ -56,15 +56,16 @@
|
||||
|
||||
{% block extra_script %}
|
||||
$(document).ready(function() {
|
||||
var groupColumn = 0;
|
||||
var table = $('#tab_permissions_audit').DataTable({
|
||||
let groupColumn = 0;
|
||||
|
||||
$('#tab_permissions_audit').DataTable({
|
||||
columnDefs: [
|
||||
{ "visible": false, "targets": groupColumn }
|
||||
],
|
||||
order: [[ groupColumn, 'asc' ], [ 2, 'asc' ] ],
|
||||
filterDropDown:
|
||||
{
|
||||
columns: [
|
||||
columns: [
|
||||
{
|
||||
idx: 0,
|
||||
title: 'Source'
|
||||
@@ -73,20 +74,20 @@
|
||||
bootstrap: true
|
||||
},
|
||||
drawCallback: function ( settings ) {
|
||||
var api = this.api();
|
||||
var rows = api.rows( {page:'current'} ).nodes();
|
||||
var last=null;
|
||||
|
||||
let api = this.api();
|
||||
let rows = api.rows( {page:'current'} ).nodes();
|
||||
let last = null;
|
||||
|
||||
api.column(groupColumn, {page:'current'} ).data().each( function ( group, i ) {
|
||||
if ( last !== group ) {
|
||||
$(rows).eq( i ).before(
|
||||
'<tr class="tr-group"><td colspan="3">' + group + '</td></tr>'
|
||||
);
|
||||
|
||||
|
||||
last = group;
|
||||
}
|
||||
} );
|
||||
}
|
||||
} );
|
||||
} );
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% extends "allianceauth/base.html" %}
|
||||
{% load bootstrap %}
|
||||
{% load staticfiles %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block page_title %}{% trans "Permissions Overview" %}{% endblock page_title %}
|
||||
@@ -9,9 +9,9 @@
|
||||
<div class="col-sm-12">
|
||||
<h1 class="page-header">{% trans "Permissions Overview" %}</h1>
|
||||
<p>
|
||||
{% if request.GET.all != 'yes' %}
|
||||
{% if request.GET.all != 'yes' %}
|
||||
{% blocktrans %}Showing only applied permissions{% endblocktrans %}
|
||||
<a href="{% url 'permissions_tool:overview' %}?all=yes" class="btn btn-primary">{% trans "Show All" %}</a>
|
||||
<a href="{% url 'permissions_tool:overview' %}?all=yes" class="btn btn-primary">{% trans "Show All" %}</a>
|
||||
{% else %}
|
||||
{% blocktrans %}Showing all permissions{% endblocktrans %}
|
||||
<a href="{% url 'permissions_tool:overview' %}?all=no" class="btn btn-primary">{% trans "Show Applied" %}</a>
|
||||
@@ -79,7 +79,7 @@
|
||||
{% endblock content %}
|
||||
|
||||
{% block extra_javascript %}
|
||||
{% include 'bundles/datatables-js.html' %}
|
||||
{% include 'bundles/datatables-js.html' %}
|
||||
<script type="application/javascript" src="{% static 'js/filterDropDown/filterDropDown.min.js' %}"></script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -89,15 +89,16 @@
|
||||
|
||||
{% block extra_script %}
|
||||
$(document).ready(function() {
|
||||
var groupColumn = 0;
|
||||
var table = $('#tab_permissions_overview').DataTable({
|
||||
let groupColumn = 0;
|
||||
|
||||
$('#tab_permissions_overview').DataTable({
|
||||
columnDefs: [
|
||||
{ "visible": false, "targets": groupColumn }
|
||||
],
|
||||
order: [[ groupColumn, 'asc' ], [ 1, 'asc' ], [ 2, 'asc' ] ],
|
||||
filterDropDown:
|
||||
{
|
||||
columns: [
|
||||
columns: [
|
||||
{
|
||||
idx: 0
|
||||
},
|
||||
@@ -108,20 +109,20 @@
|
||||
bootstrap: true
|
||||
},
|
||||
drawCallback: function ( settings ) {
|
||||
var api = this.api();
|
||||
var rows = api.rows( {page:'current'} ).nodes();
|
||||
var last=null;
|
||||
|
||||
let api = this.api();
|
||||
let rows = api.rows( {page:'current'} ).nodes();
|
||||
let last = null;
|
||||
|
||||
api.column(groupColumn, {page:'current'} ).data().each( function ( group, i ) {
|
||||
if ( last !== group ) {
|
||||
$(rows).eq( i ).before(
|
||||
'<tr class="tr-group"><td colspan="6">' + group + '</td></tr>'
|
||||
);
|
||||
|
||||
|
||||
last = group;
|
||||
}
|
||||
} );
|
||||
}
|
||||
} );
|
||||
} );
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import os
|
||||
from celery import Celery
|
||||
from celery.app import trace
|
||||
|
||||
# set the default Django settings module for the 'celery' program.
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', '{{ project_name }}.settings.local')
|
||||
@@ -27,3 +28,6 @@ app.conf.ONCE = {
|
||||
|
||||
# Load task modules from all registered Django app configs.
|
||||
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
|
||||
|
||||
# Remove result from default log message on task success
|
||||
trace.LOG_SUCCESS = "Task %(name)s[%(id)s] succeeded in %(runtime)ss"
|
||||
|
||||
@@ -64,12 +64,12 @@ BASE_DIR = os.path.dirname(PROJECT_DIR)
|
||||
MIDDLEWARE = [
|
||||
'django.middleware.security.SecurityMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
'django.middleware.locale.LocaleMiddleware',
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
'django.middleware.csrf.CsrfViewMiddleware',
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
'django.contrib.messages.middleware.MessageMiddleware',
|
||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||
'django.middleware.locale.LocaleMiddleware',
|
||||
]
|
||||
|
||||
ROOT_URLCONF = 'allianceauth.urls'
|
||||
@@ -86,6 +86,8 @@ LANGUAGES = (
|
||||
('zh-hans', ugettext('Chinese Simplified')),
|
||||
('ru', ugettext('Russian')),
|
||||
('ko', ugettext('Korean')),
|
||||
('fr', ugettext('French')),
|
||||
('ja', ugettext('Japanese')),
|
||||
)
|
||||
|
||||
TEMPLATES = [
|
||||
@@ -102,8 +104,7 @@ TEMPLATES = [
|
||||
'django.template.context_processors.i18n',
|
||||
'django.template.context_processors.media',
|
||||
'django.template.context_processors.static',
|
||||
'django.template.context_processors.tz',
|
||||
'allianceauth.notifications.context_processors.user_notification_count',
|
||||
'django.template.context_processors.tz',
|
||||
'allianceauth.context_processors.auth_settings',
|
||||
],
|
||||
},
|
||||
@@ -138,6 +139,8 @@ AUTHENTICATION_BACKENDS = ['allianceauth.authentication.backends.StateBackend',
|
||||
|
||||
LANGUAGE_CODE = 'en-us'
|
||||
|
||||
LANGUAGE_COOKIE_AGE = 1209600
|
||||
|
||||
TIME_ZONE = 'UTC'
|
||||
|
||||
USE_I18N = True
|
||||
@@ -169,6 +172,8 @@ CACHES = {
|
||||
}
|
||||
}
|
||||
|
||||
SESSION_ENGINE = "django.contrib.sessions.backends.cached_db"
|
||||
|
||||
DEBUG = True
|
||||
ALLOWED_HOSTS = ['*']
|
||||
DATABASES = {
|
||||
@@ -257,3 +262,5 @@ LOGGING = {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
DEFAULT_AUTO_FIELD = "django.db.models.AutoField"
|
||||
|
||||
@@ -45,6 +45,7 @@ DATABASES['default'] = {
|
||||
ESI_SSO_CLIENT_ID = ''
|
||||
ESI_SSO_CLIENT_SECRET = ''
|
||||
ESI_SSO_CALLBACK_URL = ''
|
||||
ESI_USER_CONTACT_EMAIL = '' # A server maintainer that CCP can contact in case of issues.
|
||||
|
||||
# By default emails are validated before new users can log in.
|
||||
# It's recommended to use a free service like SparkPost or Elastic Email to send email.
|
||||
|
||||
@@ -211,6 +211,7 @@ class DiscordUser(models.Model):
|
||||
Return None if user does no longer exist
|
||||
"""
|
||||
try:
|
||||
_user = self.user
|
||||
client = DiscordUser.objects._bot_client(is_rate_limited=is_rate_limited)
|
||||
success = client.remove_guild_member(
|
||||
guild_id=DISCORD_GUILD_ID, user_id=self.uid
|
||||
@@ -220,31 +221,31 @@ class DiscordUser(models.Model):
|
||||
if deleted_count > 0:
|
||||
if notify_user:
|
||||
notify(
|
||||
user=self.user,
|
||||
user=_user,
|
||||
title=gettext_lazy('Discord Account Disabled'),
|
||||
message=gettext_lazy(
|
||||
'Your Discord account was disabeled automatically '
|
||||
'Your Discord account was disabled automatically '
|
||||
'by Auth. If you think this was a mistake, '
|
||||
'please contact an admin.'
|
||||
),
|
||||
level='warning'
|
||||
)
|
||||
logger.info('Account for user %s was deleted.', self.user)
|
||||
logger.info('Account for user %s was deleted.', _user)
|
||||
return True
|
||||
else:
|
||||
logger.debug('Account for user %s was already deleted.', self.user)
|
||||
logger.debug('Account for user %s was already deleted.', _user)
|
||||
return None
|
||||
|
||||
else:
|
||||
logger.warning(
|
||||
'Failed to remove user %s from the Discord server', self.user
|
||||
'Failed to remove user %s from the Discord server', _user
|
||||
)
|
||||
return False
|
||||
|
||||
except (HTTPError, ConnectionError, DiscordApiBackoff) as ex:
|
||||
if handle_api_exceptions:
|
||||
logger.exception(
|
||||
'Failed to remove user %s from Discord server: %s', self.user, ex
|
||||
'Failed to remove user %s from Discord server: %s',self.user, ex
|
||||
)
|
||||
return False
|
||||
else:
|
||||
|
||||
@@ -12,20 +12,12 @@ import base64
|
||||
import hmac
|
||||
import hashlib
|
||||
|
||||
try:
|
||||
from urllib import unquote, urlencode
|
||||
except ImportError: #py3
|
||||
from urllib.parse import unquote, urlencode
|
||||
try:
|
||||
from urlparse import parse_qs
|
||||
except ImportError: #py3
|
||||
from urllib.parse import parse_qs
|
||||
from urllib.parse import unquote, urlencode, parse_qs
|
||||
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
ACCESS_PERM = 'discourse.access_discourse'
|
||||
|
||||
|
||||
@@ -55,7 +47,7 @@ def discourse_sso(request):
|
||||
# Validate the payload
|
||||
try:
|
||||
payload = unquote(payload).encode('utf-8')
|
||||
decoded = base64.decodestring(payload).decode('utf-8')
|
||||
decoded = base64.decodebytes(payload).decode('utf-8')
|
||||
assert 'nonce' in decoded
|
||||
assert len(payload) > 0
|
||||
except AssertionError:
|
||||
@@ -86,7 +78,7 @@ def discourse_sso(request):
|
||||
if main_char:
|
||||
params['avatar_url'] = main_char.portrait_url(256)
|
||||
|
||||
return_payload = base64.encodestring(urlencode(params).encode('utf-8'))
|
||||
return_payload = base64.encodebytes(urlencode(params).encode('utf-8'))
|
||||
h = hmac.new(key, return_payload, digestmod=hashlib.sha256)
|
||||
query_string = urlencode({'sso': return_payload, 'sig': h.hexdigest()})
|
||||
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
# Generated by Django 3.1.2 on 2021-01-08 13:54
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.migrations.operations.special
|
||||
import django.db.models.deletion
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
replaces = [('mumble', '0001_initial'), ('mumble', '0002_auto_20161212_0100'), ('mumble', '0003_mumbleuser_user'), ('mumble', '0004_auto_20161214_1024'), ('mumble', '0005_mumbleuser_hashfn'), ('mumble', '0006_service_permissions'), ('mumble', '0007_not_null_user'), ('mumble', '0008_mumbleuser_display_name'), ('mumble', '0009_set_mumble_dissplay_names'), ('mumble', '0010_mumbleuser_certhash'), ('mumble', '0011_auto_20201011_1009')]
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='MumbleUser',
|
||||
fields=[
|
||||
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, primary_key=True, related_name='mumble', serialize=False, to=settings.AUTH_USER_MODEL)),
|
||||
('username', models.CharField(max_length=254, unique=True)),
|
||||
('pwhash', models.CharField(max_length=40)),
|
||||
('groups', models.TextField(blank=True, null=True)),
|
||||
],
|
||||
options={
|
||||
'db_table': 'services_mumbleuser',
|
||||
},
|
||||
),
|
||||
migrations.AlterModelTable(
|
||||
name='mumbleuser',
|
||||
table=None,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='mumbleuser',
|
||||
name='hashfn',
|
||||
field=models.CharField(default='sha1', max_length=20),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='mumbleuser',
|
||||
name='pwhash',
|
||||
field=models.CharField(max_length=80),
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='mumbleuser',
|
||||
options={'permissions': (('access_mumble', 'Can access the Mumble service'),)},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='mumbleuser',
|
||||
name='display_name',
|
||||
field=models.CharField(max_length=254, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='mumbleuser',
|
||||
name='display_name',
|
||||
field=models.CharField(max_length=254, unique=True),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='mumbleuser',
|
||||
name='certhash',
|
||||
field=models.CharField(blank=True, editable=False, help_text='Hash of Mumble client certificate as presented when user authenticates', max_length=254, null=True, verbose_name='Certificate Hash'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='mumbleuser',
|
||||
name='pwhash',
|
||||
field=models.CharField(max_length=90),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 3.1.2 on 2020-10-11 10:09
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('mumble', '0010_mumbleuser_certhash'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='mumbleuser',
|
||||
name='pwhash',
|
||||
field=models.CharField(max_length=90),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,33 @@
|
||||
# Generated by Django 3.1.6 on 2021-03-23 13:10
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('mumble', '0001_squashed_0011_auto_20201011_1009'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='mumbleuser',
|
||||
name='last_connect',
|
||||
field=models.DateTimeField(blank=True, editable=False, help_text='Timestamp of the users Last Connection to Mumble', max_length=254, null=True, verbose_name='Last Connection'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='mumbleuser',
|
||||
name='last_disconnect',
|
||||
field=models.DateTimeField(blank=True, editable=False, help_text='Timestamp of the users Last Disconnection to Mumble', max_length=254, null=True, verbose_name='Last Disconnection'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='mumbleuser',
|
||||
name='release',
|
||||
field=models.TextField(blank=True, editable=False, help_text='The Mumble Release the user last authenticated with', max_length=254, null=True, verbose_name='Mumble Release'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='mumbleuser',
|
||||
name='version',
|
||||
field=models.IntegerField(blank=True, editable=False, help_text='Client version. Major version in upper 16 bits, followed by 8 bits of minor version and 8 bits of patchlevel. Version 1.2.3 = 0x010203.', null=True, verbose_name='Mumble Version'),
|
||||
),
|
||||
]
|
||||
@@ -63,7 +63,7 @@ class MumbleManager(models.Manager):
|
||||
|
||||
class MumbleUser(AbstractServiceModel):
|
||||
username = models.CharField(max_length=254, unique=True)
|
||||
pwhash = models.CharField(max_length=80)
|
||||
pwhash = models.CharField(max_length=90)
|
||||
hashfn = models.CharField(max_length=20, default='sha1')
|
||||
groups = models.TextField(blank=True, null=True)
|
||||
certhash = models.CharField(
|
||||
@@ -74,7 +74,41 @@ class MumbleUser(AbstractServiceModel):
|
||||
editable=False,
|
||||
help_text="Hash of Mumble client certificate as presented when user authenticates"
|
||||
)
|
||||
display_name = models.CharField(max_length=254, unique=True)
|
||||
display_name = models.CharField(
|
||||
max_length=254,
|
||||
unique=True
|
||||
)
|
||||
release = models.TextField(
|
||||
verbose_name="Mumble Release",
|
||||
max_length=254,
|
||||
blank=True,
|
||||
null=True,
|
||||
editable=False,
|
||||
help_text="The Mumble Release the user last authenticated with"
|
||||
)
|
||||
version = models.IntegerField(
|
||||
verbose_name="Mumble Version",
|
||||
blank=True,
|
||||
null=True,
|
||||
editable=False,
|
||||
help_text="Client version. Major version in upper 16 bits, followed by 8 bits of minor version and 8 bits of patchlevel. Version 1.2.3 = 0x010203."
|
||||
)
|
||||
last_connect = models.DateTimeField(
|
||||
verbose_name="Last Connection",
|
||||
max_length=254,
|
||||
blank=True,
|
||||
null=True,
|
||||
editable=False,
|
||||
help_text="Timestamp of the users Last Connection to Mumble"
|
||||
)
|
||||
last_disconnect = models.DateTimeField(
|
||||
verbose_name="Last Disconnection",
|
||||
max_length=254,
|
||||
blank=True,
|
||||
null=True,
|
||||
editable=False,
|
||||
help_text="Timestamp of the users Last Disconnection to Mumble"
|
||||
)
|
||||
|
||||
objects = MumbleManager()
|
||||
|
||||
|
||||
@@ -211,4 +211,4 @@ class MumbleManagerTestCase(TestCase):
|
||||
pwhash = self.manager.gen_pwhash('test')
|
||||
|
||||
self.assertEqual(pwhash[:15], '$bcrypt-sha256$')
|
||||
self.assertEqual(len(pwhash), 75)
|
||||
self.assertEqual(len(pwhash), 83)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% extends "allianceauth/base.html" %}
|
||||
{% load bootstrap %}
|
||||
{% load staticfiles %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block page_title %}{% trans "Jabber Broadcast" %}{% endblock page_title %}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% extends "allianceauth/base.html" %}
|
||||
{% load bootstrap %}
|
||||
{% load staticfiles %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block page_title %}{% trans "Verify Teamspeak" %}{% endblock page_title %}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% extends "allianceauth/base.html" %}
|
||||
{% load bootstrap %}
|
||||
{% load staticfiles %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block page_title %}{% trans "Fleet Formatter Tool" %}{% endblock page_title %}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{% extends "allianceauth/base.html" %}
|
||||
{% load staticfiles %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block page_title %}{% blocktrans with service_name=view.service_name|title %}{{ service_name }} Credentials{% endblocktrans %}{% endblock page_title %}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user