Deploy Django5 stuff on production #93
@@ -10,11 +10,11 @@ For production use you surly want a real web server that supports WSGI
|
|||||||
|
|
||||||
QUICK INSTALLATION FOR THE IMPATIENT
|
QUICK INSTALLATION FOR THE IMPATIENT
|
||||||
====================================
|
====================================
|
||||||
- python -m venv ./etc/python
|
- python -m venv ./env/python
|
||||||
- source env/python/bin/activate
|
- source env/python/bin/activate
|
||||||
- python -m pip install -r requirements.txt
|
- python -m pip install -r requirements.txt
|
||||||
- python -m pip install -e .
|
- python -m pip install -e .
|
||||||
- django-dav-events-admin setup ./env/django
|
- django-dav-admin setup ./env/django
|
||||||
- python ./env/django/manage.py enable_module dav_auth
|
- python ./env/django/manage.py enable_module dav_auth
|
||||||
- python ./env/django/manage.py enable_module dav_events
|
- python ./env/django/manage.py enable_module dav_events
|
||||||
- python ./env/django/manage.py enable_module dav_registration
|
- python ./env/django/manage.py enable_module dav_registration
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
default_app_config = 'dav_auth.apps.AppConfig' # pylint: disable=invalid-name
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ from django.contrib import admin
|
|||||||
from django.contrib.auth.admin import GroupAdmin as _GroupAdmin
|
from django.contrib.auth.admin import GroupAdmin as _GroupAdmin
|
||||||
from django.contrib.auth.models import Group
|
from django.contrib.auth.models import Group
|
||||||
from django.contrib.auth.models import Permission
|
from django.contrib.auth.models import Permission
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import gettext as _
|
||||||
admin.site.unregister(Group)
|
admin.site.unregister(Group)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import logging
|
import logging
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.contrib.auth import forms as auth_forms, password_validation
|
from django.contrib.auth import forms as auth_forms, password_validation
|
||||||
from django.utils.translation import ugettext, ugettext_lazy as _
|
from django.utils.translation import gettext, gettext_lazy as _
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ class SetPasswordForm(forms.Form):
|
|||||||
if password1 and password2:
|
if password1 and password2:
|
||||||
if password1 != password2:
|
if password1 != password2:
|
||||||
raise forms.ValidationError(
|
raise forms.ValidationError(
|
||||||
ugettext('Passwörter stimmen nicht überein'),
|
gettext('Passwörter stimmen nicht überein'),
|
||||||
code='password_mismatch',
|
code='password_mismatch',
|
||||||
)
|
)
|
||||||
return password2
|
return password2
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
{
|
{
|
||||||
"url_prefix": "auth"
|
"url_prefix": "auth",
|
||||||
|
"app_config": ".apps.AppConfig"
|
||||||
}
|
}
|
||||||
@@ -8,7 +8,13 @@
|
|||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu dropdown-menu-right" aria-labelledby="user_dropdown_button">
|
<ul class="dropdown-menu dropdown-menu-right" aria-labelledby="user_dropdown_button">
|
||||||
<li><a href="{% url 'dav_auth:set_password' %}">{% trans 'Passwort ändern' %}</a></li>
|
<li><a href="{% url 'dav_auth:set_password' %}">{% trans 'Passwort ändern' %}</a></li>
|
||||||
<li><a href="{% url 'dav_auth:logout' %}">{% trans 'Logout' %}</a></li>
|
<li>
|
||||||
|
<form method="post" action="{% url 'dav_auth:logout' %}" class="navbar-form">
|
||||||
|
{% csrf_token %}
|
||||||
|
<button id="id_logout_button" type="submit" class="btn btn-sm btn-danger"
|
||||||
|
style="width: 100%;">{% trans "Logout" %}</button>
|
||||||
|
</form>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|||||||
@@ -17,6 +17,10 @@ class SeleniumAuthMixin:
|
|||||||
return driver
|
return driver
|
||||||
|
|
||||||
def logout(self, driver):
|
def logout(self, driver):
|
||||||
driver.get(self.complete_url(reverse('dav_auth:logout')))
|
#driver.get(self.complete_url(reverse('dav_auth:logout')))
|
||||||
|
dropdown_button = driver.find_element(By.ID, 'user_dropdown_button')
|
||||||
|
dropdown_button.click()
|
||||||
|
logout_button = driver.find_element(By.ID, 'id_logout_button')
|
||||||
|
logout_button.click()
|
||||||
self.wait_on_presence(driver, (By.CSS_SELECTOR, "#messages .alert-success"))
|
self.wait_on_presence(driver, (By.CSS_SELECTOR, "#messages .alert-success"))
|
||||||
return driver
|
return driver
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
from unittest import skip
|
from unittest import skip
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django.core import mail as django_mail
|
from django.core import mail as django_mail
|
||||||
from django.utils.translation import ugettext
|
from django.utils.translation import gettext
|
||||||
|
|
||||||
from dav_base.tests.generic import FormDataSet, FormsTestCase
|
from dav_base.tests.generic import FormDataSet, FormsTestCase
|
||||||
|
|
||||||
@@ -25,8 +25,8 @@ class LoginFormTestCase(FormsTestCase):
|
|||||||
|
|
||||||
def test_labels(self):
|
def test_labels(self):
|
||||||
form = self.form_class()
|
form = self.form_class()
|
||||||
self.assertEqual(form.fields['username'].label, ugettext('E-Mail-Adresse'))
|
self.assertEqual(form.fields['username'].label, gettext('E-Mail-Adresse'))
|
||||||
self.assertEqual(form.fields['password'].label, ugettext('Password'))
|
self.assertEqual(form.fields['password'].label, gettext('Password'))
|
||||||
|
|
||||||
def test_required(self):
|
def test_required(self):
|
||||||
form = self.form_class()
|
form = self.form_class()
|
||||||
@@ -193,7 +193,7 @@ class CreateAndSendPasswordFormTestCase(FormsTestCase):
|
|||||||
|
|
||||||
def test_labels(self):
|
def test_labels(self):
|
||||||
form = self.form_class()
|
form = self.form_class()
|
||||||
self.assertEqual(form.fields['username'].label, ugettext('E-Mail-Adresse'))
|
self.assertEqual(form.fields['username'].label, gettext('E-Mail-Adresse'))
|
||||||
|
|
||||||
def test_required(self):
|
def test_required(self):
|
||||||
form = self.form_class()
|
form = self.form_class()
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django.test import tag
|
from django.test import tag
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.translation import ugettext
|
from django.utils.translation import gettext
|
||||||
from selenium.webdriver.common.by import By
|
from selenium.webdriver.common.by import By
|
||||||
from selenium.webdriver.common.keys import Keys
|
from selenium.webdriver.common.keys import Keys
|
||||||
|
|
||||||
@@ -105,7 +105,7 @@ class TestCase(ScreenshotTestCase):
|
|||||||
|
|
||||||
# Click on 'set password' -> save set password page
|
# Click on 'set password' -> save set password page
|
||||||
user_menu = c.find_element(By.CSS_SELECTOR, '#login-widget ul')
|
user_menu = c.find_element(By.CSS_SELECTOR, '#login-widget ul')
|
||||||
link = user_menu.find_element(By.PARTIAL_LINK_TEXT, ugettext('Passwort ändern'))
|
link = user_menu.find_element(By.PARTIAL_LINK_TEXT, gettext('Passwort ändern'))
|
||||||
link.click()
|
link.click()
|
||||||
password_field = self.wait_on_presence(c, (By.ID, 'id_new_password'))
|
password_field = self.wait_on_presence(c, (By.ID, 'id_new_password'))
|
||||||
self.save_screenshot('empty_set_password_form', sequence=sequence_name)
|
self.save_screenshot('empty_set_password_form', sequence=sequence_name)
|
||||||
@@ -189,8 +189,10 @@ class TestCase(ScreenshotTestCase):
|
|||||||
dropdown_button = self.wait_on_presence(c, (By.ID, 'user_dropdown_button'))
|
dropdown_button = self.wait_on_presence(c, (By.ID, 'user_dropdown_button'))
|
||||||
dropdown_button.click()
|
dropdown_button.click()
|
||||||
user_menu = c.find_element(By.CSS_SELECTOR, '#login-widget ul')
|
user_menu = c.find_element(By.CSS_SELECTOR, '#login-widget ul')
|
||||||
link = user_menu.find_element(By.PARTIAL_LINK_TEXT, ugettext('Logout'))
|
#link = user_menu.find_element(By.PARTIAL_LINK_TEXT, gettext('Logout'))
|
||||||
link.click()
|
#link.click()
|
||||||
|
button = c.find_element(By.ID, 'id_logout_button')
|
||||||
|
button.click()
|
||||||
self.wait_until_stale(c, user_menu)
|
self.wait_until_stale(c, user_menu)
|
||||||
self.save_screenshot('logout_succeed', sequence=sequence_name)
|
self.save_screenshot('logout_succeed', sequence=sequence_name)
|
||||||
|
|
||||||
@@ -200,7 +202,7 @@ class TestCase(ScreenshotTestCase):
|
|||||||
self.wait_on_presence(c, (By.ID, 'id_username'))
|
self.wait_on_presence(c, (By.ID, 'id_username'))
|
||||||
|
|
||||||
# Locate password recreate link, click it -> save password recreate form
|
# Locate password recreate link, click it -> save password recreate form
|
||||||
link = c.find_element(By.PARTIAL_LINK_TEXT, ugettext('Passwort vergessen'))
|
link = c.find_element(By.PARTIAL_LINK_TEXT, gettext('Passwort vergessen'))
|
||||||
link.click()
|
link.click()
|
||||||
username_field = self.wait_on_presence(c, (By.ID, 'id_username'))
|
username_field = self.wait_on_presence(c, (By.ID, 'id_username'))
|
||||||
self.save_screenshot('empty_recreate_password_form', sequence=sequence_name)
|
self.save_screenshot('empty_recreate_password_form', sequence=sequence_name)
|
||||||
@@ -212,7 +214,7 @@ class TestCase(ScreenshotTestCase):
|
|||||||
self.save_screenshot('recreate_password_invalid_user', sequence=sequence_name)
|
self.save_screenshot('recreate_password_invalid_user', sequence=sequence_name)
|
||||||
|
|
||||||
# Locate password recreate link, click it
|
# Locate password recreate link, click it
|
||||||
link = c.find_element(By.PARTIAL_LINK_TEXT, ugettext('Passwort vergessen'))
|
link = c.find_element(By.PARTIAL_LINK_TEXT, gettext('Passwort vergessen'))
|
||||||
link.click()
|
link.click()
|
||||||
username_field = self.wait_on_presence(c, (By.ID, 'id_username'))
|
username_field = self.wait_on_presence(c, (By.ID, 'id_username'))
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django.test import SimpleTestCase, tag
|
from django.test import SimpleTestCase, tag
|
||||||
from django.utils.translation import ugettext
|
from django.utils.translation import gettext
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from selenium.common.exceptions import NoSuchElementException
|
from selenium.common.exceptions import NoSuchElementException
|
||||||
from selenium.webdriver.common.by import By
|
from selenium.webdriver.common.by import By
|
||||||
@@ -20,7 +20,7 @@ class TemplatesTestCase(SimpleTestCase):
|
|||||||
def test_recreate_link_in_login_form(self):
|
def test_recreate_link_in_login_form(self):
|
||||||
login_url = reverse('dav_auth:login')
|
login_url = reverse('dav_auth:login')
|
||||||
recreate_url = reverse('dav_auth:recreate_password')
|
recreate_url = reverse('dav_auth:recreate_password')
|
||||||
text = ugettext('Passwort vergessen?')
|
text = gettext('Passwort vergessen?')
|
||||||
html = '<a href="{url}">{text}</a>'.format(url=recreate_url, text=text)
|
html = '<a href="{url}">{text}</a>'.format(url=recreate_url, text=text)
|
||||||
response = self.client.get(login_url)
|
response = self.client.get(login_url)
|
||||||
self.assertInHTML(html, response.content.decode('utf-8'))
|
self.assertInHTML(html, response.content.decode('utf-8'))
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ from .. import views
|
|||||||
class TestCase(UrlsTestCase):
|
class TestCase(UrlsTestCase):
|
||||||
urls = (
|
urls = (
|
||||||
Url('/auth/login', 'dav_auth:login', views.LoginView.as_view()),
|
Url('/auth/login', 'dav_auth:login', views.LoginView.as_view()),
|
||||||
Url('/auth/logout', 'dav_auth:logout', views.LogoutView.as_view(), status_code=302),
|
Url('/auth/logout', 'dav_auth:logout', views.LogoutView.as_view(), status_code=302,
|
||||||
|
http_method='POST'),
|
||||||
Url('/auth/password', 'dav_auth:set_password', views.SetPasswordView.as_view(),
|
Url('/auth/password', 'dav_auth:set_password', views.SetPasswordView.as_view(),
|
||||||
redirect='/auth/login?next=/auth/password'),
|
redirect='/auth/login?next=/auth/password'),
|
||||||
Url('/auth/password/recreate', 'dav_auth:recreate_password', views.CreateAndSendPasswordView.as_view()),
|
Url('/auth/password/recreate', 'dav_auth:recreate_password', views.CreateAndSendPasswordView.as_view()),
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ from django.contrib.auth import get_user_model
|
|||||||
from django.core import mail as django_mail
|
from django.core import mail as django_mail
|
||||||
from django.shortcuts import resolve_url
|
from django.shortcuts import resolve_url
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
from django.utils.translation import ugettext
|
from django.utils.translation import gettext
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
|
||||||
from ..forms import LoginForm, SetPasswordForm, CreateAndSendPasswordForm
|
from ..forms import LoginForm, SetPasswordForm, CreateAndSendPasswordForm
|
||||||
@@ -30,9 +30,9 @@ class ViewsTestCase(TestCase):
|
|||||||
cls.recreate_password_url = reverse('dav_auth:recreate_password')
|
cls.recreate_password_url = reverse('dav_auth:recreate_password')
|
||||||
|
|
||||||
# Some messages
|
# Some messages
|
||||||
cls.wrong_credentials_message = ugettext('Benutzername oder Passwort falsch.')
|
cls.wrong_credentials_message = gettext('Benutzername oder Passwort falsch.')
|
||||||
cls.logout_message = ugettext('Benutzer abgemeldet.')
|
cls.logout_message = gettext('Benutzer abgemeldet.')
|
||||||
cls.set_password_message = ugettext('Passwort gespeichert.')
|
cls.set_password_message = gettext('Passwort gespeichert.')
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super().setUp()
|
super().setUp()
|
||||||
@@ -61,7 +61,7 @@ class ViewsTestCase(TestCase):
|
|||||||
|
|
||||||
response = self.client.post(self.login_url, {'username': self.test_username, 'password': self.test_password})
|
response = self.client.post(self.login_url, {'username': self.test_username, 'password': self.test_password})
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
self.assertFormError(response, 'form', None, self.wrong_credentials_message)
|
self.assertFormError(response.context['form'], None, self.wrong_credentials_message)
|
||||||
self.assertFalse(response.context['user'].is_authenticated, 'User is logged in')
|
self.assertFalse(response.context['user'].is_authenticated, 'User is logged in')
|
||||||
|
|
||||||
def test_integrated_login_fail_with_wrong_credentials(self):
|
def test_integrated_login_fail_with_wrong_credentials(self):
|
||||||
@@ -69,12 +69,12 @@ class ViewsTestCase(TestCase):
|
|||||||
|
|
||||||
response = self.client.post(self.login_url, {'username': self.test_username, 'password': wrong_password})
|
response = self.client.post(self.login_url, {'username': self.test_username, 'password': wrong_password})
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
self.assertFormError(response, 'form', None, self.wrong_credentials_message)
|
self.assertFormError(response.context['form'],None, self.wrong_credentials_message)
|
||||||
self.assertFalse(response.context['user'].is_authenticated, 'User is logged in')
|
self.assertFalse(response.context['user'].is_authenticated, 'User is logged in')
|
||||||
|
|
||||||
def test_integrated_login_succeed(self):
|
def test_integrated_login_succeed(self):
|
||||||
username = self.user.username
|
username = self.user.username
|
||||||
message = ugettext('Benutzer angemeldet: %(username)s') % {'username': username}
|
message = gettext('Benutzer angemeldet: %(username)s') % {'username': username}
|
||||||
|
|
||||||
response = self.client.post(self.login_url, {'username': username, 'password': self.test_password})
|
response = self.client.post(self.login_url, {'username': username, 'password': self.test_password})
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 302)
|
||||||
@@ -88,7 +88,7 @@ class ViewsTestCase(TestCase):
|
|||||||
def test_integrated_logout(self):
|
def test_integrated_logout(self):
|
||||||
self.client.login(username=self.test_username, password=self.test_password)
|
self.client.login(username=self.test_username, password=self.test_password)
|
||||||
|
|
||||||
response = self.client.get(self.logout_url)
|
response = self.client.post(self.logout_url)
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 302)
|
||||||
self.assertEqual(response.url, self.logout_redirect_url)
|
self.assertEqual(response.url, self.logout_redirect_url)
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
from django.conf.urls import url
|
from django.urls import re_path
|
||||||
|
|
||||||
from . import views
|
from . import views
|
||||||
|
|
||||||
app_name = 'dav_auth'
|
app_name = 'dav_auth'
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^login$', views.LoginView.as_view(), name='login'),
|
re_path(r'^login$', views.LoginView.as_view(), name='login'),
|
||||||
url(r'^logout$', views.LogoutView.as_view(), name='logout'),
|
re_path(r'^logout$', views.LogoutView.as_view(), name='logout'),
|
||||||
url(r'^password$', views.SetPasswordView.as_view(), name='set_password'),
|
re_path(r'^password$', views.SetPasswordView.as_view(), name='set_password'),
|
||||||
url(r'^password/recreate$', views.CreateAndSendPasswordView.as_view(), name='recreate_password'),
|
re_path(r'^password/recreate$', views.CreateAndSendPasswordView.as_view(), name='recreate_password'),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ from django.http import HttpResponseRedirect
|
|||||||
from django.shortcuts import resolve_url
|
from django.shortcuts import resolve_url
|
||||||
from django.urls import reverse_lazy, reverse
|
from django.urls import reverse_lazy, reverse
|
||||||
from django.utils.safestring import mark_safe
|
from django.utils.safestring import mark_safe
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import gettext as _
|
||||||
from django.views import generic
|
from django.views import generic
|
||||||
|
|
||||||
from . import emails
|
from . import emails
|
||||||
@@ -48,9 +48,10 @@ class LoginView(auth_views.LoginView):
|
|||||||
|
|
||||||
|
|
||||||
class LogoutView(auth_views.LogoutView):
|
class LogoutView(auth_views.LogoutView):
|
||||||
def get_next_page(self):
|
@property
|
||||||
url = super().get_next_page()
|
def next_page(self):
|
||||||
if not url and app_config.settings.logout_redirect_url:
|
url = None
|
||||||
|
if app_config.settings.logout_redirect_url:
|
||||||
url = resolve_url(app_config.settings.logout_redirect_url)
|
url = resolve_url(app_config.settings.logout_redirect_url)
|
||||||
return url
|
return url
|
||||||
|
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
default_app_config = 'dav_base.apps.AppConfig' # pylint: disable=invalid-name
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import os
|
|||||||
import pkg_resources
|
import pkg_resources
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.conf.urls import url as django_conf_url, include
|
from django.urls import re_path, include
|
||||||
|
|
||||||
DJANGO_MAIN_MODULE = 'main'
|
DJANGO_MAIN_MODULE = 'main'
|
||||||
MODULE_CONFIG_FILE_NAME = 'module_config.json'
|
MODULE_CONFIG_FILE_NAME = 'module_config.json'
|
||||||
@@ -19,6 +19,7 @@ class ModuleMeta:
|
|||||||
|
|
||||||
def __init__(self, package_name):
|
def __init__(self, package_name):
|
||||||
self._package_name = package_name
|
self._package_name = package_name
|
||||||
|
self._app_config = None
|
||||||
self._additional_apps = []
|
self._additional_apps = []
|
||||||
self._url_prefix = None
|
self._url_prefix = None
|
||||||
self._load_from_package()
|
self._load_from_package()
|
||||||
@@ -28,9 +29,19 @@ class ModuleMeta:
|
|||||||
return t
|
return t
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def app(self):
|
def package(self):
|
||||||
return self._package_name
|
return self._package_name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def app(self):
|
||||||
|
if self._app_config:
|
||||||
|
app = self._app_config
|
||||||
|
if app.startswith('.'):
|
||||||
|
app = self._package_name + app
|
||||||
|
else:
|
||||||
|
app = self._package_name
|
||||||
|
return app
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def additional_apps(self):
|
def additional_apps(self):
|
||||||
return self._additional_apps
|
return self._additional_apps
|
||||||
@@ -50,7 +61,7 @@ class ModuleMeta:
|
|||||||
def url_conf_pattern(self):
|
def url_conf_pattern(self):
|
||||||
url_pattern = '^{}/'.format(self.url_prefix)
|
url_pattern = '^{}/'.format(self.url_prefix)
|
||||||
url_conf = self._package_name + '.urls'
|
url_conf = self._package_name + '.urls'
|
||||||
return django_conf_url(url_pattern, include(url_conf, self.url_namespace))
|
return re_path(url_pattern, include(url_conf, self.url_namespace))
|
||||||
|
|
||||||
def _load_from_package(self):
|
def _load_from_package(self):
|
||||||
package_name = self._package_name
|
package_name = self._package_name
|
||||||
@@ -61,6 +72,7 @@ class ModuleMeta:
|
|||||||
|
|
||||||
def load_from_dict(self, meta_dict):
|
def load_from_dict(self, meta_dict):
|
||||||
self._package_name = meta_dict.get('package', None)
|
self._package_name = meta_dict.get('package', None)
|
||||||
|
self._app_config = meta_dict.get('app_config', None)
|
||||||
self._additional_apps = meta_dict.get('additional_apps', [])
|
self._additional_apps = meta_dict.get('additional_apps', [])
|
||||||
self._url_prefix = meta_dict.get('url_prefix', None)
|
self._url_prefix = meta_dict.get('url_prefix', None)
|
||||||
|
|
||||||
@@ -68,6 +80,8 @@ class ModuleMeta:
|
|||||||
d = {
|
d = {
|
||||||
'package': self._package_name,
|
'package': self._package_name,
|
||||||
}
|
}
|
||||||
|
if self._app_config:
|
||||||
|
d['app_config'] = self._app_config
|
||||||
if self._additional_apps:
|
if self._additional_apps:
|
||||||
d['additional_apps'] = self._additional_apps
|
d['additional_apps'] = self._additional_apps
|
||||||
if self._url_prefix:
|
if self._url_prefix:
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ INSTALLED_APPS += [
|
|||||||
'django_countries',
|
'django_countries',
|
||||||
# 'django_extensions',
|
# 'django_extensions',
|
||||||
# Our main app
|
# Our main app
|
||||||
'dav_base',
|
'dav_base.apps.AppConfig',
|
||||||
]
|
]
|
||||||
|
|
||||||
# Add apps from our modules
|
# Add apps from our modules
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.conf.urls import url, include
|
from django.urls import re_path, include
|
||||||
|
|
||||||
urlpatterns = []
|
urlpatterns = []
|
||||||
|
|
||||||
@@ -8,5 +8,5 @@ for module_meta_obj in settings.MODULE_CONFIG.modules.values():
|
|||||||
urlpatterns.append(module_meta_obj.url_conf_pattern)
|
urlpatterns.append(module_meta_obj.url_conf_pattern)
|
||||||
|
|
||||||
urlpatterns += [
|
urlpatterns += [
|
||||||
url(r'^', include('dav_base.urls'))
|
re_path(r'^', include('dav_base.urls'))
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -171,6 +171,8 @@ class Url: # pylint: disable=too-few-public-methods
|
|||||||
self.location = location
|
self.location = location
|
||||||
self.name = name
|
self.name = name
|
||||||
self.func = func
|
self.func = func
|
||||||
|
self.http_method = kwargs.get('http_method', "GET")
|
||||||
|
self.post_data = kwargs.get('post_data', {})
|
||||||
self.redirect = kwargs.get('redirect', False)
|
self.redirect = kwargs.get('redirect', False)
|
||||||
self.status_code = kwargs.get('status_code', 200)
|
self.status_code = kwargs.get('status_code', 200)
|
||||||
self.follow = kwargs.get('follow', False)
|
self.follow = kwargs.get('follow', False)
|
||||||
@@ -182,7 +184,12 @@ class UrlsTestCase(TestCase):
|
|||||||
def test_locations(self):
|
def test_locations(self):
|
||||||
for url in self.urls:
|
for url in self.urls:
|
||||||
if url.location:
|
if url.location:
|
||||||
|
if url.http_method == "GET":
|
||||||
response = self.client.get(url.location, follow=url.follow)
|
response = self.client.get(url.location, follow=url.follow)
|
||||||
|
elif url.http_method == "POST":
|
||||||
|
response = self.client.post(url.location, data=url.post_data, follow=url.follow)
|
||||||
|
else: # pragma: no cover
|
||||||
|
raise NotImplementedError("Method {} is not supported".format(url.http_method))
|
||||||
|
|
||||||
if url.redirect:
|
if url.redirect:
|
||||||
self.assertRedirects(response, url.redirect)
|
self.assertRedirects(response, url.redirect)
|
||||||
@@ -198,7 +205,13 @@ class UrlsTestCase(TestCase):
|
|||||||
def test_names(self):
|
def test_names(self):
|
||||||
for url in self.urls:
|
for url in self.urls:
|
||||||
if url.name:
|
if url.name:
|
||||||
response = self.client.get(reverse(url.name), follow=url.follow)
|
location = reverse(url.name)
|
||||||
|
if url.http_method == "GET":
|
||||||
|
response = self.client.get(location, follow=url.follow)
|
||||||
|
elif url.http_method == "POST":
|
||||||
|
response = self.client.post(location, data=url.post_data, follow=url.follow)
|
||||||
|
else: # pragma: no cover
|
||||||
|
raise NotImplementedError("Method {} is not supported".format(url.http_method))
|
||||||
|
|
||||||
if url.redirect:
|
if url.redirect:
|
||||||
self.assertRedirects(response, url.redirect)
|
self.assertRedirects(response, url.redirect)
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
from django.conf.urls import url
|
from django.urls import re_path
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.views import generic
|
from django.views import generic
|
||||||
|
|
||||||
from . import views
|
from . import views
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^$', views.RootView.as_view(), name='root'),
|
re_path(r'^$', views.RootView.as_view(), name='root'),
|
||||||
url(r'^css-demo$', generic.TemplateView.as_view(template_name='dav_base/css_demo.html'), name='css-demo'),
|
re_path(r'^css-demo$', generic.TemplateView.as_view(template_name='dav_base/css_demo.html'), name='css-demo'),
|
||||||
url(r'^djangoadmin/', admin.site.urls),
|
re_path(r'^djangoadmin/', admin.site.urls),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from django.core.validators import RegexValidator
|
from django.core.validators import RegexValidator
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
|
||||||
DAVNumberValidator = RegexValidator(r'^'
|
DAVNumberValidator = RegexValidator(r'^'
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ class RootView(generic.TemplateView):
|
|||||||
root_url_name = '%s:%s' % (module_meta_obj.url_namespace, root_url_name)
|
root_url_name = '%s:%s' % (module_meta_obj.url_namespace, root_url_name)
|
||||||
try:
|
try:
|
||||||
reverse(root_url_name)
|
reverse(root_url_name)
|
||||||
root_urls.append((module_meta_obj.app, root_url_name))
|
root_urls.append((module_meta_obj.package, root_url_name))
|
||||||
except NoReverseMatch:
|
except NoReverseMatch:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
default_app_config = 'dav_event_office.apps.AppConfig' # pylint: disable=invalid-name
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
{
|
{
|
||||||
"url_prefix": "office/events"
|
"url_prefix": "office/events",
|
||||||
|
"app_config": ".apps.AppConfig"
|
||||||
}
|
}
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
from django.conf.urls import url
|
from django.urls import re_path
|
||||||
|
|
||||||
from . import views
|
from . import views
|
||||||
|
|
||||||
app_name = 'dav_event_office'
|
app_name = 'dav_event_office'
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^home$', views.HomeView.as_view(), name='root'),
|
re_path(r'^home$', views.HomeView.as_view(), name='root'),
|
||||||
url(r'^participants$', views.ParticipantListView.as_view(), name='participant-list'),
|
re_path(r'^participants$', views.ParticipantListView.as_view(), name='participant-list'),
|
||||||
url(r'^$', views.EventListView.as_view(), name='event-list'),
|
re_path(r'^$', views.EventListView.as_view(), name='event-list'),
|
||||||
url(r'^(?P<pk>\d+)/', views.EventDetailView.as_view(), name='event-detail'),
|
re_path(r'^(?P<pk>\d+)/', views.EventDetailView.as_view(), name='event-detail'),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
default_app_config = 'dav_events.apps.AppConfig' # pylint: disable=invalid-name
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from django_countries import Countries
|
from django_countries import Countries
|
||||||
|
|
||||||
CHOICE_FIELD_MAX_LENGTH = 25
|
CHOICE_FIELD_MAX_LENGTH = 25
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from dav_events.config import FieldInitial
|
from dav_events.config import FieldInitial
|
||||||
|
|
||||||
# E-Mails
|
# E-Mails
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import re
|
|||||||
from babel.dates import format_date
|
from babel.dates import format_date
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.apps import apps
|
from django.apps import apps
|
||||||
from django.utils.translation import get_language, ugettext, ugettext_lazy as _
|
from django.utils.translation import get_language, gettext, gettext_lazy as _
|
||||||
from django_countries.fields import Country, LazyTypedChoiceField
|
from django_countries.fields import Country, LazyTypedChoiceField
|
||||||
from datetimewidget.widgets import DateWidget, TimeWidget, DateTimeWidget
|
from datetimewidget.widgets import DateWidget, TimeWidget, DateTimeWidget
|
||||||
from six import string_types
|
from six import string_types
|
||||||
@@ -840,7 +840,7 @@ class ChargesForm(EventCreateForm):
|
|||||||
|
|
||||||
additional_costs_text = u''
|
additional_costs_text = u''
|
||||||
if transport != 'coach':
|
if transport != 'coach':
|
||||||
additional_costs_text += ugettext(u'Fahrtkosten')
|
additional_costs_text += gettext(u'Fahrtkosten')
|
||||||
if transport == 'public':
|
if transport == 'public':
|
||||||
pubtrans_planned = True
|
pubtrans_planned = True
|
||||||
else:
|
else:
|
||||||
@@ -852,7 +852,7 @@ class ChargesForm(EventCreateForm):
|
|||||||
if accommodation != 'NONE':
|
if accommodation != 'NONE':
|
||||||
if additional_costs_text:
|
if additional_costs_text:
|
||||||
additional_costs_text += u', '
|
additional_costs_text += u', '
|
||||||
additional_costs_text += ugettext(u'Unterkunft und Verpflegung')
|
additional_costs_text += gettext(u'Unterkunft und Verpflegung')
|
||||||
else:
|
else:
|
||||||
ndays = 1
|
ndays = 1
|
||||||
|
|
||||||
@@ -901,7 +901,7 @@ class ChargesForm(EventCreateForm):
|
|||||||
self.fields['trainer1_reward'].initial = trainer1_reward
|
self.fields['trainer1_reward'].initial = trainer1_reward
|
||||||
self.fields['trainer23_reward'].initial = trainer23_reward
|
self.fields['trainer23_reward'].initial = trainer23_reward
|
||||||
|
|
||||||
self.fields['pubtrans_bonus'].widget.attrs['title'] = ugettext(u'Der Bonus wird nachträglich'
|
self.fields['pubtrans_bonus'].widget.attrs['title'] = gettext(u'Der Bonus wird nachträglich'
|
||||||
u' auf Meldung der Tourenleitung'
|
u' auf Meldung der Tourenleitung'
|
||||||
u' verrechnet und ist noch nicht'
|
u' verrechnet und ist noch nicht'
|
||||||
u' in den hier dargestellten Zahlen enthalten.')
|
u' in den hier dargestellten Zahlen enthalten.')
|
||||||
@@ -941,7 +941,7 @@ class ChargesForm(EventCreateForm):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
self.fields['additional_costs'].widget.attrs['placeholder'] = ugettext(u'Kann freigelassen werden')
|
self.fields['additional_costs'].widget.attrs['placeholder'] = gettext(u'Kann freigelassen werden')
|
||||||
self.fields['additional_costs'].initial = additional_costs_text
|
self.fields['additional_costs'].initial = additional_costs_text
|
||||||
|
|
||||||
|
|
||||||
@@ -1011,32 +1011,32 @@ class DescriptionForm(EventCreateForm):
|
|||||||
if mode == 'training':
|
if mode == 'training':
|
||||||
# Titelprefix für Kurse
|
# Titelprefix für Kurse
|
||||||
if level == 'family':
|
if level == 'family':
|
||||||
value += u'%s' % ugettext(u'Familienkurs')
|
value += u'%s' % gettext(u'Familienkurs')
|
||||||
elif level == 'beginner':
|
elif level == 'beginner':
|
||||||
value += u'%s' % ugettext(u'Grundkurs')
|
value += u'%s' % gettext(u'Grundkurs')
|
||||||
else:
|
else:
|
||||||
value += u'%s' % ugettext(u'Aufbaukurs')
|
value += u'%s' % gettext(u'Aufbaukurs')
|
||||||
|
|
||||||
if sport == 'B':
|
if sport == 'B':
|
||||||
value += u' %s' % ugettext(u'Alpin')
|
value += u' %s' % gettext(u'Alpin')
|
||||||
elif sport == 'K':
|
elif sport == 'K':
|
||||||
if terrain == 'gym':
|
if terrain == 'gym':
|
||||||
value += u' %s' % ugettext(u'Indoorklettern')
|
value += u' %s' % gettext(u'Indoorklettern')
|
||||||
elif terrain == 'crag':
|
elif terrain == 'crag':
|
||||||
value += u' %s' % ugettext(u'Fels')
|
value += u' %s' % gettext(u'Fels')
|
||||||
elif terrain == 'alpine':
|
elif terrain == 'alpine':
|
||||||
value += u' %s' % ugettext(u'Alpinklettern')
|
value += u' %s' % gettext(u'Alpinklettern')
|
||||||
|
|
||||||
value += u': ...'
|
value += u': ...'
|
||||||
elif sport == 'W':
|
elif sport == 'W':
|
||||||
# Titelprefix für Wanderungen
|
# Titelprefix für Wanderungen
|
||||||
if level == 'family':
|
if level == 'family':
|
||||||
value += u'%s ...' % ugettext(u'Familienwanderung')
|
value += u'%s ...' % gettext(u'Familienwanderung')
|
||||||
elif not last_day:
|
elif not last_day:
|
||||||
value += u'%s ...' % ugettext(u'Tageswanderung')
|
value += u'%s ...' % gettext(u'Tageswanderung')
|
||||||
elif level == 'family':
|
elif level == 'family':
|
||||||
# Titelprefix für sonstige Familientouren
|
# Titelprefix für sonstige Familientouren
|
||||||
value += u'%s: ...' % ugettext(u'Familientour')
|
value += u'%s: ...' % gettext(u'Familientour')
|
||||||
|
|
||||||
if app_config.settings.forms_development_init:
|
if app_config.settings.forms_development_init:
|
||||||
if not value:
|
if not value:
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
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 RegistrationResponseForm(forms.Form):
|
class RegistrationResponseForm(forms.Form):
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ from django.contrib.auth import get_user_model
|
|||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.template.loader import get_template
|
from django.template.loader import get_template
|
||||||
from django.utils.translation import get_language, ugettext_lazy as _
|
from django.utils.translation import get_language, gettext_lazy as _
|
||||||
from django_countries.fields import Country, CountryField
|
from django_countries.fields import Country, CountryField
|
||||||
|
|
||||||
from .. import choices
|
from .. import choices
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from ..validators import IdStringValidator
|
from ..validators import IdStringValidator
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ from django.contrib.auth import get_user_model
|
|||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.utils.translation import ugettext, ugettext_lazy as _
|
from django.utils.translation import gettext, gettext_lazy as _
|
||||||
|
|
||||||
from .event import Event
|
from .event import Event
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ class OneClickAction(models.Model):
|
|||||||
if self.done and not self.allow_repeat:
|
if self.done and not self.allow_repeat:
|
||||||
result['context'] = {
|
result['context'] = {
|
||||||
'status': 'warning',
|
'status': 'warning',
|
||||||
'message': ugettext('Diese Aktion hast du bereits ausgeführt.'),
|
'message': gettext('Diese Aktion hast du bereits ausgeführt.'),
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
|
|
||||||
@@ -78,7 +78,7 @@ class OneClickAction(models.Model):
|
|||||||
|
|
||||||
flag = event.flags.filter(status__code=status_code).first()
|
flag = event.flags.filter(status__code=status_code).first()
|
||||||
if flag:
|
if flag:
|
||||||
message = (ugettext('Der Status wurde bereits'
|
message = (gettext('Der Status wurde bereits'
|
||||||
' am %(date)s'
|
' am %(date)s'
|
||||||
' von %(user)s'
|
' von %(user)s'
|
||||||
' auf \'%(status)s\' gesetzt.') % {
|
' auf \'%(status)s\' gesetzt.') % {
|
||||||
@@ -88,7 +88,7 @@ class OneClickAction(models.Model):
|
|||||||
})
|
})
|
||||||
else:
|
else:
|
||||||
flag = event.workflow.update_status(status_code, user)
|
flag = event.workflow.update_status(status_code, user)
|
||||||
message = (ugettext('Der Status wurde auf \'%(status)s\' gesetzt.') %
|
message = (gettext('Der Status wurde auf \'%(status)s\' gesetzt.') %
|
||||||
{'status': flag.status.label})
|
{'status': flag.status.label})
|
||||||
|
|
||||||
result['context'] = {
|
result['context'] = {
|
||||||
@@ -109,7 +109,7 @@ class OneClickAction(models.Model):
|
|||||||
else:
|
else:
|
||||||
result['context'] = {
|
result['context'] = {
|
||||||
'status': 'danger',
|
'status': 'danger',
|
||||||
'message': ugettext('Invalid Command. Code on fire!'),
|
'message': gettext('Invalid Command. Code on fire!'),
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import datetime
|
|||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.db import models
|
from django.db import models
|
||||||
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 dav_base.validators import DAVNumberValidator
|
from dav_base.validators import DAVNumberValidator
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from ..participant import AbstractParticipant
|
from ..participant import AbstractParticipant
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
{
|
{
|
||||||
"url_prefix": "events"
|
"url_prefix": "events",
|
||||||
|
"app_config": ".apps.AppConfig"
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
from django.dispatch import Signal
|
from django.dispatch import Signal
|
||||||
|
|
||||||
event_created = Signal(providing_args=['event'])
|
event_created = Signal()
|
||||||
event_updated = Signal(providing_args=['event', 'diff', 'user'])
|
event_updated = Signal()
|
||||||
event_status_updated = Signal(providing_args=['event', 'flag'])
|
event_status_updated = Signal()
|
||||||
event_registration_closed = Signal(providing_args=['event', 'user'])
|
event_registration_closed = Signal()
|
||||||
|
|
||||||
|
|
||||||
def signal_handler_for_event_update(sender, **kwargs):
|
def signal_handler_for_event_update(sender, **kwargs):
|
||||||
|
|||||||
@@ -51,7 +51,7 @@
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<form action="" method="post">
|
<form id="id_event_update_form" action="" method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
|
|
||||||
{% if is_realized %}
|
{% if is_realized %}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ from django import template
|
|||||||
from django.utils.html import format_html
|
from django.utils.html import format_html
|
||||||
from django.utils.safestring import mark_safe
|
from django.utils.safestring import mark_safe
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import gettext as _
|
||||||
|
|
||||||
from ..models.eventchange import EventChange
|
from ..models.eventchange import EventChange
|
||||||
from ..models.eventstatus import EventStatus, get_or_create_event_status
|
from ..models.eventstatus import EventStatus, get_or_create_event_status
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import re
|
|||||||
from django.apps import apps
|
from django.apps import apps
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.translation import ugettext
|
from django.utils.translation import gettext
|
||||||
|
|
||||||
from dav_base.tests.generic import EmailTestMixin
|
from dav_base.tests.generic import EmailTestMixin
|
||||||
|
|
||||||
@@ -80,7 +80,7 @@ class ActionTestCase(EmailTestMixin, RoleMixin, EventMixin, TestCase):
|
|||||||
|
|
||||||
content = response.content.decode('utf-8')
|
content = response.content.decode('utf-8')
|
||||||
status_label = self.get_status_label(status_code)
|
status_label = self.get_status_label(status_code)
|
||||||
message = ugettext('Der Status wurde auf \'%(status)s\' gesetzt.') % {'status': status_label}
|
message = gettext('Der Status wurde auf \'%(status)s\' gesetzt.') % {'status': status_label}
|
||||||
html = message.replace('\'', ''')
|
html = message.replace('\'', ''')
|
||||||
self.assertInHTML(html, content)
|
self.assertInHTML(html, content)
|
||||||
self.assertRegex(content, r'alert-success')
|
self.assertRegex(content, r'alert-success')
|
||||||
@@ -103,7 +103,7 @@ class ActionTestCase(EmailTestMixin, RoleMixin, EventMixin, TestCase):
|
|||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
content = response.content.decode('utf-8')
|
content = response.content.decode('utf-8')
|
||||||
html = ugettext('Diese Aktion hast du bereits ausgeführt.')
|
html = gettext('Diese Aktion hast du bereits ausgeführt.')
|
||||||
self.assertInHTML(html, content)
|
self.assertInHTML(html, content)
|
||||||
self.assertRegex(content, r'alert-warning')
|
self.assertRegex(content, r'alert-warning')
|
||||||
|
|
||||||
@@ -112,13 +112,13 @@ class ActionTestCase(EmailTestMixin, RoleMixin, EventMixin, TestCase):
|
|||||||
|
|
||||||
content = response.content.decode('utf-8')
|
content = response.content.decode('utf-8')
|
||||||
status_label = self.get_status_label(status_code)
|
status_label = self.get_status_label(status_code)
|
||||||
message = (ugettext('Der Status wurde bereits'
|
message = (gettext('Der Status wurde bereits'
|
||||||
' am %(date)s'
|
' am %(date)s'
|
||||||
' von %(user)s'
|
' von %(user)s'
|
||||||
' auf \'%(status)s\' gesetzt.') % {
|
' auf \'%(status)s\' gesetzt.') % {
|
||||||
'status': status_label,
|
'status': status_label,
|
||||||
# 'date': datetime.datetime.now().strftime('%d.%m.%Y %H:%M:%S'),
|
# 'date': datetime.datetime.now().strftime('%d.%m.%Y %H:%M:%S'),
|
||||||
'date': '\d{2}\.\d{2}\.\d{4} \d{2}:\d{2}:\d{2}',
|
'date': r'\d{2}\.\d{2}\.\d{4} \d{2}:\d{2}:\d{2}',
|
||||||
'user': user.get_full_name(),
|
'user': user.get_full_name(),
|
||||||
})
|
})
|
||||||
html = message.replace('\'', ''')
|
html = message.replace('\'', ''')
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import time
|
import time
|
||||||
from django.test import tag
|
from django.test import tag
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.translation import ugettext
|
from django.utils.translation import gettext
|
||||||
from selenium.common.exceptions import NoSuchElementException
|
from selenium.common.exceptions import NoSuchElementException
|
||||||
from selenium.webdriver.common.by import By
|
from selenium.webdriver.common.by import By
|
||||||
from selenium.webdriver.common.keys import Keys
|
from selenium.webdriver.common.keys import Keys
|
||||||
@@ -528,7 +528,7 @@ class TestCase(SeleniumAuthMixin, RoleMixin, ScreenshotTestCase):
|
|||||||
self.wait_until_stale(c, link)
|
self.wait_until_stale(c, link)
|
||||||
|
|
||||||
action_tabs = c.find_element(By.CSS_SELECTOR, '.action-tabs > ul.nav-tabs')
|
action_tabs = c.find_element(By.CSS_SELECTOR, '.action-tabs > ul.nav-tabs')
|
||||||
tab = action_tabs.find_element(By.LINK_TEXT, ugettext(u'Ändern'))
|
tab = action_tabs.find_element(By.LINK_TEXT, gettext(u'Ändern'))
|
||||||
tab.click()
|
tab.click()
|
||||||
self.wait_until_stale(c, tab)
|
self.wait_until_stale(c, tab)
|
||||||
|
|
||||||
@@ -537,14 +537,14 @@ class TestCase(SeleniumAuthMixin, RoleMixin, ScreenshotTestCase):
|
|||||||
if screenshots:
|
if screenshots:
|
||||||
self.save_screenshot('edit-form', sequence=sequence_name)
|
self.save_screenshot('edit-form', sequence=sequence_name)
|
||||||
|
|
||||||
button = panel.find_element(By.PARTIAL_LINK_TEXT, ugettext(u'Nächster Abschnitt'))
|
button = panel.find_element(By.PARTIAL_LINK_TEXT, gettext(u'Nächster Abschnitt'))
|
||||||
button.click()
|
button.click()
|
||||||
time.sleep(.5)
|
time.sleep(.5)
|
||||||
|
|
||||||
if screenshots:
|
if screenshots:
|
||||||
self.save_screenshot('edit-form', sequence=sequence_name)
|
self.save_screenshot('edit-form', sequence=sequence_name)
|
||||||
|
|
||||||
button = c.find_element(By.CSS_SELECTOR, 'form button[type="submit"]')
|
button = c.find_element(By.CSS_SELECTOR, '#id_event_update_form button[type="submit"]')
|
||||||
button.click()
|
button.click()
|
||||||
self.wait_until_stale(c, button)
|
self.wait_until_stale(c, button)
|
||||||
|
|
||||||
@@ -580,7 +580,7 @@ class TestCase(SeleniumAuthMixin, RoleMixin, ScreenshotTestCase):
|
|||||||
if screenshots:
|
if screenshots:
|
||||||
self.save_screenshot('accepted', sequence=sequence_name)
|
self.save_screenshot('accepted', sequence=sequence_name)
|
||||||
|
|
||||||
link = c.find_element(By.LINK_TEXT, ugettext('Veranstaltungsliste'))
|
link = c.find_element(By.LINK_TEXT, gettext('Veranstaltungsliste'))
|
||||||
link.click()
|
link.click()
|
||||||
self.wait_until_stale(c, link)
|
self.wait_until_stale(c, link)
|
||||||
if screenshots:
|
if screenshots:
|
||||||
@@ -618,7 +618,7 @@ class TestCase(SeleniumAuthMixin, RoleMixin, ScreenshotTestCase):
|
|||||||
if screenshots:
|
if screenshots:
|
||||||
self.save_screenshot('confirmed_{}'.format(channel), sequence=sequence_name)
|
self.save_screenshot('confirmed_{}'.format(channel), sequence=sequence_name)
|
||||||
|
|
||||||
link = c.find_element(By.LINK_TEXT, ugettext('Veranstaltungsliste'))
|
link = c.find_element(By.LINK_TEXT, gettext('Veranstaltungsliste'))
|
||||||
link.click()
|
link.click()
|
||||||
self.wait_until_stale(c, link)
|
self.wait_until_stale(c, link)
|
||||||
if screenshots:
|
if screenshots:
|
||||||
@@ -650,7 +650,7 @@ class TestCase(SeleniumAuthMixin, RoleMixin, ScreenshotTestCase):
|
|||||||
if screenshots:
|
if screenshots:
|
||||||
self.save_screenshot('confirmed_clearance', sequence=sequence_name)
|
self.save_screenshot('confirmed_clearance', sequence=sequence_name)
|
||||||
|
|
||||||
link = c.find_element(By.LINK_TEXT, ugettext('Veranstaltungsliste'))
|
link = c.find_element(By.LINK_TEXT, gettext('Veranstaltungsliste'))
|
||||||
link.click()
|
link.click()
|
||||||
self.wait_until_stale(c, link)
|
self.wait_until_stale(c, link)
|
||||||
if screenshots:
|
if screenshots:
|
||||||
@@ -730,7 +730,7 @@ class TestCase(SeleniumAuthMixin, RoleMixin, ScreenshotTestCase):
|
|||||||
button.click()
|
button.click()
|
||||||
self.wait_until_stale(c, button)
|
self.wait_until_stale(c, button)
|
||||||
|
|
||||||
link = c.find_element(By.PARTIAL_LINK_TEXT, ugettext(u'Veranstaltungsliste herunterladen'))
|
link = c.find_element(By.PARTIAL_LINK_TEXT, gettext(u'Veranstaltungsliste herunterladen'))
|
||||||
link.click()
|
link.click()
|
||||||
self.wait_until_stale(c, link)
|
self.wait_until_stale(c, link)
|
||||||
self.save_screenshot('event_export_form')
|
self.save_screenshot('event_export_form')
|
||||||
|
|||||||
@@ -1,20 +1,20 @@
|
|||||||
from django.conf.urls import url
|
from django.urls import re_path
|
||||||
|
|
||||||
from . import views
|
from . import views
|
||||||
|
|
||||||
app_name = 'dav_events'
|
app_name = 'dav_events'
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^home$', views.base.HomeView.as_view(), name='root'),
|
re_path(r'^home$', views.base.HomeView.as_view(), name='root'),
|
||||||
url(r'^$', views.events.EventListView.as_view(), name='list'),
|
re_path(r'^$', views.events.EventListView.as_view(), name='list'),
|
||||||
url(r'^export$', views.events.EventListExportView.as_view(), name='list_export'),
|
re_path(r'^export$', views.events.EventListExportView.as_view(), name='list_export'),
|
||||||
url(r'^create$', views.events.EventCreateView.as_view(), name='create'),
|
re_path(r'^create$', views.events.EventCreateView.as_view(), name='create'),
|
||||||
url(r'^(?P<pk>\d+)/registrations', views.events.EventRegistrationsView.as_view(), name='registrations'),
|
re_path(r'^(?P<pk>\d+)/registrations', views.events.EventRegistrationsView.as_view(), name='registrations'),
|
||||||
url(r'^(?P<pk>\d+)/status/(?P<status>[a-z0-9._-][a-z0-9._-]*)',
|
re_path(r'^(?P<pk>\d+)/status/(?P<status>[a-z0-9._-][a-z0-9._-]*)',
|
||||||
views.events.EventUpdateStatusView.as_view(), name='updatestatus'),
|
views.events.EventUpdateStatusView.as_view(), name='updatestatus'),
|
||||||
url(r'^(?P<pk>\d+)/edit', views.events.EventUpdateView.as_view(), name='update'),
|
re_path(r'^(?P<pk>\d+)/edit', views.events.EventUpdateView.as_view(), name='update'),
|
||||||
url(r'^(?P<pk>\d+)/', views.events.EventDetailView.as_view(), name='detail'),
|
re_path(r'^(?P<pk>\d+)/', views.events.EventDetailView.as_view(), name='detail'),
|
||||||
url(r'^registration/(?P<pk>\d+)/', views.events.RespondRegistrationView.as_view(), name='respond_registration'),
|
re_path(r'^registration/(?P<pk>\d+)/', views.events.RespondRegistrationView.as_view(), name='respond_registration'),
|
||||||
url(r'^action/(?P<pk>[a-fA-F0-9]{8}-([a-fA-F0-9]{4}-){3}[a-fA-F0-9]{12})/',
|
re_path(r'^action/(?P<pk>[a-fA-F0-9]{8}-([a-fA-F0-9]{4}-){3}[a-fA-F0-9]{12})/',
|
||||||
views.actions.OneClickActionRunView.as_view(), name='action_run'),
|
views.actions.OneClickActionRunView.as_view(), name='action_run'),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import logging
|
|||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.contrib.auth import login
|
from django.contrib.auth import login
|
||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponseRedirect
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import gettext as _
|
||||||
from django.views import generic
|
from django.views import generic
|
||||||
|
|
||||||
from .. import models
|
from .. import models
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ from django.shortcuts import get_object_or_404
|
|||||||
from django.urls import reverse, reverse_lazy
|
from django.urls import reverse, reverse_lazy
|
||||||
from django.utils.decorators import method_decorator
|
from django.utils.decorators import method_decorator
|
||||||
from django.utils.text import normalize_newlines
|
from django.utils.text import normalize_newlines
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import gettext as _
|
||||||
from django.views import generic
|
from django.views import generic
|
||||||
|
|
||||||
from .. import choices
|
from .. import choices
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import re
|
|||||||
from django.apps import apps
|
from django.apps import apps
|
||||||
from django.db.models.functions import Length
|
from django.db.models.functions import Length
|
||||||
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 . import emails
|
from . import emails
|
||||||
from . import signals
|
from . import signals
|
||||||
@@ -264,6 +264,9 @@ class BasicWorkflow(object):
|
|||||||
status_list = []
|
status_list = []
|
||||||
self._check_status()
|
self._check_status()
|
||||||
|
|
||||||
|
if not event.id:
|
||||||
|
return status_list
|
||||||
|
|
||||||
heaviest_flag = event.flags.order_by('status').last()
|
heaviest_flag = event.flags.order_by('status').last()
|
||||||
if heaviest_flag:
|
if heaviest_flag:
|
||||||
flags = []
|
flags = []
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
default_app_config = 'dav_registration.apps.AppConfig' # pylint: disable=invalid-name
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import datetime
|
import datetime
|
||||||
import logging
|
import logging
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.utils.translation import ugettext, ugettext_lazy as _
|
from django.utils.translation import gettext, gettext_lazy as _
|
||||||
|
|
||||||
from .models import Registration
|
from .models import Registration
|
||||||
|
|
||||||
@@ -40,14 +40,14 @@ class RegistrationForm(forms.ModelForm):
|
|||||||
val = self.cleaned_data.get('year_of_birth')
|
val = self.cleaned_data.get('year_of_birth')
|
||||||
if val > year_now:
|
if val > year_now:
|
||||||
raise forms.ValidationError(
|
raise forms.ValidationError(
|
||||||
ugettext('Dein Geburtsjahr liegt in der Zukunft?'
|
gettext('Dein Geburtsjahr liegt in der Zukunft?'
|
||||||
' Das finden wir gut,'
|
' Das finden wir gut,'
|
||||||
' aber bitte melde dich besser mal per E-Mail bei uns.'),
|
' aber bitte melde dich besser mal per E-Mail bei uns.'),
|
||||||
code='to_young',
|
code='to_young',
|
||||||
)
|
)
|
||||||
elif val < (year_now - max_age):
|
elif val < (year_now - max_age):
|
||||||
raise forms.ValidationError(
|
raise forms.ValidationError(
|
||||||
ugettext('Du bist schon über %(max_age)d Jahre alt?'
|
gettext('Du bist schon über %(max_age)d Jahre alt?'
|
||||||
' Das finden wir gut,'
|
' Das finden wir gut,'
|
||||||
' aber bitte melde dich besser mal per E-Mail bei uns.'),
|
' aber bitte melde dich besser mal per E-Mail bei uns.'),
|
||||||
params={'max_age': max_age},
|
params={'max_age': max_age},
|
||||||
@@ -63,7 +63,7 @@ class RegistrationForm(forms.ModelForm):
|
|||||||
need_experience = False
|
need_experience = False
|
||||||
if need_experience:
|
if need_experience:
|
||||||
raise forms.ValidationError(
|
raise forms.ValidationError(
|
||||||
ugettext('Die Tourenleiter*innen brauchen ein paar Angaben,'
|
gettext('Die Tourenleiter*innen brauchen ein paar Angaben,'
|
||||||
' was du bereits kannst oder wie fit du bist.'),
|
' was du bereits kannst oder wie fit du bist.'),
|
||||||
code='need_experience',
|
code='need_experience',
|
||||||
)
|
)
|
||||||
@@ -73,7 +73,7 @@ class RegistrationForm(forms.ModelForm):
|
|||||||
val = self.cleaned_data.get('privacy_policy_accepted')
|
val = self.cleaned_data.get('privacy_policy_accepted')
|
||||||
if not val and self.instance.privacy_policy:
|
if not val and self.instance.privacy_policy:
|
||||||
raise forms.ValidationError(
|
raise forms.ValidationError(
|
||||||
ugettext('Wir müssen deine Daten leider speichern können,'
|
gettext('Wir müssen deine Daten leider speichern können,'
|
||||||
' damit wir wissen, dass du teilnehmen möchtest.'),
|
' damit wir wissen, dass du teilnehmen möchtest.'),
|
||||||
code='privacy_policy_not_accepted',
|
code='privacy_policy_not_accepted',
|
||||||
)
|
)
|
||||||
@@ -84,7 +84,7 @@ class RegistrationForm(forms.ModelForm):
|
|||||||
dav_member = self.cleaned_data.get('dav_member')
|
dav_member = self.cleaned_data.get('dav_member')
|
||||||
dav_number = self.cleaned_data.get('dav_number')
|
dav_number = self.cleaned_data.get('dav_number')
|
||||||
if dav_member and not dav_number:
|
if dav_member and not dav_number:
|
||||||
error_msg = ugettext('Wenn du DAV Mitglied bist, brauchen wir deine Mitgliedsnummer.')
|
error_msg = gettext('Wenn du DAV Mitglied bist, brauchen wir deine Mitgliedsnummer.')
|
||||||
self.add_error('not_dav_member', error_msg)
|
self.add_error('not_dav_member', error_msg)
|
||||||
raise forms.ValidationError(error_msg, code='dav_number_missing')
|
raise forms.ValidationError(error_msg, code='dav_number_missing')
|
||||||
return self.cleaned_data
|
return self.cleaned_data
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ from django.core.exceptions import ValidationError
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
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 dav_base.validators import DAVNumberValidator
|
from dav_base.validators import DAVNumberValidator
|
||||||
from dav_events.models.event import Event
|
from dav_events.models.event import Event
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
{
|
{
|
||||||
"url_prefix": "registration"
|
"url_prefix": "registration",
|
||||||
|
"app_config": ".apps.AppConfig"
|
||||||
}
|
}
|
||||||
@@ -2,7 +2,7 @@ from django.dispatch import Signal
|
|||||||
|
|
||||||
from . import emails
|
from . import emails
|
||||||
|
|
||||||
registration_created = Signal(providing_args=['registration'])
|
registration_created = Signal()
|
||||||
|
|
||||||
|
|
||||||
def send_emails_on_registration(sender, **kwargs): # pylint: disable=unused-argument
|
def send_emails_on_registration(sender, **kwargs): # pylint: disable=unused-argument
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
from django.conf.urls import url
|
from django.urls import re_path
|
||||||
|
|
||||||
from . import views
|
from . import views
|
||||||
|
|
||||||
app_name = 'dav_registration'
|
app_name = 'dav_registration'
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^$', views.RootView.as_view(), name='root'),
|
re_path(r'^$', views.RootView.as_view(), name='root'),
|
||||||
url(r'^home/$', views.HomeView.as_view(), name='home'),
|
re_path(r'^home/$', views.HomeView.as_view(), name='home'),
|
||||||
url(r'^event/$', views.EventListView.as_view(), name='events'),
|
re_path(r'^event/$', views.EventListView.as_view(), name='events'),
|
||||||
url(r'^event/(?P<pk>\d+)/$', views.EventDetailView.as_view(), name='event'),
|
re_path(r'^event/(?P<pk>\d+)/$', views.EventDetailView.as_view(), name='event'),
|
||||||
url(r'^event/(?P<pk>\d+)/registration/$', views.RegistrationView.as_view(), name='register'),
|
re_path(r'^event/(?P<pk>\d+)/registration/$', views.RegistrationView.as_view(), name='register'),
|
||||||
url(r'^finished/$', views.RegistrationSuccessView.as_view(), name='registered'),
|
re_path(r'^finished/$', views.RegistrationSuccessView.as_view(), name='registered'),
|
||||||
url(r'^api/v1/event/$', views.EventListAsJSONView, name='api_events'),
|
re_path(r'^api/v1/event/$', views.EventListAsJSONView, name='api_events'),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ from django.contrib import messages
|
|||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
from django.http import JsonResponse
|
from django.http import JsonResponse
|
||||||
from django.urls import reverse_lazy
|
from django.urls import reverse_lazy
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import gettext as _
|
||||||
from django.views import generic
|
from django.views import generic
|
||||||
|
|
||||||
from dav_events.choices import SPORT_CHOICES, LEVEL_CHOICES
|
from dav_events.choices import SPORT_CHOICES, LEVEL_CHOICES
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
babel
|
babel
|
||||||
django<3.3
|
django<5.1
|
||||||
django-bootstrap3
|
django-bootstrap3
|
||||||
django-countries
|
django-countries
|
||||||
django-datetime-widget2
|
django-datetime-widget2
|
||||||
|
|||||||
Reference in New Issue
Block a user