mirror of
https://gitlab.com/allianceauth/allianceauth.git
synced 2026-02-05 14:46:20 +01:00
Compare commits
100 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 |
@@ -1,54 +1,94 @@
|
|||||||
stages:
|
stages:
|
||||||
|
- gitlab
|
||||||
- test
|
- test
|
||||||
- deploy
|
- deploy
|
||||||
|
|
||||||
before_script:
|
include:
|
||||||
- apt-get update && apt-get install redis-server -y
|
- template: Dependency-Scanning.gitlab-ci.yml
|
||||||
- redis-server --daemonize yes
|
- template: Security/SAST.gitlab-ci.yml
|
||||||
- redis-cli ping
|
|
||||||
- python -V
|
|
||||||
- pip install wheel tox
|
|
||||||
|
|
||||||
test-3.6-core:
|
before_script:
|
||||||
image: python:3.6-buster
|
- apt-get update && apt-get install redis-server -y
|
||||||
script:
|
- redis-server --daemonize yes
|
||||||
- tox -e py36-core
|
- 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:
|
test-3.7-core:
|
||||||
image: python:3.7-buster
|
image: python:3.7-buster
|
||||||
script:
|
script:
|
||||||
- tox -e py37-core
|
- tox -e py37-core
|
||||||
|
artifacts:
|
||||||
|
when: always
|
||||||
|
reports:
|
||||||
|
cobertura: coverage.xml
|
||||||
|
|
||||||
test-3.8-core:
|
test-3.8-core:
|
||||||
image: python:3.8-buster
|
image: python:3.8-buster
|
||||||
script:
|
script:
|
||||||
- tox -e py38-core
|
- tox -e py38-core
|
||||||
|
artifacts:
|
||||||
|
when: always
|
||||||
|
reports:
|
||||||
|
cobertura: coverage.xml
|
||||||
|
|
||||||
test-3.6-all:
|
test-3.9-core:
|
||||||
image: python:3.6-buster
|
image: python:3.9-buster
|
||||||
script:
|
script:
|
||||||
- tox -e py36-all
|
- tox -e py39-core
|
||||||
|
artifacts:
|
||||||
|
when: always
|
||||||
|
reports:
|
||||||
|
cobertura: coverage.xml
|
||||||
|
|
||||||
test-3.7-all:
|
test-3.7-all:
|
||||||
image: python:3.7-buster
|
image: python:3.7-buster
|
||||||
script:
|
script:
|
||||||
- tox -e py37-all
|
- tox -e py37-all
|
||||||
|
artifacts:
|
||||||
|
when: always
|
||||||
|
reports:
|
||||||
|
cobertura: coverage.xml
|
||||||
|
|
||||||
test-3.8-all:
|
test-3.8-all:
|
||||||
image: python:3.8-buster
|
image: python:3.8-buster
|
||||||
script:
|
script:
|
||||||
- tox -e py38-all
|
- 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:
|
deploy_production:
|
||||||
stage: deploy
|
stage: deploy
|
||||||
image: python:3.8-buster
|
image: python:3.9-buster
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
- pip install twine
|
- pip install twine wheel
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- python setup.py sdist
|
- python setup.py sdist bdist_wheel
|
||||||
- twine upload dist/*
|
- twine upload dist/*
|
||||||
|
|
||||||
rules:
|
rules:
|
||||||
- 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
|
# Optionally set the version of Python and requirements required to build your docs
|
||||||
python:
|
python:
|
||||||
version: 3.7
|
version: 3.7
|
||||||
install:
|
install:
|
||||||
- method: pip
|
- requirements: docs/requirements.txt
|
||||||
path: .
|
|
||||||
extra_requirements:
|
|
||||||
- testing
|
|
||||||
system_packages: true
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
# This will make sure the app is always imported when
|
# This will make sure the app is always imported when
|
||||||
# Django starts so that shared_task will use this app.
|
# Django starts so that shared_task will use this app.
|
||||||
|
|
||||||
__version__ = '2.8.0'
|
__version__ = '2.9.0a2'
|
||||||
__title__ = 'Alliance Auth'
|
__title__ = 'Alliance Auth'
|
||||||
__url__ = 'https://gitlab.com/allianceauth/allianceauth'
|
__url__ = 'https://gitlab.com/allianceauth/allianceauth'
|
||||||
NAME = '%s v%s' % (__title__, __version__)
|
NAME = '%s v%s' % (__title__, __version__)
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
from django.conf import settings
|
|
||||||
|
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
|
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
|
||||||
from django.contrib.auth.models import User as BaseUser, \
|
from django.contrib.auth.models import User as BaseUser, \
|
||||||
Permission as BasePermission, Group
|
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 allianceauth.services.hooks import ServicesHook
|
||||||
from django.db.models.signals import pre_save, post_save, pre_delete, \
|
from django.db.models.signals import pre_save, post_save, pre_delete, \
|
||||||
post_delete, m2m_changed
|
post_delete, m2m_changed
|
||||||
@@ -24,11 +22,6 @@ from allianceauth.eveonline.tasks import update_character
|
|||||||
from .app_settings import AUTHENTICATION_ADMIN_USERS_MAX_GROUPS, \
|
from .app_settings import AUTHENTICATION_ADMIN_USERS_MAX_GROUPS, \
|
||||||
AUTHENTICATION_ADMIN_USERS_MAX_CHARS
|
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):
|
def make_service_hooks_update_groups_action(service):
|
||||||
"""
|
"""
|
||||||
@@ -91,8 +84,7 @@ class UserProfileInline(admin.StackedInline):
|
|||||||
if request.user.is_superuser:
|
if request.user.is_superuser:
|
||||||
query |= Q(userprofile__isnull=True)
|
query |= Q(userprofile__isnull=True)
|
||||||
else:
|
else:
|
||||||
query |= Q(character_ownership__user=obj)
|
query |= Q(character_ownership__user=obj)
|
||||||
qs = EveCharacter.objects.filter(query)
|
|
||||||
formset = super().get_formset(request, obj=obj, **kwargs)
|
formset = super().get_formset(request, obj=obj, **kwargs)
|
||||||
|
|
||||||
def get_kwargs(self, index):
|
def get_kwargs(self, index):
|
||||||
@@ -121,6 +113,8 @@ def user_profile_pic(obj):
|
|||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
user_profile_pic.short_description = ''
|
user_profile_pic.short_description = ''
|
||||||
|
|
||||||
|
|
||||||
@@ -152,6 +146,7 @@ def user_username(obj):
|
|||||||
user_obj.username,
|
user_obj.username,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
user_username.short_description = 'user / main'
|
user_username.short_description = 'user / main'
|
||||||
user_username.admin_order_field = 'username'
|
user_username.admin_order_field = 'username'
|
||||||
|
|
||||||
@@ -168,7 +163,8 @@ def user_main_organization(obj):
|
|||||||
else:
|
else:
|
||||||
corporation = user_obj.profile.main_character.corporation_name
|
corporation = user_obj.profile.main_character.corporation_name
|
||||||
if user_obj.profile.main_character.alliance_id:
|
if user_obj.profile.main_character.alliance_id:
|
||||||
result = format_html('{}<br>{}',
|
result = format_html(
|
||||||
|
'{}<br>{}',
|
||||||
corporation,
|
corporation,
|
||||||
user_obj.profile.main_character.alliance_name
|
user_obj.profile.main_character.alliance_name
|
||||||
)
|
)
|
||||||
@@ -176,6 +172,7 @@ def user_main_organization(obj):
|
|||||||
result = corporation
|
result = corporation
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
user_main_organization.short_description = 'Corporation / Alliance (Main)'
|
user_main_organization.short_description = 'Corporation / Alliance (Main)'
|
||||||
user_main_organization.admin_order_field = \
|
user_main_organization.admin_order_field = \
|
||||||
'profile__main_character__corporation_name'
|
'profile__main_character__corporation_name'
|
||||||
@@ -205,13 +202,13 @@ class MainCorporationsFilter(admin.SimpleListFilter):
|
|||||||
return qs.all()
|
return qs.all()
|
||||||
else:
|
else:
|
||||||
if qs.model == User:
|
if qs.model == User:
|
||||||
return qs\
|
return qs.filter(
|
||||||
.filter(profile__main_character__corporation_id=\
|
profile__main_character__corporation_id=self.value()
|
||||||
self.value())
|
)
|
||||||
else:
|
else:
|
||||||
return qs\
|
return qs.filter(
|
||||||
.filter(user__profile__main_character__corporation_id=\
|
user__profile__main_character__corporation_id=self.value()
|
||||||
self.value())
|
)
|
||||||
|
|
||||||
|
|
||||||
class MainAllianceFilter(admin.SimpleListFilter):
|
class MainAllianceFilter(admin.SimpleListFilter):
|
||||||
@@ -239,12 +236,11 @@ class MainAllianceFilter(admin.SimpleListFilter):
|
|||||||
return qs.all()
|
return qs.all()
|
||||||
else:
|
else:
|
||||||
if qs.model == User:
|
if qs.model == User:
|
||||||
return qs\
|
return qs.filter(profile__main_character__alliance_id=self.value())
|
||||||
.filter(profile__main_character__alliance_id=self.value())
|
|
||||||
else:
|
else:
|
||||||
return qs\
|
return qs.filter(
|
||||||
.filter(user__profile__main_character__alliance_id=\
|
user__profile__main_character__alliance_id=self.value()
|
||||||
self.value())
|
)
|
||||||
|
|
||||||
|
|
||||||
def update_main_character_model(modeladmin, request, queryset):
|
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 from ESI started for {} characters'.format(tasks_count)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
update_main_character_model.short_description = \
|
update_main_character_model.short_description = \
|
||||||
'Update main character model from ESI'
|
'Update main character model from ESI'
|
||||||
|
|
||||||
@@ -267,32 +264,16 @@ class UserAdmin(BaseUserAdmin):
|
|||||||
"""Extending Django's UserAdmin model
|
"""Extending Django's UserAdmin model
|
||||||
|
|
||||||
Behavior of groups and characters columns can be configured via settings
|
Behavior of groups and characters columns can be configured via settings
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
class Media:
|
class Media:
|
||||||
css = {
|
css = {
|
||||||
"all": ("authentication/css/admin.css",)
|
"all": ("authentication/css/admin.css",)
|
||||||
}
|
}
|
||||||
|
|
||||||
class RealGroupsFilter(admin.SimpleListFilter):
|
def get_queryset(self, request):
|
||||||
"""Custom filter to get groups w/o Autogroups"""
|
qs = super().get_queryset(request)
|
||||||
title = 'group'
|
return qs.prefetch_related("character_ownerships__character", "groups")
|
||||||
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_actions(self, request):
|
def get_actions(self, request):
|
||||||
actions = super(BaseUserAdmin, self).get_actions(request)
|
actions = super(BaseUserAdmin, self).get_actions(request)
|
||||||
@@ -341,11 +322,9 @@ class UserAdmin(BaseUserAdmin):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
inlines = BaseUserAdmin.inlines + [UserProfileInline]
|
inlines = BaseUserAdmin.inlines + [UserProfileInline]
|
||||||
|
ordering = ('username', )
|
||||||
ordering = ('username', )
|
list_select_related = ('profile__state', 'profile__main_character')
|
||||||
list_select_related = True
|
show_full_result_count = True
|
||||||
show_full_result_count = True
|
|
||||||
|
|
||||||
list_display = (
|
list_display = (
|
||||||
user_profile_pic,
|
user_profile_pic,
|
||||||
user_username,
|
user_username,
|
||||||
@@ -358,10 +337,9 @@ class UserAdmin(BaseUserAdmin):
|
|||||||
'_role'
|
'_role'
|
||||||
)
|
)
|
||||||
list_display_links = None
|
list_display_links = None
|
||||||
|
|
||||||
list_filter = (
|
list_filter = (
|
||||||
'profile__state',
|
'profile__state',
|
||||||
RealGroupsFilter,
|
'groups',
|
||||||
MainCorporationsFilter,
|
MainCorporationsFilter,
|
||||||
MainAllianceFilter,
|
MainAllianceFilter,
|
||||||
'is_active',
|
'is_active',
|
||||||
@@ -375,41 +353,25 @@ class UserAdmin(BaseUserAdmin):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def _characters(self, obj):
|
def _characters(self, obj):
|
||||||
my_characters = [
|
character_ownerships = list(obj.character_ownerships.all())
|
||||||
x.character.character_name
|
characters = [obj.character.character_name for obj in character_ownerships]
|
||||||
for x in CharacterOwnership.objects\
|
|
||||||
.filter(user=obj)\
|
|
||||||
.order_by('character__character_name')\
|
|
||||||
.select_related()
|
|
||||||
]
|
|
||||||
return self._list_2_html_w_tooltips(
|
return self._list_2_html_w_tooltips(
|
||||||
my_characters,
|
sorted(characters),
|
||||||
AUTHENTICATION_ADMIN_USERS_MAX_CHARS
|
AUTHENTICATION_ADMIN_USERS_MAX_CHARS
|
||||||
)
|
)
|
||||||
|
|
||||||
_characters.short_description = 'characters'
|
_characters.short_description = 'characters'
|
||||||
|
|
||||||
|
|
||||||
def _state(self, obj):
|
def _state(self, obj):
|
||||||
return obj.profile.state.name
|
return obj.profile.state.name
|
||||||
|
|
||||||
_state.short_description = 'state'
|
_state.short_description = 'state'
|
||||||
_state.admin_order_field = 'profile__state'
|
_state.admin_order_field = 'profile__state'
|
||||||
|
|
||||||
def _groups(self, obj):
|
def _groups(self, obj):
|
||||||
if not _has_auto_groups:
|
my_groups = sorted([group.name for group in list(obj.groups.all())])
|
||||||
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')
|
|
||||||
]
|
|
||||||
|
|
||||||
return self._list_2_html_w_tooltips(
|
return self._list_2_html_w_tooltips(
|
||||||
my_groups,
|
my_groups, AUTHENTICATION_ADMIN_USERS_MAX_GROUPS
|
||||||
AUTHENTICATION_ADMIN_USERS_MAX_GROUPS
|
|
||||||
)
|
)
|
||||||
|
|
||||||
_groups.short_description = 'groups'
|
_groups.short_description = 'groups'
|
||||||
@@ -446,9 +408,14 @@ class StateAdmin(admin.ModelAdmin):
|
|||||||
list_select_related = True
|
list_select_related = True
|
||||||
list_display = ('name', 'priority', '_user_count')
|
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):
|
def _user_count(self, obj):
|
||||||
return obj.userprofile_set.all().count()
|
return obj.user_count
|
||||||
_user_count.short_description = 'Users'
|
_user_count.short_description = 'Users'
|
||||||
|
_user_count.admin_order_field = 'user_count'
|
||||||
|
|
||||||
fieldsets = (
|
fieldsets = (
|
||||||
(None, {
|
(None, {
|
||||||
@@ -504,7 +471,8 @@ class BaseOwnershipAdmin(admin.ModelAdmin):
|
|||||||
"all": ("authentication/css/admin.css",)
|
"all": ("authentication/css/admin.css",)
|
||||||
}
|
}
|
||||||
|
|
||||||
list_select_related = True
|
list_select_related = (
|
||||||
|
'user__profile__state', 'user__profile__main_character', 'character')
|
||||||
list_display = (
|
list_display = (
|
||||||
user_profile_pic,
|
user_profile_pic,
|
||||||
user_username,
|
user_username,
|
||||||
@@ -542,6 +510,7 @@ class CharacterOwnershipAdmin(BaseOwnershipAdmin):
|
|||||||
class PermissionAdmin(admin.ModelAdmin):
|
class PermissionAdmin(admin.ModelAdmin):
|
||||||
actions = None
|
actions = None
|
||||||
readonly_fields = [field.name for field in BasePermission._meta.fields]
|
readonly_fields = [field.name for field in BasePermission._meta.fields]
|
||||||
|
search_fields = ('codename', )
|
||||||
list_display = ('admin_name', 'name', 'codename', 'content_type')
|
list_display = ('admin_name', 'name', 'codename', 'content_type')
|
||||||
list_filter = ('content_type__app_label',)
|
list_filter = ('content_type__app_label',)
|
||||||
|
|
||||||
|
|||||||
@@ -10,9 +10,10 @@ def get_admin_change_view_url(obj: object) -> str:
|
|||||||
args=(obj.pk,)
|
args=(obj.pk,)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_admin_search_url(ModelClass: type) -> str:
|
def get_admin_search_url(ModelClass: type) -> str:
|
||||||
"""returns URL to search URL for model of given object"""
|
"""returns URL to search URL for model of given object"""
|
||||||
return '{}{}/'.format(
|
return '{}{}/'.format(
|
||||||
reverse('admin:app_list', args=(ModelClass._meta.app_label,)),
|
reverse('admin:app_list', args=(ModelClass._meta.app_label,)),
|
||||||
ModelClass.__name__.lower()
|
ModelClass.__name__.lower()
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
from urllib.parse import quote
|
from urllib.parse import quote
|
||||||
from unittest.mock import patch, MagicMock
|
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.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 django.test import TestCase, RequestFactory, Client
|
||||||
|
|
||||||
from allianceauth.authentication.models import (
|
from allianceauth.authentication.models import (
|
||||||
@@ -18,8 +16,7 @@ from allianceauth.tests.auth_utils import AuthUtils
|
|||||||
|
|
||||||
from ..admin import (
|
from ..admin import (
|
||||||
BaseUserAdmin,
|
BaseUserAdmin,
|
||||||
CharacterOwnershipAdmin,
|
CharacterOwnershipAdmin,
|
||||||
PermissionAdmin,
|
|
||||||
StateAdmin,
|
StateAdmin,
|
||||||
MainCorporationsFilter,
|
MainCorporationsFilter,
|
||||||
MainAllianceFilter,
|
MainAllianceFilter,
|
||||||
@@ -35,11 +32,6 @@ from ..admin import (
|
|||||||
)
|
)
|
||||||
from . import get_admin_change_view_url, get_admin_search_url
|
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'
|
MODULE_PATH = 'allianceauth.authentication.admin'
|
||||||
|
|
||||||
@@ -48,6 +40,7 @@ class MockRequest(object):
|
|||||||
def __init__(self, user=None):
|
def __init__(self, user=None):
|
||||||
self.user = user
|
self.user = user
|
||||||
|
|
||||||
|
|
||||||
class TestCaseWithTestData(TestCase):
|
class TestCaseWithTestData(TestCase):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@@ -279,6 +272,7 @@ class TestStateAdmin(TestCaseWithTestData):
|
|||||||
expected = 200
|
expected = 200
|
||||||
self.assertEqual(response.status_code, expected)
|
self.assertEqual(response.status_code, expected)
|
||||||
|
|
||||||
|
|
||||||
class TestUserAdmin(TestCaseWithTestData):
|
class TestUserAdmin(TestCaseWithTestData):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
@@ -287,24 +281,12 @@ class TestUserAdmin(TestCaseWithTestData):
|
|||||||
model=User, admin_site=AdminSite()
|
model=User, admin_site=AdminSite()
|
||||||
)
|
)
|
||||||
self.character_1 = self.user_1.character_ownerships.first().character
|
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):
|
def test_user_profile_pic_u1(self):
|
||||||
expected = ('<img src="https://images.evetech.net/characters/1001/'
|
expected = (
|
||||||
'portrait?size=32" class="img-circle">')
|
'<img src="https://images.evetech.net/characters/1001/'
|
||||||
|
'portrait?size=32" class="img-circle">'
|
||||||
|
)
|
||||||
self.assertEqual(user_profile_pic(self.user_1), expected)
|
self.assertEqual(user_profile_pic(self.user_1), expected)
|
||||||
|
|
||||||
def test_user_profile_pic_u3(self):
|
def test_user_profile_pic_u3(self):
|
||||||
@@ -351,37 +333,17 @@ class TestUserAdmin(TestCaseWithTestData):
|
|||||||
result = self.modeladmin._characters(self.user_3)
|
result = self.modeladmin._characters(self.user_3)
|
||||||
self.assertEqual(result, expected)
|
self.assertEqual(result, expected)
|
||||||
|
|
||||||
def test_groups_u1(self):
|
def test_groups_u1(self):
|
||||||
self._create_autogroups()
|
|
||||||
expected = 'Group 1'
|
expected = 'Group 1'
|
||||||
result = self.modeladmin._groups(self.user_1)
|
result = self.modeladmin._groups(self.user_1)
|
||||||
self.assertEqual(result, expected)
|
self.assertEqual(result, expected)
|
||||||
|
|
||||||
def test_groups_u2(self):
|
def test_groups_u2(self):
|
||||||
self._create_autogroups()
|
|
||||||
expected = 'Group 2'
|
expected = 'Group 2'
|
||||||
result = self.modeladmin._groups(self.user_2)
|
result = self.modeladmin._groups(self.user_2)
|
||||||
self.assertEqual(result, expected)
|
self.assertEqual(result, expected)
|
||||||
|
|
||||||
def test_groups_u3(self):
|
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):
|
|
||||||
result = self.modeladmin._groups(self.user_3)
|
result = self.modeladmin._groups(self.user_3)
|
||||||
self.assertIsNone(result)
|
self.assertIsNone(result)
|
||||||
|
|
||||||
@@ -413,8 +375,10 @@ class TestUserAdmin(TestCaseWithTestData):
|
|||||||
|
|
||||||
def test_list_2_html_w_tooltips_w_cutoff(self):
|
def test_list_2_html_w_tooltips_w_cutoff(self):
|
||||||
items = ['one', 'two', 'three']
|
items = ['one', 'two', 'three']
|
||||||
expected = ('<span data-tooltip="one, two, three" '
|
expected = (
|
||||||
'class="tooltip">one, two, (...)</span>')
|
'<span data-tooltip="one, two, three" '
|
||||||
|
'class="tooltip">one, two, (...)</span>'
|
||||||
|
)
|
||||||
result = self.modeladmin._list_2_html_w_tooltips(items, 2)
|
result = self.modeladmin._list_2_html_w_tooltips(items, 2)
|
||||||
self.assertEqual(expected, result)
|
self.assertEqual(expected, result)
|
||||||
|
|
||||||
@@ -439,63 +403,7 @@ class TestUserAdmin(TestCaseWithTestData):
|
|||||||
self.assertTrue(mock_message_user.called)
|
self.assertTrue(mock_message_user.called)
|
||||||
|
|
||||||
# filters
|
# 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):
|
def test_filter_main_corporations(self):
|
||||||
|
|
||||||
class UserAdminTest(BaseUserAdmin):
|
class UserAdminTest(BaseUserAdmin):
|
||||||
@@ -603,7 +511,6 @@ class TestMakeServicesHooksActions(TestCaseWithTestData):
|
|||||||
def sync_nicknames_bulk(self, user):
|
def sync_nicknames_bulk(self, user):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def test_service_has_update_groups_only(self):
|
def test_service_has_update_groups_only(self):
|
||||||
service = self.MyServicesHookTypeA()
|
service = self.MyServicesHookTypeA()
|
||||||
mock_service = MagicMock(spec=service)
|
mock_service = MagicMock(spec=service)
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
from math import ceil
|
from math import ceil
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
from requests import RequestException
|
|
||||||
import requests_mock
|
import requests_mock
|
||||||
from packaging.version import Version as Pep440Version
|
from packaging.version import Version as Pep440Version
|
||||||
|
|
||||||
|
from django.core.cache import cache
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
|
|
||||||
from allianceauth.templatetags.admin_status import (
|
from allianceauth.templatetags.admin_status import (
|
||||||
@@ -12,8 +12,7 @@ from allianceauth.templatetags.admin_status import (
|
|||||||
_fetch_list_from_gitlab,
|
_fetch_list_from_gitlab,
|
||||||
_current_notifications,
|
_current_notifications,
|
||||||
_current_version_summary,
|
_current_version_summary,
|
||||||
_fetch_notification_issues_from_gitlab,
|
_fetch_notification_issues_from_gitlab,
|
||||||
_fetch_tags_from_gitlab,
|
|
||||||
_latests_versions
|
_latests_versions
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -103,35 +102,51 @@ class TestStatusOverviewTag(TestCase):
|
|||||||
|
|
||||||
class TestNotifications(TestCase):
|
class TestNotifications(TestCase):
|
||||||
|
|
||||||
|
def setUp(self) -> None:
|
||||||
|
cache.clear()
|
||||||
|
|
||||||
@requests_mock.mock()
|
@requests_mock.mock()
|
||||||
def test_fetch_notification_issues_from_gitlab(self, requests_mocker):
|
def test_fetch_notification_issues_from_gitlab(self, requests_mocker):
|
||||||
|
# given
|
||||||
url = (
|
url = (
|
||||||
'https://gitlab.com/api/v4/projects/allianceauth%2Fallianceauth/issues'
|
'https://gitlab.com/api/v4/projects/allianceauth%2Fallianceauth/issues'
|
||||||
'?labels=announcement'
|
'?labels=announcement'
|
||||||
)
|
)
|
||||||
requests_mocker.get(url, json=GITHUB_NOTIFICATION_ISSUES)
|
requests_mocker.get(url, json=GITHUB_NOTIFICATION_ISSUES)
|
||||||
|
# when
|
||||||
result = _fetch_notification_issues_from_gitlab()
|
result = _fetch_notification_issues_from_gitlab()
|
||||||
|
# then
|
||||||
self.assertEqual(result, GITHUB_NOTIFICATION_ISSUES)
|
self.assertEqual(result, GITHUB_NOTIFICATION_ISSUES)
|
||||||
|
|
||||||
@patch(MODULE_PATH + '.admin_status.cache')
|
@patch(MODULE_PATH + '.admin_status.cache')
|
||||||
def test_current_notifications_normal(self, mock_cache):
|
def test_current_notifications_normal(self, mock_cache):
|
||||||
|
# given
|
||||||
mock_cache.get_or_set.return_value = GITHUB_NOTIFICATION_ISSUES
|
mock_cache.get_or_set.return_value = GITHUB_NOTIFICATION_ISSUES
|
||||||
|
# when
|
||||||
result = _current_notifications()
|
result = _current_notifications()
|
||||||
|
# then
|
||||||
self.assertEqual(result['notifications'], GITHUB_NOTIFICATION_ISSUES[:5])
|
self.assertEqual(result['notifications'], GITHUB_NOTIFICATION_ISSUES[:5])
|
||||||
|
|
||||||
@patch(MODULE_PATH + '.admin_status.cache')
|
@requests_mock.mock()
|
||||||
def test_current_notifications_failed(self, mock_cache):
|
def test_current_notifications_failed(self, requests_mocker):
|
||||||
mock_cache.get_or_set.side_effect = RequestException
|
# given
|
||||||
|
url = (
|
||||||
|
'https://gitlab.com/api/v4/projects/allianceauth%2Fallianceauth/issues'
|
||||||
|
'?labels=announcement'
|
||||||
|
)
|
||||||
|
requests_mocker.get(url, status_code=404)
|
||||||
|
# when
|
||||||
result = _current_notifications()
|
result = _current_notifications()
|
||||||
|
# then
|
||||||
self.assertEqual(result['notifications'], list())
|
self.assertEqual(result['notifications'], list())
|
||||||
|
|
||||||
@patch(MODULE_PATH + '.admin_status.cache')
|
@patch(MODULE_PATH + '.admin_status.cache')
|
||||||
def test_current_notifications_is_none(self, mock_cache):
|
def test_current_notifications_is_none(self, mock_cache):
|
||||||
|
# given
|
||||||
mock_cache.get_or_set.return_value = None
|
mock_cache.get_or_set.return_value = None
|
||||||
|
# when
|
||||||
result = _current_notifications()
|
result = _current_notifications()
|
||||||
|
# then
|
||||||
self.assertEqual(result['notifications'], list())
|
self.assertEqual(result['notifications'], list())
|
||||||
|
|
||||||
|
|
||||||
@@ -143,12 +158,17 @@ class TestCeleryQueueLength(TestCase):
|
|||||||
|
|
||||||
class TestVersionTags(TestCase):
|
class TestVersionTags(TestCase):
|
||||||
|
|
||||||
|
def setUp(self) -> None:
|
||||||
|
cache.clear()
|
||||||
|
|
||||||
@patch(MODULE_PATH + '.admin_status.__version__', TEST_VERSION)
|
@patch(MODULE_PATH + '.admin_status.__version__', TEST_VERSION)
|
||||||
@patch(MODULE_PATH + '.admin_status.cache')
|
@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
|
mock_cache.get_or_set.return_value = GITHUB_TAGS
|
||||||
|
# when
|
||||||
result = _current_version_summary()
|
result = _current_version_summary()
|
||||||
|
# then
|
||||||
self.assertTrue(result['latest_major'])
|
self.assertTrue(result['latest_major'])
|
||||||
self.assertTrue(result['latest_minor'])
|
self.assertTrue(result['latest_minor'])
|
||||||
self.assertTrue(result['latest_patch'])
|
self.assertTrue(result['latest_patch'])
|
||||||
@@ -158,32 +178,41 @@ class TestVersionTags(TestCase):
|
|||||||
self.assertEqual(result['latest_beta_version'], '2.4.6a1')
|
self.assertEqual(result['latest_beta_version'], '2.4.6a1')
|
||||||
|
|
||||||
@patch(MODULE_PATH + '.admin_status.__version__', TEST_VERSION)
|
@patch(MODULE_PATH + '.admin_status.__version__', TEST_VERSION)
|
||||||
@patch(MODULE_PATH + '.admin_status.cache')
|
@requests_mock.mock()
|
||||||
def test_current_version_info_failed(self, mock_cache):
|
def test_current_version_info_failed(self, requests_mocker):
|
||||||
mock_cache.get_or_set.side_effect = RequestException
|
# given
|
||||||
|
url = (
|
||||||
expected = {}
|
'https://gitlab.com/api/v4/projects/allianceauth%2Fallianceauth'
|
||||||
|
'/repository/tags'
|
||||||
|
)
|
||||||
|
requests_mocker.get(url, status_code=500)
|
||||||
|
# when
|
||||||
result = _current_version_summary()
|
result = _current_version_summary()
|
||||||
self.assertEqual(result, expected)
|
# then
|
||||||
|
self.assertEqual(result, {})
|
||||||
|
|
||||||
@requests_mock.mock()
|
@requests_mock.mock()
|
||||||
def test_fetch_tags_from_gitlab(self, requests_mocker):
|
def test_fetch_tags_from_gitlab(self, requests_mocker):
|
||||||
|
# given
|
||||||
url = (
|
url = (
|
||||||
'https://gitlab.com/api/v4/projects/allianceauth%2Fallianceauth'
|
'https://gitlab.com/api/v4/projects/allianceauth%2Fallianceauth'
|
||||||
'/repository/tags'
|
'/repository/tags'
|
||||||
)
|
)
|
||||||
requests_mocker.get(url, json=GITHUB_TAGS)
|
requests_mocker.get(url, json=GITHUB_TAGS)
|
||||||
result = _fetch_tags_from_gitlab()
|
# when
|
||||||
self.assertEqual(result, GITHUB_TAGS)
|
result = _current_version_summary()
|
||||||
|
# then
|
||||||
|
self.assertTrue(result)
|
||||||
|
|
||||||
@patch(MODULE_PATH + '.admin_status.__version__', TEST_VERSION)
|
@patch(MODULE_PATH + '.admin_status.__version__', TEST_VERSION)
|
||||||
@patch(MODULE_PATH + '.admin_status.cache')
|
@patch(MODULE_PATH + '.admin_status.cache')
|
||||||
def test_current_version_info_return_no_data(self, mock_cache):
|
def test_current_version_info_return_no_data(self, mock_cache):
|
||||||
mock_cache.get_or_set.return_value = None
|
# given
|
||||||
|
mock_cache.get_or_set.return_value = None
|
||||||
expected = {}
|
# when
|
||||||
result = _current_version_summary()
|
result = _current_version_summary()
|
||||||
self.assertEqual(result, expected)
|
# then
|
||||||
|
self.assertEqual(result, {})
|
||||||
|
|
||||||
|
|
||||||
class TestLatestsVersion(TestCase):
|
class TestLatestsVersion(TestCase):
|
||||||
|
|||||||
@@ -6,8 +6,9 @@ from django.contrib.auth import login, authenticate
|
|||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.core import signing
|
from django.core import signing
|
||||||
from django.urls import reverse, reverse_lazy
|
from django.http import JsonResponse
|
||||||
from django.shortcuts import redirect, render
|
from django.shortcuts import redirect, render
|
||||||
|
from django.urls import reverse, reverse_lazy
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from allianceauth.eveonline.models import EveCharacter
|
from allianceauth.eveonline.models import EveCharacter
|
||||||
|
|||||||
@@ -96,24 +96,62 @@ class EveAllianceForm(EveEntityForm):
|
|||||||
|
|
||||||
@admin.register(EveCorporationInfo)
|
@admin.register(EveCorporationInfo)
|
||||||
class EveCorporationInfoAdmin(admin.ModelAdmin):
|
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):
|
def get_form(self, request, obj=None, **kwargs):
|
||||||
if not obj or not obj.pk:
|
if not obj or not obj.pk:
|
||||||
return EveCorporationForm
|
return EveCorporationForm
|
||||||
return super(EveCorporationInfoAdmin, self).get_form(request, obj=obj, **kwargs)
|
return super().get_form(request, obj=obj, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
@admin.register(EveAllianceInfo)
|
@admin.register(EveAllianceInfo)
|
||||||
class EveAllianceInfoAdmin(admin.ModelAdmin):
|
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):
|
def get_form(self, request, obj=None, **kwargs):
|
||||||
if not obj or not obj.pk:
|
if not obj or not obj.pk:
|
||||||
return EveAllianceForm
|
return EveAllianceForm
|
||||||
return super(EveAllianceInfoAdmin, self).get_form(request, obj=obj, **kwargs)
|
return super().get_form(request, obj=obj, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
@admin.register(EveCharacter)
|
@admin.register(EveCharacter)
|
||||||
class EveCharacterAdmin(admin.ModelAdmin):
|
class EveCharacterAdmin(admin.ModelAdmin):
|
||||||
search_fields = ['character_name', 'corporation_name', 'alliance_name', 'character_ownership__user__username']
|
search_fields = [
|
||||||
list_display = ('character_name', 'corporation_name', 'alliance_name', 'user', 'main_character')
|
'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
|
@staticmethod
|
||||||
def user(obj):
|
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_name = models.CharField(max_length=254, unique=True)
|
||||||
corporation_ticker = models.CharField(max_length=254)
|
corporation_ticker = models.CharField(max_length=254)
|
||||||
member_count = models.IntegerField()
|
member_count = models.IntegerField()
|
||||||
|
ceo_id = models.PositiveIntegerField(blank=True, null=True, default=None)
|
||||||
alliance = models.ForeignKey(
|
alliance = models.ForeignKey(
|
||||||
EveAllianceInfo, blank=True, null=True, on_delete=models.SET_NULL
|
EveAllianceInfo, blank=True, null=True, on_delete=models.SET_NULL
|
||||||
)
|
)
|
||||||
@@ -89,10 +90,16 @@ class EveCorporationInfo(models.Model):
|
|||||||
objects = EveCorporationManager()
|
objects = EveCorporationManager()
|
||||||
provider = EveCorporationProviderManager()
|
provider = EveCorporationProviderManager()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
indexes = [
|
||||||
|
models.Index(fields=['ceo_id',]),
|
||||||
|
]
|
||||||
|
|
||||||
def update_corporation(self, corp: providers.Corporation = None):
|
def update_corporation(self, corp: providers.Corporation = None):
|
||||||
if corp is None:
|
if corp is None:
|
||||||
corp = self.provider.get_corporation(self.corporation_id)
|
corp = self.provider.get_corporation(self.corporation_id)
|
||||||
self.member_count = corp.members
|
self.member_count = corp.members
|
||||||
|
self.ceo_id = corp.ceo_id
|
||||||
try:
|
try:
|
||||||
self.alliance = EveAllianceInfo.objects.get(alliance_id=corp.alliance_id)
|
self.alliance = EveAllianceInfo.objects.get(alliance_id=corp.alliance_id)
|
||||||
except EveAllianceInfo.DoesNotExist:
|
except EveAllianceInfo.DoesNotExist:
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ from jsonschema.exceptions import RefResolutionError
|
|||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from esi.clients import esi_client_factory
|
from esi.clients import esi_client_factory
|
||||||
|
|
||||||
|
from allianceauth import __version__
|
||||||
|
|
||||||
|
|
||||||
SWAGGER_SPEC_PATH = os.path.join(os.path.dirname(
|
SWAGGER_SPEC_PATH = os.path.join(os.path.dirname(
|
||||||
os.path.abspath(__file__)), 'swagger.json'
|
os.path.abspath(__file__)), 'swagger.json'
|
||||||
@@ -166,7 +168,7 @@ class EveSwaggerProvider(EveProvider):
|
|||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
self._client = esi_client_factory(
|
self._client = esi_client_factory(
|
||||||
token=token, spec_file=SWAGGER_SPEC_PATH
|
token=token, spec_file=SWAGGER_SPEC_PATH, app_info_text=("allianceauth v" + __version__)
|
||||||
)
|
)
|
||||||
except (HTTPError, RefResolutionError):
|
except (HTTPError, RefResolutionError):
|
||||||
logger.exception(
|
logger.exception(
|
||||||
@@ -182,7 +184,7 @@ class EveSwaggerProvider(EveProvider):
|
|||||||
def client(self):
|
def client(self):
|
||||||
if self._client is None:
|
if self._client is None:
|
||||||
self._client = esi_client_factory(
|
self._client = esi_client_factory(
|
||||||
token=self._token, spec_file=SWAGGER_SPEC_PATH
|
token=self._token, spec_file=SWAGGER_SPEC_PATH, app_info_text=("allianceauth v" + __version__)
|
||||||
)
|
)
|
||||||
return self._client
|
return self._client
|
||||||
|
|
||||||
|
|||||||
@@ -592,3 +592,12 @@ class TestEveSwaggerProvider(TestCase):
|
|||||||
self.assertTrue(mock_esi_client_factory.called)
|
self.assertTrue(mock_esi_client_factory.called)
|
||||||
self.assertIsNotNone(my_provider._client)
|
self.assertIsNotNone(my_provider._client)
|
||||||
self.assertEqual(my_client, 'my_client')
|
self.assertEqual(my_client, 'my_client')
|
||||||
|
|
||||||
|
@patch(MODULE_PATH + '.__version__', '1.0.0')
|
||||||
|
def test_user_agent_header(self):
|
||||||
|
my_provider = EveSwaggerProvider()
|
||||||
|
my_client = my_provider.client
|
||||||
|
operation = my_client.Status.get_status()
|
||||||
|
self.assertEqual(
|
||||||
|
operation.future.request.headers['User-Agent'], 'allianceauth v1.0.0'
|
||||||
|
)
|
||||||
|
|||||||
@@ -42,6 +42,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
{% block extra_script %}
|
{% block extra_script %}
|
||||||
$(document).ready(function(){
|
$(document).ready(function () {
|
||||||
$("[rel=tooltip]").tooltip();
|
$("[rel=tooltip]").tooltip();
|
||||||
|
});
|
||||||
{% endblock extra_script %}
|
{% endblock extra_script %}
|
||||||
|
|||||||
@@ -44,6 +44,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
{% block extra_script %}
|
{% block extra_script %}
|
||||||
$(document).ready(function(){
|
$(document).ready(function () {
|
||||||
$("[rel=tooltip]").tooltip();
|
$("[rel=tooltip]").tooltip();
|
||||||
|
});
|
||||||
{% endblock extra_script %}
|
{% endblock extra_script %}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
from django.conf import settings
|
from django.apps import apps
|
||||||
|
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.contrib.auth.models import Group as BaseGroup, User
|
from django.contrib.auth.models import Group as BaseGroup, User
|
||||||
from django.db.models import Count
|
from django.db.models import Count
|
||||||
@@ -10,9 +9,8 @@ from django.dispatch import receiver
|
|||||||
|
|
||||||
from .models import AuthGroup
|
from .models import AuthGroup
|
||||||
from .models import GroupRequest
|
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
|
_has_auto_groups = True
|
||||||
else:
|
else:
|
||||||
_has_auto_groups = False
|
_has_auto_groups = False
|
||||||
@@ -97,9 +95,10 @@ class HasLeaderFilter(admin.SimpleListFilter):
|
|||||||
else:
|
else:
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
|
|
||||||
class GroupAdmin(admin.ModelAdmin):
|
class GroupAdmin(admin.ModelAdmin):
|
||||||
list_select_related = True
|
list_select_related = ('authgroup',)
|
||||||
ordering = ('name', )
|
ordering = ('name',)
|
||||||
list_display = (
|
list_display = (
|
||||||
'name',
|
'name',
|
||||||
'_description',
|
'_description',
|
||||||
@@ -118,9 +117,12 @@ class GroupAdmin(admin.ModelAdmin):
|
|||||||
list_filter.append(HasLeaderFilter)
|
list_filter.append(HasLeaderFilter)
|
||||||
|
|
||||||
search_fields = ('name', 'authgroup__description')
|
search_fields = ('name', 'authgroup__description')
|
||||||
|
|
||||||
def get_queryset(self, request):
|
def get_queryset(self, request):
|
||||||
qs = super().get_queryset(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(
|
qs = qs.annotate(
|
||||||
member_count=Count('user', distinct=True),
|
member_count=Count('user', distinct=True),
|
||||||
)
|
)
|
||||||
@@ -173,13 +175,29 @@ class Group(BaseGroup):
|
|||||||
verbose_name = BaseGroup._meta.verbose_name
|
verbose_name = BaseGroup._meta.verbose_name
|
||||||
verbose_name_plural = BaseGroup._meta.verbose_name_plural
|
verbose_name_plural = BaseGroup._meta.verbose_name_plural
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
admin.site.unregister(BaseGroup)
|
admin.site.unregister(BaseGroup)
|
||||||
finally:
|
finally:
|
||||||
admin.site.register(Group, GroupAdmin)
|
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)
|
@receiver(pre_save, sender=Group)
|
||||||
|
|||||||
@@ -5,3 +5,6 @@ class GroupManagementConfig(AppConfig):
|
|||||||
name = 'allianceauth.groupmanagement'
|
name = 'allianceauth.groupmanagement'
|
||||||
label = 'groupmanagement'
|
label = 'groupmanagement'
|
||||||
verbose_name = 'Group Management'
|
verbose_name = 'Group Management'
|
||||||
|
|
||||||
|
def ready(self):
|
||||||
|
from . import signals # noqa: F401
|
||||||
|
|||||||
@@ -9,15 +9,20 @@ from .managers import GroupManager
|
|||||||
|
|
||||||
class GroupManagementMenuItem(MenuItemHook):
|
class GroupManagementMenuItem(MenuItemHook):
|
||||||
""" This class ensures only authorized users will see the menu entry """
|
""" This class ensures only authorized users will see the menu entry """
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
# setup menu entry for sidebar
|
# setup menu entry for sidebar
|
||||||
MenuItemHook.__init__(
|
MenuItemHook.__init__(
|
||||||
self,
|
self,
|
||||||
text=_('Group Management'),
|
text=_("Group Management"),
|
||||||
classes='fas fa-users-cog fa-fw',
|
classes="fas fa-users-cog fa-fw",
|
||||||
url_name='groupmanagement:management',
|
url_name="groupmanagement:management",
|
||||||
order=50,
|
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):
|
def render(self, request):
|
||||||
@@ -25,14 +30,14 @@ class GroupManagementMenuItem(MenuItemHook):
|
|||||||
app_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
|
self.count = app_count if app_count and app_count > 0 else None
|
||||||
return MenuItemHook.render(self, request)
|
return MenuItemHook.render(self, request)
|
||||||
return ''
|
return ""
|
||||||
|
|
||||||
|
|
||||||
@hooks.register('menu_item_hook')
|
@hooks.register("menu_item_hook")
|
||||||
def register_menu():
|
def register_menu():
|
||||||
return GroupManagementMenuItem()
|
return GroupManagementMenuItem()
|
||||||
|
|
||||||
|
|
||||||
@hooks.register('url_hook')
|
@hooks.register("url_hook")
|
||||||
def register_urls():
|
def register_urls():
|
||||||
return UrlHook(urls, 'group', r'^group/')
|
return UrlHook(urls, "group", r"^groups/")
|
||||||
|
|||||||
@@ -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,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -107,7 +107,7 @@ class AuthGroup(models.Model):
|
|||||||
help_text="States listed here will have the ability to join this group provided "
|
help_text="States listed here will have the ability to join this group provided "
|
||||||
"they have the proper permissions.")
|
"they have the proper permissions.")
|
||||||
|
|
||||||
description = models.CharField(max_length=512, blank=True, help_text="Description of the group shown to users.")
|
description = models.TextField(max_length=512, blank=True, help_text="Short description <i>(max. 512 characters)</i> of the group shown to users.")
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.group.name
|
return self.group.name
|
||||||
|
|||||||
@@ -1,16 +1,22 @@
|
|||||||
from allianceauth.authentication.signals import state_changed
|
|
||||||
from .managers import GroupManager
|
|
||||||
from .models import Group
|
|
||||||
from django.dispatch import receiver
|
|
||||||
import logging
|
import logging
|
||||||
|
from django.dispatch import receiver
|
||||||
|
from allianceauth.authentication.signals import state_changed
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@receiver(state_changed)
|
@receiver(state_changed)
|
||||||
def check_groups_on_state_change(sender, user, state, **kwargs):
|
def check_groups_on_state_change(sender, user, state, **kwargs):
|
||||||
logger.debug("Updating auth groups for {}".format(user))
|
logger.debug(
|
||||||
visible_groups = GroupManager.get_joinable_groups(state)
|
"Checking group memberships for %s based on new state %s" % (user, state)
|
||||||
visible_groups = visible_groups | Group.objects.select_related('authgroup').filter(authgroup__internal=True)
|
)
|
||||||
groups = user.groups.all()
|
state_groups = (
|
||||||
for g in groups:
|
user.groups.select_related("authgroup").exclude(authgroup__states=None)
|
||||||
if g not in visible_groups:
|
)
|
||||||
user.groups.remove(g)
|
for group in state_groups:
|
||||||
|
if not group.authgroup.states.filter(id=state.id).exists():
|
||||||
|
logger.info(
|
||||||
|
"Removing user %s from group %s due to missing state" % (user, group)
|
||||||
|
)
|
||||||
|
user.groups.remove(group)
|
||||||
|
|||||||
@@ -8,58 +8,65 @@
|
|||||||
<div class="col-lg-12">
|
<div class="col-lg-12">
|
||||||
<br>
|
<br>
|
||||||
{% include 'groupmanagement/menu.html' %}
|
{% include 'groupmanagement/menu.html' %}
|
||||||
|
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
{{ group }} - {% trans 'Audit Log' %}
|
{{ group }} - {% trans "Audit Log" %}
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
|
||||||
<p>
|
<div class="panel-body">
|
||||||
|
<p>
|
||||||
<a class="btn btn-default" href="{% url 'groupmanagement:membership' %}" role="button">
|
<a class="btn btn-default" href="{% url 'groupmanagement:membership' %}" role="button">
|
||||||
{% trans "Back" %}
|
{% trans "Back" %}
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
{% if entries %}
|
{% if entries %}
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table table-striped" id="log-entries">
|
<table class="table table-striped" id="log-entries">
|
||||||
<thead>
|
<thead>
|
||||||
<th class="text-center" scope="col">{% trans "Date/Time" %}</th>
|
<th scope="col">{% trans "Date/Time" %}</th>
|
||||||
<th class="text-center" scope="col">{% trans "Requestor" %}</th>
|
<th scope="col">{% trans "Requestor" %}</th>
|
||||||
<th class="text-center" scope="col">{% trans "Character" %}</th>
|
<th scope="col">{% trans "Character" %}</th>
|
||||||
<th class="text-center" scope="col">{% trans "Corporation" %}</th>
|
<th scope="col">{% trans "Corporation" %}</th>
|
||||||
<th class="text-center" scope="col">{% trans "Type" %}</th>
|
<th scope="col">{% trans "Type" %}</th>
|
||||||
<th class="text-center" scope="col">{% trans "Action" %}</th>
|
<th scope="col">{% trans "Action" %}</th>
|
||||||
<th class="text-center" scope="col">{% trans "Actor" %}</th>
|
<th scope="col">{% trans "Actor" %}</th>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for entry in entries %}
|
{% for entry in entries %}
|
||||||
<tr>
|
<tr>
|
||||||
<td class="text-center">{{ entry.date|date:"Y-M-d, H:i" }}</td>
|
<td>{{ entry.date|date:"Y-M-d, H:i" }}</td>
|
||||||
<td class="text-center">{{ entry.requestor }}</td>
|
<td>{{ entry.requestor }}</td>
|
||||||
<td class="text-center">{{ entry.req_char }}</td>
|
<td>{{ entry.req_char }}</td>
|
||||||
<td class="text-center">{{ entry.req_char.corporation_name }}</td>
|
<td>{{ entry.req_char.corporation_name }}</td>
|
||||||
<td class="text-center">{{ entry.type_to_str }}</td>
|
<td>{{ entry.type_to_str }}</td>
|
||||||
|
|
||||||
{% if entry.request_type is None %}
|
{% if entry.request_type is None %}
|
||||||
<td class="text-center"> Removed</td>
|
<td>{% trans "Removed" %}</td>
|
||||||
{% else %}
|
{% else %}
|
||||||
<td class="text-center">{{ entry.action_to_str }}</td>
|
<td>{{ entry.action_to_str }}</td>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<td class="text-center">{{ entry.request_actor }}</td>
|
|
||||||
|
<td>{{ entry.request_actor }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<p class="text-muted">
|
<p class="text-muted">
|
||||||
All times displayed are EVE/UTC.
|
{% trans "All times displayed are EVE/UTC." %}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="clearfix"></div>
|
<div class="clearfix"></div>
|
||||||
<br>
|
<br>
|
||||||
<div class="alert alert-warning text-center">
|
<div class="alert alert-warning text-center">
|
||||||
{% trans "No entries found for this group." %}
|
{% trans "No entries found for this group." %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@@ -75,31 +82,30 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block extra_script %}
|
{% 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
|
// Add type detection
|
||||||
types.detect.unshift( function ( d ) {
|
types.detect.unshift(function(d) {
|
||||||
return moment( d, format, locale, true ).isValid() ?
|
return moment(d, format, locale, true).isValid() ?
|
||||||
'moment-'+format :
|
'moment-'+format :
|
||||||
null;
|
null;
|
||||||
} );
|
});
|
||||||
|
|
||||||
// Add sorting method - use an integer for the sorting
|
// Add sorting method - use an integer for the sorting
|
||||||
types.order[ 'moment-'+format+'-pre' ] = function ( d ) {
|
types.order[ 'moment-'+format+'-pre' ] = function(d) {
|
||||||
return moment( d, format, locale, true ).unix();
|
return moment(d, format, locale, true).unix();
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
$(document).ready(function(){
|
$(document).ready(function(){
|
||||||
$.fn.dataTable.moment( 'YYYY-MMM-D, HH:mm' );
|
$.fn.dataTable.moment('YYYY-MMM-D, HH:mm');
|
||||||
|
|
||||||
$('#log-entries').DataTable({
|
$('#log-entries').DataTable({
|
||||||
order: [[ 0, 'desc' ], [ 1, 'asc' ] ],
|
order: [[0, 'desc'], [1, 'asc']],
|
||||||
filterDropDown:
|
filterDropDown:
|
||||||
{
|
{
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
idx: 1
|
idx: 1
|
||||||
},
|
},
|
||||||
@@ -124,4 +130,3 @@
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|||||||
@@ -9,38 +9,35 @@
|
|||||||
<div class="col-lg-12">
|
<div class="col-lg-12">
|
||||||
<br>
|
<br>
|
||||||
{% include 'groupmanagement/menu.html' %}
|
{% include 'groupmanagement/menu.html' %}
|
||||||
|
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
{{ group.name }} - {% trans 'Members' %}
|
{{ group.name }} - {% trans 'Members' %}
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
|
||||||
<p>
|
<div class="panel-body">
|
||||||
|
<p>
|
||||||
<a class="btn btn-default" href="{% url 'groupmanagement:membership' %}" role="button">
|
<a class="btn btn-default" href="{% url 'groupmanagement:membership' %}" role="button">
|
||||||
{% trans "Back" %}
|
{% trans "Back" %}
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
{% if group.user_set %}
|
|
||||||
|
{% if group.user_set %}
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table table-aa" id="tab_group_members">
|
<table class="table table-aa" id="tab_group_members">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="text-right">{% trans "Portrait" %}</th>
|
<th>{% trans "Character" %}</th>
|
||||||
<th class="text-center">{% trans "Character" %}</th>
|
<th>{% trans "Organization" %}</th>
|
||||||
<th class="text-center">{% trans "Organization" %}</th>
|
<th></th>
|
||||||
<th class="text-center"></th>
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for member in members %}
|
{% for member in members %}
|
||||||
<tr>
|
<tr>
|
||||||
<td class="text-right">
|
<td>
|
||||||
{% if member.is_leader %}
|
<img src="{{ member.main_char|character_portrait_url:32 }}" class="img-circle" style="margin-right: 1rem;">
|
||||||
<i class="fas fa-star"></i>
|
|
||||||
{% endif %}
|
|
||||||
<img src="{{ member.main_char|character_portrait_url:32 }}" class="img-circle">
|
|
||||||
</td>
|
|
||||||
<td class="text-center">
|
|
||||||
{% if member.main_char %}
|
{% if member.main_char %}
|
||||||
<a href="{{ member.main_char|evewho_character_url }}" target="_blank">
|
<a href="{{ member.main_char|evewho_character_url }}" target="_blank">
|
||||||
{{ member.main_char.character_name }}
|
{{ member.main_char.character_name }}
|
||||||
@@ -48,28 +45,36 @@
|
|||||||
{% else %}
|
{% else %}
|
||||||
{{ member.user.username }}
|
{{ member.user.username }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
{% if member.is_leader %}
|
||||||
|
<i class="fas fa-star" title="{% trans "Group leader" %}" style="margin-left: 1rem;"></i>
|
||||||
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<td class="text-center">
|
|
||||||
|
<td>
|
||||||
{% if member.main_char %}
|
{% if member.main_char %}
|
||||||
<a href="{{ member.main_char|dotlan_corporation_url }}" target="_blank">
|
<a href="{{ member.main_char|dotlan_corporation_url }}" target="_blank">
|
||||||
{{ member.main_char.corporation_name }}
|
{{ member.main_char.corporation_name }}
|
||||||
</a><br>
|
</a><br>
|
||||||
{{ member.main_char.alliance_name|default_if_none:"" }}
|
{{ member.main_char.alliance_name|default_if_none:"" }}
|
||||||
{% else %}
|
{% else %}
|
||||||
(unknown)
|
{% trans "(unknown)" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<td class="text-center">
|
|
||||||
<a href="{% url 'groupmanagement:membership_remove' group.id member.user.id %}" class="btn btn-danger"
|
<td class="text-right">
|
||||||
title="{% trans "Remove from group" %}">
|
<a href="{% url 'groupmanagement:membership_remove' group.id member.user.id %}" class="btn btn-danger" title="{% trans "Remove from group" %}">
|
||||||
<i class="glyphicon glyphicon-remove"></i>
|
<i class="glyphicon glyphicon-remove"></i>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<p class="text-muted"><i class="fas fa-star"></i>: Group leader</p>
|
|
||||||
|
<p class="text-muted">
|
||||||
|
<i class="fas fa-star"></i>: {% trans "Group leader" %}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="alert alert-warning text-center">
|
<div class="alert alert-warning text-center">
|
||||||
@@ -77,7 +82,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
@@ -93,10 +98,13 @@
|
|||||||
{% block extra_script %}
|
{% block extra_script %}
|
||||||
$(document).ready(function(){
|
$(document).ready(function(){
|
||||||
$('#tab_group_members').DataTable({
|
$('#tab_group_members').DataTable({
|
||||||
order: [ [ 1, "asc" ] ],
|
order: [[0, "asc"]],
|
||||||
columnDefs: [
|
columnDefs: [
|
||||||
{ "sortable": false, "targets": [0, 3] },
|
{
|
||||||
|
"sortable": false,
|
||||||
|
"targets": [2]
|
||||||
|
},
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -9,31 +9,36 @@
|
|||||||
<div class="col-lg-12">
|
<div class="col-lg-12">
|
||||||
<br>
|
<br>
|
||||||
{% include 'groupmanagement/menu.html' %}
|
{% include 'groupmanagement/menu.html' %}
|
||||||
|
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
{% trans "Groups" %}
|
{% trans "Groups" %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
{% if groups %}
|
{% if groups %}
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table table-aa">
|
<table class="table table-aa">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="text-center">{% trans "Name" %}</th>
|
<th>{% trans "Name" %}</th>
|
||||||
<th class="text-center">{% trans "Description" %}</th>
|
<th>{% trans "Description" %}</th>
|
||||||
<th class="text-center">{% trans "Status" %}</th>
|
<th>{% trans "Status" %}</th>
|
||||||
<th class="text-center">{% trans "Member Count" %}</th>
|
<th style="white-space: nowrap;">{% trans "Member Count" %}</th>
|
||||||
<th class="text-center"></th>
|
<th style="min-width: 170px;"></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for group in groups %}
|
{% for group in groups %}
|
||||||
<tr>
|
<tr>
|
||||||
<td class="text-center">
|
<td>
|
||||||
<a href="{% url 'groupmanagement:membership_list' group.id %}">{{ group.name }}</a>
|
<a href="{% url 'groupmanagement:membership' group.id %}">{{ group.name }}</a>
|
||||||
</td>
|
</td>
|
||||||
<td class="text-center">{{ group.authgroup.description }}</td>
|
|
||||||
<td class="text-center">
|
<td>{{ group.authgroup.description|linebreaks|urlize }}</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
{% if group.authgroup.hidden %}
|
{% if group.authgroup.hidden %}
|
||||||
<span class="label label-info">{% trans "Hidden" %}</span>
|
<span class="label label-info">{% trans "Hidden" %}</span>
|
||||||
{% elif group.authgroup.open %}
|
{% elif group.authgroup.open %}
|
||||||
@@ -42,21 +47,23 @@
|
|||||||
<span class="label label-default">{% trans "Requestable" %}</span>
|
<span class="label label-default">{% trans "Requestable" %}</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<td class="text-center">
|
|
||||||
|
<td class="text-right">
|
||||||
{{ group.num_members }}
|
{{ group.num_members }}
|
||||||
</td>
|
</td>
|
||||||
<td class="text-center">
|
|
||||||
<a href="{% url 'groupmanagement:membership_list' group.id %}" class="btn btn-primary"
|
<td class="text-right">
|
||||||
title="{% trans "View Members" %}">
|
<a href="{% url 'groupmanagement:membership' group.id %}" class="btn btn-primary" title="{% trans "View Members" %}">
|
||||||
<i class="glyphicon glyphicon-eye-open"></i>
|
<i class="glyphicon glyphicon-eye-open"></i>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a href="{% url "groupmanagement:audit_log" group.id %}" class="btn btn-info" title="{% trans "Audit Members" %}">
|
<a href="{% url "groupmanagement:audit_log" group.id %}" class="btn btn-info" title="{% trans "Audit Members" %}">
|
||||||
<i class="glyphicon glyphicon-list-alt"></i>
|
<i class="glyphicon glyphicon-list-alt"></i>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a id="clipboard-copy" data-clipboard-text="{{ request.scheme }}://{{request.get_host}}{% url 'groupmanagement:request_add' group.id %}" class="btn btn-warning" title="{% trans "Copy Direct Join Link" %}">
|
<a id="clipboard-copy" data-clipboard-text="{{ request.scheme }}://{{request.get_host}}{% url 'groupmanagement:request_add' group.id %}" class="btn btn-warning" title="{% trans "Copy Direct Join Link" %}">
|
||||||
<i class="glyphicon glyphicon-copy"></i>
|
<i class="glyphicon glyphicon-copy"></i>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
@@ -72,9 +79,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
{% block extra_javascript %}
|
|
||||||
|
{% block extra_javascript %}
|
||||||
{% include 'bundles/clipboard-js.html' %}
|
{% include 'bundles/clipboard-js.html' %}
|
||||||
<script>
|
|
||||||
new ClipboardJS('#clipboard-copy');
|
<script>
|
||||||
</script>
|
new ClipboardJS('#clipboard-copy');
|
||||||
{% endblock %}
|
</script>
|
||||||
|
{% endblock %}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
{% block page_title %}{% trans "Available Groups" %}{% endblock page_title %}
|
{% block page_title %}{% trans "Available Groups" %}{% endblock page_title %}
|
||||||
{% block extra_css %}{% endblock extra_css %}
|
{% block extra_css %}{% endblock extra_css %}
|
||||||
url
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="col-lg-12">
|
<div class="col-lg-12">
|
||||||
<h1 class="page-header text-center">{% trans "Available Groups" %}</h1>
|
<h1 class="page-header text-center">{% trans "Available Groups" %}</h1>
|
||||||
@@ -12,17 +12,18 @@ url
|
|||||||
<table class="table table-aa">
|
<table class="table table-aa">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="text-center">{% trans "Name" %}</th>
|
<th>{% trans "Name" %}</th>
|
||||||
<th class="text-center">{% trans "Description" %}</th>
|
<th>{% trans "Description" %}</th>
|
||||||
<th class="text-center">{% trans "Action" %}</th>
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for g in groups %}
|
{% for g in groups %}
|
||||||
<tr>
|
<tr>
|
||||||
<td class="text-center">{{ g.group.name }}</td>
|
<td>{{ g.group.name }}</td>
|
||||||
<td class="text-center">{{ g.group.authgroup.description|urlize }}</td>
|
<td>{{ g.group.authgroup.description|linebreaks|urlize }}</td>
|
||||||
<td class="text-center">
|
<td class="text-right">
|
||||||
{% if g.group in user.groups.all %}
|
{% if g.group in user.groups.all %}
|
||||||
{% if not g.request %}
|
{% if not g.request %}
|
||||||
<a href="{% url 'groupmanagement:request_leave' g.group.id %}" class="btn btn-danger">
|
<a href="{% url 'groupmanagement:request_leave' g.group.id %}" class="btn btn-danger">
|
||||||
@@ -59,5 +60,4 @@ url
|
|||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|||||||
@@ -4,25 +4,26 @@
|
|||||||
{% load evelinks %}
|
{% load evelinks %}
|
||||||
|
|
||||||
{% block page_title %}{% trans "Groups Management" %}{% endblock page_title %}
|
{% block page_title %}{% trans "Groups Management" %}{% endblock page_title %}
|
||||||
{% block extra_css %}
|
|
||||||
<style>
|
|
||||||
.nav-tabs>li.active>a {
|
|
||||||
background-color: #ECF0F1 !important;
|
|
||||||
color: #2C3E50;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
|
{% block extra_css %}
|
||||||
|
<style>
|
||||||
|
.nav-tabs > li.active > a {
|
||||||
|
background-color: rgb(236, 240, 241) !important;
|
||||||
|
color: rgb(44, 62, 80);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
{% endblock extra_css %}
|
{% endblock extra_css %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="col-lg-12">
|
<div class="col-lg-12">
|
||||||
<br>
|
<br>
|
||||||
{% include 'groupmanagement/menu.html' %}
|
{% include 'groupmanagement/menu.html' %}
|
||||||
|
|
||||||
<ul class="nav nav-tabs">
|
<ul class="nav nav-tabs">
|
||||||
<li class="active">
|
<li class="active">
|
||||||
<a data-toggle="tab" href="#add">
|
<a data-toggle="tab" href="#add">
|
||||||
{% trans "Join Requests" %}
|
{% trans "Join Requests" %}
|
||||||
|
|
||||||
{% if acceptrequests %}
|
{% if acceptrequests %}
|
||||||
<span class="badge">{{ acceptrequests|length }}</span>
|
<span class="badge">{{ acceptrequests|length }}</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@@ -31,133 +32,131 @@
|
|||||||
<li>
|
<li>
|
||||||
<a data-toggle="tab" href="#leave">
|
<a data-toggle="tab" href="#leave">
|
||||||
{% trans "Leave Requests" %}
|
{% trans "Leave Requests" %}
|
||||||
|
|
||||||
{% if leaverequests %}
|
{% if leaverequests %}
|
||||||
<span class="badge">{{ leaverequests|length }}</span>
|
<span class="badge">{{ leaverequests|length }}</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<div class="tab-content">
|
|
||||||
|
|
||||||
<div id="add" class="tab-pane fade in active panel panel-default">
|
<div class="panel panel-default panel-tabs-aa">
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
{% if acceptrequests %}
|
<div class="tab-content">
|
||||||
<div class="table-responsive">
|
|
||||||
<table class="table table-aa">
|
<div id="add" class="tab-pane active">
|
||||||
<thead>
|
{% if acceptrequests %}
|
||||||
<tr>
|
<div class="table-responsive">
|
||||||
<th class="text-center"></th>
|
<table class="table table-aa">
|
||||||
<th class="text-center">{% trans "Character" %}</th>
|
<thead>
|
||||||
<th class="text-center">{% trans "Organization" %}</th>
|
<tr>
|
||||||
<th class="text-center">{% trans "Group" %}</th>
|
<th>{% trans "Character" %}</th>
|
||||||
<th class="text-center"></th>
|
<th>{% trans "Organization" %}</th>
|
||||||
</tr>
|
<th>{% trans "Group" %}</th>
|
||||||
</thead>
|
<th></th>
|
||||||
<tbody>
|
</tr>
|
||||||
{% for acceptrequest in acceptrequests %}
|
</thead>
|
||||||
<tr>
|
|
||||||
<td class="text-right">
|
<tbody>
|
||||||
<img src="{{ acceptrequest.main_char|character_portrait_url:32 }}" class="img-circle">
|
{% for acceptrequest in acceptrequests %}
|
||||||
</td>
|
<tr>
|
||||||
<td class="text-center">
|
<td>
|
||||||
{% if acceptrequest.main_char %}
|
<img src="{{ acceptrequest.main_char|character_portrait_url:32 }}" class="img-circle" style="margin-right: 1rem;">
|
||||||
<a href="{{ acceptrequest.main_char|evewho_character_url }}" target="_blank">
|
{% if acceptrequest.main_char %}
|
||||||
{{ acceptrequest.main_char.character_name }}
|
<a href="{{ acceptrequest.main_char|evewho_character_url }}" target="_blank">
|
||||||
</a>
|
{{ acceptrequest.main_char.character_name }}
|
||||||
{% else %}
|
</a>
|
||||||
{{ acceptrequest.user.username }}
|
{% else %}
|
||||||
{% endif %}
|
{{ acceptrequest.user.username }}
|
||||||
</td>
|
{% endif %}
|
||||||
<td class="text-center">
|
</td>
|
||||||
{% if acceptrequest.main_char %}
|
<td>
|
||||||
<a href="{{ acceptrequest.main_char|dotlan_corporation_url }}" target="_blank">
|
{% if acceptrequest.main_char %}
|
||||||
{{ acceptrequest.main_char.corporation_name }}
|
<a href="{{ acceptrequest.main_char|dotlan_corporation_url }}" target="_blank">
|
||||||
</a><br>
|
{{ acceptrequest.main_char.corporation_name }}
|
||||||
{{ acceptrequest.main_char.alliance_name|default_if_none:"" }}
|
</a><br>
|
||||||
{% else %}
|
{{ acceptrequest.main_char.alliance_name|default_if_none:"" }}
|
||||||
(unknown)
|
{% else %}
|
||||||
{% endif %}
|
{% trans "(unknown)" %}
|
||||||
</td>
|
{% endif %}
|
||||||
<td class="text-center">{{ acceptrequest.group.name }}</td>
|
</td>
|
||||||
<td class="text-center">
|
<td>{{ acceptrequest.group.name }}</td>
|
||||||
<a href="{% url 'groupmanagement:accept_request' acceptrequest.id %}" class="btn btn-success">
|
<td class="text-right">
|
||||||
{% trans "Accept" %}
|
<a href="{% url 'groupmanagement:accept_request' acceptrequest.id %}" class="btn btn-success">
|
||||||
</a>
|
{% trans "Accept" %}
|
||||||
<a href="{% url 'groupmanagement:reject_request' acceptrequest.id %}" class="btn btn-danger">
|
</a>
|
||||||
{% trans "Reject" %}
|
|
||||||
</a>
|
<a href="{% url 'groupmanagement:reject_request' acceptrequest.id %}" class="btn btn-danger">
|
||||||
</td>
|
{% trans "Reject" %}
|
||||||
</tr>
|
</a>
|
||||||
{% endfor %}
|
</td>
|
||||||
</tbody>
|
</tr>
|
||||||
</table>
|
{% 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>
|
</div>
|
||||||
{% else %}
|
|
||||||
<div class="alert alert-warning text-center">{% trans "No group add requests." %}</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="leave" class="tab-pane fade panel panel-default">
|
|
||||||
<div 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>
|
||||||
</div>
|
</div>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
<nav class="navbar navbar-default">
|
<nav class="navbar navbar-default">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
|
|
||||||
<div class="navbar-header">
|
<div class="navbar-header">
|
||||||
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
|
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
|
||||||
<span class="sr-only">{% trans "Toggle navigation" %}</span>
|
<span class="sr-only">{% trans "Toggle navigation" %}</span>
|
||||||
@@ -12,7 +11,7 @@
|
|||||||
<span class="icon-bar"></span>
|
<span class="icon-bar"></span>
|
||||||
<span class="icon-bar"></span>
|
<span class="icon-bar"></span>
|
||||||
</button>
|
</button>
|
||||||
<a class="navbar-brand" href="">{% trans "Group Management" %}</a>
|
<a class="navbar-brand" href="{% url 'groupmanagement:management' %}">{% trans "Group Management" %}</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
|
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
|
||||||
@@ -20,11 +19,10 @@
|
|||||||
<li class="{% navactive request 'groupmanagement:management' %}">
|
<li class="{% navactive request 'groupmanagement:management' %}">
|
||||||
<a href="{% url 'groupmanagement:management' %}">{% trans "Group Requests" %}</a>
|
<a href="{% url 'groupmanagement:management' %}">{% trans "Group Requests" %}</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="{% renavactive request '^/group/membership/' %}">
|
<li class="{% navactive request 'groupmanagement:membership groupmanagement:audit_log' %}">
|
||||||
<a href="{% url 'groupmanagement:membership' %}">{% trans "Group Membership" %}</a>
|
<a href="{% url 'groupmanagement:membership' %}">{% trans "Group Membership" %}</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|||||||
@@ -1,61 +1,100 @@
|
|||||||
from unittest import mock
|
|
||||||
|
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
from django.contrib.auth.models import User, Group
|
from django.contrib.auth.models import User, Group
|
||||||
|
|
||||||
from allianceauth.eveonline.models import EveCorporationInfo, EveAllianceInfo
|
from allianceauth.eveonline.models import EveCorporationInfo
|
||||||
|
from allianceauth.eveonline.autogroups.models import AutogroupsConfig
|
||||||
from allianceauth.tests.auth_utils import AuthUtils
|
from allianceauth.tests.auth_utils import AuthUtils
|
||||||
|
|
||||||
from ..signals import check_groups_on_state_change
|
|
||||||
|
|
||||||
|
class TestCheckGroupsOnStateChange(TestCase):
|
||||||
class GroupManagementStateTestCase(TestCase):
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpTestData(cls):
|
def setUpTestData(cls):
|
||||||
cls.user = AuthUtils.create_user('test')
|
cls.user = AuthUtils.create_user('test')
|
||||||
AuthUtils.add_main_character(
|
cls.character = AuthUtils.add_main_character_2(
|
||||||
cls.user, 'test character', '1', corp_id='2', corp_name='test_corp', corp_ticker='TEST', alliance_id='3', alliance_name='TEST'
|
cls.user, 'test character', 1001, corp_id=2001, corp_name='test corp 1', corp_ticker='TEST'
|
||||||
)
|
)
|
||||||
cls.user.profile.refresh_from_db()
|
cls.user.profile.refresh_from_db()
|
||||||
cls.alliance = EveAllianceInfo.objects.create(
|
cls.corp_1 = EveCorporationInfo.objects.create(
|
||||||
alliance_id='3', alliance_name='test alliance', alliance_ticker='TEST', executor_corp_id='2'
|
corporation_id=2001, corporation_name='test corp 1', corporation_ticker='C1', member_count=1
|
||||||
)
|
)
|
||||||
cls.corp = EveCorporationInfo.objects.create(
|
cls.corp_2 = EveCorporationInfo.objects.create(
|
||||||
corporation_id='2', corporation_name='test corp', corporation_ticker='TEST', alliance=cls.alliance, member_count=1
|
corporation_id=2002, corporation_name='test corp 2', corporation_ticker='C2', member_count=1
|
||||||
)
|
)
|
||||||
cls.state_group = Group.objects.create(name='state_group')
|
cls.guest_state = AuthUtils.get_guest_state()
|
||||||
cls.open_group = Group.objects.create(name='open_group')
|
cls.test_state_1 = AuthUtils.create_state('test_state_1', 500)
|
||||||
cls.state = AuthUtils.create_state('test state', 500)
|
cls.test_state_2 = AuthUtils.create_state('test_state_2', 600)
|
||||||
cls.state_group.authgroup.states.add(cls.state)
|
|
||||||
cls.state_group.authgroup.internal = False
|
|
||||||
cls.state_group.save()
|
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.user.refresh_from_db()
|
self.user.refresh_from_db()
|
||||||
self.state.refresh_from_db()
|
|
||||||
|
|
||||||
def _refresh_user(self):
|
def _refresh_user(self):
|
||||||
self.user = User.objects.get(pk=self.user.pk)
|
self.user = User.objects.get(pk=self.user.pk)
|
||||||
|
|
||||||
def _refresh_test_group(self):
|
|
||||||
self.state_group = Group.objects.get(pk=self.state_group.pk)
|
|
||||||
|
|
||||||
def test_drop_state_group(self):
|
def test_drop_state_group(self):
|
||||||
self.user.groups.add(self.open_group)
|
"""
|
||||||
self.user.groups.add(self.state_group)
|
given user is member of: state group, normal group and auto group
|
||||||
self.assertEqual(self.user.profile.state.name, "Guest")
|
when user looses state
|
||||||
|
then user is automatically kicked from state group
|
||||||
self.state.member_corporations.add(self.corp)
|
and remains member of normal group and auto group
|
||||||
|
"""
|
||||||
|
# setup
|
||||||
|
state_group = Group.objects.create(name='state_group')
|
||||||
|
state_group.authgroup.states.add(self.test_state_1)
|
||||||
|
state_group.authgroup.internal = False
|
||||||
|
state_group.save()
|
||||||
|
normal_group = Group.objects.create(name='normal_group')
|
||||||
|
normal_group.authgroup.internal = False
|
||||||
|
normal_group.save()
|
||||||
|
internal_group = Group.objects.create(name='internal_group')
|
||||||
|
autogroup_config = AutogroupsConfig.objects.create(corp_groups=True)
|
||||||
|
autogroup_config.states.add(self.test_state_1)
|
||||||
|
autogroup_config.states.add(self.guest_state)
|
||||||
|
auto_group = autogroup_config.corp_managed_groups.first()
|
||||||
|
internal_state_group = Group.objects.create(name='internal_state_group')
|
||||||
|
internal_state_group.authgroup.states.add(self.test_state_1)
|
||||||
|
self.test_state_1.member_corporations.add(self.corp_1)
|
||||||
|
self.user.groups.add(normal_group)
|
||||||
|
self.user.groups.add(internal_group)
|
||||||
|
self.user.groups.add(state_group)
|
||||||
|
self.user.groups.add(internal_state_group)
|
||||||
|
|
||||||
|
# user changes state back to guest
|
||||||
|
self.test_state_1.member_corporations.clear()
|
||||||
|
|
||||||
|
# assert
|
||||||
self._refresh_user()
|
self._refresh_user()
|
||||||
self.assertEqual(self.user.profile.state, self.state)
|
self.assertEqual(self.user.profile.state, self.guest_state)
|
||||||
groups = self.user.groups.all()
|
groups = self.user.groups.all()
|
||||||
self.assertIn(self.state_group, groups) #keeps group
|
self.assertNotIn(state_group, groups) # looses state group
|
||||||
self.assertIn(self.open_group, groups) #public group unafected
|
self.assertNotIn(internal_state_group, groups) # looses state group
|
||||||
|
self.assertIn(normal_group, groups) # normal group unafected
|
||||||
|
self.assertIn(internal_group, groups) # internal group unafected
|
||||||
|
self.assertIn(auto_group, groups) # auto group unafected
|
||||||
|
|
||||||
self.state.member_corporations.clear()
|
def test_change_to_other_state(self):
|
||||||
|
"""
|
||||||
|
given a state group with 2 allowed states
|
||||||
|
when user changes from one state to the other
|
||||||
|
then user remains member of that group
|
||||||
|
"""
|
||||||
|
# setup
|
||||||
|
state_group = Group.objects.create(name='state_group')
|
||||||
|
state_group.authgroup.states.add(self.test_state_1)
|
||||||
|
state_group.authgroup.states.add(self.test_state_2)
|
||||||
|
|
||||||
|
self.test_state_1.member_corporations.add(self.corp_1)
|
||||||
|
self.test_state_2.member_corporations.add(self.corp_2)
|
||||||
|
self.user.groups.add(state_group)
|
||||||
|
|
||||||
|
# user changes state back to guest
|
||||||
|
self.character.corporation_id = 2002
|
||||||
|
self.character.corporation_name = "test corp 2"
|
||||||
|
self.character.save()
|
||||||
|
|
||||||
|
# assert
|
||||||
self._refresh_user()
|
self._refresh_user()
|
||||||
self.assertEqual(self.user.profile.state.name, "Guest")
|
self.assertEqual(self.user.profile.state, self.test_state_2)
|
||||||
groups = self.user.groups.all()
|
groups = self.user.groups.all()
|
||||||
self.assertNotIn(self.state_group, groups) #looses group
|
self.assertIn(state_group, groups)
|
||||||
self.assertIn(self.open_group, groups) #public group unafected
|
|
||||||
@@ -1,29 +1,52 @@
|
|||||||
from . import views
|
from . import views
|
||||||
|
|
||||||
from django.conf.urls import url
|
from django.conf.urls import url
|
||||||
app_name = 'groupmanagement'
|
|
||||||
|
app_name = "groupmanagement"
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^groups/', views.groups_view, name='groups'),
|
# groups
|
||||||
url(r'^management/', views.group_management,
|
url(r"^groups/$", views.groups_view, name="groups"),
|
||||||
name='management'),
|
url(r"^group/request/join/(\w+)/$", views.group_request_add, name="request_add"),
|
||||||
url(r'^membership/$', views.group_membership,
|
url(
|
||||||
name='membership'),
|
r"^group/request/leave/(\w+)/$", views.group_request_leave, name="request_leave"
|
||||||
url(r'^membership/(\w+)/$', views.group_membership_list,
|
),
|
||||||
name='membership_list'),
|
# group management
|
||||||
url(r'^membership/(\w+)/audit/$', views.group_membership_audit, name="audit_log"),
|
url(r"^groupmanagement/requests/$", views.group_management, name="management"),
|
||||||
url(r'^membership/(\w+)/remove/(\w+)/$', views.group_membership_remove,
|
url(r"^groupmanagement/membership/$", views.group_membership, name="membership"),
|
||||||
name='membership_remove'),
|
url(
|
||||||
url(r'^request_add/(\w+)', views.group_request_add,
|
r"^groupmanagement/membership/(\w+)/$",
|
||||||
name='request_add'),
|
views.group_membership_list,
|
||||||
url(r'^request/accept/(\w+)', views.group_accept_request,
|
name="membership",
|
||||||
name='accept_request'),
|
),
|
||||||
url(r'^request/reject/(\w+)', views.group_reject_request,
|
url(
|
||||||
name='reject_request'),
|
r"^groupmanagement/membership/(\w+)/audit-log/$",
|
||||||
url(r'^request_leave/(\w+)', views.group_request_leave,
|
views.group_membership_audit,
|
||||||
name='request_leave'),
|
name="audit_log",
|
||||||
url(r'leave_request/accept/(\w+)', views.group_leave_accept_request,
|
),
|
||||||
name='leave_accept_request'),
|
url(
|
||||||
url(r'^leave_request/reject/(\w+)', views.group_leave_reject_request,
|
r"^groupmanagement/membership/(\w+)/remove/(\w+)/$",
|
||||||
name='leave_reject_request'),
|
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
|
# Check its a joinable group i.e. not corp or internal
|
||||||
# And the user has permission to manage it
|
# And the user has permission to manage it
|
||||||
if (not GroupManager.check_internal_group(group)
|
if (not GroupManager.check_internal_group(group)
|
||||||
or not GroupManager.can_manage_group(request.user, group)
|
or not GroupManager.can_manage_group(request.user, group)
|
||||||
):
|
):
|
||||||
logger.warning(
|
logger.warning(
|
||||||
@@ -132,7 +132,7 @@ def group_membership_list(request, group_id):
|
|||||||
render_items = {'group': group, 'members': members}
|
render_items = {'group': group, 'members': members}
|
||||||
|
|
||||||
return render(
|
return render(
|
||||||
request, 'groupmanagement/groupmembers.html',
|
request, 'groupmanagement/groupmembers.html',
|
||||||
context=render_items
|
context=render_items
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -166,7 +166,7 @@ def group_membership_remove(request, group_id, user_id):
|
|||||||
except ObjectDoesNotExist:
|
except ObjectDoesNotExist:
|
||||||
messages.warning(request, _("Group does not exist"))
|
messages.warning(request, _("Group does not exist"))
|
||||||
|
|
||||||
return redirect('groupmanagement:membership_list', group_id)
|
return redirect('groupmanagement:membership', group_id)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@@ -312,18 +312,18 @@ def group_leave_reject_request(request, group_request_id):
|
|||||||
@login_required
|
@login_required
|
||||||
def groups_view(request):
|
def groups_view(request):
|
||||||
logger.debug("groups_view called by user %s" % request.user)
|
logger.debug("groups_view called by user %s" % request.user)
|
||||||
|
|
||||||
groups_qs = GroupManager.get_joinable_groups_for_user(
|
groups_qs = GroupManager.get_joinable_groups_for_user(
|
||||||
request.user, include_hidden=False
|
request.user, include_hidden=False
|
||||||
)
|
)
|
||||||
groups_qs = groups_qs.order_by('name')
|
groups_qs = groups_qs.order_by('name')
|
||||||
groups = []
|
groups = []
|
||||||
for group in groups_qs:
|
for group in groups_qs:
|
||||||
group_request = GroupRequest.objects\
|
group_request = GroupRequest.objects\
|
||||||
.filter(user=request.user)\
|
.filter(user=request.user)\
|
||||||
.filter(group=group)
|
.filter(group=group)
|
||||||
groups.append({
|
groups.append({
|
||||||
'group': group,
|
'group': group,
|
||||||
'request': group_request[0] if group_request else None
|
'request': group_request[0] if group_request else None
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -356,6 +356,9 @@ def group_request_add(request, group_id):
|
|||||||
if group.authgroup.open:
|
if group.authgroup.open:
|
||||||
logger.info("%s joining %s as is an open group" % (request.user, group))
|
logger.info("%s joining %s as is an open group" % (request.user, group))
|
||||||
request.user.groups.add(group)
|
request.user.groups.add(group)
|
||||||
|
request_info = request.user.username + ":" + group.name
|
||||||
|
log = RequestLog(request_type=False, group=group, request_info=request_info, action=1, request_actor=request.user)
|
||||||
|
log.save()
|
||||||
return redirect("groupmanagement:groups")
|
return redirect("groupmanagement:groups")
|
||||||
req = GroupRequest.objects.filter(user=request.user, group=group)
|
req = GroupRequest.objects.filter(user=request.user, group=group)
|
||||||
if len(req) > 0:
|
if len(req) > 0:
|
||||||
@@ -389,6 +392,9 @@ def group_request_leave(request, group_id):
|
|||||||
return redirect('groupmanagement:groups')
|
return redirect('groupmanagement:groups')
|
||||||
if group.authgroup.open:
|
if group.authgroup.open:
|
||||||
logger.info("%s leaving %s as is an open group" % (request.user, group))
|
logger.info("%s leaving %s as is an open group" % (request.user, group))
|
||||||
|
request_info = request.user.username + ":" + group.name
|
||||||
|
log = RequestLog(request_type=True, group=group, request_info=request_info, action=1, request_actor=request.user)
|
||||||
|
log.save()
|
||||||
request.user.groups.remove(group)
|
request.user.groups.remove(group)
|
||||||
return redirect("groupmanagement:groups")
|
return redirect("groupmanagement:groups")
|
||||||
req = GroupRequest.objects.filter(user=request.user, group=group)
|
req = GroupRequest.objects.filter(user=request.user, group=group)
|
||||||
@@ -398,6 +404,9 @@ def group_request_leave(request, group_id):
|
|||||||
return redirect("groupmanagement:groups")
|
return redirect("groupmanagement:groups")
|
||||||
if getattr(settings, 'AUTO_LEAVE', False):
|
if getattr(settings, 'AUTO_LEAVE', False):
|
||||||
logger.info("%s leaving joinable group %s due to auto_leave" % (request.user, group))
|
logger.info("%s leaving joinable group %s due to auto_leave" % (request.user, group))
|
||||||
|
request_info = request.user.username + ":" + group.name
|
||||||
|
log = RequestLog(request_type=True, group=group, request_info=request_info, action=1, request_actor=request.user)
|
||||||
|
log.save()
|
||||||
request.user.groups.remove(group)
|
request.user.groups.remove(group)
|
||||||
return redirect('groupmanagement:groups')
|
return redirect('groupmanagement:groups')
|
||||||
grouprequest = GroupRequest()
|
grouprequest = GroupRequest()
|
||||||
|
|||||||
Binary file not shown.
@@ -13,7 +13,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2020-10-11 03:43+0000\n"
|
"POT-Creation-Date: 2020-11-20 05:33+0000\n"
|
||||||
"PO-Revision-Date: 2020-02-18 03:14+0000\n"
|
"PO-Revision-Date: 2020-02-18 03:14+0000\n"
|
||||||
"Last-Translator: Peter Pfeufer <rounon.dax@terra-nanotech.de>, 2020\n"
|
"Last-Translator: Peter Pfeufer <rounon.dax@terra-nanotech.de>, 2020\n"
|
||||||
"Language-Team: German (https://www.transifex.com/alliance-auth/teams/107430/de/)\n"
|
"Language-Team: German (https://www.transifex.com/alliance-auth/teams/107430/de/)\n"
|
||||||
@@ -82,7 +82,7 @@ msgstr "Charaktere"
|
|||||||
|
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:129
|
#: allianceauth/authentication/templates/authentication/dashboard.html:129
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:73
|
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:73
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:22
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:24
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:15
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:15
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:45
|
#: allianceauth/hrapplications/templates/hrapplications/view.html:45
|
||||||
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:34
|
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:34
|
||||||
@@ -168,11 +168,11 @@ msgstr ""
|
|||||||
msgid "Unable to authenticate as the selected character."
|
msgid "Unable to authenticate as the selected character."
|
||||||
msgstr "Authentifizierung mit dem ausgewählten Charakter nicht möglich."
|
msgstr "Authentifizierung mit dem ausgewählten Charakter nicht möglich."
|
||||||
|
|
||||||
#: allianceauth/authentication/views.py:146
|
#: allianceauth/authentication/views.py:151
|
||||||
msgid "Registration token has expired."
|
msgid "Registration token has expired."
|
||||||
msgstr "Token zur Registrierung ist abgelaufen."
|
msgstr "Token zur Registrierung ist abgelaufen."
|
||||||
|
|
||||||
#: allianceauth/authentication/views.py:201
|
#: allianceauth/authentication/views.py:206
|
||||||
msgid ""
|
msgid ""
|
||||||
"Sent confirmation email. Please follow the link to confirm your email "
|
"Sent confirmation email. Please follow the link to confirm your email "
|
||||||
"address."
|
"address."
|
||||||
@@ -180,13 +180,13 @@ msgstr ""
|
|||||||
"Bestätigungsmail gesendet. Bitte folge dem Link in der E-Mail zur "
|
"Bestätigungsmail gesendet. Bitte folge dem Link in der E-Mail zur "
|
||||||
"Bestätigung."
|
"Bestätigung."
|
||||||
|
|
||||||
#: allianceauth/authentication/views.py:206
|
#: allianceauth/authentication/views.py:211
|
||||||
msgid "Confirmed your email address. Please login to continue."
|
msgid "Confirmed your email address. Please login to continue."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Deine E-Mail Adresse wurde bestätigt. Bitte log Dich ein um fortzufahren."
|
"Deine E-Mail Adresse wurde bestätigt. Bitte log Dich ein um fortzufahren."
|
||||||
|
|
||||||
#: allianceauth/authentication/views.py:211
|
#: allianceauth/authentication/views.py:216
|
||||||
msgid "Registraion of new accounts it not allowed at this time."
|
msgid "Registration of new accounts is not allowed at this time."
|
||||||
msgstr "Registrierung von neuen Konten ist zur Zeit nicht erlaubt."
|
msgstr "Registrierung von neuen Konten ist zur Zeit nicht erlaubt."
|
||||||
|
|
||||||
#: allianceauth/corputils/auth_hooks.py:10
|
#: allianceauth/corputils/auth_hooks.py:10
|
||||||
@@ -234,16 +234,16 @@ msgstr "Letzes Update:"
|
|||||||
#: allianceauth/corputils/templates/corputils/search.html:13
|
#: allianceauth/corputils/templates/corputils/search.html:13
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html:24
|
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html:24
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:28
|
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:28
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:27
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:30
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:29
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:30
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:51
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:51
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:110
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:109
|
||||||
msgid "Character"
|
msgid "Character"
|
||||||
msgstr "Charakter"
|
msgstr "Charakter"
|
||||||
|
|
||||||
#: allianceauth/corputils/templates/corputils/corpstats.html:76
|
#: allianceauth/corputils/templates/corputils/corpstats.html:76
|
||||||
#: allianceauth/corputils/templates/corputils/search.html:14
|
#: allianceauth/corputils/templates/corputils/search.html:14
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:28
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:31
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:27
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:27
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:84
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:84
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:129
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:129
|
||||||
@@ -552,36 +552,35 @@ msgstr "Flottenteilnahme registriert."
|
|||||||
msgid "FAT link has expired."
|
msgid "FAT link has expired."
|
||||||
msgstr "FAT-Link ist abgelaufen."
|
msgstr "FAT-Link ist abgelaufen."
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/auth_hooks.py:16
|
#: allianceauth/groupmanagement/auth_hooks.py:17
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:15
|
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:14
|
||||||
msgid "Group Management"
|
msgid "Group Management"
|
||||||
msgstr "Gruppenverwaltung"
|
msgstr "Gruppenverwaltung"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:5
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:5
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:13
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:14
|
||||||
msgid "Audit Log"
|
msgid "Audit Log"
|
||||||
msgstr "Protokoll"
|
msgstr "Protokoll"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:18
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:20
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:20
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:21
|
||||||
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:13
|
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:13
|
||||||
msgid "Back"
|
msgid "Back"
|
||||||
msgstr "Zurück"
|
msgstr "Zurück"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:25
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:28
|
||||||
msgid "Date/Time"
|
msgid "Date/Time"
|
||||||
msgstr "Datum/Uhrzeit"
|
msgstr "Datum/Uhrzeit"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:26
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:29
|
||||||
msgid "Requestor"
|
msgid "Requestor"
|
||||||
msgstr "Antragsteller"
|
msgstr "Antragsteller"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:29
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:32
|
||||||
msgid "Type"
|
msgid "Type"
|
||||||
msgstr "Typ"
|
msgstr "Typ"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:30
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:33
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:17
|
|
||||||
#: allianceauth/notifications/templates/notifications/list.html:37
|
#: allianceauth/notifications/templates/notifications/list.html:37
|
||||||
#: allianceauth/notifications/templates/notifications/list.html:69
|
#: allianceauth/notifications/templates/notifications/list.html:69
|
||||||
#: allianceauth/optimer/templates/optimer/fleetoptable.html:18
|
#: allianceauth/optimer/templates/optimer/fleetoptable.html:18
|
||||||
@@ -592,11 +591,19 @@ msgstr "Typ"
|
|||||||
msgid "Action"
|
msgid "Action"
|
||||||
msgstr "Aktion"
|
msgstr "Aktion"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:31
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:34
|
||||||
msgid "Actor"
|
msgid "Actor"
|
||||||
msgstr "Ausführender"
|
msgstr "Ausführender"
|
||||||
|
|
||||||
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:47
|
||||||
|
msgid "Removed"
|
||||||
|
msgstr "Entfernt"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:59
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:59
|
||||||
|
msgid "All times displayed are EVE/UTC."
|
||||||
|
msgstr "Alle angezeigten Zeiten sind EVE/UTC"
|
||||||
|
|
||||||
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:66
|
||||||
msgid "No entries found for this group."
|
msgid "No entries found for this group."
|
||||||
msgstr "Keine Einträge für diese Gruppe gefunden."
|
msgstr "Keine Einträge für diese Gruppe gefunden."
|
||||||
|
|
||||||
@@ -604,22 +611,24 @@ msgstr "Keine Einträge für diese Gruppe gefunden."
|
|||||||
msgid "Group Members"
|
msgid "Group Members"
|
||||||
msgstr "Gruppenmitglieder"
|
msgstr "Gruppenmitglieder"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:28
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:31
|
||||||
msgid "Portrait"
|
|
||||||
msgstr "Portrait"
|
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:30
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:52
|
#: 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
|
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:23
|
||||||
msgid "Organization"
|
msgid "Organization"
|
||||||
msgstr "Organization"
|
msgstr "Organization"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:64
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:61
|
||||||
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:78
|
||||||
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:136
|
||||||
|
msgid "(unknown)"
|
||||||
|
msgstr "(unbekannt)"
|
||||||
|
|
||||||
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:66
|
||||||
msgid "Remove from group"
|
msgid "Remove from group"
|
||||||
msgstr "Aus Gruppe entfernen"
|
msgstr "Aus Gruppe entfernen"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:76
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:81
|
||||||
msgid "No group members to list."
|
msgid "No group members to list."
|
||||||
msgstr "Keine Gruppenmitglieder vorhanden."
|
msgstr "Keine Gruppenmitglieder vorhanden."
|
||||||
|
|
||||||
@@ -627,18 +636,18 @@ msgstr "Keine Gruppenmitglieder vorhanden."
|
|||||||
msgid "Groups Membership"
|
msgid "Groups Membership"
|
||||||
msgstr "Gruppenmitgliedschaft"
|
msgstr "Gruppenmitgliedschaft"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:14
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:15
|
||||||
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:40
|
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:40
|
||||||
#: allianceauth/templates/allianceauth/side-menu.html:16
|
#: allianceauth/templates/allianceauth/side-menu.html:16
|
||||||
msgid "Groups"
|
msgid "Groups"
|
||||||
msgstr "Gruppen"
|
msgstr "Gruppen"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:23
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:25
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:16
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:16
|
||||||
msgid "Description"
|
msgid "Description"
|
||||||
msgstr "Beschreibung"
|
msgstr "Beschreibung"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:24
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:26
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:28
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:28
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:85
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:85
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:130
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:130
|
||||||
@@ -647,36 +656,36 @@ msgstr "Beschreibung"
|
|||||||
msgid "Status"
|
msgid "Status"
|
||||||
msgstr "Status"
|
msgstr "Status"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:25
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:27
|
||||||
msgid "Member Count"
|
msgid "Member Count"
|
||||||
msgstr "Mitgliederzahl"
|
msgstr "Mitgliederzahl"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:38
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:43
|
||||||
msgid "Hidden"
|
msgid "Hidden"
|
||||||
msgstr "Verborgen"
|
msgstr "Verborgen"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:40
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:45
|
||||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:12
|
#: allianceauth/templates/allianceauth/admin-status/overview.html:12
|
||||||
msgid "Open"
|
msgid "Open"
|
||||||
msgstr "Öffnen"
|
msgstr "Öffnen"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:42
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:47
|
||||||
msgid "Requestable"
|
msgid "Requestable"
|
||||||
msgstr "Anfragbar"
|
msgstr "Anfragbar"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:50
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:56
|
||||||
msgid "View Members"
|
msgid "View Members"
|
||||||
msgstr "Mitglieder ansehen"
|
msgstr "Mitglieder ansehen"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:53
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:60
|
||||||
msgid "Audit Members"
|
msgid "Audit Members"
|
||||||
msgstr "Mitglieder Protokoll"
|
msgstr "Mitglieder Protokoll"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:56
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:64
|
||||||
msgid "Copy Direct Join Link"
|
msgid "Copy Direct Join Link"
|
||||||
msgstr "Direktlink kopieren"
|
msgstr "Direktlink kopieren"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:68
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:75
|
||||||
msgid "No groups to list."
|
msgid "No groups to list."
|
||||||
msgstr "Keine Gruppen vorhanden."
|
msgstr "Keine Gruppen vorhanden."
|
||||||
|
|
||||||
@@ -685,19 +694,19 @@ msgstr "Keine Gruppen vorhanden."
|
|||||||
msgid "Available Groups"
|
msgid "Available Groups"
|
||||||
msgstr "Verfügbare Gruppen"
|
msgstr "Verfügbare Gruppen"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:29
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:30
|
||||||
msgid "Leave"
|
msgid "Leave"
|
||||||
msgstr "Verlassen"
|
msgstr "Verlassen"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:39
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:40
|
||||||
msgid "Join"
|
msgid "Join"
|
||||||
msgstr "Beitreten"
|
msgstr "Beitreten"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:43
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:44
|
||||||
msgid "Request"
|
msgid "Request"
|
||||||
msgstr "Anfrage"
|
msgstr "Anfrage"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:58
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:59
|
||||||
msgid "No groups available."
|
msgid "No groups available."
|
||||||
msgstr "Keine Gruppen verfügbar"
|
msgstr "Keine Gruppen verfügbar"
|
||||||
|
|
||||||
@@ -709,24 +718,24 @@ msgstr "Gruppenverwaltung"
|
|||||||
msgid "Join Requests"
|
msgid "Join Requests"
|
||||||
msgstr "Beitrittsgesuche"
|
msgstr "Beitrittsgesuche"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:33
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:34
|
||||||
msgid "Leave Requests"
|
msgid "Leave Requests"
|
||||||
msgstr "Austrittsgesuche"
|
msgstr "Austrittsgesuche"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:53
|
#: 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/permissions_tool/templates/permissions_tool/audit.html:20
|
||||||
#: allianceauth/services/modules/openfire/forms.py:6
|
#: allianceauth/services/modules/openfire/forms.py:6
|
||||||
msgid "Group"
|
msgid "Group"
|
||||||
msgstr "Gruppen"
|
msgstr "Gruppen"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:85
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:84
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:144
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:142
|
||||||
msgid "Accept"
|
msgid "Accept"
|
||||||
msgstr "Akzeptieren"
|
msgstr "Akzeptieren"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:88
|
#: 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
|
#: allianceauth/hrapplications/templates/hrapplications/view.html:85
|
||||||
msgid "Reject"
|
msgid "Reject"
|
||||||
msgstr "Ablehnen"
|
msgstr "Ablehnen"
|
||||||
@@ -735,19 +744,19 @@ msgstr "Ablehnen"
|
|||||||
msgid "No group add requests."
|
msgid "No group add requests."
|
||||||
msgstr "Keine Gruppenbeitrittsanfragen."
|
msgstr "Keine Gruppenbeitrittsanfragen."
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:156
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:155
|
||||||
msgid "No group leave requests."
|
msgid "No group leave requests."
|
||||||
msgstr "Keine Gruppenaustrittsanfragen"
|
msgstr "Keine Gruppenaustrittsanfragen"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:10
|
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:9
|
||||||
msgid "Toggle navigation"
|
msgid "Toggle navigation"
|
||||||
msgstr "Toggle Navigation"
|
msgstr "Toggle Navigation"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:21
|
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:20
|
||||||
msgid "Group Requests"
|
msgid "Group Requests"
|
||||||
msgstr "Gruppenanfragen"
|
msgstr "Gruppenanfragen"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:24
|
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:23
|
||||||
msgid "Group Membership"
|
msgid "Group Membership"
|
||||||
msgstr "Gruppenmitgliedschaft"
|
msgstr "Gruppenmitgliedschaft"
|
||||||
|
|
||||||
@@ -1264,7 +1273,7 @@ msgstr "Flotten Comms:"
|
|||||||
|
|
||||||
#: allianceauth/services/forms.py:9
|
#: allianceauth/services/forms.py:9
|
||||||
msgid "Fleet Type:"
|
msgid "Fleet Type:"
|
||||||
msgstr "Flottenzeit:"
|
msgstr "Flottenart:"
|
||||||
|
|
||||||
#: allianceauth/services/forms.py:10
|
#: allianceauth/services/forms.py:10
|
||||||
msgid "Ship Priorities:"
|
msgid "Ship Priorities:"
|
||||||
@@ -1316,7 +1325,7 @@ msgstr "Discord Konto deaktiviert"
|
|||||||
|
|
||||||
#: allianceauth/services/modules/discord/models.py:227
|
#: allianceauth/services/modules/discord/models.py:227
|
||||||
msgid ""
|
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."
|
"was a mistake, please contact an admin."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Dein Discord Konto wurde automatisch durch Auth deaktiviert. Wenn Du glaubst"
|
"Dein Discord Konto wurde automatisch durch Auth deaktiviert. Wenn Du glaubst"
|
||||||
@@ -2089,3 +2098,6 @@ msgstr "Neuen Timer hinzugefügt in %(system)s um %(time)s."
|
|||||||
#: allianceauth/timerboard/views.py:83
|
#: allianceauth/timerboard/views.py:83
|
||||||
msgid "Saved changes to the timer."
|
msgid "Saved changes to the timer."
|
||||||
msgstr "Änderungen am Timer gespeichert"
|
msgstr "Änderungen am Timer gespeichert"
|
||||||
|
|
||||||
|
#~ msgid "Portrait"
|
||||||
|
#~ msgstr "Portrait"
|
||||||
|
|||||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -4,17 +4,17 @@
|
|||||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||||
#
|
#
|
||||||
# Translators:
|
# Translators:
|
||||||
# frank1210 <francolopez_16@hotmail.com>, 2020
|
|
||||||
# Joel Falknau <ozirascal@gmail.com>, 2020
|
# Joel Falknau <ozirascal@gmail.com>, 2020
|
||||||
|
# frank1210 <francolopez_16@hotmail.com>, 2020
|
||||||
#
|
#
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2020-10-11 03:43+0000\n"
|
"POT-Creation-Date: 2020-11-20 05:33+0000\n"
|
||||||
"PO-Revision-Date: 2020-02-18 03:14+0000\n"
|
"PO-Revision-Date: 2020-02-18 03:14+0000\n"
|
||||||
"Last-Translator: Joel Falknau <ozirascal@gmail.com>, 2020\n"
|
"Last-Translator: frank1210 <francolopez_16@hotmail.com>, 2020\n"
|
||||||
"Language-Team: Spanish (https://www.transifex.com/alliance-auth/teams/107430/es/)\n"
|
"Language-Team: Spanish (https://www.transifex.com/alliance-auth/teams/107430/es/)\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
@@ -79,7 +79,7 @@ msgstr "Personajes"
|
|||||||
|
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:129
|
#: allianceauth/authentication/templates/authentication/dashboard.html:129
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:73
|
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:73
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:22
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:24
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:15
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:15
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:45
|
#: allianceauth/hrapplications/templates/hrapplications/view.html:45
|
||||||
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:34
|
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:34
|
||||||
@@ -161,26 +161,26 @@ msgstr ""
|
|||||||
msgid "Unable to authenticate as the selected character."
|
msgid "Unable to authenticate as the selected character."
|
||||||
msgstr "Imposible validar con el personaje seleccionado."
|
msgstr "Imposible validar con el personaje seleccionado."
|
||||||
|
|
||||||
#: allianceauth/authentication/views.py:146
|
#: allianceauth/authentication/views.py:151
|
||||||
msgid "Registration token has expired."
|
msgid "Registration token has expired."
|
||||||
msgstr "El token de registracion expiro."
|
msgstr "El token de registracion expiro."
|
||||||
|
|
||||||
#: allianceauth/authentication/views.py:201
|
#: allianceauth/authentication/views.py:206
|
||||||
msgid ""
|
msgid ""
|
||||||
"Sent confirmation email. Please follow the link to confirm your email "
|
"Sent confirmation email. Please follow the link to confirm your email "
|
||||||
"address."
|
"address."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Confirmacion de mail enviada. Por favor siga el enlace para confirmar "
|
"Confirmacion de mail enviada. Por favor siga el enlace para confirmar "
|
||||||
|
|
||||||
#: allianceauth/authentication/views.py:206
|
#: allianceauth/authentication/views.py:211
|
||||||
msgid "Confirmed your email address. Please login to continue."
|
msgid "Confirmed your email address. Please login to continue."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Se ha confirmado su direccion de mail. Por favor igrese su token para "
|
"Se ha confirmado su direccion de mail. Por favor igrese su token para "
|
||||||
"continuar."
|
"continuar."
|
||||||
|
|
||||||
#: allianceauth/authentication/views.py:211
|
#: allianceauth/authentication/views.py:216
|
||||||
msgid "Registraion of new accounts it not allowed at this time."
|
msgid "Registration of new accounts is not allowed at this time."
|
||||||
msgstr "Registracion de nuevas cuentas no es permitido por el momento."
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/corputils/auth_hooks.py:10
|
#: allianceauth/corputils/auth_hooks.py:10
|
||||||
msgid "Corporation Stats"
|
msgid "Corporation Stats"
|
||||||
@@ -227,16 +227,16 @@ msgstr "Ultima Actualizacion:"
|
|||||||
#: allianceauth/corputils/templates/corputils/search.html:13
|
#: allianceauth/corputils/templates/corputils/search.html:13
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html:24
|
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html:24
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:28
|
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:28
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:27
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:30
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:29
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:30
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:51
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:51
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:110
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:109
|
||||||
msgid "Character"
|
msgid "Character"
|
||||||
msgstr "Personaje"
|
msgstr "Personaje"
|
||||||
|
|
||||||
#: allianceauth/corputils/templates/corputils/corpstats.html:76
|
#: allianceauth/corputils/templates/corputils/corpstats.html:76
|
||||||
#: allianceauth/corputils/templates/corputils/search.html:14
|
#: allianceauth/corputils/templates/corputils/search.html:14
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:28
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:31
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:27
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:27
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:84
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:84
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:129
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:129
|
||||||
@@ -546,36 +546,35 @@ msgstr "Participacion de flota registrada."
|
|||||||
msgid "FAT link has expired."
|
msgid "FAT link has expired."
|
||||||
msgstr "Enlace de participacion expirado."
|
msgstr "Enlace de participacion expirado."
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/auth_hooks.py:16
|
#: allianceauth/groupmanagement/auth_hooks.py:17
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:15
|
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:14
|
||||||
msgid "Group Management"
|
msgid "Group Management"
|
||||||
msgstr "Manejo de Grupo"
|
msgstr "Manejo de Grupo"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:5
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:5
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:13
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:14
|
||||||
msgid "Audit Log"
|
msgid "Audit Log"
|
||||||
msgstr "Log de Auditoria"
|
msgstr "Log de Auditoria"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:18
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:20
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:20
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:21
|
||||||
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:13
|
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:13
|
||||||
msgid "Back"
|
msgid "Back"
|
||||||
msgstr "Volver"
|
msgstr "Volver"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:25
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:28
|
||||||
msgid "Date/Time"
|
msgid "Date/Time"
|
||||||
msgstr "Fecha/Hora"
|
msgstr "Fecha/Hora"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:26
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:29
|
||||||
msgid "Requestor"
|
msgid "Requestor"
|
||||||
msgstr "Solicitante"
|
msgstr "Solicitante"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:29
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:32
|
||||||
msgid "Type"
|
msgid "Type"
|
||||||
msgstr "Tipo"
|
msgstr "Tipo"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:30
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:33
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:17
|
|
||||||
#: allianceauth/notifications/templates/notifications/list.html:37
|
#: allianceauth/notifications/templates/notifications/list.html:37
|
||||||
#: allianceauth/notifications/templates/notifications/list.html:69
|
#: allianceauth/notifications/templates/notifications/list.html:69
|
||||||
#: allianceauth/optimer/templates/optimer/fleetoptable.html:18
|
#: allianceauth/optimer/templates/optimer/fleetoptable.html:18
|
||||||
@@ -586,11 +585,19 @@ msgstr "Tipo"
|
|||||||
msgid "Action"
|
msgid "Action"
|
||||||
msgstr "Accion"
|
msgstr "Accion"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:31
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:34
|
||||||
msgid "Actor"
|
msgid "Actor"
|
||||||
msgstr "Actor"
|
msgstr "Actor"
|
||||||
|
|
||||||
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:47
|
||||||
|
msgid "Removed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:59
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:59
|
||||||
|
msgid "All times displayed are EVE/UTC."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:66
|
||||||
msgid "No entries found for this group."
|
msgid "No entries found for this group."
|
||||||
msgstr "No se encontraron entradas para este grupo."
|
msgstr "No se encontraron entradas para este grupo."
|
||||||
|
|
||||||
@@ -598,22 +605,24 @@ msgstr "No se encontraron entradas para este grupo."
|
|||||||
msgid "Group Members"
|
msgid "Group Members"
|
||||||
msgstr "Miembros del Grupo"
|
msgstr "Miembros del Grupo"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:28
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:31
|
||||||
msgid "Portrait"
|
|
||||||
msgstr "Retrato"
|
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:30
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:52
|
#: 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
|
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:23
|
||||||
msgid "Organization"
|
msgid "Organization"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:64
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:61
|
||||||
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:78
|
||||||
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:136
|
||||||
|
msgid "(unknown)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:66
|
||||||
msgid "Remove from group"
|
msgid "Remove from group"
|
||||||
msgstr "Remover del grupo"
|
msgstr "Remover del grupo"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:76
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:81
|
||||||
msgid "No group members to list."
|
msgid "No group members to list."
|
||||||
msgstr "no hay miembros para listar."
|
msgstr "no hay miembros para listar."
|
||||||
|
|
||||||
@@ -621,18 +630,18 @@ msgstr "no hay miembros para listar."
|
|||||||
msgid "Groups Membership"
|
msgid "Groups Membership"
|
||||||
msgstr "Membresia de grupos"
|
msgstr "Membresia de grupos"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:14
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:15
|
||||||
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:40
|
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:40
|
||||||
#: allianceauth/templates/allianceauth/side-menu.html:16
|
#: allianceauth/templates/allianceauth/side-menu.html:16
|
||||||
msgid "Groups"
|
msgid "Groups"
|
||||||
msgstr "Grupos"
|
msgstr "Grupos"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:23
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:25
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:16
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:16
|
||||||
msgid "Description"
|
msgid "Description"
|
||||||
msgstr "Descripcion"
|
msgstr "Descripcion"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:24
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:26
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:28
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:28
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:85
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:85
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:130
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:130
|
||||||
@@ -641,36 +650,36 @@ msgstr "Descripcion"
|
|||||||
msgid "Status"
|
msgid "Status"
|
||||||
msgstr "Estado"
|
msgstr "Estado"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:25
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:27
|
||||||
msgid "Member Count"
|
msgid "Member Count"
|
||||||
msgstr "Contador de miembros"
|
msgstr "Contador de miembros"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:38
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:43
|
||||||
msgid "Hidden"
|
msgid "Hidden"
|
||||||
msgstr "Escondido"
|
msgstr "Escondido"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:40
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:45
|
||||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:12
|
#: allianceauth/templates/allianceauth/admin-status/overview.html:12
|
||||||
msgid "Open"
|
msgid "Open"
|
||||||
msgstr "Abierto"
|
msgstr "Abierto"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:42
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:47
|
||||||
msgid "Requestable"
|
msgid "Requestable"
|
||||||
msgstr "Solicitable"
|
msgstr "Solicitable"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:50
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:56
|
||||||
msgid "View Members"
|
msgid "View Members"
|
||||||
msgstr "Ver Miembros"
|
msgstr "Ver Miembros"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:53
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:60
|
||||||
msgid "Audit Members"
|
msgid "Audit Members"
|
||||||
msgstr "Auditar Miembros"
|
msgstr "Auditar Miembros"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:56
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:64
|
||||||
msgid "Copy Direct Join Link"
|
msgid "Copy Direct Join Link"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:68
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:75
|
||||||
msgid "No groups to list."
|
msgid "No groups to list."
|
||||||
msgstr "No hay grupos para listar"
|
msgstr "No hay grupos para listar"
|
||||||
|
|
||||||
@@ -679,19 +688,19 @@ msgstr "No hay grupos para listar"
|
|||||||
msgid "Available Groups"
|
msgid "Available Groups"
|
||||||
msgstr "Grupos Disponibles"
|
msgstr "Grupos Disponibles"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:29
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:30
|
||||||
msgid "Leave"
|
msgid "Leave"
|
||||||
msgstr "Dejar"
|
msgstr "Dejar"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:39
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:40
|
||||||
msgid "Join"
|
msgid "Join"
|
||||||
msgstr "Unirse"
|
msgstr "Unirse"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:43
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:44
|
||||||
msgid "Request"
|
msgid "Request"
|
||||||
msgstr "Solicitar"
|
msgstr "Solicitar"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:58
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:59
|
||||||
msgid "No groups available."
|
msgid "No groups available."
|
||||||
msgstr "No hay grupos disponibles"
|
msgstr "No hay grupos disponibles"
|
||||||
|
|
||||||
@@ -703,24 +712,24 @@ msgstr "Manejo de Grupos"
|
|||||||
msgid "Join Requests"
|
msgid "Join Requests"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:33
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:34
|
||||||
msgid "Leave Requests"
|
msgid "Leave Requests"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:53
|
#: 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/permissions_tool/templates/permissions_tool/audit.html:20
|
||||||
#: allianceauth/services/modules/openfire/forms.py:6
|
#: allianceauth/services/modules/openfire/forms.py:6
|
||||||
msgid "Group"
|
msgid "Group"
|
||||||
msgstr "Grupo"
|
msgstr "Grupo"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:85
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:84
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:144
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:142
|
||||||
msgid "Accept"
|
msgid "Accept"
|
||||||
msgstr "Aceptar"
|
msgstr "Aceptar"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:88
|
#: 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
|
#: allianceauth/hrapplications/templates/hrapplications/view.html:85
|
||||||
msgid "Reject"
|
msgid "Reject"
|
||||||
msgstr "Rechazar"
|
msgstr "Rechazar"
|
||||||
@@ -729,19 +738,19 @@ msgstr "Rechazar"
|
|||||||
msgid "No group add requests."
|
msgid "No group add requests."
|
||||||
msgstr "No hay solicitudes de ingreso."
|
msgstr "No hay solicitudes de ingreso."
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:156
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:155
|
||||||
msgid "No group leave requests."
|
msgid "No group leave requests."
|
||||||
msgstr "No hay solicitudes paradejar el grupo."
|
msgstr "No hay solicitudes paradejar el grupo."
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:10
|
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:9
|
||||||
msgid "Toggle navigation"
|
msgid "Toggle navigation"
|
||||||
msgstr "Navegacion"
|
msgstr "Navegacion"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:21
|
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:20
|
||||||
msgid "Group Requests"
|
msgid "Group Requests"
|
||||||
msgstr "Solicitudes de Grupo"
|
msgstr "Solicitudes de Grupo"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:24
|
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:23
|
||||||
msgid "Group Membership"
|
msgid "Group Membership"
|
||||||
msgstr "Membresia de Grupo"
|
msgstr "Membresia de Grupo"
|
||||||
|
|
||||||
@@ -1309,7 +1318,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: allianceauth/services/modules/discord/models.py:227
|
#: allianceauth/services/modules/discord/models.py:227
|
||||||
msgid ""
|
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."
|
"was a mistake, please contact an admin."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -2065,3 +2074,6 @@ msgstr "Se agrego un nuevo timer en %(system)s a las %(time)s."
|
|||||||
#: allianceauth/timerboard/views.py:83
|
#: allianceauth/timerboard/views.py:83
|
||||||
msgid "Saved changes to the timer."
|
msgid "Saved changes to the timer."
|
||||||
msgstr "Se guardaron los cambios en el timer."
|
msgstr "Se guardaron los cambios en el timer."
|
||||||
|
|
||||||
|
#~ msgid "Portrait"
|
||||||
|
#~ msgstr "Retrato"
|
||||||
|
|||||||
Binary file not shown.
@@ -6,15 +6,16 @@
|
|||||||
# Translators:
|
# Translators:
|
||||||
# François LACROIX-DURANT <umbre@fallenstarscreations.com>, 2020
|
# François LACROIX-DURANT <umbre@fallenstarscreations.com>, 2020
|
||||||
# Philippe Querin-Laporte <philippe.querin@hotmail.com>, 2020
|
# Philippe Querin-Laporte <philippe.querin@hotmail.com>, 2020
|
||||||
|
# Keven D. <theenarki@gmail.com>, 2020
|
||||||
#
|
#
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2020-10-11 03:43+0000\n"
|
"POT-Creation-Date: 2020-11-20 05:33+0000\n"
|
||||||
"PO-Revision-Date: 2020-02-18 03:14+0000\n"
|
"PO-Revision-Date: 2020-02-18 03:14+0000\n"
|
||||||
"Last-Translator: Philippe Querin-Laporte <philippe.querin@hotmail.com>, 2020\n"
|
"Last-Translator: Keven D. <theenarki@gmail.com>, 2020\n"
|
||||||
"Language-Team: French (France) (https://www.transifex.com/alliance-auth/teams/107430/fr_FR/)\n"
|
"Language-Team: French (France) (https://www.transifex.com/alliance-auth/teams/107430/fr_FR/)\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
@@ -82,7 +83,7 @@ msgstr "Personnages"
|
|||||||
|
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:129
|
#: allianceauth/authentication/templates/authentication/dashboard.html:129
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:73
|
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:73
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:22
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:24
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:15
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:15
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:45
|
#: allianceauth/hrapplications/templates/hrapplications/view.html:45
|
||||||
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:34
|
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:34
|
||||||
@@ -167,11 +168,11 @@ msgstr "Impossible d'ajouter %(name)s à votre compte: ils ont déjà un compte.
|
|||||||
msgid "Unable to authenticate as the selected character."
|
msgid "Unable to authenticate as the selected character."
|
||||||
msgstr "Personnage principal : échec de l'identification."
|
msgstr "Personnage principal : échec de l'identification."
|
||||||
|
|
||||||
#: allianceauth/authentication/views.py:146
|
#: allianceauth/authentication/views.py:151
|
||||||
msgid "Registration token has expired."
|
msgid "Registration token has expired."
|
||||||
msgstr "Le token d'enregistrement est expiré."
|
msgstr "Le token d'enregistrement est expiré."
|
||||||
|
|
||||||
#: allianceauth/authentication/views.py:201
|
#: allianceauth/authentication/views.py:206
|
||||||
msgid ""
|
msgid ""
|
||||||
"Sent confirmation email. Please follow the link to confirm your email "
|
"Sent confirmation email. Please follow the link to confirm your email "
|
||||||
"address."
|
"address."
|
||||||
@@ -179,14 +180,14 @@ msgstr ""
|
|||||||
"Email de confirmation envoyé. Cliquez sur le lien pour valider votre adresse"
|
"Email de confirmation envoyé. Cliquez sur le lien pour valider votre adresse"
|
||||||
" email."
|
" email."
|
||||||
|
|
||||||
#: allianceauth/authentication/views.py:206
|
#: allianceauth/authentication/views.py:211
|
||||||
msgid "Confirmed your email address. Please login to continue."
|
msgid "Confirmed your email address. Please login to continue."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Votre adresse email a été confirmé. Veuillez vous connecter pour continuer."
|
"Votre adresse email a été confirmé. Veuillez vous connecter pour continuer."
|
||||||
|
|
||||||
#: allianceauth/authentication/views.py:211
|
#: allianceauth/authentication/views.py:216
|
||||||
msgid "Registraion of new accounts it not allowed at this time."
|
msgid "Registration of new accounts is not allowed at this time."
|
||||||
msgstr "Création de nouveaux comptes interdit à ce moment."
|
msgstr "La création de nouveaux comptes n'est pas actuellement permise."
|
||||||
|
|
||||||
#: allianceauth/corputils/auth_hooks.py:10
|
#: allianceauth/corputils/auth_hooks.py:10
|
||||||
msgid "Corporation Stats"
|
msgid "Corporation Stats"
|
||||||
@@ -233,16 +234,16 @@ msgstr "Dernière mise à jour:"
|
|||||||
#: allianceauth/corputils/templates/corputils/search.html:13
|
#: allianceauth/corputils/templates/corputils/search.html:13
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html:24
|
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html:24
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:28
|
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:28
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:27
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:30
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:29
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:30
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:51
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:51
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:110
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:109
|
||||||
msgid "Character"
|
msgid "Character"
|
||||||
msgstr "Personnage"
|
msgstr "Personnage"
|
||||||
|
|
||||||
#: allianceauth/corputils/templates/corputils/corpstats.html:76
|
#: allianceauth/corputils/templates/corputils/corpstats.html:76
|
||||||
#: allianceauth/corputils/templates/corputils/search.html:14
|
#: allianceauth/corputils/templates/corputils/search.html:14
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:28
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:31
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:27
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:27
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:84
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:84
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:129
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:129
|
||||||
@@ -552,36 +553,35 @@ msgstr "Participation à la flotte enregistrée."
|
|||||||
msgid "FAT link has expired."
|
msgid "FAT link has expired."
|
||||||
msgstr "le lien a expiré"
|
msgstr "le lien a expiré"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/auth_hooks.py:16
|
#: allianceauth/groupmanagement/auth_hooks.py:17
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:15
|
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:14
|
||||||
msgid "Group Management"
|
msgid "Group Management"
|
||||||
msgstr "Gestion de groupe"
|
msgstr "Gestion de groupe"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:5
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:5
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:13
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:14
|
||||||
msgid "Audit Log"
|
msgid "Audit Log"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:18
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:20
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:20
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:21
|
||||||
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:13
|
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:13
|
||||||
msgid "Back"
|
msgid "Back"
|
||||||
msgstr "Retour"
|
msgstr "Retour"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:25
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:28
|
||||||
msgid "Date/Time"
|
msgid "Date/Time"
|
||||||
msgstr "Date/Heure"
|
msgstr "Date/Heure"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:26
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:29
|
||||||
msgid "Requestor"
|
msgid "Requestor"
|
||||||
msgstr "Demandeur"
|
msgstr "Demandeur"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:29
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:32
|
||||||
msgid "Type"
|
msgid "Type"
|
||||||
msgstr "Type"
|
msgstr "Type"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:30
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:33
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:17
|
|
||||||
#: allianceauth/notifications/templates/notifications/list.html:37
|
#: allianceauth/notifications/templates/notifications/list.html:37
|
||||||
#: allianceauth/notifications/templates/notifications/list.html:69
|
#: allianceauth/notifications/templates/notifications/list.html:69
|
||||||
#: allianceauth/optimer/templates/optimer/fleetoptable.html:18
|
#: allianceauth/optimer/templates/optimer/fleetoptable.html:18
|
||||||
@@ -592,11 +592,19 @@ msgstr "Type"
|
|||||||
msgid "Action"
|
msgid "Action"
|
||||||
msgstr "Action"
|
msgstr "Action"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:31
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:34
|
||||||
msgid "Actor"
|
msgid "Actor"
|
||||||
msgstr "Acteur"
|
msgstr "Acteur"
|
||||||
|
|
||||||
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:47
|
||||||
|
msgid "Removed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:59
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:59
|
||||||
|
msgid "All times displayed are EVE/UTC."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:66
|
||||||
msgid "No entries found for this group."
|
msgid "No entries found for this group."
|
||||||
msgstr "Aucune entrée trouvée pour ce groupe."
|
msgstr "Aucune entrée trouvée pour ce groupe."
|
||||||
|
|
||||||
@@ -604,22 +612,24 @@ msgstr "Aucune entrée trouvée pour ce groupe."
|
|||||||
msgid "Group Members"
|
msgid "Group Members"
|
||||||
msgstr "Membres du groupe"
|
msgstr "Membres du groupe"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:28
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:31
|
||||||
msgid "Portrait"
|
|
||||||
msgstr "Portrait"
|
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:30
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:52
|
#: 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
|
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:23
|
||||||
msgid "Organization"
|
msgid "Organization"
|
||||||
msgstr "Organisation"
|
msgstr "Organisation"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:64
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:61
|
||||||
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:78
|
||||||
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:136
|
||||||
|
msgid "(unknown)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:66
|
||||||
msgid "Remove from group"
|
msgid "Remove from group"
|
||||||
msgstr "Retirer du groupe"
|
msgstr "Retirer du groupe"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:76
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:81
|
||||||
msgid "No group members to list."
|
msgid "No group members to list."
|
||||||
msgstr "Aucun membre à afficher"
|
msgstr "Aucun membre à afficher"
|
||||||
|
|
||||||
@@ -627,18 +637,18 @@ msgstr "Aucun membre à afficher"
|
|||||||
msgid "Groups Membership"
|
msgid "Groups Membership"
|
||||||
msgstr "Groupe appartenance "
|
msgstr "Groupe appartenance "
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:14
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:15
|
||||||
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:40
|
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:40
|
||||||
#: allianceauth/templates/allianceauth/side-menu.html:16
|
#: allianceauth/templates/allianceauth/side-menu.html:16
|
||||||
msgid "Groups"
|
msgid "Groups"
|
||||||
msgstr "Groupes"
|
msgstr "Groupes"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:23
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:25
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:16
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:16
|
||||||
msgid "Description"
|
msgid "Description"
|
||||||
msgstr "Description"
|
msgstr "Description"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:24
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:26
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:28
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:28
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:85
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:85
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:130
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:130
|
||||||
@@ -647,36 +657,36 @@ msgstr "Description"
|
|||||||
msgid "Status"
|
msgid "Status"
|
||||||
msgstr "Statut"
|
msgstr "Statut"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:25
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:27
|
||||||
msgid "Member Count"
|
msgid "Member Count"
|
||||||
msgstr "Nombre de membre"
|
msgstr "Nombre de membre"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:38
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:43
|
||||||
msgid "Hidden"
|
msgid "Hidden"
|
||||||
msgstr "Caché"
|
msgstr "Caché"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:40
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:45
|
||||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:12
|
#: allianceauth/templates/allianceauth/admin-status/overview.html:12
|
||||||
msgid "Open"
|
msgid "Open"
|
||||||
msgstr "Ouvert"
|
msgstr "Ouvert"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:42
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:47
|
||||||
msgid "Requestable"
|
msgid "Requestable"
|
||||||
msgstr "Demandable"
|
msgstr "Demandable"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:50
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:56
|
||||||
msgid "View Members"
|
msgid "View Members"
|
||||||
msgstr "Voir les membres"
|
msgstr "Voir les membres"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:53
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:60
|
||||||
msgid "Audit Members"
|
msgid "Audit Members"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:56
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:64
|
||||||
msgid "Copy Direct Join Link"
|
msgid "Copy Direct Join Link"
|
||||||
msgstr "Copier le lien d'invitation directe"
|
msgstr "Copier le lien d'invitation directe"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:68
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:75
|
||||||
msgid "No groups to list."
|
msgid "No groups to list."
|
||||||
msgstr "Aucun groupe à afficher"
|
msgstr "Aucun groupe à afficher"
|
||||||
|
|
||||||
@@ -685,19 +695,19 @@ msgstr "Aucun groupe à afficher"
|
|||||||
msgid "Available Groups"
|
msgid "Available Groups"
|
||||||
msgstr "Groupes disponibles"
|
msgstr "Groupes disponibles"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:29
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:30
|
||||||
msgid "Leave"
|
msgid "Leave"
|
||||||
msgstr "Quitter"
|
msgstr "Quitter"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:39
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:40
|
||||||
msgid "Join"
|
msgid "Join"
|
||||||
msgstr "Rejoindre"
|
msgstr "Rejoindre"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:43
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:44
|
||||||
msgid "Request"
|
msgid "Request"
|
||||||
msgstr "Demander"
|
msgstr "Demander"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:58
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:59
|
||||||
msgid "No groups available."
|
msgid "No groups available."
|
||||||
msgstr "Aucun groupe disponible"
|
msgstr "Aucun groupe disponible"
|
||||||
|
|
||||||
@@ -709,24 +719,24 @@ msgstr "Gestion de groupe"
|
|||||||
msgid "Join Requests"
|
msgid "Join Requests"
|
||||||
msgstr "Demandes de recrutement"
|
msgstr "Demandes de recrutement"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:33
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:34
|
||||||
msgid "Leave Requests"
|
msgid "Leave Requests"
|
||||||
msgstr "Demande de départ"
|
msgstr "Demande de départ"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:53
|
#: 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/permissions_tool/templates/permissions_tool/audit.html:20
|
||||||
#: allianceauth/services/modules/openfire/forms.py:6
|
#: allianceauth/services/modules/openfire/forms.py:6
|
||||||
msgid "Group"
|
msgid "Group"
|
||||||
msgstr "Groupe"
|
msgstr "Groupe"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:85
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:84
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:144
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:142
|
||||||
msgid "Accept"
|
msgid "Accept"
|
||||||
msgstr "Accepter"
|
msgstr "Accepter"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:88
|
#: 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
|
#: allianceauth/hrapplications/templates/hrapplications/view.html:85
|
||||||
msgid "Reject"
|
msgid "Reject"
|
||||||
msgstr "Rejeter"
|
msgstr "Rejeter"
|
||||||
@@ -735,19 +745,19 @@ msgstr "Rejeter"
|
|||||||
msgid "No group add requests."
|
msgid "No group add requests."
|
||||||
msgstr "Aucune demande en cours"
|
msgstr "Aucune demande en cours"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:156
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:155
|
||||||
msgid "No group leave requests."
|
msgid "No group leave requests."
|
||||||
msgstr "Aucune demande en cours"
|
msgstr "Aucune demande en cours"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:10
|
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:9
|
||||||
msgid "Toggle navigation"
|
msgid "Toggle navigation"
|
||||||
msgstr "Activer navigation"
|
msgstr "Activer navigation"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:21
|
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:20
|
||||||
msgid "Group Requests"
|
msgid "Group Requests"
|
||||||
msgstr "Demandes de groupe"
|
msgstr "Demandes de groupe"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:24
|
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:23
|
||||||
msgid "Group Membership"
|
msgid "Group Membership"
|
||||||
msgstr "Groupe appartenance "
|
msgstr "Groupe appartenance "
|
||||||
|
|
||||||
@@ -1055,11 +1065,11 @@ msgstr "Titre"
|
|||||||
|
|
||||||
#: allianceauth/notifications/templates/notifications/list.html:57
|
#: allianceauth/notifications/templates/notifications/list.html:57
|
||||||
msgid "No unread notifications."
|
msgid "No unread notifications."
|
||||||
msgstr ""
|
msgstr "Aucune notification non lue."
|
||||||
|
|
||||||
#: allianceauth/notifications/templates/notifications/list.html:89
|
#: allianceauth/notifications/templates/notifications/list.html:89
|
||||||
msgid "No read notifications."
|
msgid "No read notifications."
|
||||||
msgstr ""
|
msgstr "Aucune notification lue."
|
||||||
|
|
||||||
#: allianceauth/notifications/templates/notifications/view.html:5
|
#: allianceauth/notifications/templates/notifications/view.html:5
|
||||||
#: allianceauth/notifications/templates/notifications/view.html:11
|
#: allianceauth/notifications/templates/notifications/view.html:11
|
||||||
@@ -1072,7 +1082,7 @@ msgstr "Vous n'êtes pas autorisé a voir cette alerte."
|
|||||||
|
|
||||||
#: allianceauth/notifications/views.py:48
|
#: allianceauth/notifications/views.py:48
|
||||||
msgid "Deleted notification."
|
msgid "Deleted notification."
|
||||||
msgstr "Supprimer l'alerte."
|
msgstr "Alerte supprimée."
|
||||||
|
|
||||||
#: allianceauth/notifications/views.py:52
|
#: allianceauth/notifications/views.py:52
|
||||||
msgid "Failed to locate notification."
|
msgid "Failed to locate notification."
|
||||||
@@ -1088,7 +1098,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: allianceauth/optimer/auth_hooks.py:9
|
#: allianceauth/optimer/auth_hooks.py:9
|
||||||
msgid "Fleet Operations"
|
msgid "Fleet Operations"
|
||||||
msgstr ""
|
msgstr "Opérations de flotte"
|
||||||
|
|
||||||
#: allianceauth/optimer/form.py:6
|
#: allianceauth/optimer/form.py:6
|
||||||
#: allianceauth/optimer/templates/optimer/fleetoptable.html:10
|
#: allianceauth/optimer/templates/optimer/fleetoptable.html:10
|
||||||
@@ -1108,7 +1118,7 @@ msgstr "Nom de l'opération"
|
|||||||
#: allianceauth/optimer/form.py:11
|
#: allianceauth/optimer/form.py:11
|
||||||
#: allianceauth/srp/templates/srp/management.html:40
|
#: allianceauth/srp/templates/srp/management.html:40
|
||||||
msgid "Fleet Commander"
|
msgid "Fleet Commander"
|
||||||
msgstr ""
|
msgstr "Commandant de flotte"
|
||||||
|
|
||||||
#: allianceauth/optimer/templates/optimer/add.html:7
|
#: allianceauth/optimer/templates/optimer/add.html:7
|
||||||
#: allianceauth/optimer/templates/optimer/management.html:14
|
#: allianceauth/optimer/templates/optimer/management.html:14
|
||||||
@@ -1132,11 +1142,11 @@ msgstr ""
|
|||||||
|
|
||||||
#: allianceauth/optimer/templates/optimer/management.html:6
|
#: allianceauth/optimer/templates/optimer/management.html:6
|
||||||
msgid "Fleet Operation Management"
|
msgid "Fleet Operation Management"
|
||||||
msgstr ""
|
msgstr "Gestion des opérations de flotte"
|
||||||
|
|
||||||
#: allianceauth/optimer/templates/optimer/management.html:11
|
#: allianceauth/optimer/templates/optimer/management.html:11
|
||||||
msgid "Fleet Operation Timers"
|
msgid "Fleet Operation Timers"
|
||||||
msgstr ""
|
msgstr "Minuteurs d'opération de flotte"
|
||||||
|
|
||||||
#: allianceauth/optimer/templates/optimer/management.html:21
|
#: allianceauth/optimer/templates/optimer/management.html:21
|
||||||
#: allianceauth/timerboard/templates/timerboard/view.html:23
|
#: allianceauth/timerboard/templates/timerboard/view.html:23
|
||||||
@@ -1146,22 +1156,22 @@ msgstr "Heure d'Eve actuelle:"
|
|||||||
#: allianceauth/optimer/templates/optimer/management.html:27
|
#: allianceauth/optimer/templates/optimer/management.html:27
|
||||||
#: allianceauth/timerboard/templates/timerboard/view.html:189
|
#: allianceauth/timerboard/templates/timerboard/view.html:189
|
||||||
msgid "Next Timers"
|
msgid "Next Timers"
|
||||||
msgstr ""
|
msgstr "Prochains minuteurs"
|
||||||
|
|
||||||
#: allianceauth/optimer/templates/optimer/management.html:31
|
#: allianceauth/optimer/templates/optimer/management.html:31
|
||||||
#: allianceauth/timerboard/templates/timerboard/view.html:353
|
#: allianceauth/timerboard/templates/timerboard/view.html:353
|
||||||
msgid "No upcoming timers."
|
msgid "No upcoming timers."
|
||||||
msgstr ""
|
msgstr "Aucun minuteur à venir."
|
||||||
|
|
||||||
#: allianceauth/optimer/templates/optimer/management.html:34
|
#: allianceauth/optimer/templates/optimer/management.html:34
|
||||||
#: allianceauth/timerboard/templates/timerboard/view.html:357
|
#: allianceauth/timerboard/templates/timerboard/view.html:357
|
||||||
msgid "Past Timers"
|
msgid "Past Timers"
|
||||||
msgstr ""
|
msgstr "Minuteurs précédents"
|
||||||
|
|
||||||
#: allianceauth/optimer/templates/optimer/management.html:38
|
#: allianceauth/optimer/templates/optimer/management.html:38
|
||||||
#: allianceauth/timerboard/templates/timerboard/view.html:521
|
#: allianceauth/timerboard/templates/timerboard/view.html:521
|
||||||
msgid "No past timers."
|
msgid "No past timers."
|
||||||
msgstr ""
|
msgstr "Aucun minuteur précédent."
|
||||||
|
|
||||||
#: allianceauth/optimer/templates/optimer/update.html:7
|
#: allianceauth/optimer/templates/optimer/update.html:7
|
||||||
#: allianceauth/optimer/templates/optimer/update.html:16
|
#: allianceauth/optimer/templates/optimer/update.html:16
|
||||||
@@ -1176,17 +1186,17 @@ msgstr "L'objectif de la flotte n'existe pas."
|
|||||||
#: allianceauth/optimer/views.py:55
|
#: allianceauth/optimer/views.py:55
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Created operation timer for %(opname)s."
|
msgid "Created operation timer for %(opname)s."
|
||||||
msgstr ""
|
msgstr "Minuteur d'opération créé pour %(opname)s."
|
||||||
|
|
||||||
#: allianceauth/optimer/views.py:73
|
#: allianceauth/optimer/views.py:73
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Removed operation timer for %(opname)s."
|
msgid "Removed operation timer for %(opname)s."
|
||||||
msgstr ""
|
msgstr "Minuteur d'opération supprimé pour %(opname)s."
|
||||||
|
|
||||||
#: allianceauth/optimer/views.py:96
|
#: allianceauth/optimer/views.py:96
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Saved changes to operation timer for %(opname)s."
|
msgid "Saved changes to operation timer for %(opname)s."
|
||||||
msgstr ""
|
msgstr "Minuteur d'opération modifié pour %(opname)s."
|
||||||
|
|
||||||
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:6
|
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:6
|
||||||
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:10
|
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:10
|
||||||
@@ -1256,7 +1266,7 @@ msgstr "Nom de la Flotte:"
|
|||||||
|
|
||||||
#: allianceauth/services/forms.py:7
|
#: allianceauth/services/forms.py:7
|
||||||
msgid "Fleet Commander:"
|
msgid "Fleet Commander:"
|
||||||
msgstr "Comandant de la flotte:"
|
msgstr "Commandant de la flotte:"
|
||||||
|
|
||||||
#: allianceauth/services/forms.py:8
|
#: allianceauth/services/forms.py:8
|
||||||
msgid "Fleet Comms:"
|
msgid "Fleet Comms:"
|
||||||
@@ -1316,7 +1326,7 @@ msgstr "Compte Discord Désactivé"
|
|||||||
|
|
||||||
#: allianceauth/services/modules/discord/models.py:227
|
#: allianceauth/services/modules/discord/models.py:227
|
||||||
msgid ""
|
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."
|
"was a mistake, please contact an admin."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Votre compte Discord a été désactivé automatiquement par Auth. Si vous "
|
"Votre compte Discord a été désactivé automatiquement par Auth. Si vous "
|
||||||
@@ -1395,11 +1405,11 @@ msgstr "Une erreur est survenue durant l'activation de votre compte IPSuite4."
|
|||||||
|
|
||||||
#: allianceauth/services/modules/ips4/views.py:53
|
#: allianceauth/services/modules/ips4/views.py:53
|
||||||
msgid "Reset IPSuite4 password."
|
msgid "Reset IPSuite4 password."
|
||||||
msgstr "Supprimer le mot de passe IPSuite4."
|
msgstr "Réinitialiser le mot de passe IPSuite4."
|
||||||
|
|
||||||
#: allianceauth/services/modules/ips4/views.py:80
|
#: allianceauth/services/modules/ips4/views.py:80
|
||||||
msgid "Set IPSuite4 password."
|
msgid "Set IPSuite4 password."
|
||||||
msgstr "Mettre un mot de passe IPSuite4."
|
msgstr "Définir le mot de passe IPSuite4."
|
||||||
|
|
||||||
#: allianceauth/services/modules/ips4/views.py:100
|
#: allianceauth/services/modules/ips4/views.py:100
|
||||||
msgid "Deactivated IPSuite4 account."
|
msgid "Deactivated IPSuite4 account."
|
||||||
@@ -1444,7 +1454,7 @@ msgstr "Une erreur est survenue durant la gestion de votre compte Jabber."
|
|||||||
|
|
||||||
#: allianceauth/services/modules/openfire/views.py:70
|
#: allianceauth/services/modules/openfire/views.py:70
|
||||||
msgid "Reset jabber password."
|
msgid "Reset jabber password."
|
||||||
msgstr "Supprimer le mot de passe Jabber."
|
msgstr "Réinitialiser le mot de passe Jabber."
|
||||||
|
|
||||||
#: allianceauth/services/modules/openfire/views.py:119
|
#: allianceauth/services/modules/openfire/views.py:119
|
||||||
#, python-format
|
#, python-format
|
||||||
@@ -1453,7 +1463,7 @@ msgstr "Broadcast jabber envoyé à %s"
|
|||||||
|
|
||||||
#: allianceauth/services/modules/openfire/views.py:148
|
#: allianceauth/services/modules/openfire/views.py:148
|
||||||
msgid "Set jabber password."
|
msgid "Set jabber password."
|
||||||
msgstr "Mettre un mot de passe Jabber."
|
msgstr "Définir le mot de passe Jabber."
|
||||||
|
|
||||||
#: allianceauth/services/modules/phpbb3/views.py:34
|
#: allianceauth/services/modules/phpbb3/views.py:34
|
||||||
msgid "Activated forum account."
|
msgid "Activated forum account."
|
||||||
@@ -1472,11 +1482,11 @@ msgstr "Compte de forum désactivé."
|
|||||||
|
|
||||||
#: allianceauth/services/modules/phpbb3/views.py:71
|
#: allianceauth/services/modules/phpbb3/views.py:71
|
||||||
msgid "Reset forum password."
|
msgid "Reset forum password."
|
||||||
msgstr "Réinitialisé le mot de passe du forum"
|
msgstr "Réinitialiser le mot de passe du forum."
|
||||||
|
|
||||||
#: allianceauth/services/modules/phpbb3/views.py:100
|
#: allianceauth/services/modules/phpbb3/views.py:100
|
||||||
msgid "Set forum password."
|
msgid "Set forum password."
|
||||||
msgstr "Définir mot de passe du forum."
|
msgstr "Définir le mot de passe du forum."
|
||||||
|
|
||||||
#: allianceauth/services/modules/smf/views.py:34
|
#: allianceauth/services/modules/smf/views.py:34
|
||||||
msgid "Activated SMF account."
|
msgid "Activated SMF account."
|
||||||
@@ -1495,11 +1505,11 @@ msgstr "Compte SMF désactivé"
|
|||||||
|
|
||||||
#: allianceauth/services/modules/smf/views.py:72
|
#: allianceauth/services/modules/smf/views.py:72
|
||||||
msgid "Reset SMF password."
|
msgid "Reset SMF password."
|
||||||
msgstr "Réinitialisé le mot de passe SMF"
|
msgstr "Réinitialiser le mot de passe SMF."
|
||||||
|
|
||||||
#: allianceauth/services/modules/smf/views.py:100
|
#: allianceauth/services/modules/smf/views.py:100
|
||||||
msgid "Set SMF password."
|
msgid "Set SMF password."
|
||||||
msgstr "Définir mot de passe SMF."
|
msgstr "Définir le mot de passe SMF."
|
||||||
|
|
||||||
#: allianceauth/services/modules/teamspeak3/forms.py:14
|
#: allianceauth/services/modules/teamspeak3/forms.py:14
|
||||||
#, python-format
|
#, python-format
|
||||||
@@ -1559,11 +1569,11 @@ msgstr ""
|
|||||||
|
|
||||||
#: allianceauth/services/modules/xenforo/views.py:65
|
#: allianceauth/services/modules/xenforo/views.py:65
|
||||||
msgid "Reset XenForo account password."
|
msgid "Reset XenForo account password."
|
||||||
msgstr ""
|
msgstr "Réinitialiser le mot de passe du compte XenForo."
|
||||||
|
|
||||||
#: allianceauth/services/modules/xenforo/views.py:91
|
#: allianceauth/services/modules/xenforo/views.py:91
|
||||||
msgid "Changed XenForo password."
|
msgid "Changed XenForo password."
|
||||||
msgstr ""
|
msgstr "Mot de passe XenForo modifié."
|
||||||
|
|
||||||
#: allianceauth/services/templates/services/fleetformattertool.html:6
|
#: allianceauth/services/templates/services/fleetformattertool.html:6
|
||||||
msgid "Fleet Formatter Tool"
|
msgid "Fleet Formatter Tool"
|
||||||
@@ -1600,16 +1610,16 @@ msgstr ""
|
|||||||
#: allianceauth/services/templates/services/service_password.html:6
|
#: allianceauth/services/templates/services/service_password.html:6
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%(service_name)s Password Change"
|
msgid "%(service_name)s Password Change"
|
||||||
msgstr ""
|
msgstr "Modification du mot de passe %(service_name)s"
|
||||||
|
|
||||||
#: allianceauth/services/templates/services/service_password.html:10
|
#: allianceauth/services/templates/services/service_password.html:10
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Set %(service_name)s Password"
|
msgid "Set %(service_name)s Password"
|
||||||
msgstr ""
|
msgstr "Définir le mot de passe %(service_name)s"
|
||||||
|
|
||||||
#: allianceauth/services/templates/services/service_password.html:19
|
#: allianceauth/services/templates/services/service_password.html:19
|
||||||
msgid "Set Password"
|
msgid "Set Password"
|
||||||
msgstr ""
|
msgstr "Définir le mot de passe"
|
||||||
|
|
||||||
#: allianceauth/services/templates/services/services.html:5
|
#: allianceauth/services/templates/services/services.html:5
|
||||||
msgid "Services Management"
|
msgid "Services Management"
|
||||||
@@ -2032,12 +2042,12 @@ msgstr "Limité à la Corporation"
|
|||||||
|
|
||||||
#: allianceauth/timerboard/templates/timerboard/timer_confirm_delete.html:11
|
#: allianceauth/timerboard/templates/timerboard/timer_confirm_delete.html:11
|
||||||
msgid "Delete Timer"
|
msgid "Delete Timer"
|
||||||
msgstr "Supprimer minuteur"
|
msgstr "Supprimer le minuteur"
|
||||||
|
|
||||||
#: allianceauth/timerboard/templates/timerboard/timer_confirm_delete.html:19
|
#: allianceauth/timerboard/templates/timerboard/timer_confirm_delete.html:19
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Are you sure you want to delete timer \"%(object)s\"?"
|
msgid "Are you sure you want to delete timer \"%(object)s\"?"
|
||||||
msgstr "Etes vous sur de vouloir supprimer le minuteur \"%(object)s\" ?"
|
msgstr "Êtes-vous sûr de vouloir supprimer le minuteur \"%(object)s\" ?"
|
||||||
|
|
||||||
#: allianceauth/timerboard/templates/timerboard/timer_create_form.html:5
|
#: allianceauth/timerboard/templates/timerboard/timer_create_form.html:5
|
||||||
#: allianceauth/timerboard/templates/timerboard/timer_create_form.html:13
|
#: allianceauth/timerboard/templates/timerboard/timer_create_form.html:13
|
||||||
@@ -2076,8 +2086,11 @@ msgstr "Structure"
|
|||||||
#: allianceauth/timerboard/views.py:74
|
#: allianceauth/timerboard/views.py:74
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Added new timer in %(system)s at %(time)s."
|
msgid "Added new timer in %(system)s at %(time)s."
|
||||||
msgstr "Ajout d'un nouveau timer dans%(system)s à %(time)s"
|
msgstr "Nouveau minuteur ajouté dans %(system)s à %(time)s"
|
||||||
|
|
||||||
#: allianceauth/timerboard/views.py:83
|
#: allianceauth/timerboard/views.py:83
|
||||||
msgid "Saved changes to the timer."
|
msgid "Saved changes to the timer."
|
||||||
msgstr "Changements du Minuteur sauvegardés."
|
msgstr "Changements du minuteur sauvegardés."
|
||||||
|
|
||||||
|
#~ msgid "Portrait"
|
||||||
|
#~ msgstr "Portrait"
|
||||||
|
|||||||
Binary file not shown.
@@ -5,15 +5,16 @@
|
|||||||
#
|
#
|
||||||
# Translators:
|
# Translators:
|
||||||
# Foch Petain <brigadier.rockforward@gmail.com>, 2020
|
# Foch Petain <brigadier.rockforward@gmail.com>, 2020
|
||||||
|
# Joel Falknau <ozirascal@gmail.com>, 2020
|
||||||
#
|
#
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2020-10-11 03:43+0000\n"
|
"POT-Creation-Date: 2020-11-20 05:33+0000\n"
|
||||||
"PO-Revision-Date: 2020-02-18 03:14+0000\n"
|
"PO-Revision-Date: 2020-02-18 03:14+0000\n"
|
||||||
"Last-Translator: Foch Petain <brigadier.rockforward@gmail.com>, 2020\n"
|
"Last-Translator: Joel Falknau <ozirascal@gmail.com>, 2020\n"
|
||||||
"Language-Team: Japanese (https://www.transifex.com/alliance-auth/teams/107430/ja/)\n"
|
"Language-Team: Japanese (https://www.transifex.com/alliance-auth/teams/107430/ja/)\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
@@ -79,7 +80,7 @@ msgstr "キャラクター"
|
|||||||
|
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:129
|
#: allianceauth/authentication/templates/authentication/dashboard.html:129
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:73
|
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:73
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:22
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:24
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:15
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:15
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:45
|
#: allianceauth/hrapplications/templates/hrapplications/view.html:45
|
||||||
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:34
|
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:34
|
||||||
@@ -159,22 +160,22 @@ msgstr "%(name)sをアカウントに追加することができません。す
|
|||||||
msgid "Unable to authenticate as the selected character."
|
msgid "Unable to authenticate as the selected character."
|
||||||
msgstr "選択されたキャラクターの認証が行えませんでした。"
|
msgstr "選択されたキャラクターの認証が行えませんでした。"
|
||||||
|
|
||||||
#: allianceauth/authentication/views.py:146
|
#: allianceauth/authentication/views.py:151
|
||||||
msgid "Registration token has expired."
|
msgid "Registration token has expired."
|
||||||
msgstr "Registration tokenが期限切れです。"
|
msgstr "Registration tokenが期限切れです。"
|
||||||
|
|
||||||
#: allianceauth/authentication/views.py:201
|
#: allianceauth/authentication/views.py:206
|
||||||
msgid ""
|
msgid ""
|
||||||
"Sent confirmation email. Please follow the link to confirm your email "
|
"Sent confirmation email. Please follow the link to confirm your email "
|
||||||
"address."
|
"address."
|
||||||
msgstr "確認のメールを送りました。メール内のリンクをご確認の上、メールアドレスの認証を完了させてください。"
|
msgstr "確認のメールを送りました。メール内のリンクをご確認の上、メールアドレスの認証を完了させてください。"
|
||||||
|
|
||||||
#: allianceauth/authentication/views.py:206
|
#: allianceauth/authentication/views.py:211
|
||||||
msgid "Confirmed your email address. Please login to continue."
|
msgid "Confirmed your email address. Please login to continue."
|
||||||
msgstr "メールアドレスの確認が取れました。Loginしてください。"
|
msgstr "メールアドレスの確認が取れました。Loginしてください。"
|
||||||
|
|
||||||
#: allianceauth/authentication/views.py:211
|
#: allianceauth/authentication/views.py:216
|
||||||
msgid "Registraion of new accounts it not allowed at this time."
|
msgid "Registration of new accounts is not allowed at this time."
|
||||||
msgstr "現在新規アカウントの登録を停止しております。"
|
msgstr "現在新規アカウントの登録を停止しております。"
|
||||||
|
|
||||||
#: allianceauth/corputils/auth_hooks.py:10
|
#: allianceauth/corputils/auth_hooks.py:10
|
||||||
@@ -222,16 +223,16 @@ msgstr "最終活動日:"
|
|||||||
#: allianceauth/corputils/templates/corputils/search.html:13
|
#: allianceauth/corputils/templates/corputils/search.html:13
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html:24
|
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html:24
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:28
|
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:28
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:27
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:30
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:29
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:30
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:51
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:51
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:110
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:109
|
||||||
msgid "Character"
|
msgid "Character"
|
||||||
msgstr "Character"
|
msgstr "Character"
|
||||||
|
|
||||||
#: allianceauth/corputils/templates/corputils/corpstats.html:76
|
#: allianceauth/corputils/templates/corputils/corpstats.html:76
|
||||||
#: allianceauth/corputils/templates/corputils/search.html:14
|
#: allianceauth/corputils/templates/corputils/search.html:14
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:28
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:31
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:27
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:27
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:84
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:84
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:129
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:129
|
||||||
@@ -538,36 +539,35 @@ msgstr "Fleet参加が登録されました。"
|
|||||||
msgid "FAT link has expired."
|
msgid "FAT link has expired."
|
||||||
msgstr "Fat-Linkの有効期間が終了してます。"
|
msgstr "Fat-Linkの有効期間が終了してます。"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/auth_hooks.py:16
|
#: allianceauth/groupmanagement/auth_hooks.py:17
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:15
|
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:14
|
||||||
msgid "Group Management"
|
msgid "Group Management"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:5
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:5
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:13
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:14
|
||||||
msgid "Audit Log"
|
msgid "Audit Log"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:18
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:20
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:20
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:21
|
||||||
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:13
|
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:13
|
||||||
msgid "Back"
|
msgid "Back"
|
||||||
msgstr "戻る"
|
msgstr "戻る"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:25
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:28
|
||||||
msgid "Date/Time"
|
msgid "Date/Time"
|
||||||
msgstr "日付/時間"
|
msgstr "日付/時間"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:26
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:29
|
||||||
msgid "Requestor"
|
msgid "Requestor"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:29
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:32
|
||||||
msgid "Type"
|
msgid "Type"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:30
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:33
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:17
|
|
||||||
#: allianceauth/notifications/templates/notifications/list.html:37
|
#: allianceauth/notifications/templates/notifications/list.html:37
|
||||||
#: allianceauth/notifications/templates/notifications/list.html:69
|
#: allianceauth/notifications/templates/notifications/list.html:69
|
||||||
#: allianceauth/optimer/templates/optimer/fleetoptable.html:18
|
#: allianceauth/optimer/templates/optimer/fleetoptable.html:18
|
||||||
@@ -578,11 +578,19 @@ msgstr ""
|
|||||||
msgid "Action"
|
msgid "Action"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:31
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:34
|
||||||
msgid "Actor"
|
msgid "Actor"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:47
|
||||||
|
msgid "Removed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:59
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:59
|
||||||
|
msgid "All times displayed are EVE/UTC."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:66
|
||||||
msgid "No entries found for this group."
|
msgid "No entries found for this group."
|
||||||
msgstr "この Group での entry が見つかりませんでした。"
|
msgstr "この Group での entry が見つかりませんでした。"
|
||||||
|
|
||||||
@@ -590,22 +598,24 @@ msgstr "この Group での entry が見つかりませんでした。"
|
|||||||
msgid "Group Members"
|
msgid "Group Members"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:28
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:31
|
||||||
msgid "Portrait"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:30
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:52
|
#: 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
|
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:23
|
||||||
msgid "Organization"
|
msgid "Organization"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:64
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:61
|
||||||
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:78
|
||||||
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:136
|
||||||
|
msgid "(unknown)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:66
|
||||||
msgid "Remove from group"
|
msgid "Remove from group"
|
||||||
msgstr "Group から削除"
|
msgstr "Group から削除"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:76
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:81
|
||||||
msgid "No group members to list."
|
msgid "No group members to list."
|
||||||
msgstr "Groupメンバーはリストにいません。"
|
msgstr "Groupメンバーはリストにいません。"
|
||||||
|
|
||||||
@@ -613,18 +623,18 @@ msgstr "Groupメンバーはリストにいません。"
|
|||||||
msgid "Groups Membership"
|
msgid "Groups Membership"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:14
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:15
|
||||||
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:40
|
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:40
|
||||||
#: allianceauth/templates/allianceauth/side-menu.html:16
|
#: allianceauth/templates/allianceauth/side-menu.html:16
|
||||||
msgid "Groups"
|
msgid "Groups"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:23
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:25
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:16
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:16
|
||||||
msgid "Description"
|
msgid "Description"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:24
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:26
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:28
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:28
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:85
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:85
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:130
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:130
|
||||||
@@ -633,36 +643,36 @@ msgstr ""
|
|||||||
msgid "Status"
|
msgid "Status"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:25
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:27
|
||||||
msgid "Member Count"
|
msgid "Member Count"
|
||||||
msgstr "Member Count"
|
msgstr "Member Count"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:38
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:43
|
||||||
msgid "Hidden"
|
msgid "Hidden"
|
||||||
msgstr "閉じる"
|
msgstr "閉じる"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:40
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:45
|
||||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:12
|
#: allianceauth/templates/allianceauth/admin-status/overview.html:12
|
||||||
msgid "Open"
|
msgid "Open"
|
||||||
msgstr "開く"
|
msgstr "開く"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:42
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:47
|
||||||
msgid "Requestable"
|
msgid "Requestable"
|
||||||
msgstr "申請可能"
|
msgstr "申請可能"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:50
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:56
|
||||||
msgid "View Members"
|
msgid "View Members"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:53
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:60
|
||||||
msgid "Audit Members"
|
msgid "Audit Members"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:56
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:64
|
||||||
msgid "Copy Direct Join Link"
|
msgid "Copy Direct Join Link"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:68
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:75
|
||||||
msgid "No groups to list."
|
msgid "No groups to list."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -671,19 +681,19 @@ msgstr ""
|
|||||||
msgid "Available Groups"
|
msgid "Available Groups"
|
||||||
msgstr "参加可能Group"
|
msgstr "参加可能Group"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:29
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:30
|
||||||
msgid "Leave"
|
msgid "Leave"
|
||||||
msgstr "脱退"
|
msgstr "脱退"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:39
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:40
|
||||||
msgid "Join"
|
msgid "Join"
|
||||||
msgstr "参加"
|
msgstr "参加"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:43
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:44
|
||||||
msgid "Request"
|
msgid "Request"
|
||||||
msgstr "申請"
|
msgstr "申請"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:58
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:59
|
||||||
msgid "No groups available."
|
msgid "No groups available."
|
||||||
msgstr "参加可能なGroupがありません。"
|
msgstr "参加可能なGroupがありません。"
|
||||||
|
|
||||||
@@ -695,24 +705,24 @@ msgstr ""
|
|||||||
msgid "Join Requests"
|
msgid "Join Requests"
|
||||||
msgstr "参加希望を出す"
|
msgstr "参加希望を出す"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:33
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:34
|
||||||
msgid "Leave Requests"
|
msgid "Leave Requests"
|
||||||
msgstr "脱退希望を出す"
|
msgstr "脱退希望を出す"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:53
|
#: 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/permissions_tool/templates/permissions_tool/audit.html:20
|
||||||
#: allianceauth/services/modules/openfire/forms.py:6
|
#: allianceauth/services/modules/openfire/forms.py:6
|
||||||
msgid "Group"
|
msgid "Group"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:85
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:84
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:144
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:142
|
||||||
msgid "Accept"
|
msgid "Accept"
|
||||||
msgstr "承認"
|
msgstr "承認"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:88
|
#: 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
|
#: allianceauth/hrapplications/templates/hrapplications/view.html:85
|
||||||
msgid "Reject"
|
msgid "Reject"
|
||||||
msgstr "拒否"
|
msgstr "拒否"
|
||||||
@@ -721,19 +731,19 @@ msgstr "拒否"
|
|||||||
msgid "No group add requests."
|
msgid "No group add requests."
|
||||||
msgstr "グループ参加希望はありません。"
|
msgstr "グループ参加希望はありません。"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:156
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:155
|
||||||
msgid "No group leave requests."
|
msgid "No group leave requests."
|
||||||
msgstr "グループ脱退希望はありません。"
|
msgstr "グループ脱退希望はありません。"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:10
|
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:9
|
||||||
msgid "Toggle navigation"
|
msgid "Toggle navigation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:21
|
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:20
|
||||||
msgid "Group Requests"
|
msgid "Group Requests"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:24
|
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:23
|
||||||
msgid "Group Membership"
|
msgid "Group Membership"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -1298,9 +1308,9 @@ msgstr "Discordのアカウントを無効化"
|
|||||||
|
|
||||||
#: allianceauth/services/modules/discord/models.py:227
|
#: allianceauth/services/modules/discord/models.py:227
|
||||||
msgid ""
|
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."
|
"was a mistake, please contact an admin."
|
||||||
msgstr "あなたのDiscordアカウントは管理者によって無効化されました。もし、これが間違いの場合、管理者に確認してください。"
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:18
|
#: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:18
|
||||||
msgid "Join the Discord server"
|
msgid "Join the Discord server"
|
||||||
@@ -2055,3 +2065,6 @@ msgstr ""
|
|||||||
#: allianceauth/timerboard/views.py:83
|
#: allianceauth/timerboard/views.py:83
|
||||||
msgid "Saved changes to the timer."
|
msgid "Saved changes to the timer."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#~ msgid "Portrait"
|
||||||
|
#~ msgstr ""
|
||||||
|
|||||||
Binary file not shown.
@@ -5,18 +5,19 @@
|
|||||||
#
|
#
|
||||||
# Translators:
|
# Translators:
|
||||||
# None None <khd1226543@gmail.com>, 2020
|
# None None <khd1226543@gmail.com>, 2020
|
||||||
# Olgeda Choi <undead.choi@gmail.com>, 2020
|
|
||||||
# Seowon Jung <seowon@hawaii.edu>, 2020
|
# Seowon Jung <seowon@hawaii.edu>, 2020
|
||||||
|
# Olgeda Choi <undead.choi@gmail.com>, 2020
|
||||||
# Lahty <js03js70@gmail.com>, 2020
|
# Lahty <js03js70@gmail.com>, 2020
|
||||||
|
# Joel Falknau <ozirascal@gmail.com>, 2020
|
||||||
#
|
#
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2020-10-11 03:43+0000\n"
|
"POT-Creation-Date: 2020-11-20 05:33+0000\n"
|
||||||
"PO-Revision-Date: 2020-02-18 03:14+0000\n"
|
"PO-Revision-Date: 2020-02-18 03:14+0000\n"
|
||||||
"Last-Translator: Lahty <js03js70@gmail.com>, 2020\n"
|
"Last-Translator: Joel Falknau <ozirascal@gmail.com>, 2020\n"
|
||||||
"Language-Team: Korean (Korea) (https://www.transifex.com/alliance-auth/teams/107430/ko_KR/)\n"
|
"Language-Team: Korean (Korea) (https://www.transifex.com/alliance-auth/teams/107430/ko_KR/)\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
@@ -83,7 +84,7 @@ msgstr "캐릭터"
|
|||||||
|
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:129
|
#: allianceauth/authentication/templates/authentication/dashboard.html:129
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:73
|
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:73
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:22
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:24
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:15
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:15
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:45
|
#: allianceauth/hrapplications/templates/hrapplications/view.html:45
|
||||||
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:34
|
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:34
|
||||||
@@ -163,22 +164,22 @@ msgstr "계정에 %(name)s를 추가하지 못했습니다. 이미 추가된 계
|
|||||||
msgid "Unable to authenticate as the selected character."
|
msgid "Unable to authenticate as the selected character."
|
||||||
msgstr "선택한 캐릭터로 인증을 수행할 수 없음"
|
msgstr "선택한 캐릭터로 인증을 수행할 수 없음"
|
||||||
|
|
||||||
#: allianceauth/authentication/views.py:146
|
#: allianceauth/authentication/views.py:151
|
||||||
msgid "Registration token has expired."
|
msgid "Registration token has expired."
|
||||||
msgstr "등록토큰 만료"
|
msgstr "등록토큰 만료"
|
||||||
|
|
||||||
#: allianceauth/authentication/views.py:201
|
#: allianceauth/authentication/views.py:206
|
||||||
msgid ""
|
msgid ""
|
||||||
"Sent confirmation email. Please follow the link to confirm your email "
|
"Sent confirmation email. Please follow the link to confirm your email "
|
||||||
"address."
|
"address."
|
||||||
msgstr "확인 메일 전송됨. 다음 링크를 눌러 이메일 주소를 확인하세요."
|
msgstr "확인 메일 전송됨. 다음 링크를 눌러 이메일 주소를 확인하세요."
|
||||||
|
|
||||||
#: allianceauth/authentication/views.py:206
|
#: allianceauth/authentication/views.py:211
|
||||||
msgid "Confirmed your email address. Please login to continue."
|
msgid "Confirmed your email address. Please login to continue."
|
||||||
msgstr "이메일 주소가 확인되었습니다. 로그인 해주세요."
|
msgstr "이메일 주소가 확인되었습니다. 로그인 해주세요."
|
||||||
|
|
||||||
#: allianceauth/authentication/views.py:211
|
#: allianceauth/authentication/views.py:216
|
||||||
msgid "Registraion of new accounts it not allowed at this time."
|
msgid "Registration of new accounts is not allowed at this time."
|
||||||
msgstr "현재 새로운 계정 등록은 받지않습니다."
|
msgstr "현재 새로운 계정 등록은 받지않습니다."
|
||||||
|
|
||||||
#: allianceauth/corputils/auth_hooks.py:10
|
#: allianceauth/corputils/auth_hooks.py:10
|
||||||
@@ -226,16 +227,16 @@ msgstr "마지막 업데이트"
|
|||||||
#: allianceauth/corputils/templates/corputils/search.html:13
|
#: allianceauth/corputils/templates/corputils/search.html:13
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html:24
|
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html:24
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:28
|
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:28
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:27
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:30
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:29
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:30
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:51
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:51
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:110
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:109
|
||||||
msgid "Character"
|
msgid "Character"
|
||||||
msgstr "캐릭터"
|
msgstr "캐릭터"
|
||||||
|
|
||||||
#: allianceauth/corputils/templates/corputils/corpstats.html:76
|
#: allianceauth/corputils/templates/corputils/corpstats.html:76
|
||||||
#: allianceauth/corputils/templates/corputils/search.html:14
|
#: allianceauth/corputils/templates/corputils/search.html:14
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:28
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:31
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:27
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:27
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:84
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:84
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:129
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:129
|
||||||
@@ -542,36 +543,35 @@ msgstr "플릿 참여 등록됨"
|
|||||||
msgid "FAT link has expired."
|
msgid "FAT link has expired."
|
||||||
msgstr "플릿활동추적 링크 기한만료"
|
msgstr "플릿활동추적 링크 기한만료"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/auth_hooks.py:16
|
#: allianceauth/groupmanagement/auth_hooks.py:17
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:15
|
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:14
|
||||||
msgid "Group Management"
|
msgid "Group Management"
|
||||||
msgstr "그룹 관리"
|
msgstr "그룹 관리"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:5
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:5
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:13
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:14
|
||||||
msgid "Audit Log"
|
msgid "Audit Log"
|
||||||
msgstr "감사 기록"
|
msgstr "감사 기록"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:18
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:20
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:20
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:21
|
||||||
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:13
|
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:13
|
||||||
msgid "Back"
|
msgid "Back"
|
||||||
msgstr "돌아가기"
|
msgstr "돌아가기"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:25
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:28
|
||||||
msgid "Date/Time"
|
msgid "Date/Time"
|
||||||
msgstr "날짜/시간"
|
msgstr "날짜/시간"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:26
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:29
|
||||||
msgid "Requestor"
|
msgid "Requestor"
|
||||||
msgstr "요청인"
|
msgstr "요청인"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:29
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:32
|
||||||
msgid "Type"
|
msgid "Type"
|
||||||
msgstr "타입"
|
msgstr "타입"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:30
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:33
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:17
|
|
||||||
#: allianceauth/notifications/templates/notifications/list.html:37
|
#: allianceauth/notifications/templates/notifications/list.html:37
|
||||||
#: allianceauth/notifications/templates/notifications/list.html:69
|
#: allianceauth/notifications/templates/notifications/list.html:69
|
||||||
#: allianceauth/optimer/templates/optimer/fleetoptable.html:18
|
#: allianceauth/optimer/templates/optimer/fleetoptable.html:18
|
||||||
@@ -582,11 +582,19 @@ msgstr "타입"
|
|||||||
msgid "Action"
|
msgid "Action"
|
||||||
msgstr "활동"
|
msgstr "활동"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:31
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:34
|
||||||
msgid "Actor"
|
msgid "Actor"
|
||||||
msgstr "활동한 사람"
|
msgstr "활동한 사람"
|
||||||
|
|
||||||
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:47
|
||||||
|
msgid "Removed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:59
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:59
|
||||||
|
msgid "All times displayed are EVE/UTC."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:66
|
||||||
msgid "No entries found for this group."
|
msgid "No entries found for this group."
|
||||||
msgstr "이 그룹에는 항목 없음"
|
msgstr "이 그룹에는 항목 없음"
|
||||||
|
|
||||||
@@ -594,22 +602,24 @@ msgstr "이 그룹에는 항목 없음"
|
|||||||
msgid "Group Members"
|
msgid "Group Members"
|
||||||
msgstr "그룹 멤버"
|
msgstr "그룹 멤버"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:28
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:31
|
||||||
msgid "Portrait"
|
|
||||||
msgstr "포트레잇"
|
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:30
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:52
|
#: 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
|
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:23
|
||||||
msgid "Organization"
|
msgid "Organization"
|
||||||
msgstr "조직"
|
msgstr "조직"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:64
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:61
|
||||||
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:78
|
||||||
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:136
|
||||||
|
msgid "(unknown)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:66
|
||||||
msgid "Remove from group"
|
msgid "Remove from group"
|
||||||
msgstr "그룹에서 제거"
|
msgstr "그룹에서 제거"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:76
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:81
|
||||||
msgid "No group members to list."
|
msgid "No group members to list."
|
||||||
msgstr "목록에 그룹 멤버 없음"
|
msgstr "목록에 그룹 멤버 없음"
|
||||||
|
|
||||||
@@ -617,18 +627,18 @@ msgstr "목록에 그룹 멤버 없음"
|
|||||||
msgid "Groups Membership"
|
msgid "Groups Membership"
|
||||||
msgstr "그룹 멤버쉽"
|
msgstr "그룹 멤버쉽"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:14
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:15
|
||||||
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:40
|
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:40
|
||||||
#: allianceauth/templates/allianceauth/side-menu.html:16
|
#: allianceauth/templates/allianceauth/side-menu.html:16
|
||||||
msgid "Groups"
|
msgid "Groups"
|
||||||
msgstr "그룹"
|
msgstr "그룹"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:23
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:25
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:16
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:16
|
||||||
msgid "Description"
|
msgid "Description"
|
||||||
msgstr "설명"
|
msgstr "설명"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:24
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:26
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:28
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:28
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:85
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:85
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:130
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:130
|
||||||
@@ -637,36 +647,36 @@ msgstr "설명"
|
|||||||
msgid "Status"
|
msgid "Status"
|
||||||
msgstr "상태"
|
msgstr "상태"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:25
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:27
|
||||||
msgid "Member Count"
|
msgid "Member Count"
|
||||||
msgstr "멤버 수"
|
msgstr "멤버 수"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:38
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:43
|
||||||
msgid "Hidden"
|
msgid "Hidden"
|
||||||
msgstr "숨김"
|
msgstr "숨김"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:40
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:45
|
||||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:12
|
#: allianceauth/templates/allianceauth/admin-status/overview.html:12
|
||||||
msgid "Open"
|
msgid "Open"
|
||||||
msgstr "열기"
|
msgstr "열기"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:42
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:47
|
||||||
msgid "Requestable"
|
msgid "Requestable"
|
||||||
msgstr "요청 가능"
|
msgstr "요청 가능"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:50
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:56
|
||||||
msgid "View Members"
|
msgid "View Members"
|
||||||
msgstr "멤버 보기"
|
msgstr "멤버 보기"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:53
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:60
|
||||||
msgid "Audit Members"
|
msgid "Audit Members"
|
||||||
msgstr "멤버 검사"
|
msgstr "멤버 검사"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:56
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:64
|
||||||
msgid "Copy Direct Join Link"
|
msgid "Copy Direct Join Link"
|
||||||
msgstr "직접 참여 링크 복사"
|
msgstr "직접 참여 링크 복사"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:68
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:75
|
||||||
msgid "No groups to list."
|
msgid "No groups to list."
|
||||||
msgstr "목록에 그룹 없음"
|
msgstr "목록에 그룹 없음"
|
||||||
|
|
||||||
@@ -675,19 +685,19 @@ msgstr "목록에 그룹 없음"
|
|||||||
msgid "Available Groups"
|
msgid "Available Groups"
|
||||||
msgstr "사용 가능한 그룹"
|
msgstr "사용 가능한 그룹"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:29
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:30
|
||||||
msgid "Leave"
|
msgid "Leave"
|
||||||
msgstr "떠나기"
|
msgstr "떠나기"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:39
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:40
|
||||||
msgid "Join"
|
msgid "Join"
|
||||||
msgstr "참여하기"
|
msgstr "참여하기"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:43
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:44
|
||||||
msgid "Request"
|
msgid "Request"
|
||||||
msgstr "요청하기"
|
msgstr "요청하기"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:58
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:59
|
||||||
msgid "No groups available."
|
msgid "No groups available."
|
||||||
msgstr "사용 가능한 그룹 없음."
|
msgstr "사용 가능한 그룹 없음."
|
||||||
|
|
||||||
@@ -699,24 +709,24 @@ msgstr "그룹 관리"
|
|||||||
msgid "Join Requests"
|
msgid "Join Requests"
|
||||||
msgstr "가입 요청"
|
msgstr "가입 요청"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:33
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:34
|
||||||
msgid "Leave Requests"
|
msgid "Leave Requests"
|
||||||
msgstr "탈퇴 요청"
|
msgstr "탈퇴 요청"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:53
|
#: 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/permissions_tool/templates/permissions_tool/audit.html:20
|
||||||
#: allianceauth/services/modules/openfire/forms.py:6
|
#: allianceauth/services/modules/openfire/forms.py:6
|
||||||
msgid "Group"
|
msgid "Group"
|
||||||
msgstr "그룹"
|
msgstr "그룹"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:85
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:84
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:144
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:142
|
||||||
msgid "Accept"
|
msgid "Accept"
|
||||||
msgstr "수락"
|
msgstr "수락"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:88
|
#: 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
|
#: allianceauth/hrapplications/templates/hrapplications/view.html:85
|
||||||
msgid "Reject"
|
msgid "Reject"
|
||||||
msgstr "거절"
|
msgstr "거절"
|
||||||
@@ -725,19 +735,19 @@ msgstr "거절"
|
|||||||
msgid "No group add requests."
|
msgid "No group add requests."
|
||||||
msgstr "가입 요청 없음"
|
msgstr "가입 요청 없음"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:156
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:155
|
||||||
msgid "No group leave requests."
|
msgid "No group leave requests."
|
||||||
msgstr "탈퇴 요청 없음"
|
msgstr "탈퇴 요청 없음"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:10
|
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:9
|
||||||
msgid "Toggle navigation"
|
msgid "Toggle navigation"
|
||||||
msgstr "네비게이션 전환"
|
msgstr "네비게이션 전환"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:21
|
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:20
|
||||||
msgid "Group Requests"
|
msgid "Group Requests"
|
||||||
msgstr "그룹 요청"
|
msgstr "그룹 요청"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:24
|
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:23
|
||||||
msgid "Group Membership"
|
msgid "Group Membership"
|
||||||
msgstr "그룹 멤버쉽"
|
msgstr "그룹 멤버쉽"
|
||||||
|
|
||||||
@@ -1302,7 +1312,7 @@ msgstr "디스코드 계정 비활성화"
|
|||||||
|
|
||||||
#: allianceauth/services/modules/discord/models.py:227
|
#: allianceauth/services/modules/discord/models.py:227
|
||||||
msgid ""
|
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."
|
"was a mistake, please contact an admin."
|
||||||
msgstr "Auth에 의해 자동으로 디스코드 계정이 비활성화됐습니다. 원치 않는 사항일 경우, 관리자에게 문의해 주세요."
|
msgstr "Auth에 의해 자동으로 디스코드 계정이 비활성화됐습니다. 원치 않는 사항일 경우, 관리자에게 문의해 주세요."
|
||||||
|
|
||||||
@@ -2057,3 +2067,6 @@ msgstr "%(time)s 에 있을 %(system)s 타이머를 추가했습니다."
|
|||||||
#: allianceauth/timerboard/views.py:83
|
#: allianceauth/timerboard/views.py:83
|
||||||
msgid "Saved changes to the timer."
|
msgid "Saved changes to the timer."
|
||||||
msgstr "타이머 변경사항이 저장되었습니다."
|
msgstr "타이머 변경사항이 저장되었습니다."
|
||||||
|
|
||||||
|
#~ msgid "Portrait"
|
||||||
|
#~ msgstr "포트레잇"
|
||||||
|
|||||||
Binary file not shown.
@@ -5,15 +5,17 @@
|
|||||||
#
|
#
|
||||||
# Translators:
|
# Translators:
|
||||||
# Alexander Gess <de.alex.gess@gmail.com>, 2020
|
# Alexander Gess <de.alex.gess@gmail.com>, 2020
|
||||||
|
# Yuriy K <thedjcooltv@gmail.com>, 2020
|
||||||
|
# Андрей Зубков <and.vareba81@gmail.com>, 2020
|
||||||
#
|
#
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2020-10-11 03:43+0000\n"
|
"POT-Creation-Date: 2020-11-20 05:33+0000\n"
|
||||||
"PO-Revision-Date: 2020-02-18 03:14+0000\n"
|
"PO-Revision-Date: 2020-02-18 03:14+0000\n"
|
||||||
"Last-Translator: Alexander Gess <de.alex.gess@gmail.com>, 2020\n"
|
"Last-Translator: Андрей Зубков <and.vareba81@gmail.com>, 2020\n"
|
||||||
"Language-Team: Russian (https://www.transifex.com/alliance-auth/teams/107430/ru/)\n"
|
"Language-Team: Russian (https://www.transifex.com/alliance-auth/teams/107430/ru/)\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
@@ -70,7 +72,7 @@ msgstr "Сменить основного персонажа"
|
|||||||
|
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:101
|
#: allianceauth/authentication/templates/authentication/dashboard.html:101
|
||||||
msgid "Group Memberships"
|
msgid "Group Memberships"
|
||||||
msgstr "Групповое участие"
|
msgstr "Роли"
|
||||||
|
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:121
|
#: allianceauth/authentication/templates/authentication/dashboard.html:121
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticscorpview.html:23
|
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkstatisticscorpview.html:23
|
||||||
@@ -80,7 +82,7 @@ msgstr "Персонажи"
|
|||||||
|
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:129
|
#: allianceauth/authentication/templates/authentication/dashboard.html:129
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:73
|
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:73
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:22
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:24
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:15
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:15
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:45
|
#: allianceauth/hrapplications/templates/hrapplications/view.html:45
|
||||||
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:34
|
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:34
|
||||||
@@ -163,23 +165,23 @@ msgstr "Персонаж %(name)s уже добавлен."
|
|||||||
msgid "Unable to authenticate as the selected character."
|
msgid "Unable to authenticate as the selected character."
|
||||||
msgstr "Невозможно авторизировать этого персонажа. "
|
msgstr "Невозможно авторизировать этого персонажа. "
|
||||||
|
|
||||||
#: allianceauth/authentication/views.py:146
|
#: allianceauth/authentication/views.py:151
|
||||||
msgid "Registration token has expired."
|
msgid "Registration token has expired."
|
||||||
msgstr "Регистрационный токен просрочен."
|
msgstr "Регистрационный токен просрочен."
|
||||||
|
|
||||||
#: allianceauth/authentication/views.py:201
|
#: allianceauth/authentication/views.py:206
|
||||||
msgid ""
|
msgid ""
|
||||||
"Sent confirmation email. Please follow the link to confirm your email "
|
"Sent confirmation email. Please follow the link to confirm your email "
|
||||||
"address."
|
"address."
|
||||||
msgstr "Отправить подтверждающее письмо. Пожалуйста, подтвердите почту. "
|
msgstr "Отправить подтверждающее письмо. Пожалуйста, подтвердите почту. "
|
||||||
|
|
||||||
#: allianceauth/authentication/views.py:206
|
#: allianceauth/authentication/views.py:211
|
||||||
msgid "Confirmed your email address. Please login to continue."
|
msgid "Confirmed your email address. Please login to continue."
|
||||||
msgstr "Подтвердите Ваш email адрес. Зайти для подтверждения. "
|
msgstr "Подтвердите Ваш email адрес. Зайти для подтверждения. "
|
||||||
|
|
||||||
#: allianceauth/authentication/views.py:211
|
#: allianceauth/authentication/views.py:216
|
||||||
msgid "Registraion of new accounts it not allowed at this time."
|
msgid "Registration of new accounts is not allowed at this time."
|
||||||
msgstr "Регистрация нового аккаунта сейчас невозможна."
|
msgstr "Регистрация новых аккаунтов в настоящее время невозможна."
|
||||||
|
|
||||||
#: allianceauth/corputils/auth_hooks.py:10
|
#: allianceauth/corputils/auth_hooks.py:10
|
||||||
msgid "Corporation Stats"
|
msgid "Corporation Stats"
|
||||||
@@ -226,16 +228,16 @@ msgstr "Последнее обновление: "
|
|||||||
#: allianceauth/corputils/templates/corputils/search.html:13
|
#: allianceauth/corputils/templates/corputils/search.html:13
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html:24
|
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html:24
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:28
|
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:28
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:27
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:30
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:29
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:30
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:51
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:51
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:110
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:109
|
||||||
msgid "Character"
|
msgid "Character"
|
||||||
msgstr "Персонаж"
|
msgstr "Персонаж"
|
||||||
|
|
||||||
#: allianceauth/corputils/templates/corputils/corpstats.html:76
|
#: allianceauth/corputils/templates/corputils/corpstats.html:76
|
||||||
#: allianceauth/corputils/templates/corputils/search.html:14
|
#: allianceauth/corputils/templates/corputils/search.html:14
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:28
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:31
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:27
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:27
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:84
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:84
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:129
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:129
|
||||||
@@ -326,7 +328,7 @@ msgstr "Добавить сюда"
|
|||||||
|
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/characternotexisting.html:19
|
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/characternotexisting.html:19
|
||||||
msgid "before attempting to click fleet attendance links."
|
msgid "before attempting to click fleet attendance links."
|
||||||
msgstr "перед вступлением проверте содержимое"
|
msgstr "перед вступлением проверьте содержимое"
|
||||||
|
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkformatter.html:6
|
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkformatter.html:6
|
||||||
msgid "Create Fatlink"
|
msgid "Create Fatlink"
|
||||||
@@ -548,36 +550,35 @@ msgstr "Флотовое участие зарегистрированно."
|
|||||||
msgid "FAT link has expired."
|
msgid "FAT link has expired."
|
||||||
msgstr "ФлАк ссылка устарела"
|
msgstr "ФлАк ссылка устарела"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/auth_hooks.py:16
|
#: allianceauth/groupmanagement/auth_hooks.py:17
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:15
|
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:14
|
||||||
msgid "Group Management"
|
msgid "Group Management"
|
||||||
msgstr "Управление Группой"
|
msgstr "Управление Группой"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:5
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:5
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:13
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:14
|
||||||
msgid "Audit Log"
|
msgid "Audit Log"
|
||||||
msgstr "Записи безопасности"
|
msgstr "Записи безопасности"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:18
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:20
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:20
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:21
|
||||||
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:13
|
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:13
|
||||||
msgid "Back"
|
msgid "Back"
|
||||||
msgstr "Назад"
|
msgstr "Назад"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:25
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:28
|
||||||
msgid "Date/Time"
|
msgid "Date/Time"
|
||||||
msgstr "Дата / Время"
|
msgstr "Дата / Время"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:26
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:29
|
||||||
msgid "Requestor"
|
msgid "Requestor"
|
||||||
msgstr "Запрос от"
|
msgstr "Запрос от"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:29
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:32
|
||||||
msgid "Type"
|
msgid "Type"
|
||||||
msgstr "Тип"
|
msgstr "Тип"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:30
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:33
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:17
|
|
||||||
#: allianceauth/notifications/templates/notifications/list.html:37
|
#: allianceauth/notifications/templates/notifications/list.html:37
|
||||||
#: allianceauth/notifications/templates/notifications/list.html:69
|
#: allianceauth/notifications/templates/notifications/list.html:69
|
||||||
#: allianceauth/optimer/templates/optimer/fleetoptable.html:18
|
#: allianceauth/optimer/templates/optimer/fleetoptable.html:18
|
||||||
@@ -588,11 +589,19 @@ msgstr "Тип"
|
|||||||
msgid "Action"
|
msgid "Action"
|
||||||
msgstr "Действие"
|
msgstr "Действие"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:31
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:34
|
||||||
msgid "Actor"
|
msgid "Actor"
|
||||||
msgstr "Исполнитель"
|
msgstr "Исполнитель"
|
||||||
|
|
||||||
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:47
|
||||||
|
msgid "Removed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:59
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:59
|
||||||
|
msgid "All times displayed are EVE/UTC."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:66
|
||||||
msgid "No entries found for this group."
|
msgid "No entries found for this group."
|
||||||
msgstr "Нет вхождений в эту группу"
|
msgstr "Нет вхождений в эту группу"
|
||||||
|
|
||||||
@@ -600,22 +609,24 @@ msgstr "Нет вхождений в эту группу"
|
|||||||
msgid "Group Members"
|
msgid "Group Members"
|
||||||
msgstr "Групповые Участники"
|
msgstr "Групповые Участники"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:28
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:31
|
||||||
msgid "Portrait"
|
|
||||||
msgstr "Портрет"
|
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:30
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:52
|
#: 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
|
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:23
|
||||||
msgid "Organization"
|
msgid "Organization"
|
||||||
msgstr "Корпорация"
|
msgstr "Корпорация"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:64
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:61
|
||||||
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:78
|
||||||
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:136
|
||||||
|
msgid "(unknown)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:66
|
||||||
msgid "Remove from group"
|
msgid "Remove from group"
|
||||||
msgstr "Исключить из группы"
|
msgstr "Исключить из группы"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:76
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:81
|
||||||
msgid "No group members to list."
|
msgid "No group members to list."
|
||||||
msgstr "Нет участников в группе"
|
msgstr "Нет участников в группе"
|
||||||
|
|
||||||
@@ -623,18 +634,18 @@ msgstr "Нет участников в группе"
|
|||||||
msgid "Groups Membership"
|
msgid "Groups Membership"
|
||||||
msgstr "Участники группы"
|
msgstr "Участники группы"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:14
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:15
|
||||||
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:40
|
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:40
|
||||||
#: allianceauth/templates/allianceauth/side-menu.html:16
|
#: allianceauth/templates/allianceauth/side-menu.html:16
|
||||||
msgid "Groups"
|
msgid "Groups"
|
||||||
msgstr "Группы"
|
msgstr "Группы"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:23
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:25
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:16
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:16
|
||||||
msgid "Description"
|
msgid "Description"
|
||||||
msgstr "Описание"
|
msgstr "Описание"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:24
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:26
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:28
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:28
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:85
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:85
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:130
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:130
|
||||||
@@ -643,36 +654,36 @@ msgstr "Описание"
|
|||||||
msgid "Status"
|
msgid "Status"
|
||||||
msgstr "Статус"
|
msgstr "Статус"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:25
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:27
|
||||||
msgid "Member Count"
|
msgid "Member Count"
|
||||||
msgstr "Число участников"
|
msgstr "Число участников"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:38
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:43
|
||||||
msgid "Hidden"
|
msgid "Hidden"
|
||||||
msgstr "Скрытые"
|
msgstr "Скрытые"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:40
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:45
|
||||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:12
|
#: allianceauth/templates/allianceauth/admin-status/overview.html:12
|
||||||
msgid "Open"
|
msgid "Open"
|
||||||
msgstr "Открыть"
|
msgstr "Открыть"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:42
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:47
|
||||||
msgid "Requestable"
|
msgid "Requestable"
|
||||||
msgstr "Запрошено"
|
msgstr "Запрошено"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:50
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:56
|
||||||
msgid "View Members"
|
msgid "View Members"
|
||||||
msgstr "Посмотреть участников"
|
msgstr "Посмотреть участников"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:53
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:60
|
||||||
msgid "Audit Members"
|
msgid "Audit Members"
|
||||||
msgstr "Проверить участников"
|
msgstr "Проверить участников"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:56
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:64
|
||||||
msgid "Copy Direct Join Link"
|
msgid "Copy Direct Join Link"
|
||||||
msgstr "Скопировать ссылку подключения"
|
msgstr "Скопировать ссылку подключения"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:68
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:75
|
||||||
msgid "No groups to list."
|
msgid "No groups to list."
|
||||||
msgstr "Нет групп в списке"
|
msgstr "Нет групп в списке"
|
||||||
|
|
||||||
@@ -681,19 +692,19 @@ msgstr "Нет групп в списке"
|
|||||||
msgid "Available Groups"
|
msgid "Available Groups"
|
||||||
msgstr "Доступные группы"
|
msgstr "Доступные группы"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:29
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:30
|
||||||
msgid "Leave"
|
msgid "Leave"
|
||||||
msgstr "Покинуть"
|
msgstr "Покинуть"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:39
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:40
|
||||||
msgid "Join"
|
msgid "Join"
|
||||||
msgstr "Присоединиться"
|
msgstr "Присоединиться"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:43
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:44
|
||||||
msgid "Request"
|
msgid "Request"
|
||||||
msgstr "Запрос"
|
msgstr "Запрос"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:58
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:59
|
||||||
msgid "No groups available."
|
msgid "No groups available."
|
||||||
msgstr "Нет доступных групп."
|
msgstr "Нет доступных групп."
|
||||||
|
|
||||||
@@ -705,24 +716,24 @@ msgstr "Управление Группами"
|
|||||||
msgid "Join Requests"
|
msgid "Join Requests"
|
||||||
msgstr "Запрос на присоединение"
|
msgstr "Запрос на присоединение"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:33
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:34
|
||||||
msgid "Leave Requests"
|
msgid "Leave Requests"
|
||||||
msgstr "Запрос на Выход"
|
msgstr "Запрос на Выход"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:53
|
#: 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/permissions_tool/templates/permissions_tool/audit.html:20
|
||||||
#: allianceauth/services/modules/openfire/forms.py:6
|
#: allianceauth/services/modules/openfire/forms.py:6
|
||||||
msgid "Group"
|
msgid "Group"
|
||||||
msgstr "Группа"
|
msgstr "Группа"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:85
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:84
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:144
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:142
|
||||||
msgid "Accept"
|
msgid "Accept"
|
||||||
msgstr "Принять"
|
msgstr "Принять"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:88
|
#: 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
|
#: allianceauth/hrapplications/templates/hrapplications/view.html:85
|
||||||
msgid "Reject"
|
msgid "Reject"
|
||||||
msgstr "Сбросить"
|
msgstr "Сбросить"
|
||||||
@@ -731,19 +742,19 @@ msgstr "Сбросить"
|
|||||||
msgid "No group add requests."
|
msgid "No group add requests."
|
||||||
msgstr "Нет групповых запросов на вступление"
|
msgstr "Нет групповых запросов на вступление"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:156
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:155
|
||||||
msgid "No group leave requests."
|
msgid "No group leave requests."
|
||||||
msgstr "Нет групповых запросов на выход"
|
msgstr "Нет групповых запросов на выход"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:10
|
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:9
|
||||||
msgid "Toggle navigation"
|
msgid "Toggle navigation"
|
||||||
msgstr "Проложить маршрут"
|
msgstr "Проложить маршрут"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:21
|
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:20
|
||||||
msgid "Group Requests"
|
msgid "Group Requests"
|
||||||
msgstr "Групповой запрос"
|
msgstr "Групповой запрос"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:24
|
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:23
|
||||||
msgid "Group Membership"
|
msgid "Group Membership"
|
||||||
msgstr "Групповое участие"
|
msgstr "Групповое участие"
|
||||||
|
|
||||||
@@ -1029,7 +1040,7 @@ msgstr "Не прочитанно"
|
|||||||
|
|
||||||
#: allianceauth/notifications/templates/notifications/list.html:18
|
#: allianceauth/notifications/templates/notifications/list.html:18
|
||||||
msgid "Read"
|
msgid "Read"
|
||||||
msgstr "Прочитать"
|
msgstr "Прочитано"
|
||||||
|
|
||||||
#: allianceauth/notifications/templates/notifications/list.html:22
|
#: allianceauth/notifications/templates/notifications/list.html:22
|
||||||
msgid "Mark All Read"
|
msgid "Mark All Read"
|
||||||
@@ -1137,7 +1148,7 @@ msgstr "Таймера Флотовых операций"
|
|||||||
#: allianceauth/optimer/templates/optimer/management.html:21
|
#: allianceauth/optimer/templates/optimer/management.html:21
|
||||||
#: allianceauth/timerboard/templates/timerboard/view.html:23
|
#: allianceauth/timerboard/templates/timerboard/view.html:23
|
||||||
msgid "Current Eve Time:"
|
msgid "Current Eve Time:"
|
||||||
msgstr "ET"
|
msgstr "Текущий EVE Time:"
|
||||||
|
|
||||||
#: allianceauth/optimer/templates/optimer/management.html:27
|
#: allianceauth/optimer/templates/optimer/management.html:27
|
||||||
#: allianceauth/timerboard/templates/timerboard/view.html:189
|
#: allianceauth/timerboard/templates/timerboard/view.html:189
|
||||||
@@ -1244,7 +1255,7 @@ msgstr "{} Пароль успешно обновлен."
|
|||||||
|
|
||||||
#: allianceauth/services/auth_hooks.py:11
|
#: allianceauth/services/auth_hooks.py:11
|
||||||
msgid "Services"
|
msgid "Services"
|
||||||
msgstr "Сервисные услуги"
|
msgstr "Подключение сервисов"
|
||||||
|
|
||||||
#: allianceauth/services/forms.py:6
|
#: allianceauth/services/forms.py:6
|
||||||
msgid "Name of Fleet:"
|
msgid "Name of Fleet:"
|
||||||
@@ -1312,11 +1323,9 @@ msgstr "Discord персонаж отключен"
|
|||||||
|
|
||||||
#: allianceauth/services/modules/discord/models.py:227
|
#: allianceauth/services/modules/discord/models.py:227
|
||||||
msgid ""
|
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."
|
"was a mistake, please contact an admin."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Ваш доступ на сервер Discord был отменен. Если Вы считаете что по ошибке, "
|
|
||||||
"пожалуйста, свяжитесь с СЕО."
|
|
||||||
|
|
||||||
#: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:18
|
#: allianceauth/services/modules/discord/templates/services/discord/discord_service_ctrl.html:18
|
||||||
msgid "Join the Discord server"
|
msgid "Join the Discord server"
|
||||||
@@ -1625,7 +1634,7 @@ msgstr "Домен"
|
|||||||
|
|
||||||
#: allianceauth/srp/auth_hooks.py:12
|
#: allianceauth/srp/auth_hooks.py:12
|
||||||
msgid "Ship Replacement"
|
msgid "Ship Replacement"
|
||||||
msgstr "Замена корабля"
|
msgstr "Компенсация корабля"
|
||||||
|
|
||||||
#: allianceauth/srp/form.py:7
|
#: allianceauth/srp/form.py:7
|
||||||
#: allianceauth/srp/templates/srp/management.html:38
|
#: allianceauth/srp/templates/srp/management.html:38
|
||||||
@@ -1974,14 +1983,14 @@ msgstr "Прочие"
|
|||||||
#: allianceauth/timerboard/templates/timerboard/view.html:220
|
#: allianceauth/timerboard/templates/timerboard/view.html:220
|
||||||
#: allianceauth/timerboard/templates/timerboard/view.html:388
|
#: allianceauth/timerboard/templates/timerboard/view.html:388
|
||||||
msgid "Friendly"
|
msgid "Friendly"
|
||||||
msgstr "Дружествен"
|
msgstr "Дружественный"
|
||||||
|
|
||||||
#: allianceauth/timerboard/form.py:55
|
#: allianceauth/timerboard/form.py:55
|
||||||
#: allianceauth/timerboard/templates/timerboard/view.html:53
|
#: allianceauth/timerboard/templates/timerboard/view.html:53
|
||||||
#: allianceauth/timerboard/templates/timerboard/view.html:215
|
#: allianceauth/timerboard/templates/timerboard/view.html:215
|
||||||
#: allianceauth/timerboard/templates/timerboard/view.html:383
|
#: allianceauth/timerboard/templates/timerboard/view.html:383
|
||||||
msgid "Hostile"
|
msgid "Hostile"
|
||||||
msgstr "Заложник"
|
msgstr "Вражеский"
|
||||||
|
|
||||||
#: allianceauth/timerboard/form.py:56
|
#: allianceauth/timerboard/form.py:56
|
||||||
#: allianceauth/timerboard/templates/timerboard/view.html:63
|
#: allianceauth/timerboard/templates/timerboard/view.html:63
|
||||||
@@ -2083,3 +2092,6 @@ msgstr "Добавлен таймер в %(system)s на %(time)s."
|
|||||||
#: allianceauth/timerboard/views.py:83
|
#: allianceauth/timerboard/views.py:83
|
||||||
msgid "Saved changes to the timer."
|
msgid "Saved changes to the timer."
|
||||||
msgstr "Изменения сохранены"
|
msgstr "Изменения сохранены"
|
||||||
|
|
||||||
|
#~ msgid "Portrait"
|
||||||
|
#~ msgstr "Портрет"
|
||||||
|
|||||||
Binary file not shown.
@@ -4,18 +4,18 @@
|
|||||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||||
#
|
#
|
||||||
# Translators:
|
# Translators:
|
||||||
|
# Joel Falknau <ozirascal@gmail.com>, 2020
|
||||||
# Jesse . <sgeine@hotmail.com>, 2020
|
# Jesse . <sgeine@hotmail.com>, 2020
|
||||||
# Aaron BuBu <351793078@qq.com>, 2020
|
# Aaron BuBu <351793078@qq.com>, 2020
|
||||||
# Joel Falknau <ozirascal@gmail.com>, 2020
|
|
||||||
#
|
#
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2020-10-11 03:43+0000\n"
|
"POT-Creation-Date: 2020-11-20 05:33+0000\n"
|
||||||
"PO-Revision-Date: 2020-02-18 03:14+0000\n"
|
"PO-Revision-Date: 2020-02-18 03:14+0000\n"
|
||||||
"Last-Translator: Joel Falknau <ozirascal@gmail.com>, 2020\n"
|
"Last-Translator: Aaron BuBu <351793078@qq.com>, 2020\n"
|
||||||
"Language-Team: Chinese Simplified (https://www.transifex.com/alliance-auth/teams/107430/zh-Hans/)\n"
|
"Language-Team: Chinese Simplified (https://www.transifex.com/alliance-auth/teams/107430/zh-Hans/)\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
@@ -79,7 +79,7 @@ msgstr "角色"
|
|||||||
|
|
||||||
#: allianceauth/authentication/templates/authentication/dashboard.html:129
|
#: allianceauth/authentication/templates/authentication/dashboard.html:129
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:73
|
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:73
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:22
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:24
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:15
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:15
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/view.html:45
|
#: allianceauth/hrapplications/templates/hrapplications/view.html:45
|
||||||
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:34
|
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:34
|
||||||
@@ -159,23 +159,23 @@ msgstr "添加%(name)s到您的账户失败:他们已经在一个账户中了"
|
|||||||
msgid "Unable to authenticate as the selected character."
|
msgid "Unable to authenticate as the selected character."
|
||||||
msgstr "无法作为选定的角色进行身份验证"
|
msgstr "无法作为选定的角色进行身份验证"
|
||||||
|
|
||||||
#: allianceauth/authentication/views.py:146
|
#: allianceauth/authentication/views.py:151
|
||||||
msgid "Registration token has expired."
|
msgid "Registration token has expired."
|
||||||
msgstr "注册令牌过期。"
|
msgstr "注册令牌过期。"
|
||||||
|
|
||||||
#: allianceauth/authentication/views.py:201
|
#: allianceauth/authentication/views.py:206
|
||||||
msgid ""
|
msgid ""
|
||||||
"Sent confirmation email. Please follow the link to confirm your email "
|
"Sent confirmation email. Please follow the link to confirm your email "
|
||||||
"address."
|
"address."
|
||||||
msgstr "已经发送了确认邮件。请按照链接确定您的电邮地址"
|
msgstr "已经发送了确认邮件。请按照链接确定您的电邮地址"
|
||||||
|
|
||||||
#: allianceauth/authentication/views.py:206
|
#: allianceauth/authentication/views.py:211
|
||||||
msgid "Confirmed your email address. Please login to continue."
|
msgid "Confirmed your email address. Please login to continue."
|
||||||
msgstr "已确认您的电邮地址。请登录以继续"
|
msgstr "已确认您的电邮地址。请登录以继续"
|
||||||
|
|
||||||
#: allianceauth/authentication/views.py:211
|
#: allianceauth/authentication/views.py:216
|
||||||
msgid "Registraion of new accounts it not allowed at this time."
|
msgid "Registration of new accounts is not allowed at this time."
|
||||||
msgstr "现在不允许注册新账户。"
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/corputils/auth_hooks.py:10
|
#: allianceauth/corputils/auth_hooks.py:10
|
||||||
msgid "Corporation Stats"
|
msgid "Corporation Stats"
|
||||||
@@ -222,16 +222,16 @@ msgstr "最后一次更新"
|
|||||||
#: allianceauth/corputils/templates/corputils/search.html:13
|
#: allianceauth/corputils/templates/corputils/search.html:13
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html:24
|
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html:24
|
||||||
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:28
|
#: allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkview.html:28
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:27
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:30
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:29
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:30
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:51
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:51
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:110
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:109
|
||||||
msgid "Character"
|
msgid "Character"
|
||||||
msgstr "角色"
|
msgstr "角色"
|
||||||
|
|
||||||
#: allianceauth/corputils/templates/corputils/corpstats.html:76
|
#: allianceauth/corputils/templates/corputils/corpstats.html:76
|
||||||
#: allianceauth/corputils/templates/corputils/search.html:14
|
#: allianceauth/corputils/templates/corputils/search.html:14
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:28
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:31
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:27
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:27
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:84
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:84
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:129
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:129
|
||||||
@@ -538,36 +538,35 @@ msgstr "成功注册舰队PAP"
|
|||||||
msgid "FAT link has expired."
|
msgid "FAT link has expired."
|
||||||
msgstr "PAP链接已过期"
|
msgstr "PAP链接已过期"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/auth_hooks.py:16
|
#: allianceauth/groupmanagement/auth_hooks.py:17
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:15
|
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:14
|
||||||
msgid "Group Management"
|
msgid "Group Management"
|
||||||
msgstr "用户组管理"
|
msgstr "用户组管理"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:5
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:5
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:13
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:14
|
||||||
msgid "Audit Log"
|
msgid "Audit Log"
|
||||||
msgstr "审计日志"
|
msgstr "审计日志"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:18
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:20
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:20
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:21
|
||||||
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:13
|
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:13
|
||||||
msgid "Back"
|
msgid "Back"
|
||||||
msgstr "返回"
|
msgstr "返回"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:25
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:28
|
||||||
msgid "Date/Time"
|
msgid "Date/Time"
|
||||||
msgstr "日期/时间"
|
msgstr "日期/时间"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:26
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:29
|
||||||
msgid "Requestor"
|
msgid "Requestor"
|
||||||
msgstr "申请人"
|
msgstr "申请人"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:29
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:32
|
||||||
msgid "Type"
|
msgid "Type"
|
||||||
msgstr "类型"
|
msgstr "类型"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:30
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:33
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:17
|
|
||||||
#: allianceauth/notifications/templates/notifications/list.html:37
|
#: allianceauth/notifications/templates/notifications/list.html:37
|
||||||
#: allianceauth/notifications/templates/notifications/list.html:69
|
#: allianceauth/notifications/templates/notifications/list.html:69
|
||||||
#: allianceauth/optimer/templates/optimer/fleetoptable.html:18
|
#: allianceauth/optimer/templates/optimer/fleetoptable.html:18
|
||||||
@@ -578,11 +577,19 @@ msgstr "类型"
|
|||||||
msgid "Action"
|
msgid "Action"
|
||||||
msgstr "操作"
|
msgstr "操作"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:31
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:34
|
||||||
msgid "Actor"
|
msgid "Actor"
|
||||||
msgstr "操作者"
|
msgstr "操作者"
|
||||||
|
|
||||||
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:47
|
||||||
|
msgid "Removed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:59
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:59
|
||||||
|
msgid "All times displayed are EVE/UTC."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: allianceauth/groupmanagement/templates/groupmanagement/audit.html:66
|
||||||
msgid "No entries found for this group."
|
msgid "No entries found for this group."
|
||||||
msgstr "这一用户组下面没有任何条目呀"
|
msgstr "这一用户组下面没有任何条目呀"
|
||||||
|
|
||||||
@@ -590,22 +597,24 @@ msgstr "这一用户组下面没有任何条目呀"
|
|||||||
msgid "Group Members"
|
msgid "Group Members"
|
||||||
msgstr "群组成员"
|
msgstr "群组成员"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:28
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:31
|
||||||
msgid "Portrait"
|
|
||||||
msgstr "人物头像"
|
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:30
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:52
|
#: 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
|
#: allianceauth/permissions_tool/templates/permissions_tool/audit.html:23
|
||||||
msgid "Organization"
|
msgid "Organization"
|
||||||
msgstr "组织"
|
msgstr "组织"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:64
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:61
|
||||||
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:78
|
||||||
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:136
|
||||||
|
msgid "(unknown)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:66
|
||||||
msgid "Remove from group"
|
msgid "Remove from group"
|
||||||
msgstr "从用户组中移除"
|
msgstr "从用户组中移除"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:76
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembers.html:81
|
||||||
msgid "No group members to list."
|
msgid "No group members to list."
|
||||||
msgstr "用户组里没人呀,你叫我怎么列"
|
msgstr "用户组里没人呀,你叫我怎么列"
|
||||||
|
|
||||||
@@ -613,18 +622,18 @@ msgstr "用户组里没人呀,你叫我怎么列"
|
|||||||
msgid "Groups Membership"
|
msgid "Groups Membership"
|
||||||
msgstr "用户组成员"
|
msgstr "用户组成员"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:14
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:15
|
||||||
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:40
|
#: allianceauth/permissions_tool/templates/permissions_tool/overview.html:40
|
||||||
#: allianceauth/templates/allianceauth/side-menu.html:16
|
#: allianceauth/templates/allianceauth/side-menu.html:16
|
||||||
msgid "Groups"
|
msgid "Groups"
|
||||||
msgstr "群组"
|
msgstr "群组"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:23
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:25
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:16
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:16
|
||||||
msgid "Description"
|
msgid "Description"
|
||||||
msgstr "描述"
|
msgstr "描述"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:24
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:26
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:28
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:28
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:85
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:85
|
||||||
#: allianceauth/hrapplications/templates/hrapplications/management.html:130
|
#: allianceauth/hrapplications/templates/hrapplications/management.html:130
|
||||||
@@ -633,36 +642,36 @@ msgstr "描述"
|
|||||||
msgid "Status"
|
msgid "Status"
|
||||||
msgstr "状态"
|
msgstr "状态"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:25
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:27
|
||||||
msgid "Member Count"
|
msgid "Member Count"
|
||||||
msgstr "成员数量"
|
msgstr "成员数量"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:38
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:43
|
||||||
msgid "Hidden"
|
msgid "Hidden"
|
||||||
msgstr "已隐藏"
|
msgstr "已隐藏"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:40
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:45
|
||||||
#: allianceauth/templates/allianceauth/admin-status/overview.html:12
|
#: allianceauth/templates/allianceauth/admin-status/overview.html:12
|
||||||
msgid "Open"
|
msgid "Open"
|
||||||
msgstr "公开"
|
msgstr "公开"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:42
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:47
|
||||||
msgid "Requestable"
|
msgid "Requestable"
|
||||||
msgstr "可申请"
|
msgstr "可申请"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:50
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:56
|
||||||
msgid "View Members"
|
msgid "View Members"
|
||||||
msgstr "查看成员"
|
msgstr "查看成员"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:53
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:60
|
||||||
msgid "Audit Members"
|
msgid "Audit Members"
|
||||||
msgstr "编辑成员"
|
msgstr "编辑成员"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:56
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:64
|
||||||
msgid "Copy Direct Join Link"
|
msgid "Copy Direct Join Link"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:68
|
#: allianceauth/groupmanagement/templates/groupmanagement/groupmembership.html:75
|
||||||
msgid "No groups to list."
|
msgid "No groups to list."
|
||||||
msgstr "无可用组"
|
msgstr "无可用组"
|
||||||
|
|
||||||
@@ -671,19 +680,19 @@ msgstr "无可用组"
|
|||||||
msgid "Available Groups"
|
msgid "Available Groups"
|
||||||
msgstr "可用组"
|
msgstr "可用组"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:29
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:30
|
||||||
msgid "Leave"
|
msgid "Leave"
|
||||||
msgstr "离开"
|
msgstr "离开"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:39
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:40
|
||||||
msgid "Join"
|
msgid "Join"
|
||||||
msgstr "加入"
|
msgstr "加入"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:43
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:44
|
||||||
msgid "Request"
|
msgid "Request"
|
||||||
msgstr "申请"
|
msgstr "申请"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:58
|
#: allianceauth/groupmanagement/templates/groupmanagement/groups.html:59
|
||||||
msgid "No groups available."
|
msgid "No groups available."
|
||||||
msgstr "没有可用用户组"
|
msgstr "没有可用用户组"
|
||||||
|
|
||||||
@@ -695,24 +704,24 @@ msgstr "用户组管理"
|
|||||||
msgid "Join Requests"
|
msgid "Join Requests"
|
||||||
msgstr "入组的请求"
|
msgstr "入组的请求"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:33
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:34
|
||||||
msgid "Leave Requests"
|
msgid "Leave Requests"
|
||||||
msgstr "离组的请求"
|
msgstr "离组的请求"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:53
|
#: 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/permissions_tool/templates/permissions_tool/audit.html:20
|
||||||
#: allianceauth/services/modules/openfire/forms.py:6
|
#: allianceauth/services/modules/openfire/forms.py:6
|
||||||
msgid "Group"
|
msgid "Group"
|
||||||
msgstr "用户组"
|
msgstr "用户组"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:85
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:84
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:144
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:142
|
||||||
msgid "Accept"
|
msgid "Accept"
|
||||||
msgstr "接受"
|
msgstr "接受"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:88
|
#: 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
|
#: allianceauth/hrapplications/templates/hrapplications/view.html:85
|
||||||
msgid "Reject"
|
msgid "Reject"
|
||||||
msgstr "拒绝"
|
msgstr "拒绝"
|
||||||
@@ -721,19 +730,19 @@ msgstr "拒绝"
|
|||||||
msgid "No group add requests."
|
msgid "No group add requests."
|
||||||
msgstr "没有加入用户组的请求,小老弟你是不是摇不到人"
|
msgstr "没有加入用户组的请求,小老弟你是不是摇不到人"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:156
|
#: allianceauth/groupmanagement/templates/groupmanagement/index.html:155
|
||||||
msgid "No group leave requests."
|
msgid "No group leave requests."
|
||||||
msgstr "没有离开用户组的请求,小老弟你人缘可以啊?"
|
msgstr "没有离开用户组的请求,小老弟你人缘可以啊?"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:10
|
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:9
|
||||||
msgid "Toggle navigation"
|
msgid "Toggle navigation"
|
||||||
msgstr "打开导航栏"
|
msgstr "打开导航栏"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:21
|
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:20
|
||||||
msgid "Group Requests"
|
msgid "Group Requests"
|
||||||
msgstr "用户组请求"
|
msgstr "用户组请求"
|
||||||
|
|
||||||
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:24
|
#: allianceauth/groupmanagement/templates/groupmanagement/menu.html:23
|
||||||
msgid "Group Membership"
|
msgid "Group Membership"
|
||||||
msgstr "用户组成员"
|
msgstr "用户组成员"
|
||||||
|
|
||||||
@@ -1298,7 +1307,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: allianceauth/services/modules/discord/models.py:227
|
#: allianceauth/services/modules/discord/models.py:227
|
||||||
msgid ""
|
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."
|
"was a mistake, please contact an admin."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -2052,3 +2061,6 @@ msgstr "已经把%(system)s星系里%(time)s的时间节点设置好了!CTA!
|
|||||||
#: allianceauth/timerboard/views.py:83
|
#: allianceauth/timerboard/views.py:83
|
||||||
msgid "Saved changes to the timer."
|
msgid "Saved changes to the timer."
|
||||||
msgstr "保存至新的计划表"
|
msgstr "保存至新的计划表"
|
||||||
|
|
||||||
|
#~ msgid "Portrait"
|
||||||
|
#~ msgstr "人物头像"
|
||||||
|
|||||||
@@ -1,22 +1,9 @@
|
|||||||
default_app_config = 'allianceauth.notifications.apps.NotificationsConfig'
|
default_app_config = 'allianceauth.notifications.apps.NotificationsConfig'
|
||||||
import logging
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
MAX_NOTIFICATIONS = 50
|
|
||||||
|
|
||||||
|
|
||||||
def notify(user, title, message=None, level='info'):
|
def notify(
|
||||||
|
user: object, title: str, message: str = None, level: str = 'info'
|
||||||
|
) -> None:
|
||||||
|
"""Sends a new notification to user. Convenience function to manager pendant."""
|
||||||
from .models import Notification
|
from .models import Notification
|
||||||
if Notification.objects.filter(user=user).count() > MAX_NOTIFICATIONS:
|
Notification.objects.notify_user(user, title, message, level)
|
||||||
for n in Notification.objects.filter(user=user)[MAX_NOTIFICATIONS-1:]:
|
|
||||||
n.delete()
|
|
||||||
notif = Notification()
|
|
||||||
notif.user = user
|
|
||||||
notif.title = title
|
|
||||||
if not message:
|
|
||||||
message = title
|
|
||||||
notif.message = message
|
|
||||||
notif.level = level
|
|
||||||
notif.save()
|
|
||||||
logger.info("Created notification %s" % notif)
|
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
from .models import Notification
|
|
||||||
from django.core.cache import cache
|
|
||||||
|
|
||||||
def user_notification_count(request):
|
|
||||||
user_id = request.user.id
|
|
||||||
notification_count = cache.get("u-note:{}".format(user_id), -1)
|
|
||||||
if notification_count<0:
|
|
||||||
notification_count = Notification.objects.filter(user__id=user_id).filter(viewed=False).count()
|
|
||||||
cache.set("u-note:{}".format(user_id),notification_count,5)
|
|
||||||
|
|
||||||
return {'notifications': notification_count}
|
|
||||||
101
allianceauth/notifications/managers.py
Normal file
101
allianceauth/notifications/managers.py
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
import logging
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.core.cache import cache
|
||||||
|
from django.db import models
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class NotificationQuerySet(models.QuerySet):
|
||||||
|
"""Custom QuerySet for Notification model"""
|
||||||
|
|
||||||
|
def update(self, *args, **kwargs):
|
||||||
|
# overriden update to ensure cache is invaidated on very call
|
||||||
|
super().update(*args, **kwargs)
|
||||||
|
user_pks = set(self.select_related("user").values_list('user__pk', flat=True))
|
||||||
|
for user_pk in user_pks:
|
||||||
|
NotificationManager.invalidate_user_notification_cache(user_pk)
|
||||||
|
|
||||||
|
|
||||||
|
class NotificationManager(models.Manager):
|
||||||
|
|
||||||
|
USER_NOTIFICATION_COUNT_PREFIX = 'USER_NOTIFICATION_COUNT'
|
||||||
|
USER_NOTIFICATION_COUNT_CACHE_DURATION = 86_400
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return NotificationQuerySet(self.model, using=self._db)
|
||||||
|
|
||||||
|
def notify_user(
|
||||||
|
self, user: object, title: str, message: str = None, level: str = 'info'
|
||||||
|
) -> object:
|
||||||
|
"""Sends a new notification to user. Returns newly created notification object.
|
||||||
|
"""
|
||||||
|
max_notifications = self._max_notifications_per_user()
|
||||||
|
if self.filter(user=user).count() >= max_notifications:
|
||||||
|
to_be_deleted_qs = self.filter(user=user).order_by(
|
||||||
|
"-timestamp"
|
||||||
|
)[max_notifications - 1:]
|
||||||
|
for notification in to_be_deleted_qs:
|
||||||
|
notification.delete()
|
||||||
|
|
||||||
|
if not message:
|
||||||
|
message = title
|
||||||
|
|
||||||
|
obj = self.create(user=user, title=title, message=message, level=level)
|
||||||
|
logger.info("Created notification %s", obj)
|
||||||
|
return obj
|
||||||
|
|
||||||
|
def _max_notifications_per_user(self):
|
||||||
|
"""return the maximum number of notifications allowed per user"""
|
||||||
|
max_notifications = getattr(settings, 'NOTIFICATIONS_MAX_PER_USER', None)
|
||||||
|
if (
|
||||||
|
max_notifications is None
|
||||||
|
or not isinstance(max_notifications, int)
|
||||||
|
or max_notifications < 0
|
||||||
|
):
|
||||||
|
logger.warning(
|
||||||
|
'NOTIFICATIONS_MAX_PER_USER setting is invalid. Using default.'
|
||||||
|
)
|
||||||
|
max_notifications = self.model.NOTIFICATIONS_MAX_PER_USER_DEFAULT
|
||||||
|
|
||||||
|
return max_notifications
|
||||||
|
|
||||||
|
def user_unread_count(self, user_pk: int) -> int:
|
||||||
|
"""returns the cached unread count for a user given by user PK
|
||||||
|
|
||||||
|
Will return -1 if user can not be found
|
||||||
|
"""
|
||||||
|
cache_key = self._user_notification_cache_key(user_pk)
|
||||||
|
unread_count = cache.get(key=cache_key)
|
||||||
|
if not unread_count:
|
||||||
|
try:
|
||||||
|
user = User.objects.get(pk=user_pk)
|
||||||
|
except User.DoesNotExist:
|
||||||
|
unread_count = -1
|
||||||
|
else:
|
||||||
|
logger.debug(
|
||||||
|
'Updating notification cache for user with pk %s', user_pk
|
||||||
|
)
|
||||||
|
unread_count = user.notification_set.filter(viewed=False).count()
|
||||||
|
cache.set(
|
||||||
|
key=cache_key,
|
||||||
|
value=unread_count,
|
||||||
|
timeout=self.USER_NOTIFICATION_COUNT_CACHE_DURATION
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
logger.debug(
|
||||||
|
'Returning notification count from cache for user with pk %s', user_pk
|
||||||
|
)
|
||||||
|
|
||||||
|
return unread_count
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def invalidate_user_notification_cache(cls, user_pk: int) -> None:
|
||||||
|
cache.delete(key=cls._user_notification_cache_key(user_pk))
|
||||||
|
logger.debug('Invalided notification cache for user with pk %s', user_pk)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _user_notification_cache_key(cls, user_pk: int) -> str:
|
||||||
|
return f'{cls.USER_NOTIFICATION_COUNT_PREFIX}_{user_pk}'
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
# Generated by Django 3.1.5 on 2021-01-07 21:09
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('notifications', '0003_make_strings_more_stringy'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='notification',
|
||||||
|
options={},
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='notification',
|
||||||
|
name='timestamp',
|
||||||
|
field=models.DateTimeField(auto_now_add=True, db_index=True),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='notification',
|
||||||
|
name='viewed',
|
||||||
|
field=models.BooleanField(db_index=True, default=False),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -1,11 +1,19 @@
|
|||||||
|
import logging
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
import logging
|
|
||||||
|
from .managers import NotificationManager
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class Notification(models.Model):
|
class Notification(models.Model):
|
||||||
|
"""Notification to a user within Auth"""
|
||||||
|
|
||||||
|
NOTIFICATIONS_MAX_PER_USER_DEFAULT = 50
|
||||||
|
NOTIFICATIONS_REFRESH_TIME_DEFAULT = 30
|
||||||
|
|
||||||
LEVEL_CHOICES = (
|
LEVEL_CHOICES = (
|
||||||
('danger', 'CRITICAL'),
|
('danger', 'CRITICAL'),
|
||||||
('danger', 'ERROR'),
|
('danger', 'ERROR'),
|
||||||
@@ -18,19 +26,41 @@ class Notification(models.Model):
|
|||||||
level = models.CharField(choices=LEVEL_CHOICES, max_length=10)
|
level = models.CharField(choices=LEVEL_CHOICES, max_length=10)
|
||||||
title = models.CharField(max_length=254)
|
title = models.CharField(max_length=254)
|
||||||
message = models.TextField()
|
message = models.TextField()
|
||||||
timestamp = models.DateTimeField(auto_now_add=True)
|
timestamp = models.DateTimeField(auto_now_add=True, db_index=True)
|
||||||
viewed = models.BooleanField(default=False)
|
viewed = models.BooleanField(default=False, db_index=True)
|
||||||
|
|
||||||
def view(self):
|
objects = NotificationManager()
|
||||||
|
|
||||||
|
def __str__(self) -> str:
|
||||||
|
return "%s: %s" % (self.user, self.title)
|
||||||
|
|
||||||
|
def save(self, *args, **kwargs):
|
||||||
|
# overriden save to ensure cache is invaidated on very call
|
||||||
|
super().save(*args, **kwargs)
|
||||||
|
Notification.objects.invalidate_user_notification_cache(self.user.pk)
|
||||||
|
|
||||||
|
def delete(self, *args, **kwargs):
|
||||||
|
# overriden delete to ensure cache is invaidated on very call
|
||||||
|
super().delete(*args, **kwargs)
|
||||||
|
Notification.objects.invalidate_user_notification_cache(self.user.pk)
|
||||||
|
|
||||||
|
def mark_viewed(self) -> None:
|
||||||
|
"""mark notification as viewed"""
|
||||||
logger.info("Marking notification as viewed: %s" % self)
|
logger.info("Marking notification as viewed: %s" % self)
|
||||||
self.viewed = True
|
self.viewed = True
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
def __str__(self):
|
def set_level(self, level_name: str) -> None:
|
||||||
return "%s: %s" % (self.user, self.title)
|
"""set notification level according to level name, e.g. 'CRITICAL'
|
||||||
|
|
||||||
|
raised exception on invalid level names
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
new_level = [
|
||||||
|
item[0] for item in self.LEVEL_CHOICES if item[1] == level_name
|
||||||
|
][0]
|
||||||
|
except IndexError:
|
||||||
|
raise ValueError('Invalid level name: %s' % level_name)
|
||||||
|
|
||||||
def set_level(self, level):
|
self.level = new_level
|
||||||
self.level = [item[0] for item in self.LEVEL_CHOICES if item[1] == level][0]
|
self.save()
|
||||||
|
|
||||||
class Meta:
|
|
||||||
ordering = ['-timestamp']
|
|
||||||
|
|||||||
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/delete_all_read/$', views.delete_all_read, name='delete_all_read'),
|
||||||
url(r'^notifications/$', views.notification_list, name='list'),
|
url(r'^notifications/$', views.notification_list, name='list'),
|
||||||
url(r'^notifications/(\w+)/$', views.notification_view, name='view'),
|
url(r'^notifications/(\w+)/$', views.notification_view, name='view'),
|
||||||
|
url(
|
||||||
|
r'^user_notifications_count/(?P<user_pk>\d+)/$',
|
||||||
|
views.user_notifications_count,
|
||||||
|
name='user_notifications_count'
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
from django.shortcuts import render, get_object_or_404, redirect
|
import logging
|
||||||
from .models import Notification
|
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.http import JsonResponse
|
||||||
import logging
|
from django.shortcuts import render, get_object_or_404, redirect
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
from .models import Notification
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -11,9 +14,15 @@ logger = logging.getLogger(__name__)
|
|||||||
@login_required
|
@login_required
|
||||||
def notification_list(request):
|
def notification_list(request):
|
||||||
logger.debug("notification_list called by user %s" % request.user)
|
logger.debug("notification_list called by user %s" % request.user)
|
||||||
new_notifs = Notification.objects.filter(user=request.user).filter(viewed=False)
|
notifications_qs = Notification.objects.filter(user=request.user).order_by("-timestamp")
|
||||||
old_notifs = Notification.objects.filter(user=request.user).filter(viewed=True)
|
new_notifs = notifications_qs.filter(viewed=False)
|
||||||
logger.debug("User %s has %s unread and %s read notifications" % (request.user, len(new_notifs), len(old_notifs)))
|
old_notifs = notifications_qs.filter(viewed=True)
|
||||||
|
logger.debug(
|
||||||
|
"User %s has %s unread and %s read notifications",
|
||||||
|
request.user,
|
||||||
|
len(new_notifs),
|
||||||
|
len(old_notifs)
|
||||||
|
)
|
||||||
context = {
|
context = {
|
||||||
'read': old_notifs,
|
'read': old_notifs,
|
||||||
'unread': new_notifs,
|
'unread': new_notifs,
|
||||||
@@ -23,39 +32,53 @@ def notification_list(request):
|
|||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def notification_view(request, notif_id):
|
def notification_view(request, notif_id):
|
||||||
logger.debug("notification_view called by user %s for notif_id %s" % (request.user, notif_id))
|
logger.debug(
|
||||||
|
"notification_view called by user %s for notif_id %s",
|
||||||
|
request.user,
|
||||||
|
notif_id
|
||||||
|
)
|
||||||
notif = get_object_or_404(Notification, pk=notif_id)
|
notif = get_object_or_404(Notification, pk=notif_id)
|
||||||
if notif.user == request.user:
|
if notif.user == request.user:
|
||||||
logger.debug("Providing notification for user %s" % request.user)
|
logger.debug("Providing notification for user %s", request.user)
|
||||||
context = {'notif': notif}
|
context = {'notif': notif}
|
||||||
notif.view()
|
notif.mark_viewed()
|
||||||
return render(request, 'notifications/view.html', context)
|
return render(request, 'notifications/view.html', context)
|
||||||
else:
|
else:
|
||||||
logger.warn(
|
logger.warn(
|
||||||
"User %s not authorized to view notif_id %s belonging to user %s" % (request.user, notif_id, notif.user))
|
"User %s not authorized to view notif_id %s belonging to user %s",
|
||||||
|
request.user,
|
||||||
|
notif_id, notif.user
|
||||||
|
)
|
||||||
messages.error(request, _('You are not authorized to view that notification.'))
|
messages.error(request, _('You are not authorized to view that notification.'))
|
||||||
return redirect('notifications:list')
|
return redirect('notifications:list')
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def remove_notification(request, notif_id):
|
def remove_notification(request, notif_id):
|
||||||
logger.debug("remove notification called by user %s for notif_id %s" % (request.user, notif_id))
|
logger.debug(
|
||||||
|
"remove notification called by user %s for notif_id %s",
|
||||||
|
request.user,
|
||||||
|
notif_id
|
||||||
|
)
|
||||||
notif = get_object_or_404(Notification, pk=notif_id)
|
notif = get_object_or_404(Notification, pk=notif_id)
|
||||||
if notif.user == request.user:
|
if notif.user == request.user:
|
||||||
if Notification.objects.filter(id=notif_id).exists():
|
if Notification.objects.filter(id=notif_id).exists():
|
||||||
notif.delete()
|
notif.delete()
|
||||||
logger.info("Deleting notif id %s by user %s" % (notif_id, request.user))
|
logger.info("Deleting notif id %s by user %s", notif_id, request.user)
|
||||||
messages.success(request, _('Deleted notification.'))
|
messages.success(request, _('Deleted notification.'))
|
||||||
else:
|
else:
|
||||||
logger.error(
|
logger.error(
|
||||||
"Unable to delete notif id %s for user %s - notif matching id not found." % (notif_id, request.user))
|
"Unable to delete notif id %s for user %s - notif matching id not found.",
|
||||||
|
notif_id,
|
||||||
|
request.user
|
||||||
|
)
|
||||||
messages.error(request, _('Failed to locate notification.'))
|
messages.error(request, _('Failed to locate notification.'))
|
||||||
return redirect('notifications:list')
|
return redirect('notifications:list')
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def mark_all_read(request):
|
def mark_all_read(request):
|
||||||
logger.debug('mark all notifications read called by user %s' % request.user)
|
logger.debug('mark all notifications read called by user %s', request.user)
|
||||||
Notification.objects.filter(user=request.user).update(viewed=True)
|
Notification.objects.filter(user=request.user).update(viewed=True)
|
||||||
messages.success(request, _('Marked all notifications as read.'))
|
messages.success(request, _('Marked all notifications as read.'))
|
||||||
return redirect('notifications:list')
|
return redirect('notifications:list')
|
||||||
@@ -63,7 +86,17 @@ def mark_all_read(request):
|
|||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def delete_all_read(request):
|
def delete_all_read(request):
|
||||||
logger.debug('delete all read notifications called by user %s' % request.user)
|
logger.debug('delete all read notifications called by user %s', request.user)
|
||||||
Notification.objects.filter(user=request.user).filter(viewed=True).delete()
|
Notification.objects.filter(user=request.user).filter(viewed=True).delete()
|
||||||
messages.success(request, _('Deleted all read notifications.'))
|
messages.success(request, _('Deleted all read notifications.'))
|
||||||
return redirect('notifications:list')
|
return redirect('notifications:list')
|
||||||
|
|
||||||
|
|
||||||
|
def user_notifications_count(request, user_pk: int):
|
||||||
|
"""returns to notifications count for the give user as JSON
|
||||||
|
|
||||||
|
This view is public and does not require login
|
||||||
|
"""
|
||||||
|
unread_count = Notification.objects.user_unread_count(user_pk)
|
||||||
|
data = {'unread_count': unread_count}
|
||||||
|
return JsonResponse(data, safe=False)
|
||||||
|
|||||||
@@ -34,17 +34,15 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block extra_script %}
|
{% block extra_script %}
|
||||||
|
|
||||||
$('#id_start').datetimepicker({
|
$('#id_start').datetimepicker({
|
||||||
setlocale: '{{ LANGUAGE_CODE }}',
|
setlocale: '{{ LANGUAGE_CODE }}',
|
||||||
{% if NIGHT_MODE %}
|
{% if NIGHT_MODE %}
|
||||||
theme: 'dark',
|
theme: 'dark',
|
||||||
{% else %}
|
{% else %}
|
||||||
theme: 'default',
|
theme: 'default',
|
||||||
{% endif %}
|
{% endif %}
|
||||||
mask: true,
|
mask: true,
|
||||||
format: 'Y-m-d H:i',
|
format: 'Y-m-d H:i',
|
||||||
minDate: 0
|
minDate: 0
|
||||||
});
|
});
|
||||||
|
|
||||||
{% endblock extra_script %}
|
{% endblock extra_script %}
|
||||||
|
|||||||
@@ -41,9 +41,10 @@
|
|||||||
|
|
||||||
{% include 'bundles/moment-js.html' with locale=True %}
|
{% include 'bundles/moment-js.html' with locale=True %}
|
||||||
<script src="{% static 'js/timers.js' %}"></script>
|
<script src="{% static 'js/timers.js' %}"></script>
|
||||||
|
|
||||||
<script type="application/javascript">
|
<script type="application/javascript">
|
||||||
// Data
|
// Data
|
||||||
var timers = [
|
let timers = [
|
||||||
{% for op in optimer %}
|
{% for op in optimer %}
|
||||||
{
|
{
|
||||||
'id': {{ op.id }},
|
'id': {{ op.id }},
|
||||||
@@ -52,67 +53,66 @@
|
|||||||
},
|
},
|
||||||
{% endfor %}
|
{% 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
|
* Update a timer
|
||||||
* @param timer Timer information
|
* @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())) {
|
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);
|
document.getElementById("countdown" + timer.id).innerHTML = getDurationString(duration);
|
||||||
} else {
|
} else {
|
||||||
timer.expired = true;
|
timer.expired = true;
|
||||||
|
|
||||||
document.getElementById("countdown" + timer.id).innerHTML = "";
|
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) {
|
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
|
* Set the local time info for the timer
|
||||||
* @param timer Timer information
|
* @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");
|
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();
|
document.getElementById("current-time").innerHTML = getCurrentEveTimeString();
|
||||||
}
|
};
|
||||||
|
|
||||||
|
let timedUpdate = function () {
|
||||||
|
updateClock();
|
||||||
|
updateAllTimers();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Set initial values
|
||||||
|
setAllLocalTimes();
|
||||||
|
timedUpdate();
|
||||||
|
|
||||||
|
// Start timed updates
|
||||||
|
setInterval(timedUpdate, 1000);
|
||||||
</script>
|
</script>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for user in permission.users %}
|
{% for user in permission.users %}
|
||||||
{% include 'permissions_tool/audit_row.html' with type="User" name="Permission granted directlty" %}
|
{% include 'permissions_tool/audit_row.html' with type="User" name="Permission granted directlty" %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% for group in permission.groups %}
|
{% for group in permission.groups %}
|
||||||
@@ -35,13 +35,13 @@
|
|||||||
{% for state in permission.states %}
|
{% for state in permission.states %}
|
||||||
{% for profile in state.userprofile_set.all %}
|
{% for profile in state.userprofile_set.all %}
|
||||||
{% with profile.user as user %}
|
{% 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 %}
|
{% endwith %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|
||||||
@@ -56,15 +56,16 @@
|
|||||||
|
|
||||||
{% block extra_script %}
|
{% block extra_script %}
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
var groupColumn = 0;
|
let groupColumn = 0;
|
||||||
var table = $('#tab_permissions_audit').DataTable({
|
|
||||||
|
$('#tab_permissions_audit').DataTable({
|
||||||
columnDefs: [
|
columnDefs: [
|
||||||
{ "visible": false, "targets": groupColumn }
|
{ "visible": false, "targets": groupColumn }
|
||||||
],
|
],
|
||||||
order: [[ groupColumn, 'asc' ], [ 2, 'asc' ] ],
|
order: [[ groupColumn, 'asc' ], [ 2, 'asc' ] ],
|
||||||
filterDropDown:
|
filterDropDown:
|
||||||
{
|
{
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
idx: 0,
|
idx: 0,
|
||||||
title: 'Source'
|
title: 'Source'
|
||||||
@@ -73,20 +74,20 @@
|
|||||||
bootstrap: true
|
bootstrap: true
|
||||||
},
|
},
|
||||||
drawCallback: function ( settings ) {
|
drawCallback: function ( settings ) {
|
||||||
var api = this.api();
|
let api = this.api();
|
||||||
var rows = api.rows( {page:'current'} ).nodes();
|
let rows = api.rows( {page:'current'} ).nodes();
|
||||||
var last=null;
|
let last = null;
|
||||||
|
|
||||||
api.column(groupColumn, {page:'current'} ).data().each( function ( group, i ) {
|
api.column(groupColumn, {page:'current'} ).data().each( function ( group, i ) {
|
||||||
if ( last !== group ) {
|
if ( last !== group ) {
|
||||||
$(rows).eq( i ).before(
|
$(rows).eq( i ).before(
|
||||||
'<tr class="tr-group"><td colspan="3">' + group + '</td></tr>'
|
'<tr class="tr-group"><td colspan="3">' + group + '</td></tr>'
|
||||||
);
|
);
|
||||||
|
|
||||||
last = group;
|
last = group;
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
} );
|
} );
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -9,9 +9,9 @@
|
|||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<h1 class="page-header">{% trans "Permissions Overview" %}</h1>
|
<h1 class="page-header">{% trans "Permissions Overview" %}</h1>
|
||||||
<p>
|
<p>
|
||||||
{% if request.GET.all != 'yes' %}
|
{% if request.GET.all != 'yes' %}
|
||||||
{% blocktrans %}Showing only applied permissions{% endblocktrans %}
|
{% 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 %}
|
{% else %}
|
||||||
{% blocktrans %}Showing all permissions{% endblocktrans %}
|
{% blocktrans %}Showing all permissions{% endblocktrans %}
|
||||||
<a href="{% url 'permissions_tool:overview' %}?all=no" class="btn btn-primary">{% trans "Show Applied" %}</a>
|
<a href="{% url 'permissions_tool:overview' %}?all=no" class="btn btn-primary">{% trans "Show Applied" %}</a>
|
||||||
@@ -79,7 +79,7 @@
|
|||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|
||||||
{% block extra_javascript %}
|
{% 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>
|
<script type="application/javascript" src="{% static 'js/filterDropDown/filterDropDown.min.js' %}"></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
@@ -89,15 +89,16 @@
|
|||||||
|
|
||||||
{% block extra_script %}
|
{% block extra_script %}
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
var groupColumn = 0;
|
let groupColumn = 0;
|
||||||
var table = $('#tab_permissions_overview').DataTable({
|
|
||||||
|
$('#tab_permissions_overview').DataTable({
|
||||||
columnDefs: [
|
columnDefs: [
|
||||||
{ "visible": false, "targets": groupColumn }
|
{ "visible": false, "targets": groupColumn }
|
||||||
],
|
],
|
||||||
order: [[ groupColumn, 'asc' ], [ 1, 'asc' ], [ 2, 'asc' ] ],
|
order: [[ groupColumn, 'asc' ], [ 1, 'asc' ], [ 2, 'asc' ] ],
|
||||||
filterDropDown:
|
filterDropDown:
|
||||||
{
|
{
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
idx: 0
|
idx: 0
|
||||||
},
|
},
|
||||||
@@ -108,20 +109,20 @@
|
|||||||
bootstrap: true
|
bootstrap: true
|
||||||
},
|
},
|
||||||
drawCallback: function ( settings ) {
|
drawCallback: function ( settings ) {
|
||||||
var api = this.api();
|
let api = this.api();
|
||||||
var rows = api.rows( {page:'current'} ).nodes();
|
let rows = api.rows( {page:'current'} ).nodes();
|
||||||
var last=null;
|
let last = null;
|
||||||
|
|
||||||
api.column(groupColumn, {page:'current'} ).data().each( function ( group, i ) {
|
api.column(groupColumn, {page:'current'} ).data().each( function ( group, i ) {
|
||||||
if ( last !== group ) {
|
if ( last !== group ) {
|
||||||
$(rows).eq( i ).before(
|
$(rows).eq( i ).before(
|
||||||
'<tr class="tr-group"><td colspan="6">' + group + '</td></tr>'
|
'<tr class="tr-group"><td colspan="6">' + group + '</td></tr>'
|
||||||
);
|
);
|
||||||
|
|
||||||
last = group;
|
last = group;
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
} );
|
} );
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import os
|
import os
|
||||||
from celery import Celery
|
from celery import Celery
|
||||||
|
from celery.app import trace
|
||||||
|
|
||||||
# set the default Django settings module for the 'celery' program.
|
# set the default Django settings module for the 'celery' program.
|
||||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', '{{ project_name }}.settings.local')
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', '{{ project_name }}.settings.local')
|
||||||
@@ -27,3 +28,6 @@ app.conf.ONCE = {
|
|||||||
|
|
||||||
# Load task modules from all registered Django app configs.
|
# Load task modules from all registered Django app configs.
|
||||||
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
|
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
|
||||||
|
|
||||||
|
# Remove result from default log message on task success
|
||||||
|
trace.LOG_SUCCESS = "Task %(name)s[%(id)s] succeeded in %(runtime)ss"
|
||||||
|
|||||||
@@ -104,8 +104,7 @@ TEMPLATES = [
|
|||||||
'django.template.context_processors.i18n',
|
'django.template.context_processors.i18n',
|
||||||
'django.template.context_processors.media',
|
'django.template.context_processors.media',
|
||||||
'django.template.context_processors.static',
|
'django.template.context_processors.static',
|
||||||
'django.template.context_processors.tz',
|
'django.template.context_processors.tz',
|
||||||
'allianceauth.notifications.context_processors.user_notification_count',
|
|
||||||
'allianceauth.context_processors.auth_settings',
|
'allianceauth.context_processors.auth_settings',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -173,6 +172,8 @@ CACHES = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SESSION_ENGINE = "django.contrib.sessions.backends.cached_db"
|
||||||
|
|
||||||
DEBUG = True
|
DEBUG = True
|
||||||
ALLOWED_HOSTS = ['*']
|
ALLOWED_HOSTS = ['*']
|
||||||
DATABASES = {
|
DATABASES = {
|
||||||
@@ -261,3 +262,5 @@ LOGGING = {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFAULT_AUTO_FIELD = "django.db.models.AutoField"
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ DATABASES['default'] = {
|
|||||||
ESI_SSO_CLIENT_ID = ''
|
ESI_SSO_CLIENT_ID = ''
|
||||||
ESI_SSO_CLIENT_SECRET = ''
|
ESI_SSO_CLIENT_SECRET = ''
|
||||||
ESI_SSO_CALLBACK_URL = ''
|
ESI_SSO_CALLBACK_URL = ''
|
||||||
|
ESI_USER_CONTACT_EMAIL = '' # A server maintainer that CCP can contact in case of issues.
|
||||||
|
|
||||||
# By default emails are validated before new users can log in.
|
# By default emails are validated before new users can log in.
|
||||||
# It's recommended to use a free service like SparkPost or Elastic Email to send email.
|
# It's recommended to use a free service like SparkPost or Elastic Email to send email.
|
||||||
|
|||||||
@@ -12,20 +12,12 @@ import base64
|
|||||||
import hmac
|
import hmac
|
||||||
import hashlib
|
import hashlib
|
||||||
|
|
||||||
try:
|
from urllib.parse import unquote, urlencode, parse_qs
|
||||||
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
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
ACCESS_PERM = 'discourse.access_discourse'
|
ACCESS_PERM = 'discourse.access_discourse'
|
||||||
|
|
||||||
|
|
||||||
@@ -55,7 +47,7 @@ def discourse_sso(request):
|
|||||||
# Validate the payload
|
# Validate the payload
|
||||||
try:
|
try:
|
||||||
payload = unquote(payload).encode('utf-8')
|
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 'nonce' in decoded
|
||||||
assert len(payload) > 0
|
assert len(payload) > 0
|
||||||
except AssertionError:
|
except AssertionError:
|
||||||
@@ -86,7 +78,7 @@ def discourse_sso(request):
|
|||||||
if main_char:
|
if main_char:
|
||||||
params['avatar_url'] = main_char.portrait_url(256)
|
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)
|
h = hmac.new(key, return_payload, digestmod=hashlib.sha256)
|
||||||
query_string = urlencode({'sso': return_payload, 'sig': h.hexdigest()})
|
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,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'),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -74,7 +74,41 @@ class MumbleUser(AbstractServiceModel):
|
|||||||
editable=False,
|
editable=False,
|
||||||
help_text="Hash of Mumble client certificate as presented when user authenticates"
|
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()
|
objects = MumbleManager()
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import re
|
||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
@@ -21,6 +23,11 @@ class SrpFleetUserRequestForm(forms.Form):
|
|||||||
data = self.cleaned_data['killboard_link']
|
data = self.cleaned_data['killboard_link']
|
||||||
if "zkillboard.com" not in data:
|
if "zkillboard.com" not in data:
|
||||||
raise forms.ValidationError(_("Invalid Link. Please use zKillboard.com"))
|
raise forms.ValidationError(_("Invalid Link. Please use zKillboard.com"))
|
||||||
|
|
||||||
|
if not re.match(r"http[s]?://zkillboard\.com/kill/\d+\/", data):
|
||||||
|
raise forms.ValidationError(
|
||||||
|
_("Invalid Link. Please post a direct link to a killmail.")
|
||||||
|
)
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -43,17 +43,15 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block extra_script %}
|
{% block extra_script %}
|
||||||
|
|
||||||
$('#id_fleet_time').datetimepicker({
|
$('#id_fleet_time').datetimepicker({
|
||||||
setlocale: '{{ LANGUAGE_CODE }}',
|
setlocale: '{{ LANGUAGE_CODE }}',
|
||||||
{% if NIGHT_MODE %}
|
{% if NIGHT_MODE %}
|
||||||
theme: 'dark',
|
theme: 'dark',
|
||||||
{% else %}
|
{% else %}
|
||||||
theme: 'default',
|
theme: 'default',
|
||||||
{% endif %}
|
{% endif %}
|
||||||
mask: true,
|
mask: true,
|
||||||
format: 'Y-m-d H:i',
|
format: 'Y-m-d H:i',
|
||||||
minDate: 0
|
minDate: 0
|
||||||
});
|
});
|
||||||
|
|
||||||
{% endblock extra_script %}
|
{% endblock extra_script %}
|
||||||
|
|||||||
@@ -10,6 +10,9 @@
|
|||||||
{% include 'bundles/x-editable.css.html' %}
|
{% include 'bundles/x-editable.css.html' %}
|
||||||
<link href="{% static 'css/checkbox.css' %}" rel="stylesheet" type="text/css">
|
<link href="{% static 'css/checkbox.css' %}" rel="stylesheet" type="text/css">
|
||||||
<style>
|
<style>
|
||||||
|
.copy-text-fa-icon:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
.radio label, .checkbox label {
|
.radio label, .checkbox label {
|
||||||
padding-left: 10px;
|
padding-left: 10px;
|
||||||
}
|
}
|
||||||
@@ -109,7 +112,8 @@ ESC to cancel{% endblocktrans %}"id="blah"></i></th>
|
|||||||
{{ srpfleetrequest.character.alliance.alliance_ticker }}
|
{{ srpfleetrequest.character.alliance.alliance_ticker }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
[{{ srpfleetrequest.character.corporation.corporation_ticker }}]
|
[{{ srpfleetrequest.character.corporation.corporation_ticker }}]
|
||||||
{{ srpfleetrequest.character.character_name }}
|
{{ srpfleetrequest.character.character_name }} <i class="copy-text-fa-icon far fa-copy" data-clipboard-text="{{ srpfleetrequest.character.character_name }}"></i>
|
||||||
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
<a href="{{ srpfleetrequest.killboard_link }}"
|
<a href="{{ srpfleetrequest.killboard_link }}"
|
||||||
@@ -182,76 +186,91 @@ ESC to cancel{% endblocktrans %}"id="blah"></i></th>
|
|||||||
{% include 'bundles/datatables-js.html' %}
|
{% include 'bundles/datatables-js.html' %}
|
||||||
{% include 'bundles/x-editable-js.html' %}
|
{% include 'bundles/x-editable-js.html' %}
|
||||||
{% include 'bundles/moment-js.html' %}
|
{% include 'bundles/moment-js.html' %}
|
||||||
{% endblock %}
|
{% include 'bundles/clipboard-js.html' %}
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var clipboard = new ClipboardJS('.copy-text-fa-icon');
|
||||||
|
clipboard.on('success', function (e) {
|
||||||
|
console.info('Action:', e.action);
|
||||||
|
console.info('Text:', e.text);
|
||||||
|
console.info('Trigger:', e.trigger);
|
||||||
|
|
||||||
|
e.clearSelection();
|
||||||
|
});
|
||||||
|
|
||||||
|
clipboard.on('error', function (e) {
|
||||||
|
console.error('Action:', e.action);
|
||||||
|
console.error('Trigger:', e.trigger);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endblock extra_javascript %}
|
||||||
|
|
||||||
{% block extra_script %}
|
{% block extra_script %}
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
$.fn.editable.defaults.mode = 'inline';
|
$.fn.editable.defaults.mode = 'inline';
|
||||||
$.fn.editable.defaults.showbuttons = false;
|
$.fn.editable.defaults.showbuttons = false;
|
||||||
$.fn.editable.defaults.highlight = "#AAFF80";
|
$.fn.editable.defaults.highlight = "#AAFF80";
|
||||||
|
|
||||||
|
$.fn.dataTable.moment = function(format, locale) {
|
||||||
|
let types = $.fn.dataTable.ext.type;
|
||||||
|
|
||||||
$('.srp').editable({
|
// Add type detection
|
||||||
display: function(value, response) {
|
types.detect.unshift(function(d) {
|
||||||
return false;
|
return moment(d, format, locale, true).isValid() ?
|
||||||
},
|
'moment-' + format :
|
||||||
success: function(response, newValue) {
|
null;
|
||||||
newValue = parseInt(newValue);
|
});
|
||||||
newvalue = newValue.toLocaleString() + " ISK";
|
|
||||||
$(this).html(newvalue.bold());
|
|
||||||
},
|
|
||||||
validate: function(value) {
|
|
||||||
if (value === null || value === '') {
|
|
||||||
return 'Empty values not allowed';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
$('.srp').on('hidden', function(e, reason){
|
|
||||||
if(reason === 'save' || reason === 'nochange') {
|
|
||||||
var $next = $(this).closest('tr').next().find('.editable');
|
|
||||||
setTimeout(function() {
|
|
||||||
$next.editable('show');
|
|
||||||
}, 400);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$(document).ready(function(){
|
// Add sorting method - use an integer for the sorting
|
||||||
$("[rel=tooltip]").tooltip({ placement: 'top'});
|
types.order[ 'moment-' + format+'-pre' ] = function(d) {
|
||||||
});
|
return moment(d, format, locale, true).unix();
|
||||||
|
};
|
||||||
|
};
|
||||||
|
$.fn.dataTable.moment('YYYY-MMM-D, HH:mm');
|
||||||
|
|
||||||
$.fn.dataTable.moment = function(format, locale) {
|
$('.srp').editable({
|
||||||
var types = $.fn.dataTable.ext.type;
|
display: function(value, response) {
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
success: function(response, newValue) {
|
||||||
|
newValue = parseInt(newValue);
|
||||||
|
let newValueOutput = newValue.toLocaleString() + " ISK";
|
||||||
|
|
||||||
// Add type detection
|
$(this).html(newValueOutput.bold());
|
||||||
types.detect.unshift(function(d) {
|
},
|
||||||
return moment(d, format, locale, true).isValid() ?
|
validate: function(value) {
|
||||||
'moment-'+format :
|
if (value === null || value === '') {
|
||||||
null;
|
return 'Empty values not allowed';
|
||||||
} );
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Add sorting method - use an integer for the sorting
|
$('.srp').on('hidden', function(e, reason){
|
||||||
types.order[ 'moment-'+format+'-pre' ] = function(d) {
|
if(reason === 'save' || reason === 'nochange') {
|
||||||
return moment(d, format, locale, true).unix();
|
let $next = $(this).closest('tr').next().find('.editable');
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
$(document).ready( function(){
|
setTimeout(function() {
|
||||||
$.fn.dataTable.moment('YYYY-MMM-D, HH:mm');
|
$next.editable('show');
|
||||||
|
}, 400);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
$('table.srplist').DataTable({
|
$('table.srplist').DataTable({
|
||||||
"order": [[ 6, "asc" ]],
|
"order": [[ 6, "asc" ]],
|
||||||
"paging": false,
|
"paging": false,
|
||||||
"columnDefs": [{
|
"columnDefs": [
|
||||||
"targets": [1, 8],
|
{
|
||||||
"orderable": false
|
"targets": [1, 8],
|
||||||
},
|
"orderable": false
|
||||||
{
|
},
|
||||||
"targets": [4, 5],
|
{
|
||||||
"type": "num"
|
"targets": [4, 5],
|
||||||
}]
|
"type": "num"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
// tooltip
|
||||||
|
$("[rel=tooltip]").tooltip({ placement: 'top'});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
{% endblock extra_script %}
|
{% endblock extra_script %}
|
||||||
|
|||||||
@@ -43,27 +43,51 @@ ul.list-group.list-group-horizontal > li.list-group-item {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* style group headers within a table */
|
@media all {
|
||||||
.tr-group {
|
/* style nav tabs in dark mode*/
|
||||||
font-weight: bold;
|
.template-dark-mode .nav-tabs > li.active > a {
|
||||||
background-color: #e6e6e6 !important;
|
background-color: rgb(70, 69, 69)!important;
|
||||||
}
|
color: rgb(255, 255, 255) !important;
|
||||||
|
}
|
||||||
|
|
||||||
/* default style for tables */
|
.panel-tabs-aa {
|
||||||
.table-aa > thead > tr > th{
|
border-top: none;
|
||||||
border-bottom: 1px solid #f2f2f2;
|
border-top-left-radius: 0%;
|
||||||
}
|
border-top-right-radius: 0%;
|
||||||
.table-aa > thead > tr > th{
|
}
|
||||||
vertical-align: middle;
|
|
||||||
}
|
/* style group headers within a table */
|
||||||
.table-aa > tbody > tr > td{
|
.template-light-mode .tr-group {
|
||||||
border-bottom: 1px solid #f2f2f2;
|
font-weight: bold;
|
||||||
}
|
background-color: #e6e6e6 !important;
|
||||||
.table-aa > tbody > tr > td {
|
}
|
||||||
vertical-align: middle;
|
.template-dark-mode .tr-group {
|
||||||
}
|
font-weight: bold;
|
||||||
.table-aa > tbody > tr:last-child {
|
background-color: rgb(105, 105, 105) !important;
|
||||||
border-bottom: none;
|
}
|
||||||
|
|
||||||
|
/* default style for tables */
|
||||||
|
.template-light-mode .table-aa > thead > tr > th{
|
||||||
|
border-bottom: 1px solid #f2f2f2;
|
||||||
|
}
|
||||||
|
.template-dark-mode .table-aa > thead > tr > th{
|
||||||
|
border-bottom: 1px solid rgb(70, 69, 69);
|
||||||
|
}
|
||||||
|
.table-aa > thead > tr > th{
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
.template-light-mode .table-aa > tbody > tr > td{
|
||||||
|
border-bottom: 1px solid #f2f2f2;
|
||||||
|
}
|
||||||
|
.template-dark-mode .table-aa > tbody > tr > td{
|
||||||
|
border-bottom: 1px solid rgb(70, 69, 69);
|
||||||
|
}
|
||||||
|
.table-aa > tbody > tr > td {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
.table-aa > tbody > tr:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* highlight active menu items
|
/* highlight active menu items
|
||||||
|
|||||||
74
allianceauth/static/js/refresh_notifications.js
Normal file
74
allianceauth/static/js/refresh_notifications.js
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
/* global notificationUPdateSettings */
|
||||||
|
|
||||||
|
/*
|
||||||
|
This script refreshed the unread notification count in the top menu
|
||||||
|
on a regular basis so to keep the user apprised about newly arrived
|
||||||
|
notifications without having to reload the page.
|
||||||
|
|
||||||
|
The refresh rate can be changes via the Django setting NOTIFICATIONS_REFRESH_TIME.
|
||||||
|
See documentation for details.
|
||||||
|
*/
|
||||||
|
$(function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
let notificationsListViewUrl = notificationUPdateSettings.notificationsListViewUrl;
|
||||||
|
let notificationsRefreshTime = notificationUPdateSettings.notificationsRefreshTime;
|
||||||
|
let userNotificationsCountViewUrl = notificationUPdateSettings.userNotificationsCountViewUrl;
|
||||||
|
|
||||||
|
// update the notification unread count in the top menu
|
||||||
|
let updateNotifications = function () {
|
||||||
|
$.getJSON(userNotificationsCountViewUrl, function (data, status) {
|
||||||
|
if (status === 'success') {
|
||||||
|
let innerHtml = '';
|
||||||
|
let unreadCount = data.unread_count;
|
||||||
|
|
||||||
|
if (unreadCount > 0) {
|
||||||
|
innerHtml = (
|
||||||
|
`Notifications <span class="badge">${unreadCount}</span>`
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
innerHtml = '<i class="far fa-bell"></i>';
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#menu_item_notifications').html(
|
||||||
|
`<a href="${notificationsListViewUrl}">${innerHtml}</a>`
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
console.error(
|
||||||
|
`Failed to load HTMl to render notifications item. Error: ${xhr.status}': '${xhr.statusText}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
let myInterval;
|
||||||
|
|
||||||
|
// activate automatic refreshing every x seconds
|
||||||
|
let activateRefreshing = function () {
|
||||||
|
if (notificationsRefreshTime > 0) {
|
||||||
|
myInterval = setInterval(
|
||||||
|
updateNotifications, notificationsRefreshTime * 1000
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// deactivate automatic refreshing
|
||||||
|
let deactivateRefreshing = function () {
|
||||||
|
if ((notificationsRefreshTime > 0) && (typeof myInterval !== 'undefined')) {
|
||||||
|
clearInterval(myInterval);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// refreshing only happens on active browser tab
|
||||||
|
$(document).on({
|
||||||
|
'show': function () {
|
||||||
|
activateRefreshing();
|
||||||
|
},
|
||||||
|
'hide': function () {
|
||||||
|
deactivateRefreshing();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Initial start of refreshing on script loading
|
||||||
|
activateRefreshing();
|
||||||
|
});
|
||||||
@@ -1,23 +1,49 @@
|
|||||||
|
/* global moment */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a duration string like countdown.js
|
* Get a duration string like countdown.js
|
||||||
* e.g. "1y 2d 3h 4m 5s"
|
* e.g. "1y 2d 3h 4m 5s"
|
||||||
* @param duration moment.duration
|
*
|
||||||
*/
|
* @param duration
|
||||||
function getDurationString(duration) {
|
* @returns {string}
|
||||||
var out = "";
|
*/
|
||||||
|
let getDurationString = function (duration) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
let out = '';
|
||||||
|
|
||||||
if (duration.years()) {
|
if (duration.years()) {
|
||||||
out += duration.years() + 'y ';
|
out += duration.years() + 'y ';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (duration.months()) {
|
if (duration.months()) {
|
||||||
out += duration.months() + 'm ';
|
out += duration.months() + 'm ';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (duration.days()) {
|
if (duration.days()) {
|
||||||
out += duration.days() + 'd ';
|
out += duration.days() + 'd ';
|
||||||
}
|
}
|
||||||
return out + duration.hours() + "h " + duration.minutes() + "m " + duration.seconds() + "s";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
return out + duration.hours() + 'h ' + duration.minutes() + 'm ' + duration.seconds() + 's';
|
||||||
|
};
|
||||||
|
|
||||||
function getCurrentEveTimeString() {
|
/**
|
||||||
return moment().utc().format('dddd LL HH:mm:ss')
|
* returns the current eve time as a formatted string
|
||||||
}
|
*
|
||||||
|
* condition:
|
||||||
|
* only if moment.js is loaded before,
|
||||||
|
* if not this function returns an empty string to avoid JS errors from happening.
|
||||||
|
*
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
let getCurrentEveTimeString = function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
let returnValue = '';
|
||||||
|
|
||||||
|
if (window.moment) {
|
||||||
|
returnValue = moment().utc().format('dddd LL HH:mm:ss');
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
};
|
||||||
|
|||||||
2
allianceauth/static/robots.txt
Normal file
2
allianceauth/static/robots.txt
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
User-agent: *
|
||||||
|
Disallow: /
|
||||||
@@ -18,9 +18,20 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-right" style="position:absolute;bottom:5px;right:5px;">
|
|
||||||
<a href="https://gitlab.com/allianceauth/allianceauth/issues"><span class="label" style="background-color:#e65328;">
|
<div class="text-right" style="position: absolute; bottom: 5px; right: 5px;">
|
||||||
<i class="fab fa-gitlab" aria-hidden="true"></i> Powered by GitLab</span>
|
<a href="https://gitlab.com/allianceauth/allianceauth/issues" target="_blank" style="margin-right: 0.5rem;">
|
||||||
|
<span class="label" style="background-color: #e65328;">
|
||||||
|
<i class="fab fa-gitlab" aria-hidden="true"></i>
|
||||||
|
{% translate 'Powered by GitLab' %}
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href="https://discord.com/invite/fjnHAmk" target="_blank">
|
||||||
|
<span class="label" style="background-color: rgb(110,133,211);">
|
||||||
|
<i class="fab fa-discord" aria-hidden="true"></i>
|
||||||
|
{% translate 'Support Discord' %}
|
||||||
|
</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
{% load static %}
|
{% load static %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load navactive %}
|
{% load navactive %}
|
||||||
|
{% load auth_notifications %}
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
@@ -9,7 +10,6 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<meta name="description" content="">
|
<meta name="description" content="">
|
||||||
<meta name="author" content="">
|
<meta name="author" content="">
|
||||||
|
|
||||||
{% include 'allianceauth/icons.html' %}
|
{% include 'allianceauth/icons.html' %}
|
||||||
|
|
||||||
<title>{% block title %}{% block page_title %}{% endblock page_title %} - Alliance Auth{% endblock title %}</title>
|
<title>{% block title %}{% block page_title %}{% endblock page_title %} - Alliance Auth{% endblock title %}</title>
|
||||||
@@ -27,7 +27,6 @@
|
|||||||
<div id="wrapper" class="container">
|
<div id="wrapper" class="container">
|
||||||
<!-- Navigation -->
|
<!-- Navigation -->
|
||||||
{% include 'allianceauth/top-menu.html' %}
|
{% include 'allianceauth/top-menu.html' %}
|
||||||
|
|
||||||
<div class="row" id="site-body-wrapper">
|
<div class="row" id="site-body-wrapper">
|
||||||
{% include 'allianceauth/side-menu.html' %}
|
{% include 'allianceauth/side-menu.html' %}
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
@@ -40,7 +39,6 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
</div>
|
</div>
|
||||||
@@ -50,10 +48,19 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% include 'bundles/bootstrap-js.html' %}
|
{% include 'bundles/bootstrap-js.html' %}
|
||||||
|
{% include 'bundles/jquery-visibility-js.html' %}
|
||||||
|
|
||||||
|
<script type="application/javascript">
|
||||||
|
let notificationUPdateSettings = {
|
||||||
|
notificationsListViewUrl: "{% url 'notifications:list' %}",
|
||||||
|
notificationsRefreshTime: "{% notifications_refresh_time %}",
|
||||||
|
userNotificationsCountViewUrl: "{% url 'notifications:user_notifications_count' request.user.pk %}"
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<script src="{% static 'js/refresh_notifications.js' %}"></script>
|
||||||
|
|
||||||
{% block extra_javascript %}
|
{% block extra_javascript %}
|
||||||
{% endblock extra_javascript %}
|
{% endblock extra_javascript %}
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
{% block extra_script %}
|
{% block extra_script %}
|
||||||
{% endblock extra_script %}
|
{% endblock extra_script %}
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
{% load auth_notifications %}
|
||||||
|
|
||||||
|
{% with unread_count=request.user|user_unread_notification_count %}
|
||||||
|
{% if unread_count > 0 %}
|
||||||
|
<a href="{% url 'notifications:list' %}">Notifications
|
||||||
|
<span class="badge">{{ unread_count }}</span>
|
||||||
|
</a>
|
||||||
|
{% else %}
|
||||||
|
<a href="{% url 'notifications:list' %}">
|
||||||
|
<i class="far fa-bell"></i>
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
|
{% endwith %}
|
||||||
@@ -20,17 +20,11 @@
|
|||||||
<li>
|
<li>
|
||||||
{% include 'allianceauth/night-toggle.html' %}
|
{% include 'allianceauth/night-toggle.html' %}
|
||||||
</li>
|
</li>
|
||||||
{% if notifications %}
|
<li
|
||||||
<li class="{% navactive request 'notifications:' %}">
|
class="{% navactive request 'notifications:' %}" id="menu_item_notifications"
|
||||||
<a href="{% url 'notifications:list' %}">Notifications
|
>
|
||||||
<span class="badge">{{ notifications }}</span>
|
{% include 'allianceauth/notifications_menu_item.html' %}
|
||||||
</a>
|
|
||||||
</li>
|
</li>
|
||||||
{% else %}
|
|
||||||
<li><a href="{% url 'notifications:list' %}">
|
|
||||||
<i class="far fa-bell"></i></a>
|
|
||||||
</li>
|
|
||||||
{% endif %}
|
|
||||||
{% if user.is_authenticated %}
|
{% if user.is_authenticated %}
|
||||||
{% if user.is_staff %}
|
{% if user.is_staff %}
|
||||||
<li><a href="{% url 'admin:index' %}">{% trans "Admin" %}</a></li>
|
<li><a href="{% url 'admin:index' %}">{% trans "Admin" %}</a></li>
|
||||||
@@ -64,3 +58,4 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
<!-- Start Clipboard.js js from cdnjs -->
|
<!-- Start Clipboard.js js from cdnjs -->
|
||||||
<script type="application/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.6/clipboard.min.js"></script>
|
<script type="application/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.8/clipboard.min.js" integrity="sha512-sIqUEnRn31BgngPmHt2JenzleDDsXwYO+iyvQ46Mw6RL+udAUZj2n/u/PGY80NxRxynO7R9xIGx5LEzw4INWJQ==" crossorigin="anonymous"></script>
|
||||||
<!-- End Clipboard.js js from cdnjs -->
|
<!-- End Clipboard.js js from cdnjs -->
|
||||||
4
allianceauth/templates/bundles/jquery-visibility-js.html
Normal file
4
allianceauth/templates/bundles/jquery-visibility-js.html
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{% load static %}
|
||||||
|
<!-- Start jQuery visibility js -->
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-visibility/1.0.11/jquery-visibility.min.js"></script>
|
||||||
|
<!-- End jQuery visibility js -->
|
||||||
@@ -27,7 +27,7 @@ GITLAB_AUTH_REPOSITORY_TAGS_URL = (
|
|||||||
)
|
)
|
||||||
GITLAB_AUTH_ANNOUNCEMENT_ISSUES_URL = (
|
GITLAB_AUTH_ANNOUNCEMENT_ISSUES_URL = (
|
||||||
'https://gitlab.com/api/v4/projects/allianceauth%2Fallianceauth/issues'
|
'https://gitlab.com/api/v4/projects/allianceauth%2Fallianceauth/issues'
|
||||||
'?labels=announcement'
|
'?labels=announcement&state=opened'
|
||||||
)
|
)
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@@ -36,7 +36,7 @@ logger = logging.getLogger(__name__)
|
|||||||
@register.inclusion_tag('allianceauth/admin-status/overview.html')
|
@register.inclusion_tag('allianceauth/admin-status/overview.html')
|
||||||
def status_overview() -> dict:
|
def status_overview() -> dict:
|
||||||
response = {
|
response = {
|
||||||
'notifications': list(),
|
'notifications': list(),
|
||||||
'current_version': __version__,
|
'current_version': __version__,
|
||||||
'task_queue_length': -1,
|
'task_queue_length': -1,
|
||||||
}
|
}
|
||||||
@@ -51,7 +51,7 @@ def _fetch_celery_queue_length() -> int:
|
|||||||
app = app_or_default(None)
|
app = app_or_default(None)
|
||||||
with app.connection_or_acquire() as conn:
|
with app.connection_or_acquire() as conn:
|
||||||
return conn.default_channel.queue_declare(
|
return conn.default_channel.queue_declare(
|
||||||
queue=getattr(settings, 'CELERY_DEFAULT_QUEUE', 'celery'),
|
queue=getattr(settings, 'CELERY_DEFAULT_QUEUE', 'celery'),
|
||||||
passive=True
|
passive=True
|
||||||
).message_count
|
).message_count
|
||||||
except amqp.exceptions.ChannelError:
|
except amqp.exceptions.ChannelError:
|
||||||
@@ -63,51 +63,51 @@ def _fetch_celery_queue_length() -> int:
|
|||||||
|
|
||||||
|
|
||||||
def _current_notifications() -> dict:
|
def _current_notifications() -> dict:
|
||||||
"""returns the newest 5 announcement issues"""
|
"""returns the newest 5 announcement issues"""
|
||||||
try:
|
try:
|
||||||
notifications = cache.get_or_set(
|
notifications = cache.get_or_set(
|
||||||
'gitlab_notification_issues',
|
'gitlab_notification_issues',
|
||||||
_fetch_notification_issues_from_gitlab,
|
_fetch_notification_issues_from_gitlab,
|
||||||
NOTIFICATION_CACHE_TIME
|
NOTIFICATION_CACHE_TIME
|
||||||
)
|
)
|
||||||
except requests.RequestException:
|
except requests.HTTPError:
|
||||||
logger.exception('Error while getting gitlab notifications')
|
logger.warning('Error while getting gitlab notifications', exc_info=True)
|
||||||
top_notifications = []
|
top_notifications = []
|
||||||
else:
|
else:
|
||||||
if notifications:
|
if notifications:
|
||||||
top_notifications = notifications[:5]
|
top_notifications = notifications[:5]
|
||||||
else:
|
else:
|
||||||
top_notifications = []
|
top_notifications = []
|
||||||
|
|
||||||
response = {
|
response = {
|
||||||
'notifications': top_notifications,
|
'notifications': top_notifications,
|
||||||
}
|
}
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
def _fetch_notification_issues_from_gitlab() -> list:
|
def _fetch_notification_issues_from_gitlab() -> list:
|
||||||
return _fetch_list_from_gitlab(GITLAB_AUTH_ANNOUNCEMENT_ISSUES_URL, max_pages=10)
|
return _fetch_list_from_gitlab(GITLAB_AUTH_ANNOUNCEMENT_ISSUES_URL, max_pages=10)
|
||||||
|
|
||||||
|
|
||||||
def _current_version_summary() -> dict:
|
def _current_version_summary() -> dict:
|
||||||
"""returns the current version info"""
|
"""returns the current version info"""
|
||||||
try:
|
try:
|
||||||
tags = cache.get_or_set(
|
tags = cache.get_or_set(
|
||||||
'git_release_tags', _fetch_tags_from_gitlab, TAG_CACHE_TIME
|
'git_release_tags', _fetch_tags_from_gitlab, TAG_CACHE_TIME
|
||||||
)
|
)
|
||||||
except requests.RequestException:
|
except requests.HTTPError:
|
||||||
logger.exception('Error while getting gitlab release tags')
|
logger.warning('Error while getting gitlab release tags', exc_info=True)
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
if not tags:
|
if not tags:
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
(
|
(
|
||||||
latest_major_version,
|
latest_major_version,
|
||||||
latest_minor_version,
|
latest_minor_version,
|
||||||
latest_patch_version,
|
latest_patch_version,
|
||||||
latest_beta_version
|
latest_beta_version
|
||||||
) = _latests_versions(tags)
|
) = _latests_versions(tags)
|
||||||
current_version = Pep440Version(__version__)
|
current_version = Pep440Version(__version__)
|
||||||
|
|
||||||
has_latest_major = \
|
has_latest_major = \
|
||||||
@@ -121,7 +121,7 @@ def _current_version_summary() -> dict:
|
|||||||
and latest_major_version.base_version <= latest_beta_version.base_version \
|
and latest_major_version.base_version <= latest_beta_version.base_version \
|
||||||
if latest_beta_version else False
|
if latest_beta_version else False
|
||||||
|
|
||||||
response = {
|
response = {
|
||||||
'latest_major': has_latest_major,
|
'latest_major': has_latest_major,
|
||||||
'latest_minor': has_latest_minor,
|
'latest_minor': has_latest_minor,
|
||||||
'latest_patch': has_latest_patch,
|
'latest_patch': has_latest_patch,
|
||||||
@@ -131,7 +131,7 @@ def _current_version_summary() -> dict:
|
|||||||
'latest_minor_version': str(latest_minor_version),
|
'latest_minor_version': str(latest_minor_version),
|
||||||
'latest_patch_version': str(latest_patch_version),
|
'latest_patch_version': str(latest_patch_version),
|
||||||
'latest_beta_version': str(latest_beta_version)
|
'latest_beta_version': str(latest_beta_version)
|
||||||
}
|
}
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
@@ -141,14 +141,14 @@ def _fetch_tags_from_gitlab():
|
|||||||
|
|
||||||
def _latests_versions(tags: list) -> tuple:
|
def _latests_versions(tags: list) -> tuple:
|
||||||
"""returns latests version from given tags list
|
"""returns latests version from given tags list
|
||||||
|
|
||||||
Non-compliant tags will be ignored
|
Non-compliant tags will be ignored
|
||||||
"""
|
"""
|
||||||
versions = list()
|
versions = list()
|
||||||
betas = list()
|
betas = list()
|
||||||
for tag in tags:
|
for tag in tags:
|
||||||
try:
|
try:
|
||||||
version = Pep440Version(tag.get('name'))
|
version = Pep440Version(tag.get('name'))
|
||||||
except InvalidVersion:
|
except InvalidVersion:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
@@ -162,21 +162,21 @@ def _latests_versions(tags: list) -> tuple:
|
|||||||
v for v in versions if v.major == latest_version.major
|
v for v in versions if v.major == latest_version.major
|
||||||
])
|
])
|
||||||
latest_minor_version = min([
|
latest_minor_version = min([
|
||||||
v for v in versions
|
v for v in versions
|
||||||
if v.major == latest_version.major and v.minor == latest_version.minor
|
if v.major == latest_version.major and v.minor == latest_version.minor
|
||||||
])
|
])
|
||||||
latest_beta_version = max(betas)
|
latest_beta_version = max(betas)
|
||||||
return (
|
return (
|
||||||
latest_major_version,
|
latest_major_version,
|
||||||
latest_minor_version,
|
latest_minor_version,
|
||||||
latest_patch_version,
|
latest_patch_version,
|
||||||
latest_beta_version
|
latest_beta_version
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def _fetch_list_from_gitlab(url: str, max_pages: int = MAX_PAGES) -> list:
|
def _fetch_list_from_gitlab(url: str, max_pages: int = MAX_PAGES) -> list:
|
||||||
"""returns a list from the GitLab API. Supports pageing"""
|
"""returns a list from the GitLab API. Supports pageing"""
|
||||||
result = list()
|
result = list()
|
||||||
for page in range(1, max_pages + 1):
|
for page in range(1, max_pages + 1):
|
||||||
request = requests.get(
|
request = requests.get(
|
||||||
url, params={'page': page}, timeout=REQUESTS_TIMEOUT
|
url, params={'page': page}, timeout=REQUESTS_TIMEOUT
|
||||||
@@ -190,8 +190,8 @@ def _fetch_list_from_gitlab(url: str, max_pages: int = MAX_PAGES) -> list:
|
|||||||
total_pages = None
|
total_pages = None
|
||||||
else:
|
else:
|
||||||
total_pages = None
|
total_pages = None
|
||||||
|
|
||||||
if not total_pages or page >= total_pages:
|
if not total_pages or page >= total_pages:
|
||||||
break
|
break
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|||||||
@@ -526,9 +526,7 @@
|
|||||||
{% include 'bundles/moment-js.html' with locale=True %}
|
{% include 'bundles/moment-js.html' with locale=True %}
|
||||||
<script src="{% static 'js/timers.js' %}"></script>
|
<script src="{% static 'js/timers.js' %}"></script>
|
||||||
<script type="application/javascript">
|
<script type="application/javascript">
|
||||||
var locale = "{{ LANGUAGE_CODE }}";
|
let timers = [
|
||||||
|
|
||||||
var timers = [
|
|
||||||
{% for timer in timers %}
|
{% for timer in timers %}
|
||||||
{
|
{
|
||||||
'id': {{ timer.id }},
|
'id': {{ timer.id }},
|
||||||
@@ -545,67 +543,64 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
];
|
];
|
||||||
|
|
||||||
moment.locale(locale);
|
/**
|
||||||
|
* Update a timer
|
||||||
|
* @param timer Timer information
|
||||||
|
*/
|
||||||
|
let updateTimer = function (timer) {
|
||||||
|
if (timer.targetDate.isAfter(Date.now())) {
|
||||||
|
let duration = moment.duration(timer.targetDate - moment(), 'milliseconds');
|
||||||
|
|
||||||
// Set initial values
|
document.getElementById("countdown" + timer.id).innerHTML = getDurationString(duration);
|
||||||
setAllLocalTimes();
|
} else {
|
||||||
timedUpdate();
|
timer.expired = true;
|
||||||
|
|
||||||
// Start timed updates
|
document.getElementById("countdown" + timer.id).innerHTML = "";
|
||||||
setInterval(timedUpdate, 1000);
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let updateAllTimers = function () {
|
||||||
|
let l = timers.length;
|
||||||
|
|
||||||
|
for (var i=0; i < l; ++i) {
|
||||||
|
if (timers[i].expired) continue;
|
||||||
|
|
||||||
|
updateTimer(timers[i]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
function timedUpdate() {
|
function timedUpdate() {
|
||||||
updateClock();
|
updateClock();
|
||||||
updateAllTimers();
|
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
|
* Set the local time info for the timer
|
||||||
* @param timer Timer information
|
* @param timer Timer information
|
||||||
* @param timer.targetDate Date of the timer
|
|
||||||
* @param timer.id Id number of the timer
|
|
||||||
* @param timer.expired
|
|
||||||
*/
|
*/
|
||||||
function updateTimer(timer) {
|
let setLocalTime = function (timer) {
|
||||||
if (timer.targetDate.isAfter(Date.now())) {
|
document.getElementById("localtime" + timer.id).innerHTML = timer.targetDate.format("ddd @ LT");
|
||||||
duration = moment.duration(timer.targetDate - moment(), 'milliseconds');
|
};
|
||||||
document.getElementById("countdown" + timer.id).innerHTML = getDurationString(duration);
|
|
||||||
} else {
|
|
||||||
timer.expired = true;
|
|
||||||
document.getElementById("countdown" + timer.id).innerHTML = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set all local time fields
|
* Set all local time fields
|
||||||
*/
|
*/
|
||||||
function setAllLocalTimes() {
|
let setAllLocalTimes = function () {
|
||||||
var l = timers.length;
|
let l = timers.length;
|
||||||
|
|
||||||
for (var i=0; i < l; ++i) {
|
for (var i=0; i < l; ++i) {
|
||||||
setLocalTime(timers[i]);
|
setLocalTime(timers[i]);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
let updateClock = function () {
|
||||||
* Set the local time info for the timer
|
|
||||||
* @param timer Timer information
|
|
||||||
* @param timer.targetDate Date of the timer
|
|
||||||
* @param timer.id Id number of the timer
|
|
||||||
*/
|
|
||||||
function setLocalTime(timer) {
|
|
||||||
document.getElementById("localtime" + timer.id).innerHTML = timer.targetDate.format("ddd @ LT");
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateClock() {
|
|
||||||
document.getElementById("current-time").innerHTML = getCurrentEveTimeString();
|
document.getElementById("current-time").innerHTML = getCurrentEveTimeString();
|
||||||
}
|
};
|
||||||
|
// Set initial values
|
||||||
|
setAllLocalTimes();
|
||||||
|
timedUpdate();
|
||||||
|
|
||||||
|
// Start timed updates
|
||||||
|
setInterval(timedUpdate, 1000);
|
||||||
</script>
|
</script>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|||||||
BIN
docs/_static/images/features/core/notifications.png
vendored
Normal file
BIN
docs/_static/images/features/core/notifications.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
@@ -25,6 +25,11 @@ The development environment consists of the following components:
|
|||||||
|
|
||||||
We will use the build-in Django development webserver, so we don't need to setup a WSGI server or a web server.
|
We will use the build-in Django development webserver, so we don't need to setup a WSGI server or a web server.
|
||||||
|
|
||||||
|
```eval_rst
|
||||||
|
.. note::
|
||||||
|
This setup works with both WSL 1 and WSL 2. However, due to the significantly better performance we recommend WSL 2.
|
||||||
|
```
|
||||||
|
|
||||||
## Requirement
|
## Requirement
|
||||||
|
|
||||||
The only requirement is a PC with Windows 10 and Internet connection in order to download the additional software components.
|
The only requirement is a PC with Windows 10 and Internet connection in order to download the additional software components.
|
||||||
@@ -361,8 +366,7 @@ Here is an example debug config for Celery:
|
|||||||
"module": "celery",
|
"module": "celery",
|
||||||
"cwd": "${workspaceFolder}/myauth",
|
"cwd": "${workspaceFolder}/myauth",
|
||||||
"console": "integratedTerminal",
|
"console": "integratedTerminal",
|
||||||
"args": [
|
"args": [
|
||||||
"-E",
|
|
||||||
"-A",
|
"-A",
|
||||||
"myauth",
|
"myauth",
|
||||||
"worker",
|
"worker",
|
||||||
@@ -371,7 +375,8 @@ Here is an example debug config for Celery:
|
|||||||
"-P",
|
"-P",
|
||||||
"solo",
|
"solo",
|
||||||
],
|
],
|
||||||
"django": true
|
"django": true,
|
||||||
|
"justMyCode": true,
|
||||||
},
|
},
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -386,15 +391,14 @@ Finally it makes sense to have a dedicated debug config for running unit tests.
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "${workspaceFolder}/myauth/manage.py",
|
"program": "${workspaceFolder}/myauth/manage.py",
|
||||||
"args": [
|
"args": [
|
||||||
"test",
|
"test",
|
||||||
"-v 2",
|
|
||||||
"--keepdb",
|
"--keepdb",
|
||||||
"--debug-mode",
|
"--debug-mode",
|
||||||
"--failfast",
|
"--failfast",
|
||||||
"example",
|
"example",
|
||||||
],
|
],
|
||||||
|
"django": true,
|
||||||
"django": true
|
"justMyCode": true
|
||||||
},
|
},
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -416,13 +420,31 @@ Finally you may also want to have a debug config to debug a non-Django Python sc
|
|||||||
|
|
||||||
## Additional tools
|
## Additional tools
|
||||||
|
|
||||||
The following additional tools are very helpful when developing for AA.
|
The following additional tools are very helpful when developing for AA with VS Code:
|
||||||
|
|
||||||
|
### Pylance
|
||||||
|
|
||||||
|
Pylance is an extension that works alongside Python in Visual Studio Code to provide performant language support: [Pylance](https://marketplace.visualstudio.com/items?itemName=ms-python.vscode-pylance)
|
||||||
|
|
||||||
### Code Spell Checker
|
### Code Spell Checker
|
||||||
|
|
||||||
Typos in your user facing comments can be quite embarrassing. This spell checker helps you avoid them.
|
Typos in your user facing comments can be quite embarrassing. This spell checker helps you avoid them: [Code Spell Checker](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker)
|
||||||
|
|
||||||
Install from here: [Code Spell Checker](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker)
|
### markdownlint
|
||||||
|
|
||||||
|
Extension for Visual Studio Code - Markdown linting and style checking for Visual Studio Code: [markdownlint](https://marketplace.visualstudio.com/items?itemName=DavidAnson.vscode-markdownlint)
|
||||||
|
|
||||||
|
### GitLens
|
||||||
|
|
||||||
|
Extension for Visual Studio Code - Supercharge the Git capabilities built into Visual Studio Code: [GitLens](https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens)
|
||||||
|
|
||||||
|
### RST preview
|
||||||
|
|
||||||
|
A VS Code extension to preview restructured text and provide syntax highlighting: [RST Preview](https://marketplace.visualstudio.com/items?itemName=tht13.rst-vscode)
|
||||||
|
|
||||||
|
### Django Template
|
||||||
|
|
||||||
|
This extension adds language colorization support and user snippets for the Django template language to VS Code: [Django Template](https://marketplace.visualstudio.com/items?itemName=bibhasdn.django-html)
|
||||||
|
|
||||||
### DBeaver
|
### DBeaver
|
||||||
|
|
||||||
|
|||||||
@@ -9,5 +9,6 @@ To reduce redundancy and help speed up development we encourage developers to ut
|
|||||||
esi
|
esi
|
||||||
evelinks
|
evelinks
|
||||||
eveonline
|
eveonline
|
||||||
|
notifications
|
||||||
testutils
|
testutils
|
||||||
```
|
```
|
||||||
|
|||||||
25
docs/development/tech_docu/api/notifications.rst
Normal file
25
docs/development/tech_docu/api/notifications.rst
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
======================
|
||||||
|
notifications
|
||||||
|
======================
|
||||||
|
|
||||||
|
The notifications package has an API for sending notifications.
|
||||||
|
|
||||||
|
Location: ``allianceauth.notifications``
|
||||||
|
|
||||||
|
.. automodule:: allianceauth.notifications.__init__
|
||||||
|
:members: notify
|
||||||
|
:undoc-members:
|
||||||
|
|
||||||
|
models
|
||||||
|
===========
|
||||||
|
|
||||||
|
.. autoclass:: allianceauth.notifications.models.Notification
|
||||||
|
:members: LEVEL_CHOICES, mark_viewed, set_level
|
||||||
|
:undoc-members:
|
||||||
|
|
||||||
|
managers
|
||||||
|
===========
|
||||||
|
|
||||||
|
.. autoclass:: allianceauth.notifications.managers.NotificationManager
|
||||||
|
:members: notify_user, user_unread_count
|
||||||
|
:undoc-members:
|
||||||
@@ -33,3 +33,21 @@ When you create an autogroup config you will be given the following options:
|
|||||||
- Corp/Alliance name source sets the source of the Corp/Alliance name used in creating the group name. Currently the options are Full name and Ticker.
|
- Corp/Alliance name source sets the source of the Corp/Alliance name used in creating the group name. Currently the options are Full name and Ticker.
|
||||||
|
|
||||||
- Replace spaces allows you to replace spaces in the autogroup name with the value in the Replace spaces with field. This can be blank.
|
- Replace spaces allows you to replace spaces in the autogroup name with the value in the Replace spaces with field. This can be blank.
|
||||||
|
|
||||||
|
## Permissions
|
||||||
|
|
||||||
|
Auto Groups are configured via models in the Admin Interface, a user will require the `Staff` Flag in addition to the following permissions.
|
||||||
|
|
||||||
|
```eval_rst
|
||||||
|
+-------------------------------------------+------------------+----------------+
|
||||||
|
| Permission | Admin Site | Auth Site |
|
||||||
|
+===========================================+==================+================+
|
||||||
|
| eve_autogroups.add_autogroupsconfig | Can create model | None. |
|
||||||
|
+-------------------------------------------+------------------+----------------+
|
||||||
|
| eve_autogroups.change_autogroupsconfig | Can edit model | None. |
|
||||||
|
+-------------------------------------------+------------------+----------------+
|
||||||
|
| eve_autogroups.delete_autogroupsconfig | Can delete model | None. |
|
||||||
|
+-------------------------------------------+------------------+----------------+
|
||||||
|
```
|
||||||
|
|
||||||
|
There exists more models that will be automatically created and maintained by this module, they do not require end-user/admin interaction. `managedalliancegroup` `managedcorpgroups`
|
||||||
|
|||||||
@@ -102,11 +102,6 @@ To use this feature, users will require some of the following:
|
|||||||
+---------------------------------------+------------------+----------------------------------------------------+
|
+---------------------------------------+------------------+----------------------------------------------------+
|
||||||
| corpstats.add_corpstats | Can create model | Can add new corpstats using an SSO token. |
|
| corpstats.add_corpstats | Can create model | Can add new corpstats using an SSO token. |
|
||||||
+---------------------------------------+------------------+----------------------------------------------------+
|
+---------------------------------------+------------------+----------------------------------------------------+
|
||||||
| corpstats.change_corpstats | Can edit model | None. |
|
|
||||||
+---------------------------------------+------------------+----------------------------------------------------+
|
|
||||||
| corpstats.remove_corpstats | Can delete model | None. |
|
|
||||||
+---------------------------------------+------------------+----------------------------------------------------+
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Users who add a Corp Stats with their token will be granted permissions to view it regardless of the above permissions. View permissions are interpreted in the "OR" sense: a user can view their corporation's Corp Stats without the `view_corp_corpstats` permission if they have the `view_alliance_corpstats` permission, same idea for their state. Note that these evaluate against the user's main character.
|
Users who add a Corp Stats with their token will be granted permissions to view it regardless of the above permissions. View permissions are interpreted in the "OR" sense: a user can view their corporation's Corp Stats without the `view_corp_corpstats` permission if they have the `view_alliance_corpstats` permission, same idea for their state. Note that these evaluate against the user's main character.
|
||||||
|
|||||||
@@ -9,3 +9,20 @@ The Fleet Activity Tracking (FAT) app allows you to track fleet participation.
|
|||||||
Fleet Activity Tracking requires access to the `esi-location.read_location.v1`, `esi-location.read_ship_type.v1`, and `esi-universe.read_structures.v1` SSO scopes. Update your application on the [EVE Developers site](https://developers.eveonline.com) to ensure these are available.
|
Fleet Activity Tracking requires access to the `esi-location.read_location.v1`, `esi-location.read_ship_type.v1`, and `esi-universe.read_structures.v1` SSO scopes. Update your application on the [EVE Developers site](https://developers.eveonline.com) to ensure these are available.
|
||||||
|
|
||||||
Add `'allianceauth.fleetactivitytracking',` to your `INSTALLED_APPS` list in your auth project's settings file. Run migrations to complete installation.
|
Add `'allianceauth.fleetactivitytracking',` to your `INSTALLED_APPS` list in your auth project's settings file. Run migrations to complete installation.
|
||||||
|
|
||||||
|
## Permissions
|
||||||
|
|
||||||
|
To administer this feature, users will require some of the following.
|
||||||
|
|
||||||
|
Users do not require any permissions to interact with FAT Links created.
|
||||||
|
|
||||||
|
```eval_rst
|
||||||
|
+---------------------------------------+------------------+--------------------------------------------------------------------------+
|
||||||
|
| Permission | Admin Site | Auth Site |
|
||||||
|
+=======================================+==================+==========================================================================+
|
||||||
|
| auth.fleetactivitytracking | None | Create and Modify FATLinks |
|
||||||
|
+---------------------------------------+------------------+--------------------------------------------------------------------------+
|
||||||
|
| auth.fleetactivitytracking_statistics | None | Can view detailed statistics for corp models and other characters. |
|
||||||
|
+---------------------------------------+------------------+--------------------------------------------------------------------------+
|
||||||
|
|
||||||
|
```
|
||||||
|
|||||||
@@ -40,7 +40,9 @@ Any reviewer who can see the application can view the applicant's APIs if they p
|
|||||||
|
|
||||||
## Permissions
|
## Permissions
|
||||||
|
|
||||||
The following permissions have an effect on the website above and beyond their usual admin site functions.
|
To administer this feature, users will require some of the following.
|
||||||
|
|
||||||
|
Users do not require any permission to apply to a corporation and fill out the form.
|
||||||
|
|
||||||
```eval_rst
|
```eval_rst
|
||||||
+---------------------------------------+------------------+----------------------------------------------------+
|
+---------------------------------------+------------------+----------------------------------------------------+
|
||||||
@@ -54,13 +56,12 @@ The following permissions have an effect on the website above and beyond their u
|
|||||||
+---------------------------------------+------------------+----------------------------------------------------+
|
+---------------------------------------+------------------+----------------------------------------------------+
|
||||||
| hrapplications.reject_applications | None | Can reject applications |
|
| hrapplications.reject_applications | None | Can reject applications |
|
||||||
+---------------------------------------+------------------+----------------------------------------------------+
|
+---------------------------------------+------------------+----------------------------------------------------+
|
||||||
| hrapplications.view_apis | None | Can view applicant API keys, and audit in Jacknife |
|
|
||||||
+---------------------------------------+------------------+----------------------------------------------------+
|
|
||||||
| hrapplications.add_applicationcomment | Can create model | Can comment on applications |
|
| hrapplications.add_applicationcomment | Can create model | Can comment on applications |
|
||||||
+---------------------------------------+------------------+----------------------------------------------------+
|
+---------------------------------------+------------------+----------------------------------------------------+
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
A user with `auth.human_resources` can only see applications to their own corp.
|
||||||
|
|
||||||
Best practice is to bundle the `auth.human_resources` permission alongside the `hrapplications.approve_application` and `hrapplications.reject_application` permissions, as in isolation these don't make much sense.
|
Best practice is to bundle the `auth.human_resources` permission alongside the `hrapplications.approve_application` and `hrapplications.reject_application` permissions, as in isolation these don't make much sense.
|
||||||
|
|
||||||
## Models
|
## Models
|
||||||
|
|||||||
@@ -7,3 +7,17 @@ Fleet Operations is an app for organizing and communicating fleet schedules.
|
|||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
Add `'allianceauth.optimer',` to your `INSTALLED_APPS` list in your auth project's settings file. Run migrations to complete installation.
|
Add `'allianceauth.optimer',` to your `INSTALLED_APPS` list in your auth project's settings file. Run migrations to complete installation.
|
||||||
|
|
||||||
|
## Permissions
|
||||||
|
|
||||||
|
To use and administer this feature, users will require some of the following.
|
||||||
|
|
||||||
|
```eval_rst
|
||||||
|
+---------------------------------------+------------------+--------------------------------------------------------------------------+
|
||||||
|
| Permission | Admin Site | Auth Site |
|
||||||
|
+=======================================+==================+==========================================================================+
|
||||||
|
| auth.optimer_view | None | Can view Fleet Operation Timers |
|
||||||
|
+---------------------------------------+------------------+--------------------------------------------------------------------------+
|
||||||
|
| auth.optimer_manage | None | Can Manage Fleet Operation timers |
|
||||||
|
+---------------------------------------+------------------+--------------------------------------------------------------------------+
|
||||||
|
```
|
||||||
|
|||||||
@@ -37,3 +37,15 @@ The permissions audit page will give you an overview of all the users who have a
|
|||||||

|

|
||||||
|
|
||||||
Please note that users may appear multiple times if this permission is granted via multiple sources.
|
Please note that users may appear multiple times if this permission is granted via multiple sources.
|
||||||
|
|
||||||
|
## Permissions
|
||||||
|
|
||||||
|
To use this feature, users will require some of the following.
|
||||||
|
|
||||||
|
```eval_rst
|
||||||
|
+---------------------------------------+------------------+--------------------------------------------------------------------------+
|
||||||
|
| Permission | Admin Site | Auth Site |
|
||||||
|
+=======================================+==================+==========================================================================+
|
||||||
|
| permissions_tool.audit_permissions | None | Can view the Permissions Audit tool |
|
||||||
|
+---------------------------------------+------------------+--------------------------------------------------------------------------+
|
||||||
|
```
|
||||||
|
|||||||
@@ -7,3 +7,19 @@ Ship Replacement helps you to organize ship replacement programs (SRP) for your
|
|||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
Add `'allianceauth.srp',` to your `INSTALLED_APPS` list in your auth project's settings file. Run migrations to complete installation.
|
Add `'allianceauth.srp',` to your `INSTALLED_APPS` list in your auth project's settings file. Run migrations to complete installation.
|
||||||
|
|
||||||
|
## Permissions
|
||||||
|
|
||||||
|
To use and administer this feature, users will require some of the following.
|
||||||
|
|
||||||
|
```eval_rst
|
||||||
|
+----------------------+------------------+------------------------------------------------------------+
|
||||||
|
| Permission | Admin Site | Auth Site |
|
||||||
|
+======================+==================+============================================================+
|
||||||
|
| auth.access_srp | None | Can create an SRP request from a fleet |
|
||||||
|
+----------------------+------------------+------------------------------------------------------------+
|
||||||
|
| auth.srp_management | None | Can Approve and Deny SRP requests, Can create an SRP Fleet |
|
||||||
|
+----------------------+------------------+------------------------------------------------------------+
|
||||||
|
| srp.add_srpfleetmain | Can Add Model | Can Create an SRP Fleet |
|
||||||
|
+----------------------+------------------+------------------------------------------------------------+
|
||||||
|
```
|
||||||
|
|||||||
@@ -7,3 +7,17 @@ Structure Timers helps you keep track of both offensive and defensive structure
|
|||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
Add `'allianceauth.timerboard',` to your `INSTALLED_APPS` list in your auth project's settings file. Run migrations to complete installation.
|
Add `'allianceauth.timerboard',` to your `INSTALLED_APPS` list in your auth project's settings file. Run migrations to complete installation.
|
||||||
|
|
||||||
|
## Permissions
|
||||||
|
|
||||||
|
To use and administer this feature, users will require some of the following.
|
||||||
|
|
||||||
|
```eval_rst
|
||||||
|
+---------------------------------------+------------------+--------------------------------------------------------------------------+
|
||||||
|
| Permission | Admin Site | Auth Site |
|
||||||
|
+=======================================+==================+==========================================================================+
|
||||||
|
| auth.timer_view | None | Can view Timerboard Timers |
|
||||||
|
+---------------------------------------+------------------+--------------------------------------------------------------------------+
|
||||||
|
| auth.timer_manage | None | Can Manage Timerboard timers |
|
||||||
|
+---------------------------------------+------------------+--------------------------------------------------------------------------+
|
||||||
|
```
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user