Merge branch 'django4' into 'v3.x'

v2.10.x Uplifts, DJ4, Py3.8 + More

See merge request allianceauth/allianceauth!1387
This commit is contained in:
Ariel Rin 2022-02-08 13:04:45 +00:00
commit 703c2392a9
56 changed files with 265 additions and 244 deletions

View File

@ -14,6 +14,7 @@ stages:
include: include:
- template: Dependency-Scanning.gitlab-ci.yml - template: Dependency-Scanning.gitlab-ci.yml
- template: Security/SAST.gitlab-ci.yml - template: Security/SAST.gitlab-ci.yml
- template: Security/Secret-Detection.gitlab-ci.yml
before_script: before_script:
- apt-get update && apt-get install redis-server -y - apt-get update && apt-get install redis-server -y

View File

@ -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.9.4' __version__ = '2.10.0'
__title__ = 'Alliance Auth' __title__ = 'Alliance Auth'
__url__ = 'https://gitlab.com/allianceauth/allianceauth' __url__ = 'https://gitlab.com/allianceauth/allianceauth'
NAME = f'{__title__} v{__version__}' NAME = f'{__title__} v{__version__}'

View File

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

View File

@ -1,14 +1,16 @@
from django.conf.urls import url, include from django.conf.urls import include
from allianceauth.authentication import views from allianceauth.authentication import views
from django.urls import re_path
from django.urls import path
urlpatterns = [ urlpatterns = [
url(r'^activate/complete/$', views.activation_complete, name='registration_activation_complete'), path('activate/complete/', views.activation_complete, name='registration_activation_complete'),
# The activation key can make use of any character from the # The activation key can make use of any character from the
# URL-safe base64 alphabet, plus the colon as a separator. # URL-safe base64 alphabet, plus the colon as a separator.
url(r'^activate/(?P<activation_key>[-:\w]+)/$', views.ActivationView.as_view(), name='registration_activate'), re_path(r'^activate/(?P<activation_key>[-:\w]+)/$', views.ActivationView.as_view(), name='registration_activate'),
url(r'^register/$', views.RegistrationView.as_view(), name='registration_register'), path('register/', views.RegistrationView.as_view(), name='registration_register'),
url(r'^register/complete/$', views.registration_complete, name='registration_complete'), path('register/complete/', views.registration_complete, name='registration_complete'),
url(r'^register/closed/$', views.registration_closed, name='registration_disallowed'), path('register/closed/', views.registration_closed, name='registration_disallowed'),
url(r'', include('django.contrib.auth.urls')), path('', include('django.contrib.auth.urls')),
] ]

View File

@ -2,7 +2,7 @@ import logging
from django.contrib.auth.models import User, Permission from django.contrib.auth.models import User, Permission
from django.db import models, transaction from django.db import models, transaction
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import gettext_lazy as _
from allianceauth.eveonline.models import EveCharacter, EveCorporationInfo, EveAllianceInfo, EveFactionInfo from allianceauth.eveonline.models import EveCharacter, EveCorporationInfo, EveAllianceInfo, EveFactionInfo
from allianceauth.notifications import notify from allianceauth.notifications import notify

View File

@ -11,7 +11,7 @@ from allianceauth.eveonline.models import EveCharacter
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
state_changed = Signal(providing_args=['user', 'state']) state_changed = Signal()
def trigger_state_check(state): def trigger_state_check(state):

View File

@ -1,5 +1,4 @@
from django.conf.urls import url from django.urls import path
from django.contrib.auth.decorators import login_required
from django.views.generic.base import TemplateView from django.views.generic.base import TemplateView
from . import views from . import views
@ -7,21 +6,21 @@ from . import views
app_name = 'authentication' app_name = 'authentication'
urlpatterns = [ urlpatterns = [
url(r'^$', views.index, name='index'), path('', views.index, name='index'),
url( path(
r'^account/login/$', 'account/login/',
TemplateView.as_view(template_name='public/login.html'), TemplateView.as_view(template_name='public/login.html'),
name='login' name='login'
), ),
url( path(
r'^account/characters/main/$', 'account/characters/main/',
views.main_character_change, views.main_character_change,
name='change_main_character' name='change_main_character'
), ),
url( path(
r'^account/characters/add/$', 'account/characters/add/',
views.add_character, views.add_character,
name='add_character' name='add_character'
), ),
url(r'^dashboard/$', views.dashboard, name='dashboard'), path('dashboard/', views.dashboard, name='dashboard'),
] ]

View File

@ -1,5 +1,5 @@
from allianceauth.services.hooks import MenuItemHook, UrlHook from allianceauth.services.hooks import MenuItemHook, UrlHook
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import gettext_lazy as _
from allianceauth import hooks from allianceauth import hooks
from allianceauth.corputils import urls from allianceauth.corputils import urls

View File

@ -1,12 +1,11 @@
from django.conf.urls import url from django.urls import path
from . import views from . import views
app_name = 'corputils' app_name = 'corputils'
urlpatterns = [ urlpatterns = [
url(r'^$', views.corpstats_view, name='view'), path('', views.corpstats_view, name='view'),
url(r'^add/$', views.corpstats_add, name='add'), path('add/', views.corpstats_add, name='add'),
url(r'^(?P<corp_id>(\d)*)/$', views.corpstats_view, name='view_corp'), path('<int:corp_id>/', views.corpstats_view, name='view_corp'),
url(r'^(?P<corp_id>(\d)+)/update/$', views.corpstats_update, name='update'), path('<int:corp_id>/update/', views.corpstats_update, name='update'),
url(r'^search/$', views.corpstats_search, name='search'), path('search/', views.corpstats_search, name='search'),
] ]

View File

@ -6,7 +6,7 @@ from django.contrib.auth.decorators import login_required, permission_required,
from django.core.exceptions import PermissionDenied, ObjectDoesNotExist from django.core.exceptions import PermissionDenied, ObjectDoesNotExist
from django.db import IntegrityError from django.db import IntegrityError
from django.shortcuts import render, redirect, get_object_or_404 from django.shortcuts import render, redirect, get_object_or_404
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import gettext_lazy as _
from esi.decorators import token_required from esi.decorators import token_required
from allianceauth.eveonline.models import EveCharacter, EveCorporationInfo from allianceauth.eveonline.models import EveCharacter, EveCorporationInfo

View File

@ -1,5 +1,5 @@
from . import urls from . import urls
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import gettext_lazy as _
from allianceauth import hooks from allianceauth import hooks
from allianceauth.services.hooks import MenuItemHook, UrlHook from allianceauth.services.hooks import MenuItemHook, UrlHook

View File

@ -1,5 +1,5 @@
from django import forms from django import forms
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import gettext_lazy as _
class FatlinkForm(forms.Form): class FatlinkForm(forms.Form):

View File

@ -1,30 +1,30 @@
from django.conf.urls import url from django.urls import path
from . import views from . import views
app_name = 'fleetactivitytracking' app_name = 'fleetactivitytracking'
urlpatterns = [ urlpatterns = [
# FleetActivityTracking (FAT) # FleetActivityTracking (FAT)
url(r'^$', views.fatlink_view, name='view'), path('', views.fatlink_view, name='view'),
url(r'^statistics/$', views.fatlink_statistics_view, name='statistics'), path('statistics/', views.fatlink_statistics_view, name='statistics'),
url(r'^statistics/corp/(\w+)$', views.fatlink_statistics_corp_view, path('statistics/corp/<int:corpid>/', views.fatlink_statistics_corp_view,
name='statistics_corp'), name='statistics_corp'),
url(r'^statistics/corp/(?P<corpid>\w+)/(?P<year>[0-9]+)/(?P<month>[0-9]+)/', path('statistics/corp/<int:corpid>/<int:year>/<int:month>/',
views.fatlink_statistics_corp_view, views.fatlink_statistics_corp_view,
name='statistics_corp_month'), name='statistics_corp_month'),
url(r'^statistics/(?P<year>[0-9]+)/(?P<month>[0-9]+)/$', views.fatlink_statistics_view, path('statistics/<int:year>/<int:month>/', views.fatlink_statistics_view,
name='statistics_month'), name='statistics_month'),
url(r'^user/statistics/$', views.fatlink_personal_statistics_view, path('user/statistics/', views.fatlink_personal_statistics_view,
name='personal_statistics'), name='personal_statistics'),
url(r'^user/statistics/(?P<year>[0-9]+)/$', views.fatlink_personal_statistics_view, path('user/statistics/<int:year>/', views.fatlink_personal_statistics_view,
name='personal_statistics_year'), name='personal_statistics_year'),
url(r'^user/statistics/(?P<year>[0-9]+)/(?P<month>[0-9]+)/$', path('user/statistics/<int:year>/<int:month>/',
views.fatlink_monthly_personal_statistics_view, views.fatlink_monthly_personal_statistics_view,
name='personal_statistics_month'), name='personal_statistics_month'),
url(r'^user/(?P<char_id>[0-9]+)/statistics/(?P<year>[0-9]+)/(?P<month>[0-9]+)/$', path('user/<int:char_id>/statistics/<int:year>/<int:month>/',
views.fatlink_monthly_personal_statistics_view, views.fatlink_monthly_personal_statistics_view,
name='user_statistics_month'), name='user_statistics_month'),
url(r'^create/$', views.create_fatlink_view, name='create'), path('create/', views.create_fatlink_view, name='create'),
url(r'^modify/(?P<fat_hash>[a-zA-Z0-9_-]+)/$', views.modify_fatlink_view, name='modify'), path('modify/<str:fat_hash>/', views.modify_fatlink_view, name='modify'),
url(r'^link/(?P<fat_hash>[a-zA-Z0-9]+)/$', views.click_fatlink_view, name='click'), path('link/<str:fat_hash>/', views.click_fatlink_view, name='click'),
] ]

View File

@ -10,7 +10,7 @@ from django.contrib.auth.models import User
from django.core.exceptions import ValidationError, ObjectDoesNotExist from django.core.exceptions import ValidationError, ObjectDoesNotExist
from django.shortcuts import render, redirect, get_object_or_404, Http404 from django.shortcuts import render, redirect, get_object_or_404, Http404
from django.utils import timezone from django.utils import timezone
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import gettext_lazy as _
from esi.decorators import token_required from esi.decorators import token_required
from allianceauth.eveonline.providers import provider from allianceauth.eveonline.providers import provider
from .forms import FatlinkForm from .forms import FatlinkForm

View File

@ -1,4 +1,4 @@
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import gettext_lazy as _
from allianceauth.services.hooks import MenuItemHook, UrlHook from allianceauth.services.hooks import MenuItemHook, UrlHook
from allianceauth import hooks from allianceauth import hooks

View File

@ -1,51 +1,50 @@
from django.urls import path
from . import views from . import views
from django.conf.urls import url
app_name = "groupmanagement" app_name = "groupmanagement"
urlpatterns = [ urlpatterns = [
# groups # groups
url(r"^groups/$", views.groups_view, name="groups"), path("groups", views.groups_view, name="groups"),
url(r"^group/request/join/(\w+)/$", views.group_request_add, name="request_add"), path("group/request/join/<int:group_id>/", views.group_request_add, name="request_add"),
url( path(
r"^group/request/leave/(\w+)/$", views.group_request_leave, name="request_leave" "group/request/leave/<int:group_id>/", views.group_request_leave, name="request_leave"
), ),
# group management # group management
url(r"^groupmanagement/requests/$", views.group_management, name="management"), path("groupmanagement/requests/", views.group_management, name="management"),
url(r"^groupmanagement/membership/$", views.group_membership, name="membership"), path("groupmanagement/membership/", views.group_membership, name="membership"),
url( path(
r"^groupmanagement/membership/(\w+)/$", "groupmanagement/membership/<int:group_id>/",
views.group_membership_list, views.group_membership_list,
name="membership", name="membership",
), ),
url( path(
r"^groupmanagement/membership/(\w+)/audit-log/$", "groupmanagement/membership/<int:group_id>/audit-log/",
views.group_membership_audit, views.group_membership_audit,
name="audit_log", name="audit_log",
), ),
url( path(
r"^groupmanagement/membership/(\w+)/remove/(\w+)/$", "groupmanagement/membership/<int:group_id>/remove/<int:user_id>/",
views.group_membership_remove, views.group_membership_remove,
name="membership_remove", name="membership_remove",
), ),
url( path(
r"^groupmanagement/request/join/accept/(\w+)/$", "groupmanagement/request/join/accept/<int:group_request_id>/",
views.group_accept_request, views.group_accept_request,
name="accept_request", name="accept_request",
), ),
url( path(
r"^groupmanagement/request/join/reject/(\w+)/$", "groupmanagement/request/join/reject/<int:group_request_id>/",
views.group_reject_request, views.group_reject_request,
name="reject_request", name="reject_request",
), ),
url( path(
r"^groupmanagement/request/leave/accept/(\w+)/$", "groupmanagement/request/leave/accept/<int:group_request_id>/",
views.group_leave_accept_request, views.group_leave_accept_request,
name="leave_accept_request", name="leave_accept_request",
), ),
url( path(
r"^groupmanagement/request/leave/reject/(\w+)/$", "groupmanagement/request/leave/reject/<int:group_request_id>/",
views.group_leave_reject_request, views.group_leave_reject_request,
name="leave_reject_request", name="leave_reject_request",
), ),

View File

@ -9,7 +9,7 @@ from django.core.exceptions import ObjectDoesNotExist, PermissionDenied
from django.db.models import Count from django.db.models import Count
from django.http import Http404 from django.http import Http404
from django.shortcuts import render, redirect, get_object_or_404 from django.shortcuts import render, redirect, get_object_or_404
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import gettext_lazy as _
from allianceauth.notifications import notify from allianceauth.notifications import notify

View File

@ -1,4 +1,4 @@
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import gettext_lazy as _
from allianceauth import hooks from allianceauth import hooks
from allianceauth.services.hooks import MenuItemHook, UrlHook from allianceauth.services.hooks import MenuItemHook, UrlHook

View File

@ -1,5 +1,5 @@
from django import forms from django import forms
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import gettext_lazy as _
class HRApplicationCommentForm(forms.Form): class HRApplicationCommentForm(forms.Form):

View File

@ -1,31 +1,31 @@
from django.conf.urls import url from django.urls import path
from . import views from . import views
app_name = 'hrapplications' app_name = 'hrapplications'
urlpatterns = [ urlpatterns = [
url(r'^$', views.hr_application_management_view, path('', views.hr_application_management_view,
name="index"), name="index"),
url(r'^create/$', views.hr_application_create_view, path('create/', views.hr_application_create_view,
name="create_view"), name="create_view"),
url(r'^create/(\d+)', views.hr_application_create_view, path('create/<int:form_id>/', views.hr_application_create_view,
name="create_view"), name="create_view"),
url(r'^remove/(\w+)', views.hr_application_remove, path('remove/<int:app_id>/', views.hr_application_remove,
name="remove"), name="remove"),
url(r'^view/(\w+)', views.hr_application_view, path('view/<int:app_id>/', views.hr_application_view,
name="view"), name="view"),
url(r'^personal/view/(\w+)', views.hr_application_personal_view, path('personal/view/<int:app_id>/', views.hr_application_personal_view,
name="personal_view"), name="personal_view"),
url(r'^personal/removal/(\w+)', path('personal/removal/<int:app_id>/',
views.hr_application_personal_removal, views.hr_application_personal_removal,
name="personal_removal"), name="personal_removal"),
url(r'^approve/(\w+)', views.hr_application_approve, path('approve/<int:app_id>/', views.hr_application_approve,
name="approve"), name="approve"),
url(r'^reject/(\w+)', views.hr_application_reject, path('reject/<int:app_id>/', views.hr_application_reject,
name="reject"), name="reject"),
url(r'^search/', views.hr_application_search, path('search/', views.hr_application_search,
name="search"), name="search"),
url(r'^mark_in_progress/(\w+)', views.hr_application_mark_in_progress, path('mark_in_progress/<int:app_id>/', views.hr_application_mark_in_progress,
name="mark_in_progress"), name="mark_in_progress"),
] ]

View File

@ -1,16 +1,16 @@
from django.conf.urls import url from django.urls import path
from . import views from . import views
app_name = 'notifications' app_name = 'notifications'
# Notifications # Notifications
urlpatterns = [ urlpatterns = [
url(r'^remove_notifications/(\w+)/$', views.remove_notification, name='remove'), path('remove_notifications/<int:notif_id>/', views.remove_notification, name='remove'),
url(r'^notifications/mark_all_read/$', views.mark_all_read, name='mark_all_read'), path('notifications/mark_all_read/', views.mark_all_read, name='mark_all_read'),
url(r'^notifications/delete_all_read/$', views.delete_all_read, name='delete_all_read'), path('notifications/delete_all_read/', views.delete_all_read, name='delete_all_read'),
url(r'^notifications/$', views.notification_list, name='list'), path('notifications/', views.notification_list, name='list'),
url(r'^notifications/(\w+)/$', views.notification_view, name='view'), path('notifications/<int:notif_id>/', views.notification_view, name='view'),
url( path(
r'^user_notifications_count/(?P<user_pk>\d+)/$', 'user_notifications_count/<int:user_pk>/',
views.user_notifications_count, views.user_notifications_count,
name='user_notifications_count' name='user_notifications_count'
), ),

View File

@ -1,5 +1,5 @@
from allianceauth.services.hooks import MenuItemHook, UrlHook from allianceauth.services.hooks import MenuItemHook, UrlHook
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import gettext_lazy as _
from allianceauth import hooks from allianceauth import hooks
from . import urls from . import urls

View File

@ -1,5 +1,5 @@
from django import forms from django import forms
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import gettext_lazy as _
from allianceauth.optimer.form_widgets import DataListWidget from allianceauth.optimer.form_widgets import DataListWidget

View File

@ -1,12 +1,12 @@
from django.conf.urls import url from django.urls import path
from . import views from . import views
app_name = 'optimer' app_name = 'optimer'
urlpatterns = [ urlpatterns = [
url(r'^$', views.optimer_view, name='view'), path('', views.optimer_view, name='view'),
url(r'^add$', views.add_optimer_view, name='add'), path('add/', views.add_optimer_view, name='add'),
url(r'^(\w+)/remove$', views.remove_optimer, name='remove'), path('<int:optimer_id>/remove/', views.remove_optimer, name='remove'),
url(r'^(\w+)/edit$', views.edit_optimer, name='edit'), path('<int:optimer_id>/edit/', views.edit_optimer, name='edit'),
] ]

View File

@ -6,7 +6,7 @@ from django.contrib.auth.decorators import permission_required
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from django.shortcuts import render, redirect from django.shortcuts import render, redirect
from django.utils import timezone from django.utils import timezone
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import gettext_lazy as _
from .form import OpForm from .form import OpForm
from .models import OpTimer, OpTimerType from .models import OpTimer, OpTimerType

View File

@ -1,11 +1,12 @@
from django.conf.urls import url from django.urls import re_path
from django.urls import path
from . import views from . import views
app_name = 'permissions_tool' app_name = 'permissions_tool'
urlpatterns = [ urlpatterns = [
url(r'^overview/$', views.permissions_overview, name='overview'), path('overview/', views.permissions_overview, name='overview'),
url(r'^audit/(?P<app_label>[\w\-_]+)/(?P<model>[\w\-_]+)/(?P<codename>[\w\-_]+)/$', views.permissions_audit, re_path(r'^audit/(?P<app_label>[\w\-_]+)/(?P<model>[\w\-_]+)/(?P<codename>[\w\-_]+)/$', views.permissions_audit,
name='audit'), name='audit'),
] ]

View File

@ -1,8 +1,9 @@
from django.conf.urls import include, url from django.conf.urls import include
from allianceauth import urls from allianceauth import urls
from django.urls import re_path
urlpatterns = [ urlpatterns = [
url(r'', include(urls)), re_path(r'', include(urls)),
] ]
handler500 = 'allianceauth.views.Generic500Redirect' handler500 = 'allianceauth.views.Generic500Redirect'

View File

@ -1,5 +1,5 @@
from django import forms from django import forms
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import gettext_lazy as _
class FleetFormatterForm(forms.Form): class FleetFormatterForm(forms.Form):

View File

@ -1,4 +1,5 @@
from django.conf.urls import include, url from django.conf.urls import include
from django.urls import re_path
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from django.template.loader import render_to_string from django.template.loader import render_to_string
from django.utils.functional import cached_property from django.utils.functional import cached_property
@ -9,7 +10,6 @@ from allianceauth.hooks import get_hooks
from .models import NameFormatConfig from .models import NameFormatConfig
def get_extension_logger(name): def get_extension_logger(name):
""" """
Takes the name of a plugin/extension and generates a child logger of the extensions logger Takes the name of a plugin/extension and generates a child logger of the extensions logger
@ -157,7 +157,7 @@ class MenuItemHook:
class UrlHook: class UrlHook:
def __init__(self, urls, namespace, base_url): def __init__(self, urls, namespace, base_url):
self.include_pattern = url(base_url, include(urls, namespace=namespace)) self.include_pattern = re_path(base_url, include(urls, namespace=namespace))
class NameFormatter: class NameFormatter:

View File

@ -1,4 +1,5 @@
from django.conf.urls import url, include from django.conf.urls import include
from django.urls import path
from . import views from . import views
@ -6,13 +7,13 @@ app_name = 'discord'
module_urls = [ module_urls = [
# Discord Service Control # Discord Service Control
url(r'^activate/$', views.activate_discord, name='activate'), path('activate/', views.activate_discord, name='activate'),
url(r'^deactivate/$', views.deactivate_discord, name='deactivate'), path('deactivate/', views.deactivate_discord, name='deactivate'),
url(r'^reset/$', views.reset_discord, name='reset'), path('reset/', views.reset_discord, name='reset'),
url(r'^callback/$', views.discord_callback, name='callback'), path('callback/', views.discord_callback, name='callback'),
url(r'^add_bot/$', views.discord_add_bot, name='add_bot'), path('add_bot/', views.discord_add_bot, name='add_bot'),
] ]
urlpatterns = [ urlpatterns = [
url(r'^discord/', include((module_urls, app_name), namespace=app_name)) path('discord/', include((module_urls, app_name), namespace=app_name))
] ]

View File

@ -1,8 +1,8 @@
from django.conf.urls import url from django.urls import path
from . import views from . import views
urlpatterns = [ urlpatterns = [
# Discourse Service Control # Discourse Service Control
url(r'^discourse/sso$', views.discourse_sso, name='auth_discourse_sso'), path('discourse/sso', views.discourse_sso, name='auth_discourse_sso'),
] ]

View File

@ -1,4 +1,5 @@
from django.conf.urls import url, include from django.conf.urls import include
from django.urls import path
app_name = 'example' app_name = 'example'
@ -7,5 +8,5 @@ module_urls = [
] ]
urlpatterns = [ urlpatterns = [
url(r'^example/', include((module_urls, app_name), namespace=app_name)), path('example/', include((module_urls, app_name), namespace=app_name)),
] ]

View File

@ -1,4 +1,5 @@
from django.conf.urls import url, include from django.conf.urls import include
from django.urls import path
from . import views from . import views
@ -6,12 +7,12 @@ app_name = 'ips4'
module_urls = [ module_urls = [
# IPS4 Service Control # IPS4 Service Control
url(r'^activate/$', views.activate_ips4, name='activate'), path('activate/', views.activate_ips4, name='activate'),
url(r'^deactivate/$', views.deactivate_ips4, name='deactivate'), path('deactivate/', views.deactivate_ips4, name='deactivate'),
url(r'^reset_password/$', views.reset_ips4_password, name='reset_password'), path('reset_password/', views.reset_ips4_password, name='reset_password'),
url(r'^set_password/$', views.set_ips4_password, name='set_password'), path('set_password/', views.set_ips4_password, name='set_password'),
] ]
urlpatterns = [ urlpatterns = [
url(r'^ips4/', include((module_urls, app_name), namespace=app_name)) path('ips4/', include((module_urls, app_name), namespace=app_name))
] ]

View File

@ -3,7 +3,7 @@
<td class="text-center">{{ username }}</td> <td class="text-center">{{ username }}</td>
<td class="text-center"><a href="mumble://{{ service_url }}">{{ service_url }}</a></td> <td class="text-center"><a href="mumble://{{ service_url }}">{{ service_url }}</a></td>
<td class="text-center"> <td class="text-center">
{% ifequal username "" %} {% if username == "" %}
<a href="{% url urls.auth_activate %}" title="Activate" class="btn btn-warning"> <a href="{% url urls.auth_activate %}" title="Activate" class="btn btn-warning">
<span class="glyphicon glyphicon-ok"></span> <span class="glyphicon glyphicon-ok"></span>
</a> </a>
@ -20,6 +20,6 @@
<a href="mumble://{{ connect_url }}" class="btn btn-success" title="Connect"> <a href="mumble://{{ connect_url }}" class="btn btn-success" title="Connect">
<span class="glyphicon glyphicon-arrow-right"></span> <span class="glyphicon glyphicon-arrow-right"></span>
</a> </a>
{% endifequal %} {% endif %}
</td> </td>
</tr> </tr>

View File

@ -1,4 +1,5 @@
from django.conf.urls import url, include from django.conf.urls import include
from django.urls import path
from . import views from . import views
@ -6,12 +7,12 @@ app_name = 'mumble'
module_urls = [ module_urls = [
# Mumble service control # Mumble service control
url(r'^activate/$', views.CreateAccountMumbleView.as_view(), name='activate'), path('activate/', views.CreateAccountMumbleView.as_view(), name='activate'),
url(r'^deactivate/$', views.DeleteMumbleView.as_view(), name='deactivate'), path('deactivate/', views.DeleteMumbleView.as_view(), name='deactivate'),
url(r'^reset_password/$', views.ResetPasswordMumbleView.as_view(), name='reset_password'), path('reset_password/', views.ResetPasswordMumbleView.as_view(), name='reset_password'),
url(r'^set_password/$', views.SetPasswordMumbleView.as_view(), name='set_password'), path('set_password/', views.SetPasswordMumbleView.as_view(), name='set_password'),
] ]
urlpatterns = [ urlpatterns = [
url(r'^mumble/', include((module_urls, app_name), namespace=app_name)) path('mumble/', include((module_urls, app_name), namespace=app_name))
] ]

View File

@ -1,5 +1,5 @@
from django import forms from django import forms
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import gettext_lazy as _
class JabberBroadcastForm(forms.Form): class JabberBroadcastForm(forms.Form):

View File

@ -1,4 +1,5 @@
from django.conf.urls import url, include from django.conf.urls import include
from django.urls import path
from . import views from . import views
@ -6,13 +7,13 @@ app_name = 'openfire'
module_urls = [ module_urls = [
# Jabber Service Control # Jabber Service Control
url(r'^activate/$', views.activate_jabber, name='activate'), path('activate/', views.activate_jabber, name='activate'),
url(r'^deactivate/$', views.deactivate_jabber, name='deactivate'), path('deactivate/', views.deactivate_jabber, name='deactivate'),
url(r'^reset_password/$', views.reset_jabber_password, name='reset_password'), path('reset_password/', views.reset_jabber_password, name='reset_password'),
url(r'^set_password/$', views.set_jabber_password, name='set_password'), path('set_password/', views.set_jabber_password, name='set_password'),
url(r'^broadcast/$', views.jabber_broadcast_view, name='broadcast'), path('broadcast/', views.jabber_broadcast_view, name='broadcast'),
] ]
urlpatterns = [ urlpatterns = [
url(r'^openfire/', include((module_urls, app_name), namespace=app_name)), path('openfire/', include((module_urls, app_name), namespace=app_name)),
] ]

View File

@ -1,4 +1,5 @@
from django.conf.urls import url, include from django.conf.urls import include
from django.urls import path
from . import views from . import views
@ -6,12 +7,12 @@ app_name = 'phpbb3'
module_urls = [ module_urls = [
# Forum Service Control # Forum Service Control
url(r'^activate/$', views.activate_forum, name='activate'), path('activate/', views.activate_forum, name='activate'),
url(r'^deactivate/$', views.deactivate_forum, name='deactivate'), path('deactivate/', views.deactivate_forum, name='deactivate'),
url(r'^reset_password/$', views.reset_forum_password, name='reset_password'), path('reset_password/', views.reset_forum_password, name='reset_password'),
url(r'^set_password/$', views.set_forum_password, name='set_password'), path('set_password/', views.set_forum_password, name='set_password'),
] ]
urlpatterns = [ urlpatterns = [
url(r'^phpbb3/', include((module_urls, app_name), namespace=app_name)) path('phpbb3/', include((module_urls, app_name), namespace=app_name))
] ]

View File

@ -1,4 +1,5 @@
from django.conf.urls import url, include from django.conf.urls import include
from django.urls import path
from . import views from . import views
@ -6,12 +7,12 @@ app_name = 'smf'
module_urls = [ module_urls = [
# SMF Service Control # SMF Service Control
url(r'^activate/$', views.activate_smf, name='activate'), path('activate/', views.activate_smf, name='activate'),
url(r'^deactivate/$', views.deactivate_smf, name='deactivate'), path('deactivate/', views.deactivate_smf, name='deactivate'),
url(r'^reset_password/$', views.reset_smf_password, name='reset_password'), path('reset_password/', views.reset_smf_password, name='reset_password'),
url(r'^set_password/$', views.set_smf_password, name='set_password'), path('set_password/', views.set_smf_password, name='set_password'),
] ]
urlpatterns = [ urlpatterns = [
url(r'^smf/', include((module_urls, app_name), namespace=app_name)), path('smf/', include((module_urls, app_name), namespace=app_name)),
] ]

View File

@ -1,5 +1,5 @@
from django import forms from django import forms
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import gettext_lazy as _
from .manager import Teamspeak3Manager from .manager import Teamspeak3Manager

View File

@ -5,7 +5,7 @@
<td class="text-center">{{ authinfo.teamspeak3_uid }}</td> <td class="text-center">{{ authinfo.teamspeak3_uid }}</td>
<td class="text-center"><a href="ts3server://{{ TEAMSPEAK3_PUBLIC_URL }}">{{ TEAMSPEAK3_PUBLIC_URL }}</a></td> <td class="text-center"><a href="ts3server://{{ TEAMSPEAK3_PUBLIC_URL }}">{{ TEAMSPEAK3_PUBLIC_URL }}</a></td>
<td class="text-center"> <td class="text-center">
{% ifequal authinfo.teamspeak3_uid "" %} {% if authinfo.teamspeak3_uid == "" %}
<a href="{% url 'teamspeak3:activate' %}" title="Activate" class="btn btn-warning"> <a href="{% url 'teamspeak3:activate' %}" title="Activate" class="btn btn-warning">
<span class="glyphicon glyphicon-ok"></span> <span class="glyphicon glyphicon-ok"></span>
</a> </a>
@ -22,6 +22,6 @@
<a href="ts3server://{{ TEAMSPEAK3_PUBLIC_URL }}?nickname={{ authinfo.teamspeak3_uid }}" title="Connect" class="btn btn-success"> <a href="ts3server://{{ TEAMSPEAK3_PUBLIC_URL }}?nickname={{ authinfo.teamspeak3_uid }}" title="Connect" class="btn btn-success">
<span class="glyphicon glyphicon-arrow-right"></span> <span class="glyphicon glyphicon-arrow-right"></span>
</a> </a>
{% endifequal %} {% endif %}
</td> </td>
</tr> </tr>

View File

@ -1,4 +1,5 @@
from django.conf.urls import url, include from django.conf.urls import include
from django.urls import path
from . import views from . import views
@ -6,19 +7,19 @@ app_name = 'teamspeak3'
module_urls = [ module_urls = [
# Teamspeak3 service control # Teamspeak3 service control
url(r'^activate/$', views.activate_teamspeak3, name='activate'), path('activate/', views.activate_teamspeak3, name='activate'),
url(r'^deactivate/$', views.deactivate_teamspeak3, name='deactivate'), path('deactivate/', views.deactivate_teamspeak3, name='deactivate'),
url(r'^reset_perm/$', views.reset_teamspeak3_perm, name='reset_perm'), path('reset_perm/', views.reset_teamspeak3_perm, name='reset_perm'),
url( path(
r'^admin_update_ts3_groups/$', 'admin_update_ts3_groups/',
views.admin_update_ts3_groups, views.admin_update_ts3_groups,
name='admin_update_ts3_groups' name='admin_update_ts3_groups'
), ),
# Teamspeak Urls # Teamspeak Urls
url(r'^verify/$', views.verify_teamspeak3, name='verify'), path('verify/', views.verify_teamspeak3, name='verify'),
] ]
urlpatterns = [ urlpatterns = [
url(r'^teamspeak3/', include((module_urls, app_name), namespace=app_name)), path('teamspeak3/', include((module_urls, app_name), namespace=app_name)),
] ]

View File

@ -1,4 +1,5 @@
from django.conf.urls import url, include from django.conf.urls import include
from django.urls import path
from . import views from . import views
@ -6,12 +7,12 @@ app_name = 'xenforo'
module_urls = [ module_urls = [
# XenForo service control # XenForo service control
url(r'^activate/$', views.activate_xenforo_forum, name='activate'), path('activate/', views.activate_xenforo_forum, name='activate'),
url(r'^deactivate/$', views.deactivate_xenforo_forum, name='deactivate'), path('deactivate/', views.deactivate_xenforo_forum, name='deactivate'),
url(r'^reset_password/$', views.reset_xenforo_password, name='reset_password'), path('reset_password/', views.reset_xenforo_password, name='reset_password'),
url(r'^set_password/$', views.set_xenforo_password, name='set_password'), path('set_password/', views.set_xenforo_password, name='set_password'),
] ]
urlpatterns = [ urlpatterns = [
url(r'^xenforo/', include((module_urls, app_name), namespace=app_name)), path('xenforo/', include((module_urls, app_name), namespace=app_name)),
] ]

View File

@ -5,7 +5,7 @@
<td class="text-center">{{ username }}</td> <td class="text-center">{{ username }}</td>
<td class="text-center"><a href="{{ service_url }}">{{ service_url }}</a></td> <td class="text-center"><a href="{{ service_url }}">{{ service_url }}</a></td>
<td class="text-center"> <td class="text-center">
{% ifequal username "" %} {% if username == "" %}
{% if urls.auth_activate %} {% if urls.auth_activate %}
<a href="{% url urls.auth_activate %}" title="Activate" class="btn btn-warning"> <a href="{% url urls.auth_activate %}" title="Activate" class="btn btn-warning">
<span class="glyphicon glyphicon-ok"></span> <span class="glyphicon glyphicon-ok"></span>
@ -27,6 +27,6 @@
<span class="glyphicon glyphicon-remove"></span> <span class="glyphicon glyphicon-remove"></span>
</a> </a>
{% endif %} {% endif %}
{% endifequal %} {% endif %}
</td> </td>
</tr> </tr>

View File

@ -1,14 +1,15 @@
from django.conf.urls import include, url from django.conf.urls import include
from allianceauth.hooks import get_hooks from allianceauth.hooks import get_hooks
from django.urls import path
from . import views from . import views
urlpatterns = [ urlpatterns = [
# Services # Services
url(r'^services/', include(([ path('services/', include(([
url(r'^$', views.services_view, name='services'), path('', views.services_view, name='services'),
# Tools # Tools
url(r'^tool/fleet_formatter_tool/$', views.fleet_formatter_view, name='fleet_format_tool'), path('tool/fleet_formatter_tool/', views.fleet_formatter_view, name='fleet_format_tool'),
], 'services'), namespace='services')), ], 'services'), namespace='services')),
] ]

View File

@ -1,4 +1,4 @@
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import gettext_lazy as _
from allianceauth import hooks from allianceauth import hooks
from allianceauth.services.hooks import MenuItemHook, UrlHook from allianceauth.services.hooks import MenuItemHook, UrlHook

View File

@ -1,7 +1,7 @@
import re import re
from django import forms from django import forms
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import gettext_lazy as _
class SrpFleetMainForm(forms.Form): class SrpFleetMainForm(forms.Form):

View File

@ -1,4 +1,4 @@
from django.conf.urls import url from django.urls import path
from . import views from . import views
@ -6,27 +6,27 @@ app_name = 'srp'
urlpatterns = [ urlpatterns = [
# SRP URLS # SRP URLS
url(r'^$', views.srp_management, name='management'), path('', views.srp_management, name='management'),
url(r'^all/$', views.srp_management, {'all': True}, name='all'), path('all/', views.srp_management, {'all': True}, name='all'),
url(r'^(\w+)/view$', views.srp_fleet_view, name='fleet'), path('<int:fleet_id>/view/', views.srp_fleet_view, name='fleet'),
url(r'^add/$', views.srp_fleet_add_view, name='add'), path('add/', views.srp_fleet_add_view, name='add'),
url(r'^(\w+)/edit$', views.srp_fleet_edit_view, name='edit'), path('<int:fleet_id>/edit/', views.srp_fleet_edit_view, name='edit'),
url(r'^(\w+)/request', views.srp_request_view, name='request'), path('<str:fleet_srp>/request', views.srp_request_view, name='request'),
# SRP URLS # SRP URLS
url(r'^(\w+)/remove$', views.srp_fleet_remove, name='remove'), path('<int:fleet_id>/remove/', views.srp_fleet_remove, name='remove'),
url(r'^(\w+)/disable$', views.srp_fleet_disable, name='disable'), path('<int:fleet_id>/disable/', views.srp_fleet_disable, name='disable'),
url(r'^(\w+)/enable$', views.srp_fleet_enable, name='enable'), path('<int:fleet_id>/enable/', views.srp_fleet_enable, name='enable'),
url(r'^(\w+)/complete$', views.srp_fleet_mark_completed, path('<int:fleet_id>/complete/', views.srp_fleet_mark_completed,
name='mark_completed'), name='mark_completed'),
url(r'^(\w+)/incomplete$', views.srp_fleet_mark_uncompleted, path('<int:fleet_id>/incomplete/', views.srp_fleet_mark_uncompleted,
name='mark_uncompleted'), name='mark_uncompleted'),
url(r'^request/remove/', views.srp_request_remove, path('request/remove/', views.srp_request_remove,
name="request_remove"), name="request_remove"),
url(r'^request/approve/', views.srp_request_approve, path('request/approve/', views.srp_request_approve,
name='request_approve'), name='request_approve'),
url(r'^request/reject/', views.srp_request_reject, path('request/reject/', views.srp_request_reject,
name='request_reject'), name='request_reject'),
url(r'^request/(\w+)/update', views.srp_request_update_amount, path('request/<int:fleet_srp_request_id>/update', views.srp_request_update_amount,
name="request_update_amount"), name="request_update_amount"),
] ]

View File

@ -3,7 +3,7 @@ import datetime
from django import forms from django import forms
from django.utils import timezone from django.utils import timezone
from django.core.validators import MaxValueValidator, MinValueValidator from django.core.validators import MaxValueValidator, MinValueValidator
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import gettext_lazy as _
from .models import Timer, TimerType from .models import Timer, TimerType

View File

@ -1,12 +1,12 @@
from django.conf.urls import url from django.urls import path
from . import views from . import views
app_name = 'timerboard' app_name = 'timerboard'
urlpatterns = [ urlpatterns = [
url(r'^$', views.TimerView.as_view(), name='view'), path('', views.TimerView.as_view(), name='view'),
url(r'^add/$', views.AddTimerView.as_view(), name='add'), path('add/', views.AddTimerView.as_view(), name='add'),
url(r'^remove/(?P<pk>\w+)$', views.RemoveTimerView.as_view(), name='delete'), path('remove/<int:pk>/', views.RemoveTimerView.as_view(), name='delete'),
url(r'^edit/(?P<pk>\w+)$', views.EditTimerView.as_view(), name='edit'), path('edit/<int:pk>/', views.EditTimerView.as_view(), name='edit'),
] ]

View File

@ -9,7 +9,7 @@ from django.urls import reverse_lazy
from django.views.generic import CreateView, UpdateView, DeleteView from django.views.generic import CreateView, UpdateView, DeleteView
from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
from django.utils import timezone from django.utils import timezone
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import gettext_lazy as _
from .form import TimerForm from .form import TimerForm
from .models import Timer from .models import Timer

View File

@ -1,6 +1,7 @@
from django.urls import path
import esi.urls import esi.urls
from django.conf.urls import include, url from django.conf.urls import include
from django.contrib import admin from django.contrib import admin
from django.views.generic.base import TemplateView from django.views.generic.base import TemplateView
@ -21,35 +22,35 @@ admin.site.site_header = NAME
# Functional/Untranslated URL's # Functional/Untranslated URL's
urlpatterns = [ urlpatterns = [
# Locale # Locale
url(r'^i18n/', include('django.conf.urls.i18n')), path('i18n/', include('django.conf.urls.i18n')),
# Authentication # Authentication
url(r'', include(allianceauth.authentication.urls)), path('', include(allianceauth.authentication.urls)),
url(r'^account/login/$', TemplateView.as_view(template_name='public/login.html'), name='auth_login_user'), path('account/login/', TemplateView.as_view(template_name='public/login.html'), name='auth_login_user'),
url(r'^account/', include(hmac_urls)), path('account/', include(hmac_urls)),
# Admin urls # Admin urls
url(r'^admin/', admin.site.urls), path('admin/', admin.site.urls),
# SSO # SSO
url(r'^sso/', include((esi.urls, 'esi'), namespace='esi')), path('sso/', include((esi.urls, 'esi'), namespace='esi')),
url(r'^sso/login$', allianceauth.authentication.views.sso_login, name='auth_sso_login'), path('sso/login', allianceauth.authentication.views.sso_login, name='auth_sso_login'),
# Notifications # Notifications
url(r'', include(allianceauth.notifications.urls)), path('', include(allianceauth.notifications.urls)),
# Groups # Groups
url(r'', include(allianceauth.groupmanagement.urls)), path('', include(allianceauth.groupmanagement.urls)),
# Services # Services
url(r'', decorate_url_patterns(allianceauth.services.urls.urlpatterns, main_character_required)), path('', decorate_url_patterns(allianceauth.services.urls.urlpatterns, main_character_required)),
# Night mode # Night mode
url(r'^night/', views.NightModeRedirectView.as_view(), name='nightmode') path('night/', views.NightModeRedirectView.as_view(), name='nightmode')
] ]
# Append app urls # Append app urls
app_urls = get_hooks('url_hook') app_urls = get_hooks('url_hook')
for app in app_urls: for app in app_urls:
urlpatterns += [url(r'', decorate_url_patterns([app().include_pattern], main_character_required))] urlpatterns += [path('', decorate_url_patterns([app().include_pattern], main_character_required))]

View File

@ -30,10 +30,13 @@ It is possible to overload static and templates shipped with Django or Alliance
It is possible to add or override URLs with your auth project's URL config file. Upon install it is of the form: It is possible to add or override URLs with your auth project's URL config file. Upon install it is of the form:
```python ```python
from django.urls import re_path
from django.urls import include
import allianceauth.urls import allianceauth.urls
urlpatterns = [ urlpatterns = [
url(r'', include(allianceauth.urls)), re_path(r'', include(allianceauth.urls)),
] ]
``` ```
@ -42,23 +45,29 @@ This means every request gets passed to the Alliance Auth URL config to be inter
If you wanted to add a URL pointing to a custom view, it can be added anywhere in the list if not already used by Alliance Auth: If you wanted to add a URL pointing to a custom view, it can be added anywhere in the list if not already used by Alliance Auth:
```python ```python
from django.urls import re_path
from django.urls import include, path
import allianceauth.urls import allianceauth.urls
import myauth.views import myauth.views
urlpatterns = [ urlpatterns = [
url(r'', include(allianceauth.urls)), re_path(r'', include(allianceauth.urls)),
url(r'myview/$', myauth.views.myview, name='myview'), path('myview/', myauth.views.myview, name='myview'),
] ]
``` ```
Additionally you can override URLs used by Alliance Auth here: Additionally you can override URLs used by Alliance Auth here:
```python ```python
from django.urls import re_path
from django.urls import include, path
import allianceauth.urls import allianceauth.urls
import myauth.views import myauth.views
urlpatterns = [ urlpatterns = [
url(r'account/login/$', myauth.views.login, name='auth_login_user'), path('account/login/', myauth.views.login, name='auth_login_user'),
url(r'', include(allianceauth.urls)), re_path(r'', include(allianceauth.urls)),
] ]
``` ```

View File

@ -34,12 +34,12 @@ An app called `plugin` provides a single view:
The app's `urls.py` would look like so: The app's `urls.py` would look like so:
from django.conf.urls import url from django.urls import path
import plugin.views import plugin.views
urlpatterns = [ urlpatterns = [
url(r^'index$', plugins.views.index, name='index'), path('index/', plugins.views.index, name='index'),
] ]
Subsequently it would implement the UrlHook in a dedicated `auth_hooks.py` file like so: Subsequently it would implement the UrlHook in a dedicated `auth_hooks.py` file like so:

View File

@ -7,7 +7,7 @@ with open(os.path.join(this_directory, 'README.md'), encoding='utf-8') as f:
long_description = f.read() long_description = f.read()
install_requires = [ install_requires = [
'mysqlclient', 'mysqlclient>=2.1.0',
'dnspython', 'dnspython',
'passlib', 'passlib',
'requests>=2.9.1,<3.0.0', 'requests>=2.9.1,<3.0.0',
@ -18,22 +18,22 @@ install_requires = [
'packaging>=21.0,<22', 'packaging>=21.0,<22',
'beautifulsoup4', 'beautifulsoup4',
'redis>=3.3.1,<4.0.0', 'redis>=4.0.0,<5.0.0',
'celery>=4.3.0,<6.0.0,!=4.4.4', # 4.4.4 is missing a dependency 'celery>=5.2.0,<6.0.0',
'celery_once>=2.0.1', 'celery_once>=3.0.1',
'django>=3.2.9,<4.0.0', 'django>=4.0.2,<5.0.0',
'django-bootstrap-form', 'django-bootstrap-form',
'django-registration>=3.1', 'django-registration>=3.2',
'django-sortedm2m', 'django-sortedm2m',
'django-redis>=5.2.0<6.0.0', 'django-redis>=5.2.0<6.0.0',
'django-celery-beat>=2.0.0', 'django-celery-beat @ git+https://github.com/celery/django-celery-beat.git',
'openfire-restapi', 'openfire-restapi',
'sleekxmpp', 'sleekxmpp',
'pydiscourse', 'pydiscourse',
'django-esi>=3.0.0,<4.0.0' 'django-esi @ git+https://gitlab.com/soratidus999/django-esi.git@py310',
] ]
testing_extras = [ testing_extras = [
@ -70,7 +70,7 @@ setup(
classifiers=[ classifiers=[
'Environment :: Web Environment', 'Environment :: Web Environment',
'Framework :: Django', 'Framework :: Django',
'Framework :: Django :: 3.2', 'Framework :: Django :: 4',
'Intended Audience :: Developers', 'Intended Audience :: Developers',
'License :: OSI Approved :: GNU General Public License v2 (GPLv2)', 'License :: OSI Approved :: GNU General Public License v2 (GPLv2)',
'Operating System :: POSIX :: Linux', 'Operating System :: POSIX :: Linux',

View File

@ -1,18 +1,17 @@
from django.conf.urls import url
import allianceauth.urls import allianceauth.urls
from django.urls import path
from . import views from . import views
urlpatterns = allianceauth.urls.urlpatterns urlpatterns = allianceauth.urls.urlpatterns
urlpatterns += [ urlpatterns += [
# Navhelper test urls # Navhelper test urls
url(r'^main-page/$', views.page, name='p1'), path("main-page/", views.page, name="p1"),
url(r'^main-page/sub-section/$', views.page, name='p1-s1'), path("main-page/sub-section/", views.page, name="p1-s1"),
url(r'^second-page/$', views.page, name='p1'), path("second-page/", views.page, name="p1"),
] ]
handler500 = 'allianceauth.views.Generic500Redirect' handler500 = "allianceauth.views.Generic500Redirect"
handler404 = 'allianceauth.views.Generic404Redirect' handler404 = "allianceauth.views.Generic404Redirect"
handler403 = 'allianceauth.views.Generic403Redirect' handler403 = "allianceauth.views.Generic403Redirect"
handler400 = 'allianceauth.views.Generic400Redirect' handler400 = "allianceauth.views.Generic400Redirect"