1 Commits

Author SHA1 Message Date
06785a3e49 Code Cleanup with ruff. 2023-08-13 15:37:48 +02:00
60 changed files with 1042 additions and 715 deletions

View File

@@ -1,42 +0,0 @@
[project]
name = "kasu"
version = "4.230918"
description = "Homepage CMS for Kasu.at"
authors = [
{ name = "Christian Berg", email = "xeniac@xendynastie.at" }
]
requires-python = ">=3.8"
dependencies = ["beautifulsoup4",
"django < 5.0",
"django-appconf",
"django-ckeditor",
"django-contrib-comments",
"django-csp",
"django-compressor",
"django-extra-views",
"django-markdown",
"django-recaptcha",
"easy_thumbnails[svg]",
"icalendar",
"openpyxl",
"markdown",
"pillow",
"psycopg2-binary",
"PyJWT",
"pytz",
"requests",
"requests-oauthlib"
]
[project.optional-dependencies]
dev = [
"django-debug-toolbar",
"django-rosetta",
"sqlparse",
"pylint>=2.0",
"pylint-django"
]
[tool.setuptools.packages.find]
where = ["src"]

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: kasu.content\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-07-27 00:05+0200\n"
"POT-Creation-Date: 2023-08-07 20:38+0200\n"
"PO-Revision-Date: 2018-01-12 15:25+0105\n"
"Last-Translator: b'Christian Berg <kasu@xendynastie.at>'\n"
"Language-Team: Deutsch <>\n"
@@ -20,7 +20,7 @@ msgstr ""
"X-Generator: Poedit 1.8.9\n"
"X-Translated-Using: django-rosetta 0.7.14\n"
#: feeds.py:18
#: feeds.py:17 feeds.py:19
msgid "Current news from Kasu"
msgstr "Aktuelle Nachrichten von Kasu"
@@ -32,7 +32,7 @@ msgstr "Neueste Kommentare auf Kasu.at "
msgid "Kasu - latest comments"
msgstr "Kasu - neue Kommentare"
#: forms.py:57 models.py:318
#: forms.py:57 models.py:320
msgid "Please upload a PDF-File to this PDF-Page."
msgstr "Bitte eine PDF Datei für diese PDF Seite hochladen."
@@ -44,15 +44,15 @@ msgstr "Schlagzeile"
msgid "Content"
msgstr "Inhalt"
#: models.py:82 models.py:150 templates/content/article_detail.html:28
#: models.py:82 models.py:151 templates/content/article_detail.html:28
msgid "Category"
msgstr "Kategorie"
#: models.py:83 models.py:143
#: models.py:83 models.py:144
msgid "Image"
msgstr "Bild"
#: models.py:85 models.py:145
#: models.py:85 models.py:146
msgid "Slug"
msgstr "Slug"
@@ -80,77 +80,77 @@ msgstr "Artikel"
msgid "Articles"
msgstr "Artikel"
#: models.py:139 models.py:140
#: models.py:140 models.py:141
msgid "Name"
msgstr "Name"
#: models.py:141 models.py:142
#: models.py:142 models.py:143
msgid "Description"
msgstr "Beschreibung"
#: models.py:151
#: models.py:152
msgid "Categories"
msgstr "Kategorien"
#: models.py:182 models.py:188
#: models.py:184 models.py:190
msgid "The short name for the menu-entry of this page"
msgstr "Ein kurzer Name für den Menüeintrag"
#: models.py:193 models.py:198
#: models.py:195 models.py:200
msgid "The page title as you'd like it to be seen by the public"
msgstr "Der Seitentitel der öffentlich angezeigt werden soll"
#: models.py:200
#: models.py:202
msgid "slug"
msgstr "Slug"
#: models.py:203
#: models.py:205
msgid ""
"The name of the page as it will appear in URLs e.g http://domain.com/blog/"
"[my-slug]/"
msgstr "Wie die Seite in der URL aufscheint also http://domain.com/blog/[slug]"
#: models.py:212
#: models.py:214
msgid "Path"
msgstr "Pfad"
#: models.py:224
#: models.py:226
msgid "Position"
msgstr "Position"
#: models.py:229
#: models.py:231
msgid "status"
msgstr "Status"
#: models.py:232 models.py:234
#: models.py:234 models.py:236
msgid "search description"
msgstr "Beschreibung für Suchfunktion"
#: models.py:237
#: models.py:239
msgid "content type"
msgstr "Inhaltstyp"
#: models.py:242
#: models.py:244
msgid "enable comments"
msgstr "Kommentare möglich"
#: models.py:247
#: models.py:249
msgid "Template"
msgstr "Vorlage"
#: models.py:255
#: models.py:257
msgid "first created at"
msgstr "erstellt am"
#: models.py:260
#: models.py:262
msgid "latest updated at"
msgstr "letzte Aktualisierung am"
#: models.py:331
#: models.py:333
msgid "Page"
msgstr "Seite"
#: models.py:332
#: models.py:334
msgid "Pages"
msgstr "Seiten"
@@ -206,7 +206,7 @@ msgstr "Erstellt am"
msgid "share on"
msgstr "Teile auf"
#: templates/content/article_detail.html:48 views.py:159
#: templates/content/article_detail.html:48 views.py:160
msgid "Edit Article"
msgstr "Artikel bearbeiten"
@@ -251,16 +251,16 @@ msgstr "HTML spezifisch"
msgid "This Category does not exist."
msgstr "Diese Kategorie existiert nicht."
#: views.py:160
#: views.py:161
msgid "Create Article"
msgstr "Artikel erstellen"
#: views.py:240
#: views.py:241
#, python-format
msgid "No Page found matching the Path %s"
msgstr "Keine Seite unter dem Pfad %s gefunden"
#: views.py:269
#: views.py:270
#, python-format
msgid "No PDF Document found matching the Path %s"
msgstr "Kein PDF Dokument unter dem Pfad %s gefunden."

View File

@@ -2,7 +2,6 @@
from __future__ import unicode_literals
from django.db import migrations
from django.db import models
import ckeditor.fields

View File

@@ -7,7 +7,6 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('content', '0005_auto_20161012_2236'),
]
@@ -16,52 +15,68 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='article',
name='content_de',
field=ckeditor_uploader.fields.RichTextUploadingField(verbose_name='Inhalt'),
field=ckeditor_uploader.fields.RichTextUploadingField(
verbose_name='Inhalt'),
),
migrations.AlterField(
model_name='article',
name='content_en',
field=ckeditor_uploader.fields.RichTextUploadingField(blank=True, verbose_name='Content'),
field=ckeditor_uploader.fields.RichTextUploadingField(
blank=True, verbose_name='Content'),
),
migrations.AlterField(
model_name='article',
name='headline_en',
field=models.CharField(blank=True, max_length=255, verbose_name='Headline'),
field=models.CharField(
blank=True, max_length=255, verbose_name='Headline'),
),
migrations.AlterField(
model_name='article',
name='image',
field=models.ImageField(blank=True, null=True, upload_to='news/', verbose_name='Bild'),
field=models.ImageField(blank=True, null=True, upload_to='news/',
verbose_name='Bild'),
),
migrations.AlterField(
model_name='article',
name='slug',
field=models.SlugField(unique_for_month='date_created', verbose_name='Slug'),
field=models.SlugField(unique_for_month='date_created',
verbose_name='Slug'),
),
migrations.AlterField(
model_name='category',
name='image',
field=models.ImageField(blank=True, null=True, upload_to='news/categories/', verbose_name='Bild'),
field=models.ImageField(blank=True, null=True,
upload_to='news/categories/',
verbose_name='Bild'),
),
migrations.AlterField(
model_name='page',
name='content_de',
field=ckeditor_uploader.fields.RichTextUploadingField(blank=True, verbose_name='Inhalt'),
field=ckeditor_uploader.fields.RichTextUploadingField(
blank=True,
verbose_name='Inhalt'),
),
migrations.AlterField(
model_name='page',
name='content_en',
field=ckeditor_uploader.fields.RichTextUploadingField(blank=True, verbose_name='Content'),
field=ckeditor_uploader.fields.RichTextUploadingField(
blank=True,
verbose_name='Content'),
),
migrations.AlterField(
model_name='page',
name='menu_name_de',
field=models.CharField(help_text='Ein kurzer Name für den Menüeintrag', max_length=255, verbose_name='Menü Name'),
field=models.CharField(
help_text='Ein kurzer Name für den Menüeintrag',
max_length=255, verbose_name='Menü Name'),
),
migrations.AlterField(
model_name='page',
name='menu_name_en',
field=models.CharField(blank=True, help_text='Ein kurzer Name für den Menüeintrag', max_length=255, verbose_name='Menu Name'),
field=models.CharField(
blank=True,
help_text='Ein kurzer Name für den Menüeintrag',
max_length=255, verbose_name='Menu Name'),
),
migrations.AlterField(
model_name='page',
@@ -76,16 +91,22 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='page',
name='template',
field=models.CharField(default='content/page.html', max_length=255, verbose_name='Vorlage'),
field=models.CharField(default='content/page.html', max_length=255,
verbose_name='Vorlage'),
),
migrations.AlterField(
model_name='page',
name='title_de',
field=models.CharField(help_text="The page title as you'd like it to be seen by the public", max_length=255, verbose_name='Titel'),
field=models.CharField(
help_text="The page title as you'd like it to be seen by the public",
max_length=255, verbose_name='Titel'),
),
migrations.AlterField(
model_name='page',
name='title_en',
field=models.CharField(blank=True, help_text="The page title as you'd like it to be seen by the public", max_length=255, verbose_name='Title'),
field=models.CharField(
blank=True,
help_text="The page title as you'd like it to be seen by the public",
max_length=255, verbose_name='Title'),
),
]

View File

@@ -8,7 +8,6 @@ import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('content', '0006_auto_20171115_0653'),
]
@@ -17,11 +16,15 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='article',
name='author',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL, verbose_name='Autor'),
field=models.ForeignKey(
on_delete=django.db.models.deletion.PROTECT,
to=settings.AUTH_USER_MODEL, verbose_name='Autor'),
),
migrations.AlterField(
model_name='article',
name='category',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='content.Category', verbose_name='Kategorie'),
field=models.ForeignKey(
on_delete=django.db.models.deletion.PROTECT,
to='content.Category', verbose_name='Kategorie'),
),
]

View File

@@ -4,7 +4,6 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('content', '0007_auto_20171214_1215'),
]
@@ -13,46 +12,63 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='article',
name='status',
field=models.SmallIntegerField(choices=[(-1, 'Rejected'), (0, 'Waiting...'), (1, 'Published')], default=1, verbose_name='Status'),
field=models.SmallIntegerField(
choices=[(-1, 'Rejected'), (0, 'Waiting...'), (1, 'Published')],
default=1, verbose_name='Status'),
),
migrations.AlterField(
model_name='page',
name='date_created',
field=models.DateTimeField(auto_now_add=True, db_index=True, verbose_name='erstellt am'),
field=models.DateTimeField(
auto_now_add=True, db_index=True,
verbose_name='erstellt am'),
),
migrations.AlterField(
model_name='page',
name='date_modified',
field=models.DateTimeField(auto_now=True, verbose_name='letzte Aktualisierung am'),
field=models.DateTimeField(auto_now=True,
verbose_name='letzte Aktualisierung am'),
),
migrations.AlterField(
model_name='page',
name='description_de',
field=models.TextField(blank=True, verbose_name='Beschreibung für Suchfunktion'),
field=models.TextField(blank=True,
verbose_name='Beschreibung für Suchfunktion'),
),
migrations.AlterField(
model_name='page',
name='description_en',
field=models.TextField(blank=True, verbose_name='Beschreibung für Suchfunktion'),
field=models.TextField(blank=True,
verbose_name='Beschreibung für Suchfunktion'),
),
migrations.AlterField(
model_name='page',
name='slug',
field=models.SlugField(help_text='Wie die Seite in der URL aufscheint also http://domain.com/blog/[slug]', max_length=100, verbose_name='Slug'),
field=models.SlugField(
help_text='Wie die Seite in der URL aufscheint also ' +
'http://domain.com/blog/[slug]',
max_length=100, verbose_name='Slug'),
),
migrations.AlterField(
model_name='page',
name='status',
field=models.SmallIntegerField(choices=[(-1, 'Rejected'), (0, 'Waiting...'), (1, 'Published')], default=0, verbose_name='Status'),
field=models.SmallIntegerField(
choices=[(-1, 'Rejected'), (0, 'Waiting...'), (1, 'Published')],
default=0, verbose_name='Status'),
),
migrations.AlterField(
model_name='page',
name='title_de',
field=models.CharField(help_text='Der Seitentitel der öffentlich angezeigt werden soll', max_length=255, verbose_name='Titel'),
field=models.CharField(
help_text='Der Seitentitel der öffentlich angezeigt werden soll',
max_length=255, verbose_name='Titel'),
),
migrations.AlterField(
model_name='page',
name='title_en',
field=models.CharField(blank=True, help_text='Der Seitentitel der öffentlich angezeigt werden soll', max_length=255, verbose_name='Title'),
field=models.CharField(
blank=True,
help_text='Der Seitentitel der öffentlich angezeigt werden soll',
max_length=255, verbose_name='Title'),
),
]

View File

@@ -5,7 +5,6 @@ import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('content', '0009_alter_page_id'),
]
@@ -14,6 +13,8 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='page',
name='parent',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='subpages', to='content.page'),
field=models.ForeignKey(
blank=True, null=True, on_delete=django.db.models.deletion.CASCADE,
related_name='subpages', to='content.page'),
),
]

View File

@@ -4,7 +4,6 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('content', '0010_alter_page_parent'),
]
@@ -13,6 +12,8 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='page',
name='id',
field=models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
field=models.AutoField(
auto_created=True, primary_key=True, serialize=False,
verbose_name='ID'),
),
]

View File

@@ -5,18 +5,21 @@ Created on 03.10.2011
@author: christian
"""
from django.urls import path
from .views import ArticleArchiveIndex, ArticleForm, ArticleYearArchive, \
ArticleMonthArchive, ArticleDetail
from . import views
urlpatterns = [
path("", ArticleArchiveIndex.as_view(), name='article-archive'),
path('add/', ArticleForm.as_view(), name='add-article'),
path('edit/<int:pk>/', ArticleForm.as_view(), name='edit-article'),
path('<int:year>/', ArticleYearArchive.as_view(), name='article-archive'),
path('<int:year>/<int:month>/', ArticleMonthArchive.as_view(), name='article-archive'),
path('<int:year>/<int:month>/<slug:slug>/', ArticleDetail.as_view(), name='show-article'),
path('<slug:category>/', ArticleArchiveIndex.as_view(), name='article-archive'),
path('<slug:category>/<int:year>/', ArticleYearArchive.as_view(), name='article-archive'),
path('<slug:category>/<int:year>/<int:month>/', ArticleMonthArchive.as_view(), name='article-archive'),
path("", views.ArticleArchiveIndex.as_view(), name='article-archive'),
path('add/', views.ArticleForm.as_view(), name='add-article'),
path('edit/<int:pk>/', views.ArticleForm.as_view(), name='edit-article'),
path('<int:year>/', views.ArticleYearArchive.as_view(), name='article-archive'),
path('<int:year>/<int:month>/', views.ArticleMonthArchive.as_view(),
name='article-archive'),
path('<int:year>/<int:month>/<slug:slug>/', views.ArticleDetail.as_view(),
name='show-article'),
path('<slug:category>/', views.ArticleArchiveIndex.as_view(),
name='article-archive'),
path('<slug:category>/<int:year>/', views.ArticleYearArchive.as_view(),
name='article-archive'),
path('<slug:category>/<int:year>/<int:month>/', views.ArticleMonthArchive.as_view(),
name='article-archive'),
]

View File

@@ -10,7 +10,7 @@ def events_overview(request: HttpRequest) -> dict[str, Event]:
For speed reasons everything will be cached for an hour. the following
variables will be added to the template context:
* current_event: If an event is running at this moment, the corresponding event object.
* current_event: object for the currently running event.
* next_event: the next event that is upcoming.
* upcoming_events: the next 3 events that are upcoming.

View File

@@ -4,9 +4,14 @@ from . import views
urlpatterns = [
path("", views.EventGallery.as_view(), name='event-gallery'),
path('<int:event>/', views.EventPhotoList.as_view(), name='event-photo-list'),
path('<int:event>/upload/', views.EventPhotoUpload.as_view(), name='event-photo-upload'),
path('<int:event>/<int:pk>/', views.EventPhoto.as_view(), name='event-photo'),
path('delete/<int:pk>/', views.DeleteEventPhoto.as_view(), name='delete-event-photo'),
path('upload/', views.EventPhotoUpload.as_view(), name='event-photo-upload'),
path('<int:event>/', views.EventPhotoList.as_view(),
name='event-photo-list'),
path('<int:event>/upload/', views.EventPhotoUpload.as_view(),
name='event-photo-upload'),
path('<int:event>/<int:pk>/', views.EventPhoto.as_view(),
name='event-photo'),
path('delete/<int:pk>/', views.DeleteEventPhoto.as_view(),
name='delete-event-photo'),
path('upload/', views.EventPhotoUpload.as_view(),
name='event-photo-upload'),
]

View File

@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: kasu.events\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-07-26 18:31+0200\n"
"POT-Creation-Date: 2023-08-07 20:38+0200\n"
"PO-Revision-Date: 2018-01-12 15:25+0105\n"
"Last-Translator: b'Christian Berg <kasu@xendynastie.at>'\n"
"Language-Team: Kasu <verein@kasu.at>\n"
@@ -19,7 +19,7 @@ msgstr ""
"X-Generator: Poedit 1.8.9\n"
"X-Translated-Using: django-rosetta 0.7.14\n"
#: admin.py:14 models.py:82
#: admin.py:14 models.py:83
msgid "Event Series"
msgstr "Veranstaltungsreihen"
@@ -35,43 +35,42 @@ msgstr "Beginn"
msgid "end"
msgstr "Ende"
#: mixins.py:87
#: mixins.py:86
msgid "Event does not exist"
msgstr "Veranstaltung gibt es nicht"
#: models.py:52 models.py:176 models.py:217
#: models.py:53 models.py:177 models.py:218
msgid "Name"
msgstr "Name"
#: models.py:53 models.py:177 models.py:225
#: models.py:54 models.py:178 models.py:226
msgid "Description"
msgstr "Beschreibung"
#: models.py:55 templates/events/event_detail.html:29
#: models.py:56 templates/events/event_detail.html:29
#: templates/events/event_detail.html:87 templates/events/event_list.html:28
#: templates/events/photo_upload.html:13
msgid "Start"
msgstr "Beginn"
#: models.py:56 templates/events/event_detail.html:30
#: models.py:57 templates/events/event_detail.html:30
#: templates/events/event_detail.html:89
msgid "End"
msgstr "Ende"
#: models.py:57 models.py:185 templates/events/event_detail.html:34
#: models.py:58 models.py:186 templates/events/event_detail.html:34
#: templates/events/event_detail.html:80 templates/events/event_detail.html:92
msgid "Homepage"
msgstr "Homepage"
#: models.py:59 models.py:179 models.py:219
#: models.py:60 models.py:180 models.py:220
msgid "Image"
msgstr "Bild"
#: models.py:66
#: models.py:67
msgid "Mahjong Tournament"
msgstr "Mahjong Turnier"
#: models.py:68
#: models.py:69
msgid ""
"This event is a tournament, different rules apply for the kyu "
"ranking."
@@ -79,11 +78,11 @@ msgstr ""
"Diese Veranstaltung ist ein Turnier, es gelten andere Regeln für das Kyu "
"Ranking."
#: models.py:72
#: models.py:73
msgid "Mahjong Season"
msgstr "Mahjong Saison"
#: models.py:83
#: models.py:84
msgid ""
"Wenn dieser Event zu einer Veranstaltungsreihe gehört werden Ort, "
"Beschreibung, Bild und Homepage von dem hier angegebenen Event "
@@ -92,72 +91,72 @@ msgstr ""
"Wenn dieser Termin zu einer Veranstaltungsreihe gehört werden Ort, "
"Beschreibung, Bild und Homepage von dem hier angegebenen Event übernommen."
#: models.py:92 models.py:195 models.py:248
#: models.py:93 models.py:196 models.py:249
msgid "first created at"
msgstr "erstellt am"
#: models.py:97 models.py:200 models.py:253
#: models.py:98 models.py:201 models.py:254
msgid "latest updated at"
msgstr "letzte Aktualisierung am"
#: models.py:103
#: models.py:104
msgid "Event"
msgstr "Termin"
#: models.py:104
#: models.py:105
msgid "Events"
msgstr "Termine"
#: models.py:117
#: models.py:118
msgid "A event can't end before it had started"
msgstr "Eine Veranstaltung kann nicht enden bevor sie begonnen hat"
#: models.py:186
#: models.py:187
msgid "Postal Code"
msgstr "Postleitzahl"
#: models.py:187
#: models.py:188
msgid "Street Address"
msgstr "Straße"
#: models.py:188
#: models.py:189
msgid "Locality"
msgstr "Ort"
#: models.py:189
#: models.py:190
msgid "Country"
msgstr "Land"
#: models.py:204
#: models.py:205
msgid "Venue"
msgstr "Veranstaltungsort"
#: models.py:205
#: models.py:206
msgid "Venues"
msgstr "Veranstaltungsorte"
#: models.py:232
#: models.py:233
msgid "Startpage"
msgstr "Startseite"
#: models.py:235
#: models.py:236
msgid "Display this Photo on the Startpage Teaser"
msgstr "Foto als Teaser auf der Startseite verwenden."
#: models.py:237
#: models.py:238
msgid "Published on"
msgstr "Veröffentlicht am"
#: models.py:239
#: models.py:240
msgid "Number of views"
msgstr "Wie oft gesehen"
#: models.py:263 templates/events/event_archive.html:38
#: models.py:264 templates/events/event_archive.html:38
#: templates/events/event_list.html:18
msgid "Event Image"
msgstr "Veranstaltungsbild"
#: models.py:264
#: models.py:265
msgid "Event Images"
msgstr "Veranstaltungsbilder"
@@ -174,28 +173,25 @@ msgstr "Datum"
msgid "Time"
msgstr "Zeit"
#: templates/events/event_archive.html:49 templates/events/photo_upload.html:16
#: templates/events/event_archive.html:49
msgid "from"
msgstr "von"
#: templates/events/event_archive.html:49 templates/events/photo_upload.html:16
#: templates/events/event_archive.html:49
msgid "to"
msgstr "bis"
#: templates/events/event_archive.html:57 templates/events/event_detail.html:31
#: templates/events/event_detail.html:72 templates/events/event_list.html:32
#: templates/events/photo_upload.html:23
msgid "Location"
msgstr "Ort"
#: templates/events/event_archive.html:58 templates/events/event_list.html:35
#: templates/events/photo_upload.html:25 templates/events/photo_upload.html:26
msgid "Comments"
msgstr "Kommentare"
#: templates/events/event_archive.html:59 templates/events/event_detail.html:36
#: templates/events/event_detail.html:48 templates/events/photo_list.html:4
#: templates/events/photo_upload.html:28 templates/events/photo_upload.html:29
msgid "Photos"
msgstr "Fotos"
@@ -242,7 +238,7 @@ msgid "Show on Google Maps"
msgstr "Auf Google Maps zeigen"
#: templates/events/event_detail.html:127 templates/events/event_form.html:9
#: views.py:63
#: views.py:61
msgid "Edit Event"
msgstr "Termin bearbeiten"
@@ -250,7 +246,7 @@ msgstr "Termin bearbeiten"
msgid "Add Dates"
msgstr "Termine hinzufügen"
#: templates/events/event_form.html:9 templates/events/page.html:9 views.py:65
#: templates/events/event_form.html:9 templates/events/page.html:9 views.py:61
msgid "Add Event"
msgstr "Neuer Termin"
@@ -292,24 +288,23 @@ msgstr "Fotograf"
msgid "share on"
msgstr "Teile auf"
#: templates/events/photo_detail.html:81
#: templates/events/photo_detail.html:78
msgid "download"
msgstr "Herunterladen"
#: templates/events/photo_detail.html:82
#: templates/events/photo_detail.html:79
msgid "Rotate counter clockwise"
msgstr "mit dem Uhrzeiger drehen"
#: templates/events/photo_detail.html:83
#: templates/events/photo_detail.html:80
msgid "Rotate clockwise"
msgstr "gegen den Uhrzeiger drehen"
#: templates/events/photo_detail.html:84
#: templates/events/photo_detail.html:81
msgid "Save"
msgstr "Speichern"
#: templates/events/photo_list.html:36 templates/events/photo_upload.html:35
#: templates/events/photo_upload.html:49
#: templates/events/photo_list.html:36 templates/events/photo_upload.html:13
msgid "Upload"
msgstr "Hochladen"

View File

@@ -29,16 +29,21 @@ class Migration(migrations.Migration):
('image', models.ImageField(storage=utils.OverwriteStorage(
), upload_to=events.models.get_upload_path, null=True,
verbose_name='Bild', blank=True)),
('is_tournament', models.BooleanField(default=False,
help_text='Diese Veranstaltung ist ein Turnier, es gelten andere Regeln f\xfcr das Kyu Ranking.',
('is_tournament', models.BooleanField(
default=False,
help_text='Diese Veranstaltung ist ein Turnier, ' +
'es gelten andere Regeln f\xfcr das Kyu Ranking.',
verbose_name='Turnier')),
('photo_count', models.PositiveIntegerField(
default=0, editable=False)),
('event_series',
models.ForeignKey(on_delete=django.db.models.deletion.SET_NULL,
models.ForeignKey(
on_delete=django.db.models.deletion.SET_NULL,
editable=False, to='events.Event',
blank=True,
help_text='Wenn dieser Termin zu einer Veranstaltungsreihe geh\xf6rt werden Ort, Beschreibung, Bild und Homepage von dem hier angegebenen Event \xfcbernommen.',
help_text='Wenn dieser Termin zu einer Veranstaltungsreihe ' +
'geh\xf6rt werden Ort, Beschreibung, Bild und ' +
'Homepage von dem hier angegebenen Event \xfcbernommen.',
null=True,
verbose_name='Veranstaltungsreihen')),
],
@@ -67,21 +72,19 @@ class Migration(migrations.Migration):
max_length=127, verbose_name='Stra\xdfe')),
('locality',
models.CharField(max_length=127, verbose_name='Ort')),
('country', models.CharField(max_length=2, verbose_name='Land',
choices=[(b'GB',
'Vereinigtes K\xf6nigreich'),
('country', models.CharField(
max_length=2, verbose_name='Land',
choices=[(b'GB', 'Vereinigtes K\xf6nigreich'),
(b'AF', 'Afghanistan'),
(b'AX', 'Aland Islands'),
(b'AL', 'Albanien'),
(b'DZ', 'Algerien'), (
b'AS',
'Amerikanisch-Samoa'),
(b'DZ', 'Algerien'),
(b'AS', 'Amerikanisch-Samoa'),
(b'AD', 'Andorra'),
(b'AO', 'Angola'),
(b'AI', 'Anguilla'),
(b'AQ', 'Antarktika'), (
b'AG',
'Antigua und Barbuda'),
(b'AQ', 'Antarktika'),
(b'AG', 'Antigua und Barbuda'),
(b'AR', 'Argentinien'),
(b'AM', 'Armenien'),
(b'AW', 'Aruba'),
@@ -91,24 +94,20 @@ class Migration(migrations.Migration):
(b'BS', 'Bahamas'),
(b'BH', 'Bahrein'),
(b'BD', 'Bangladesch'),
(b'BB', 'Barbados'), (
b'BY',
'Wei\xdfrussland'),
(b'BB', 'Barbados'),
(b'BY', 'Wei\xdfrussland'),
(b'BE', 'Belgien'),
(b'BZ', 'Belize'),
(b'BJ', 'Benin'),
(b'BM', 'Bermuda'),
(b'BT', 'Bhutan'),
(b'BO', 'Bolivien'), (
b'BA',
'Bosnien und Herzegowina'),
(b'BO', 'Bolivien'),
(b'BA', 'Bosnien und Herzegowina'),
(b'BW', 'Botswana'),
(b'BV', 'Bouvet Island'),
(b'BR', 'Brasilien'), (
b'IO',
'British Indian Ocean Territory'),
(b'BN',
'Brunei Darussalam'),
(b'BR', 'Brasilien'),
(b'IO', 'British Indian Ocean Territory'),
(b'BN', 'Brunei Darussalam'),
(b'BG', 'Bulgarien'),
(b'BF', 'Burkina Faso'),
(b'BI', 'Burundi'),
@@ -117,51 +116,42 @@ class Migration(migrations.Migration):
(b'CA', 'Kanada'),
(b'CV', 'Cape Verde'),
(b'KY', 'Cayman Islands'),
(b'CF',
'Zentralafrikanische Republik'),
(b'CF', 'Zentralafrikanische Republik'),
(b'TD', 'Tschad'),
(b'CL', 'Chile'),
(b'CN', 'China'), (b'CX',
'Christmas Island'),
(b'CC',
'Cocos (Keeling) Islands'),
(b'CN', 'China'),
(b'CX', 'Christmas Island'),
(b'CC', 'Cocos (Keeling) Islands'),
(b'CO', 'Kolumbien'),
(b'KM', 'Komoren'),
(b'CG', 'Kongo'), (b'CD',
'Kongo, Demokratische Republik'),
(b'CG', 'Kongo'),
(b'CD', 'Kongo, Demokratische Republik'),
(b'CK', 'Cook-Inseln'),
(b'CR', 'Costa Rica'),
(b'CI', "Cote d'Ivoire"),
(b'HR', 'Kroatien'),
(b'CU', 'Kuba'),
(b'CY', 'Zypern'), (b'CZ',
'Tschechische Republik'),
(b'CY', 'Zypern'),
(b'CZ', 'Tschechische Republik'),
(b'DK', 'D\xe4nemark'),
(b'DJ', 'Dschibuti'),
(b'DM', 'Dominica'), (
b'DO',
'Dominikanische Republik'),
(b'DM', 'Dominica'),
(b'DO', 'Dominikanische Republik'),
(b'EC', 'Ecuador'),
(b'EG', '\xc4gypten'),
(b'SV', 'El Salvador'), (
b'GQ',
'\xc4quatorial-Guinea'),
(b'SV', 'El Salvador'),
(b'GQ', '\xc4quatorial-Guinea'),
(b'ER', 'Eritrea'),
(b'EE', 'Estland'),
(b'ET', '\xc4thiopien'), (
b'FK',
'Falklandinseln (Malvinas)'),
(b'FO',
'F\xe4r\xf6er-Inseln'),
(b'ET', '\xc4thiopien'),
(b'FK', 'Falklandinseln (Malvinas)'),
(b'FO', 'F\xe4r\xf6er-Inseln'),
(b'FJ', 'Fidschi'),
(b'FI', 'Finnland'),
(b'FR', 'Frankreich'), (
b'GF',
'Franz\xf6sisch-Guayana'),
(b'PF',
'Franz\xf6sisch-Polynesien'),
(b'TF',
'Franz\xf6sisch S\xfcdliche Territorien'),
(b'FR', 'Frankreich'),
(b'GF', 'Franz\xf6sisch-Guayana'),
(b'PF', 'Franz\xf6sisch-Polynesien'),
(b'TF', 'Franz\xf6sisch S\xfcdliche Territorien'),
(b'GA', 'Gabun'),
(b'GM', 'Gambia'),
(b'GE', 'Georgia'),
@@ -178,18 +168,16 @@ class Migration(migrations.Migration):
(b'GN', 'Guinea'),
(b'GW', 'Guinea-Bissau'),
(b'GY', 'Guyana'),
(b'HT', 'Haiti'), (b'HM',
'Heard und McDonald Inseln'),
(b'VA',
'Heiliger Stuhl (Vatikanstadt)'),
(b'HT', 'Haiti'),
(b'HM', 'Heard und McDonald Inseln'),
(b'VA', 'Heiliger Stuhl (Vatikanstadt)'),
(b'HN', 'Honduras'),
(b'HK', 'Hongkong'),
(b'HU', 'Ungarn'),
(b'IS', 'Island'),
(b'IN', 'Indien'),
(b'ID', 'Indonesien'), (
b'IR',
'Iran, Islamische Republik'),
(b'ID', 'Indonesien'),
(b'IR', 'Iran, Islamische Republik'),
(b'IQ', 'Irak'),
(b'IE', 'Irland'),
(b'IM', 'Isle of Man'),
@@ -201,39 +189,36 @@ class Migration(migrations.Migration):
(b'JO', 'Jordan'),
(b'KZ', 'Kasachstan'),
(b'KE', 'Kenia'),
(b'KI', 'Kiribati'), (
b'KP',
'Korea, Demokratische Volksrepublik'),
(
b'KR',
'Korea, Republik'),
(b'KI', 'Kiribati'),
(b'KP', 'Korea, Demokratische Volksrepublik'),
(b'KR', 'Korea, Republik'),
(b'KW', 'Kuwait'),
(b'KG', 'Kirgisistan'), (
b'LA',
'Lao Demokratischen Volksrepublik'),
(b'KG', 'Kirgisistan'),
(b'LA', 'Lao Demokratischen Volksrepublik'),
(b'LV', 'Lettland'),
(b'LB', 'Libanon'), (
b'LS', 'Lesotho'),
(b'LB', 'Libanon'),
(b'LS', 'Lesotho'),
(b'LR', 'Liberia'),
(b'LY', 'Libyen'),
(b'LI', 'Liechtenstein'),
(b'LT', 'Litauen'),
(b'LU', 'Luxemburg'),
(b'MO', 'Macao'), (b'MK',
(b'MO', 'Macao'),
(b'MK',
'Mazedonien, die ehemalige jugoslawische Republik'),
(b'MG', 'Madagaskar'),
(b'MW', 'Malawi'),
(b'MY', 'Malaysia'),
(b'MV', 'Malediven'),
(b'ML', 'Mali'),
(b'MT', 'Malta'), (b'MH',
'Marshall Islands'),
(b'MT', 'Malta'),
(b'MH', 'Marshall Islands'),
(b'MQ', 'Martinique'),
(b'MR', 'Mauretanien'),
(b'MU', 'Mauritius'),
(b'YT', 'Mayotte'),
(b'MX', 'Mexiko'), (b'FM',
'Mikronesien, F\xf6derierte Staaten von'),
(b'MX', 'Mexiko'),
(b'FM', 'Mikronesien, F\xf6derierte Staaten von'),
(b'MD', 'Moldawien'),
(b'MC', 'Monaco'),
(b'MN', 'Mongolei'),
@@ -245,9 +230,8 @@ class Migration(migrations.Migration):
(b'NA', 'Namibia'),
(b'NR', 'Nauru'),
(b'NP', 'Nepal'),
(b'NL', 'Niederlande'), (
b'AN',
'Niederl\xe4ndische Antillen'),
(b'NL', 'Niederlande'),
(b'AN', 'Niederl\xe4ndische Antillen'),
(b'NC', 'Neukaledonien'),
(b'NZ', 'New Zealand'),
(b'NI', 'Nicaragua'),
@@ -260,11 +244,10 @@ class Migration(migrations.Migration):
(b'NO', 'Norwegen'),
(b'OM', 'Oman'),
(b'PK', 'Pakistan'),
(b'PW', 'Palau'), (b'PS',
'Pal\xe4stinensische Autonomiegebiete'),
(b'PA', 'Panama'), (
b'PG',
'Papua-Neuguinea'),
(b'PW', 'Palau'),
(b'PS', 'Pal\xe4stinensische Autonomiegebiete'),
(b'PA', 'Panama'),
(b'PG', 'Papua-Neuguinea'),
(b'PY', 'Paraguay'),
(b'PE', 'Peru'),
(b'PH', 'Philippinen'),
@@ -272,26 +255,21 @@ class Migration(migrations.Migration):
(b'PL', 'Polen'),
(b'PT', 'Portugal'),
(b'PR', 'Puerto Rico'),
(b'QA', 'Katar'), (b'RE',
'Wiedervereinigung'),
(b'RO', 'Rum\xe4nien'), (
b'RU',
'Russischen F\xf6deration'),
(b'RW', 'Ruanda'), (b'BL',
'Saint Barthelemy'),
(b'SH', 'Saint Helena'), (
b'KN',
'Saint Kitts und Nevis'),
(b'QA', 'Katar'),
(b'RE', 'Wiedervereinigung'),
(b'RO', 'Rum\xe4nien'),
(b'RU', 'Russischen F\xf6deration'),
(b'RW', 'Ruanda'),
(b'BL', 'Saint Barthelemy'),
(b'SH', 'Saint Helena'),
(b'KN', 'Saint Kitts und Nevis'),
(b'LC', 'Santa Lucia'),
(b'MF', 'Santa Martin'), (
b'PM',
'Saint Pierre und Miquelon'),
(b'VC',
'Saint Vincent und die Grenadinen'),
(b'MF', 'Santa Martin'),
(b'PM', 'Saint Pierre und Miquelon'),
(b'VC', 'Saint Vincent und die Grenadinen'),
(b'WS', 'Samoa'),
(b'SM', 'San Marino'), (
b'ST',
'Sao Tome und Principe'),
(b'SM', 'San Marino'),
(b'ST', 'Sao Tome und Principe'),
(b'SA', 'Saudi-Arabien'),
(b'SN', 'Senegal'),
(b'RS', 'Serbien'),
@@ -302,56 +280,46 @@ class Migration(migrations.Migration):
(b'SI', 'Slowenien'),
(b'SB', 'Salomon-Inseln'),
(b'SO', 'Somalia'),
(b'ZA', 'S\xfcdafrika'), (
b'GS',
(b'ZA', 'S\xfcdafrika'),
(b'GS',
'S\xfcdgeorgien und die S\xfcdlichen Sandwichinseln'),
(b'ES', 'Spanien'),
(b'LK', 'Sri Lanka'),
(b'SD', 'Sudan'),
(b'SR', 'Suriname'), (
b'SJ',
'Svalbard und Jan Mayen'),
(b'SR', 'Suriname'),
(b'SJ', 'Svalbard und Jan Mayen'),
(b'SZ', 'Swaziland'),
(b'SE', 'Schweden'),
(b'CH', 'Schweiz'), (
b'SY',
'Arabische Republik Syrien'),
(b'CH', 'Schweiz'),
(b'SY', 'Arabische Republik Syrien'),
(b'TW',
'Taiwan, Province of China'),
(b'TJ', 'Tadschikistan'),
(b'TZ',
'Tansania, Vereinigte Republik'),
(b'TZ', 'Tansania, Vereinigte Republik'),
(b'TH', 'Thailand'),
(b'TL', 'Timor-Leste'),
(b'TG', 'Togo'),
(b'TK', 'Tokelau'),
(b'TO', 'Tonga'), (b'TT',
'Trinidad und Tobago'),
(b'TO', 'Tonga'),
(b'TT', 'Trinidad und Tobago'),
(b'TN', 'Tunesien'),
(b'TR', 'T\xfcrkei'),
(b'TM', 'Turkmenistan'), (
b'TC',
'Turks-und Caicosinseln'),
(b'TM', 'Turkmenistan'),
(b'TC', 'Turks-und Caicosinseln'),
(b'TV', 'Tuvalu'),
(b'UG', 'Uganda'),
(b'UA', 'Ukraine'), (
b'AE',
'Vereinigte Arabische Emirate'),
(b'US',
'Vereinigte Staaten'), (
b'UM',
'United States Minor Outlying Islands'),
(b'UA', 'Ukraine'),
(b'AE', 'Vereinigte Arabische Emirate'),
(b'US', 'Vereinigte Staaten'),
(b'UM', 'United States Minor Outlying Islands'),
(b'UY', 'Uruguay'),
(b'UZ', 'Usbekistan'),
(b'VU', 'Vanuatu'),
(b'VE', 'Venezuela'),
(b'VN', 'Vietnam'), (
b'VG',
'Virgin Islands, British'),
(b'VI',
'Virgin Islands, US'), (
b'WF',
'Wallis und Futuna'),
(b'VN', 'Vietnam'),
(b'VG', 'Virgin Islands, British'),
(b'VI', 'Virgin Islands, US'),
(b'WF', 'Wallis und Futuna'),
(b'EH', 'Westsahara'),
(b'YE', 'Jemen'),
(b'ZM', 'Sambia'),

View File

@@ -5,7 +5,6 @@ from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('events', '0001_initial'),
]
@@ -25,6 +24,9 @@ class Migration(migrations.Migration):
model_name='event',
name='mahjong_tournament',
field=models.BooleanField(
default=False, help_text='Diese Veranstaltung ist ein Turnier, es gelten andere Regeln f\xfcr das Kyu Ranking.', verbose_name='Mahjong Tournament'),
default=False,
help_text='Diese Veranstaltung ist ein Turnier, ' +
'es gelten andere Regeln f\xfcr das Kyu Ranking.',
verbose_name='Mahjong Tournament'),
),
]

View File

@@ -5,7 +5,6 @@ from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('events', '0002_auto_20150818_2139'),
]
@@ -15,6 +14,9 @@ class Migration(migrations.Migration):
model_name='event',
name='mahjong_tournament',
field=models.BooleanField(
default=False, help_text='Diese Veranstaltung ist ein Turnier, es gelten andere Regeln f\xfcr das Kyu Ranking.', verbose_name='Mahjong Turnier'),
default=False,
help_text='Diese Veranstaltung ist ein Turnier, ' +
'es gelten andere Regeln f\xfcr das Kyu Ranking.',
verbose_name='Mahjong Turnier'),
),
]

View File

@@ -32,12 +32,14 @@ class Migration(migrations.Migration):
('description', models.TextField(max_length=300,
verbose_name='Beschreibung',
blank=True)),
('on_startpage', models.BooleanField(default=False,
('on_startpage', models.BooleanField(
default=False,
help_text='Display this Photo on the Startpage Teaser',
verbose_name='Startpage')),
('created_date',
models.DateTimeField(verbose_name='Published on')),
('views', models.PositiveIntegerField(default=0,
('views', models.PositiveIntegerField(
default=0,
verbose_name='Number of views',
editable=False)),
],
@@ -67,7 +69,9 @@ class Migration(migrations.Migration):
field=models.ForeignKey(
on_delete=django.db.models.deletion.SET_NULL, blank=True,
to='events.Event',
help_text='Wenn dieser Termin zu einer Veranstaltungsreihe geh\xf6rt werden Ort, Beschreibung, Bild und Homepage von dem hier angegebenen Event \xfcbernommen.',
help_text='Wenn dieser Termin zu einer Veranstaltungsreihe geh\xf6rt ' +
'werden Ort, Beschreibung, Bild und Homepage von dem hier ' +
'angegebenen Event \xfcbernommen.',
null=True, verbose_name='Veranstaltungsreihen'),
),
migrations.AlterField(

View File

@@ -5,7 +5,6 @@ from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('events', '0004_auto_20150901_2204'),
]
@@ -15,6 +14,7 @@ class Migration(migrations.Migration):
model_name='photo',
name='on_startpage',
field=models.BooleanField(
default=False, help_text='Display this Photo on the Startpage Teaser', db_index=True, verbose_name='Startpage'),
default=False, help_text='Display this Photo on the Startpage Teaser',
db_index=True, verbose_name='Startpage'),
),
]

View File

@@ -5,7 +5,6 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('events', '0005_auto_20150907_2021'),
]
@@ -14,7 +13,8 @@ class Migration(migrations.Migration):
migrations.AlterModelOptions(
name='photo',
options={'ordering': ['created_date'], 'get_latest_by': 'created_date',
'verbose_name': 'Veranstaltungsbild', 'verbose_name_plural': 'Veranstaltungsbilder'},
'verbose_name': 'Veranstaltungsbild',
'verbose_name_plural': 'Veranstaltungsbilder'},
),
migrations.AlterField(
model_name='event',
@@ -31,7 +31,9 @@ class Migration(migrations.Migration):
model_name='photo',
name='on_startpage',
field=models.BooleanField(
default=False, help_text='Foto als Teaser auf der Startseite verwenden.', db_index=True, verbose_name='Startseite'),
default=False,
help_text='Foto als Teaser auf der Startseite verwenden.',
db_index=True, verbose_name='Startseite'),
),
migrations.AlterField(
model_name='photo',

View File

@@ -7,7 +7,6 @@ from datetime import timezone
class Migration(migrations.Migration):
dependencies = [
('events', '0006_auto_20160916_1800'),
]
@@ -17,39 +16,45 @@ class Migration(migrations.Migration):
model_name='event',
name='date_created',
field=models.DateTimeField(
auto_now_add=True, null=True, verbose_name='first created at', db_index=True),
auto_now_add=True, null=True, verbose_name='first created at',
db_index=True),
),
migrations.AddField(
model_name='event',
name='date_modified',
field=models.DateTimeField(default=datetime.datetime(
2016, 10, 12, 20, 24, 39, 910492, tzinfo=timezone.utc), verbose_name='latest updated at', auto_now=True),
2016, 10, 12, 20, 24, 39, 910492, tzinfo=timezone.utc),
verbose_name='latest updated at', auto_now=True),
preserve_default=False,
),
migrations.AddField(
model_name='location',
name='date_created',
field=models.DateTimeField(
auto_now_add=True, null=True, verbose_name='first created at', db_index=True),
auto_now_add=True, null=True, verbose_name='first created at',
db_index=True),
),
migrations.AddField(
model_name='location',
name='date_modified',
field=models.DateTimeField(default=datetime.datetime(
2016, 10, 12, 20, 24, 44, 566305, tzinfo=timezone.utc), verbose_name='latest updated at', auto_now=True),
2016, 10, 12, 20, 24, 44, 566305, tzinfo=timezone.utc),
verbose_name='latest updated at', auto_now=True),
preserve_default=False,
),
migrations.AddField(
model_name='photo',
name='date_created',
field=models.DateTimeField(
auto_now_add=True, null=True, verbose_name='first created at', db_index=True),
auto_now_add=True, null=True, verbose_name='first created at',
db_index=True),
),
migrations.AddField(
model_name='photo',
name='date_modified',
field=models.DateTimeField(default=datetime.datetime(
2016, 10, 12, 20, 24, 50, 509970, tzinfo=timezone.utc), verbose_name='latest updated at', auto_now=True),
2016, 10, 12, 20, 24, 50, 509970, tzinfo=timezone.utc),
verbose_name='latest updated at', auto_now=True),
preserve_default=False,
),
]

File diff suppressed because one or more lines are too long

View File

@@ -8,7 +8,6 @@ import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('events', '0008_auto_20171115_0653'),
]
@@ -17,16 +16,19 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='event',
name='location',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='events.Location'),
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT,
to='events.Location'),
),
migrations.AlterField(
model_name='photo',
name='event',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='events.Event'),
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT,
to='events.Event'),
),
migrations.AlterField(
model_name='photo',
name='photographer',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL),
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT,
to=settings.AUTH_USER_MODEL),
),
]

File diff suppressed because one or more lines are too long

View File

@@ -33,7 +33,8 @@ class EventDetailMixin(object):
event = None
def get_context_data(self, **kwargs):
"""Add this event or the related event of the given object to the template context.
"""Adds this or the related event of the given object to the
template context.
:return: TemplateContext object"""
context = super(EventDetailMixin, self).get_context_data(**kwargs)

View File

@@ -109,7 +109,7 @@ class Event(models.Model):
try:
return "%(name)s (%(date)s)" % {'name': self.name,
'date': self.start.date()}
except:
except AttributeError:
return "New Event Model"
def clean(self):
@@ -165,7 +165,7 @@ class Event(models.Model):
self.location = master_event.location
self.url = master_event.url
self.image = self.image or master_event.image
self.photo_count = self.photo_set.count() if self.pk else 0
self.photo_count = self.photo_set.count()
super(Event, self).save(**kwargs)
# Update the Hanchans if necessary:

View File

@@ -1,5 +1,4 @@
from kasu.sitemaps import GenericSitemap
from django.utils import timezone
from .models import Event

View File

@@ -6,10 +6,15 @@ from . import views
urlpatterns = [
path("", RedirectView.as_view(url='/events/upcoming/', permanent=True)),
path('<int:year>/', views.EventArchiveYear.as_view(), name='event-archive'),
path('<int:year>/<int:month>/', views.EventArchiveMonth.as_view(), name='event-archive'),
path('<int:year>/<int:month>/<int:pk>/', views.EventDetail.as_view(), name='event-detail'),
path('<int:year>/<int:month>/<int:pk>/add_dates/', views.EventSeriesForm.as_view(), name='event-series-form'),
path('<int:year>/<int:month>/<int:pk>/edit/', views.EventForm.as_view(), name='event-form'),
path('<int:year>/<int:month>/', views.EventArchiveMonth.as_view(),
name='event-archive'),
path('<int:year>/<int:month>/<int:pk>/', views.EventDetail.as_view(),
name='event-detail'),
path('<int:year>/<int:month>/<int:pk>/add_dates/',
views.EventSeriesForm.as_view(),
name='event-series-form'),
path('<int:year>/<int:month>/<int:pk>/edit/', views.EventForm.as_view(),
name='event-form'),
path('add/', views.EventForm.as_view(), name='event-form'),
path('archive/', views.EventArchiveIndex.as_view(), name='event-archive'),
path('upcoming/', views.UpcomingEvents.as_view(), name='upcoming-events'),

View File

@@ -4,8 +4,6 @@ from datetime import timedelta
from django.contrib.auth import get_user_model
from django.contrib.auth.mixins import PermissionRequiredMixin
from django.urls import reverse
from django.db.models import Q
from django.http import Http404
from django.http import HttpResponse
from django.shortcuts import redirect, get_object_or_404
from django.utils import timezone
@@ -56,7 +54,8 @@ class EventForm(PermissionRequiredMixin, mixins.EventDetailMixin,
permission_required = 'events.add_event'
def get_context_data(self, **kwargs):
"""set the title to add or edit Event, depending on the fact if an event ID was given."""
"""sets the title to add or edit Event,
depending on the fact if an event ID was given."""
context = super(EventForm, self).get_context_data(**kwargs)
context['title'] = _("Edit Event") if self.kwargs.get('pk') else _("Add Event")
return context

View File

@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: kasu.utils\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-07-26 18:31+0200\n"
"POT-Creation-Date: 2023-08-07 20:38+0200\n"
"PO-Revision-Date: 2018-12-30 11:14+0105\n"
"Last-Translator: b' <kasu@xendynastie.at>'\n"
"Language-Team: Kasu <verein@kasu.at>\n"
@@ -79,7 +79,7 @@ msgstr "Bevorstehende Veranstaltungen"
msgid "No events found"
msgstr "Keine Veranstaltungen gefunden"
#: templates/base.html:149
#: templates/base.html:150
msgid "Add Subpage"
msgstr "Unterseite Hinzufügen"
@@ -87,43 +87,43 @@ msgstr "Unterseite Hinzufügen"
msgid "Edit Page"
msgstr "Seite bearbeiten"
#: templates/base.html:162
#: templates/base.html:163
msgid "Imprint"
msgstr "Impressum"
#: templates/base.html:163
#: templates/base.html:164
msgid "contact"
msgstr "Kontakt"
#: templates/base.html:168
#: templates/base.html:169
msgid "Language"
msgstr "Sprache"
#: templates/base.html:177
#: templates/base.html:178
msgid "Go"
msgstr "Los"
#: templates/base.html:182
#: templates/base.html:183
msgid "Logged in as"
msgstr "Angemeldet als"
#: templates/base.html:184
#: templates/base.html:185
msgid "Admin"
msgstr "Admin"
#: templates/base.html:185
#: templates/base.html:186
msgid "Logout"
msgstr "Abmelden"
#: templates/base.html:187
#: templates/base.html:188
msgid "no user logged in"
msgstr "Niemand angemeldet"
#: templates/base.html:188 templates/comments/form.html:43
#: templates/base.html:189 templates/comments/form.html:43
msgid "register"
msgstr "Registrieren"
#: templates/base.html:189 templates/comments/form.html:44
#: templates/base.html:190 templates/comments/form.html:44
msgid "login"
msgstr "anmelden"
@@ -215,11 +215,11 @@ msgstr "Besuche uns auf"
msgid "Add Article"
msgstr "Artikel hinzufügen"
#: templates/paginator.html:7
#: templates/paginator.html:5 templates/paginator.html:7
msgid "Previous"
msgstr "Vorherige"
#: templates/paginator.html:18
#: templates/paginator.html:17 templates/paginator.html:20
msgid "Next"
msgstr "Nächste"

View File

@@ -191,7 +191,8 @@ LOGGING = {
},
'formatters': {
'verbose': {
'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s'
'format': '%(levelname)s %(asctime)s %(module)s %(process)d ' +
'%(thread)d %(message)s'
},
'simple': {
'format': '%(levelname)s %(message)s'
@@ -275,7 +276,7 @@ KYU_RANKS = (
)
try:
from .local_settings import * # Ignore PyLintBear (W0401, W0614)
from .local_settings import * # noqa: F403
except ImportError:
pass

View File

@@ -10,18 +10,19 @@ from content import views, feeds
from content.sitemaps import ArticleSitemap, PageSitemap
from events.sitemaps import EventSitemap
from events.views import EventListIcal
from mahjong_ranking.sitemaps import *
from maistar_ranking.sitemaps import *
import mahjong_ranking.sitemaps
import maistar_ranking.sitemaps
from membership.views import MembershipDetail
admin.autodiscover()
# register_converter('path')
sitemaps = {
'event_rankings': EventRankingSitemap,
'event_hanchans': EventHanchanSitemap,
'mahjong_seasons': MahjongSeasonSitemap,
'maistar_games': MaistarGamesSitemap,
'event_rankings': mahjong_ranking.sitemaps.EventRankingSitemap,
'event_hanchans': mahjong_ranking.sitemaps.EventHanchanSitemap,
'mahjong_seasons': mahjong_ranking.sitemaps.MahjongSeasonSitemap,
'maistar_games': maistar_ranking.sitemaps.MaistarGamesSitemap,
'articles': ArticleSitemap,
'events': EventSitemap,
'pages': PageSitemap,
@@ -40,21 +41,24 @@ urlpatterns = [ # Ignore PyLintBear (C0103)
path('feeds/latest/', feeds.LatestNews(), name='feed-latest-news'),
path('feeds/comments/', feeds.LatestComments(), name='feed-latest-comments'),
path('gallery/', include('events.gallery_urls')),
path('google25dabc1a49a9ef03.html', TemplateView.as_view(template_name='google25dabc1a49a9ef03.html')),
path('google25dabc1a49a9ef03.html',
TemplateView.as_view(template_name='google25dabc1a49a9ef03.html')),
path('i18n/', include('django.conf.urls.i18n'), name='start-page'),
path('manifest.json', TemplateView.as_view(template_name='manifest.json')),
path('membership/', include('membership.urls')),
path('news/', include('content.news_urls')),
path('ranking/', include('mahjong_ranking.urls')),
path('ranking/', include('maistar_ranking.urls')),
path('sitemap.xml', sitemap, {'sitemaps': sitemaps}, name='django.contrib.sitemaps.views.sitemap'),
path('robots.txt', TemplateView.as_view(template_name='robots.txt')),
path('users/', MembershipDetail.as_view(), name='membership-details'),
path('users/<slug:username>/', MembershipDetail.as_view(), name='membership-details'),
path('users/<slug:username>/',
MembershipDetail.as_view(), name='membership-details'),
path('add_page/<path:path>', views.PageAddForm.as_view(), name='add-page'),
path('edit_page/<path:path>', views.PageEditForm.as_view(), name='edit-page'),
path('<path:path>.html', views.PageHtml.as_view(), name='view-page'),
path('<path:path>.pdf', views.PagePdf.as_view()),
path('sitemap.xml', sitemap, {'sitemaps': sitemaps},
name='django.contrib.sitemaps.views.sitemap'),
]
if settings.DEBUG:

View File

@@ -1,7 +1,7 @@
""" Script to start Django as an WSGI Application.
src_path and virtpy_path are host dependet variables.
TODO: Check if this file is really needet and make it host independet
TODO: Check if this file is really needed and make it independent from host
"""
import os
import sys
@@ -14,7 +14,7 @@ if VENV_PATH not in sys.path:
if SOURCE_PATH not in sys.path:
sys.path.append(SOURCE_PATH)
from django.core.wsgi import get_wsgi_application
from django.core.wsgi import get_wsgi_application # noqa: E402
os.environ['DJANGO_SETTINGS_MODULE'] = 'kasu.settings'

View File

@@ -62,7 +62,7 @@ def getattr_recursive(obj, attr_string):
:param obj: a python object.
:param attr_string: the desired attribute of the object.
:return: a getattr_recursice(obj, 'attr1.attr2') will return the value of attr2 of attr1 from obj
:return: return the value from attr2 of attr1 from obj
"""
attr_list = attr_string.split('.')
return_value = None

View File

@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: kasu.mahjong_ranking\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-07-27 00:05+0200\n"
"POT-Creation-Date: 2023-08-07 20:38+0200\n"
"PO-Revision-Date: 2018-05-08 00:20+0105\n"
"Last-Translator: b'Christian Berg <kasu@xendynastie.at>'\n"
"Language-Team: Kasu <verein@kasu.at>\n"
@@ -28,8 +28,8 @@ msgid "Confirm"
msgstr "Bestätigen"
#: admin.py:46
msgid "Set unconfirmed"
msgstr "Als unbestätigt markieren"
msgid "Reject"
msgstr ""
#: forms.py:22
msgid "start"
@@ -89,7 +89,7 @@ msgstr "Wurde bestätigt"
msgid "Only valid and confirmed Hanchans will be counted in the rating."
msgstr "Nur gültige und bestätigte Hanchans kommen in die Wertung."
#: models.py:181 models.py:620 templates/mahjong_ranking/ladder_redbox.html:29
#: models.py:181 models.py:619 templates/mahjong_ranking/ladder_redbox.html:29
#: templates/mahjong_ranking/player_ladder_score.html:63
msgid "Season"
msgstr "Saison"
@@ -127,11 +127,11 @@ msgstr "Spielstand ist weniger als 100.000 Punkte"
msgid "Gamescore is over 100.000 Pt."
msgstr "Spielstand ist über 100.000 Punkte."
#: models.py:368
#: models.py:367
msgid "Kyū/Dan Ranking"
msgstr "Kyū/Dan Wertung"
#: models.py:369
#: models.py:368
msgid "Kyū/Dan Rankings"
msgstr "Kyū/Dan Wertungen"
@@ -386,10 +386,13 @@ msgstr "%s wurde erfolgreich aktualisiert."
msgid "%s has been added successfully. You can now add a new one."
msgstr "%s wurde erfolgreich hinzugefügt. Du kannst eine neue eintragen."
#: views.py:218
#: views.py:222
msgid "No user found matching the name {}"
msgstr "Kein Benutzer mit dem Namen %s gefunden"
#~ msgid "Set unconfirmed"
#~ msgstr "Als unbestätigt markieren"
#~ msgid "Full Name"
#~ msgstr "Voller Name"

View File

@@ -1,5 +1,6 @@
"""
Recalculates all Kyu/Dan Rankings until the given date a writes them to the legacy fields.
Recalculates all Kyu/Dan Rankings until the given date
and writes them to the legacy fields.
"""
from django.core.management.base import BaseCommand
@@ -21,11 +22,11 @@ LEGACY_ATTRIBUTES = (
class Command(BaseCommand):
""" Recalculates all Kyu/Dan Rankings until the given date a writes them to the legacy fields. """
help = "Recalculates all Kyu/Dan Rankings until the given date " + \
"and writes them to the legacy fields."
help = "Recalculates all Kyu/Dan Rankings until the given date a writes them to the legacy fields."
def add_arguments(self, parser):
def add_arguments(self, parser):
parser.add_argument('-s', '--since', nargs='?', type=parse_date,
metavar='YYYY-MM-DD',
help='Use all Hanchans since the given date.')
@@ -33,7 +34,8 @@ class Command(BaseCommand):
metavar='YYYY-MM-DD',
help='Only use Hanchans until the given date.')
def handle(self, *args, **options):
def handle(self, *args, **options):
since = options.get('since', None)
until = options.get('until', None)
if isinstance(since, date):

View File

@@ -74,7 +74,8 @@ class HanchanManager(models.Manager):
[hanchan.get_playerdata(user) for hanchan in queryset]
return queryset
def season_hanchans(self, user: object = None, season: int = None, until: date = None):
def season_hanchans(self, user: object = None,
season: int = None, until: date = None):
"""Return all Hanchans that belong to a given or the current season.
:param user: Only return Hanchans where this user participated.
@@ -248,7 +249,8 @@ class KyuDanRankingManager(models.Manager):
for attr, old_value in old_attr.items():
if getattr(ranking, attr) != old_value:
LOGGER.warning(
"%(user)s recalc shows differences in %(attr)s! old: %(old)d, new: %(new)d",
"%(user)s recalc shows differences in %(attr)s! ' + "
"'old: %(old)d, new: %(new)d",
{'user': ranking.user, 'attr': attr,
'old': old_value or 0, 'new': getattr(ranking, attr) or 0}
'old': old_value or 0, 'new': getattr(ranking, attr, 0)}
)

View File

@@ -3,7 +3,6 @@ from django.core.cache import cache
from mahjong_ranking import models
from . import LOGGER
from . import LOGGER
class DenormalizationUpdateMiddleware:

View File

@@ -41,7 +41,8 @@ class Migration(migrations.Migration):
serialize=False, auto_created=True,
primary_key=True)),
('start', models.DateTimeField(
help_text='Wichtig damit die richtigen Hanchans in die Wertung kommen.',
help_text="Wichtig damit die richtigen Hanchans in die " + \
"Wertung kommen.",
verbose_name='Beginn')),
('player1_input_score',
models.IntegerField(verbose_name='Punkte')),
@@ -55,14 +56,14 @@ class Migration(migrations.Migration):
null=True, editable=False, blank=True)),
('player1_bonus_points', models.SmallIntegerField(
null=True, editable=False, blank=True)),
('player1_comment', models.CharField(verbose_name='Anmerkung',
('player1_comment', models.CharField(verbose_name="Anmerkung",
max_length=255,
editable=False,
blank=True)),
('player2_input_score',
models.IntegerField(verbose_name='Punkte')),
models.IntegerField(verbose_name="Punkte")),
('player2_game_score', models.PositiveIntegerField(
default=0, verbose_name='Punkte', editable=False)),
default=0, verbose_name="Punkte", editable=False)),
('player2_placement', models.PositiveSmallIntegerField(
default=0, editable=False)),
('player2_kyu_points', models.SmallIntegerField(
@@ -111,7 +112,8 @@ class Migration(migrations.Migration):
models.TextField(verbose_name='Anmerkung', blank=True)),
('confirmed', models.BooleanField(
default=True,
help_text='Nur g\xfcltige und best\xe4tigte Hanchans kommen in die Wertung.',
help_text="Nur g\xfcltige und best\xe4tigte Hanchans kommen " + \
"in die Wertung.",
verbose_name='Wurde best\xe4tigt')),
('player_names',
models.CharField(max_length=255, editable=False)),

View File

@@ -6,7 +6,6 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('mahjong_ranking', '0004_auto_20170218_1947'),
]
@@ -14,7 +13,9 @@ class Migration(migrations.Migration):
operations = [
migrations.AlterModelOptions(
name='kyudanranking',
options={'ordering': ('-dan_points', 'dan', '-kyu_points'), 'verbose_name': 'Kyū/Dan Wertung', 'verbose_name_plural': 'Kyū/Dan Wertungen'},
options={'ordering': ('-dan_points', 'dan', '-kyu_points'),
'verbose_name': 'Kyū/Dan Wertung',
'verbose_name_plural': 'Kyū/Dan Wertungen'},
),
migrations.AddField(
model_name='kyudanranking',

View File

@@ -8,7 +8,6 @@ import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('mahjong_ranking', '0005_auto_20171115_0653'),
]
@@ -42,27 +41,40 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='eventranking',
name='user',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL),
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT,
to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='hanchan',
name='player1',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='user_hanchan+', to=settings.AUTH_USER_MODEL, verbose_name='Spieler 1'),
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT,
related_name='user_hanchan+',
to=settings.AUTH_USER_MODEL,
verbose_name='Spieler 1'),
),
migrations.AlterField(
model_name='hanchan',
name='player2',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='user_hanchan+', to=settings.AUTH_USER_MODEL, verbose_name='Spieler 2'),
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT,
related_name='user_hanchan+',
to=settings.AUTH_USER_MODEL,
verbose_name='Spieler 2'),
),
migrations.AlterField(
model_name='hanchan',
name='player3',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='user_hanchan+', to=settings.AUTH_USER_MODEL, verbose_name='Spieler 3'),
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT,
related_name='user_hanchan+',
to=settings.AUTH_USER_MODEL,
verbose_name='Spieler 3'),
),
migrations.AlterField(
model_name='hanchan',
name='player4',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='user_hanchan+', to=settings.AUTH_USER_MODEL, verbose_name='Spieler 4'),
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT,
related_name='user_hanchan+',
to=settings.AUTH_USER_MODEL,
verbose_name='Spieler 4'),
),
migrations.AlterField(
model_name='kyudanranking',
@@ -82,6 +94,7 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='seasonranking',
name='user',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL),
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT,
to=settings.AUTH_USER_MODEL),
),
]

View File

@@ -4,7 +4,6 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('mahjong_ranking', '0006_auto_20171214_1318'),
]
@@ -12,7 +11,11 @@ class Migration(migrations.Migration):
operations = [
migrations.AlterModelOptions(
name='kyudanranking',
options={'ordering': (models.OrderBy(models.F('dan'), descending=True, nulls_last=True), '-dan_points', '-kyu_points', '-won_hanchans', '-good_hanchans', '-last_hanchan_date'), 'verbose_name': 'Kyū/Dan Wertung', 'verbose_name_plural': 'Kyū/Dan Wertungen'},
options={'ordering': (
models.OrderBy(models.F('dan'), descending=True, nulls_last=True),
'-dan_points', '-kyu_points', '-won_hanchans', '-good_hanchans',
'-last_hanchan_date'), 'verbose_name': 'Kyū/Dan Wertung',
'verbose_name_plural': 'Kyū/Dan Wertungen'},
),
migrations.AddField(
model_name='kyudanranking',

View File

@@ -14,7 +14,6 @@ from django.urls import reverse
from django.utils import timezone
from django.utils.translation import gettext as _
from events.models import Event
from . import DAN_RANKS_DICT, LOGGER, set_dirty
from . import managers
@@ -445,8 +444,8 @@ class KyuDanRanking(models.Model):
settings.TOURNAMENT_WIN_BONUSPOINTS)
if event_ranking.avg_placement == 1:
bonus_points += settings.TOURNAMENT_FLAWLESS_VICTORY_BONUSPOINTS
hanchan.player_comment += u'+{0:d} Pkt: alle Spiele des Turnieres gewonnen. '.format(
settings.TOURNAMENT_FLAWLESS_VICTORY_BONUSPOINTS)
hanchan.player_comment += '+{0:d} Pkt: alle Spiele des Turnieres \
gewonnen. '.format(settings.TOURNAMENT_FLAWLESS_VICTORY_BONUSPOINTS)
if bonus_points and self.dan:
hanchan.dan_points += bonus_points
@@ -504,12 +503,15 @@ class KyuDanRanking(models.Model):
else:
until = valid_hanchans.aggregate(until=models.Max("start"))["until"]
if valid_hanchans.count() > 0:
LOGGER.info(f"recalculating Kyu/Dan points for {self.user} ({since:%Y-%m-%d} - {until:%Y-%m-%d})...")
LOGGER.info(f"recalculating Kyu/Dan points for {self.user} " +
f"({since:%Y-%m-%d} - {until:%Y-%m-%d})...")
else:
LOGGER.info(f"No new valid Hanchans for {self.user}...")
for hanchan in valid_hanchans:
self.hanchan_count += 1
LOGGER.info(f"{self.user} Hanchan no. {self.hanchan_count} from {hanchan.start}")
LOGGER.info(
f"{self.user} Hanchan no. {self.hanchan_count} " +
f"from {hanchan.start}")
hanchan.get_playerdata(self.user)
if since and hanchan.start < since:
LOGGER.info(hanchan, "<", since, "no recalc")
@@ -578,14 +580,16 @@ class KyuDanRanking(models.Model):
# Only substract so much points that player has 0 Points:
if self.dan_points + hanchan.dan_points < 0:
hanchan.player_comment = 'Spieler unterschreitet 0 Punkte.' \
'(Original {} Punkte)'.format(hanchan.dan_points)
'(Original {} Punkte)'.format(
hanchan.dan_points)
hanchan.dan_points -= (self.dan_points + hanchan.dan_points)
self.dan_points += hanchan.dan_points
else:
# Only substract so much points that player has 0 Points:
if self.kyu_points + hanchan.kyu_points < 0:
hanchan.player_comment = 'Spieler unterschreitet 0 Punkte.' \
'(Original {} Punkte)'.format(hanchan.kyu_points)
'(Original {} Punkte)'.format(
hanchan.kyu_points)
hanchan.kyu_points -= (self.kyu_points + hanchan.kyu_points)
self.kyu_points += hanchan.kyu_points

View File

@@ -97,7 +97,6 @@ class KyuDanTest(TestCase):
self.assertEqual(
points[dan_kyu],
getattr(ranking, dan_kyu),
"{dan_kyu} for {player} won't compute! ranking: {ranking}, sum: {sum}".format(
dan_kyu=dan_kyu, player=ranking.user,
ranking=getattr(ranking, dan_kyu), sum=points[dan_kyu])
f"{dan_kyu} for {ranking.user} won't compute! " +
f"ranking: {ranking.dan_kyu}, sum: {points[dan_kyu]}"
)

View File

@@ -7,18 +7,32 @@ from . import views
urlpatterns = [
path("", RedirectView.as_view(url='/ranking/mahjong-ladder/', permanent=True)),
path('event/<int:event>/add-hanchan/', views.HanchanForm.as_view(), name="add-hanchan-form"),
path('event/<int:event>/edit/', views.EventHanchanForm.as_view(), name="event-hanchan-form"),
path('event/<int:event>/mahjong/', views.EventHanchanList.as_view(), name="event-hanchan-list"),
path('event/<int:event>/mahjong-ranking/', views.EventRankingList.as_view(), name="event-ranking"),
path('hanchan/<int:hanchan>/edit/', views.HanchanForm.as_view(), name="edit-hanchan"),
path('hanchan/<int:hanchan>/delete/', views.DeleteHanchan.as_view(), name="delete-hanchan"),
path('mahjong-ladder/', views.SeasonRankingList.as_view(), name="mahjong-ladder"),
path('mahjong-ladder/<int:season>/', views.SeasonRankingList.as_view(), name="mahjong-ladder"),
path('player/<slug:username>/dan/', views.PlayerDanScore.as_view(), name="player-dan-score"),
path('player/<slug:username>/invalid/', views.PlayerInvalidScore.as_view(), name="player-invalid-score"),
path('player/<slug:username>/kyu/', views.PlayerKyuScore.as_view(), name="player-kyu-score"),
path('player/<slug:username>/ladder/', views.PlayerLadderScore.as_view(), name="player-ladder-score"),
path('mahjong/', views.KyuDanRankingList.as_view(), name="kyudanranking-list"),
path('mahjong/<str:order_by>/', views.KyuDanRankingList.as_view(), name="kyudanranking-list"),
path('event/<int:event>/add-hanchan/', views.HanchanForm.as_view(),
name="add-hanchan-form"),
path('event/<int:event>/edit/', views.EventHanchanForm.as_view(),
name="event-hanchan-form"),
path('event/<int:event>/mahjong/', views.EventHanchanList.as_view(),
name="event-hanchan-list"),
path('event/<int:event>/mahjong-ranking/', views.EventRankingList.as_view(),
name="event-ranking"),
path('hanchan/<int:hanchan>/edit/', views.HanchanForm.as_view(),
name="edit-hanchan"),
path('hanchan/<int:hanchan>/delete/', views.DeleteHanchan.as_view(),
name="delete-hanchan"),
path('mahjong-ladder/', views.SeasonRankingList.as_view(),
name="mahjong-ladder"),
path('mahjong-ladder/<int:season>/', views.SeasonRankingList.as_view(),
name="mahjong-ladder"),
path('player/<slug:username>/dan/', views.PlayerDanScore.as_view(),
name="player-dan-score"),
path('player/<slug:username>/invalid/', views.PlayerInvalidScore.as_view(),
name="player-invalid-score"),
path('player/<slug:username>/kyu/', views.PlayerKyuScore.as_view(),
name="player-kyu-score"),
path('player/<slug:username>/ladder/', views.PlayerLadderScore.as_view(),
name="player-ladder-score"),
path('mahjong/', views.KyuDanRankingList.as_view(),
name="kyudanranking-list"),
path('mahjong/<str:order_by>/', views.KyuDanRankingList.as_view(),
name="kyudanranking-list"),
]

View File

@@ -6,7 +6,6 @@ from django.conf import settings
class Migration(migrations.Migration):
dependencies = [
('events', '__first__'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
@@ -17,7 +16,8 @@ class Migration(migrations.Migration):
name='Game',
fields=[
('id', models.AutoField(verbose_name='ID',
serialize=False, auto_created=True, primary_key=True)),
serialize=False, auto_created=True,
primary_key=True)),
('comment', models.TextField(verbose_name='Anmerkung', blank=True)),
('player1_score', models.SmallIntegerField(verbose_name='Punkte')),
('player1_placement', models.PositiveSmallIntegerField(editable=False)),
@@ -32,31 +32,47 @@ class Migration(migrations.Migration):
('player6_score', models.SmallIntegerField(verbose_name='Punkte')),
('player6_placement', models.PositiveSmallIntegerField(editable=False)),
('confirmed', models.BooleanField(
default=True, help_text='das Spiel z\xe4hlt nur wenn es best\xe4tigt wurde', verbose_name='Wurde best\xe4tigt')),
default=True,
help_text='das Spiel z\xe4hlt nur wenn es best\xe4tigt wurde',
verbose_name='Wurde best\xe4tigt')),
('player_names', models.CharField(max_length=255, editable=False)),
('season', models.PositiveSmallIntegerField(
verbose_name='Saison', editable=False, db_index=True)),
('event', models.ForeignKey(
related_name='maistargame_set', to='events.Event', on_delete=models.CASCADE)),
related_name='maistargame_set', to='events.Event',
on_delete=models.CASCADE)),
('player1', models.ForeignKey(related_name='+',
verbose_name='Spieler 1', to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)),
verbose_name='Spieler 1',
to=settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)),
('player2', models.ForeignKey(related_name='+',
verbose_name='Spieler 2', to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)),
verbose_name='Spieler 2',
to=settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)),
('player3', models.ForeignKey(related_name='+',
verbose_name='Spieler 3', to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)),
verbose_name='Spieler 3',
to=settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)),
('player4', models.ForeignKey(related_name='+',
verbose_name='Spieler 4', to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)),
verbose_name='Spieler 4',
to=settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)),
('player5', models.ForeignKey(related_name='+',
verbose_name='Spieler 5', to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)),
verbose_name='Spieler 5',
to=settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)),
('player6', models.ForeignKey(related_name='+',
verbose_name='Spieler 6', to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)),
verbose_name='Spieler 6',
to=settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)),
],
),
migrations.CreateModel(
name='Ranking',
fields=[
('id', models.AutoField(verbose_name='ID',
serialize=False, auto_created=True, primary_key=True)),
serialize=False, auto_created=True,
primary_key=True)),
('season', models.PositiveSmallIntegerField(verbose_name='Saison')),
('placement', models.PositiveIntegerField(null=True, blank=True)),
('avg_placement', models.PositiveSmallIntegerField(
@@ -65,7 +81,8 @@ class Migration(migrations.Migration):
('games_count', models.PositiveSmallIntegerField(default=0)),
('games_good', models.PositiveSmallIntegerField(default=0)),
('games_won', models.PositiveSmallIntegerField(default=0)),
('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)),
('user', models.ForeignKey(to=settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)),
],
options={
'ordering': ('-season', 'placement', 'avg_placement', '-avg_score'),

View File

@@ -8,7 +8,6 @@ import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('maistar_ranking', '0006_auto_20171115_0653'),
]
@@ -17,36 +16,49 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='game',
name='player1',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Spieler 1'),
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT,
related_name='+', to=settings.AUTH_USER_MODEL,
verbose_name='Spieler 1'),
),
migrations.AlterField(
model_name='game',
name='player2',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Spieler 2'),
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT,
related_name='+', to=settings.AUTH_USER_MODEL,
verbose_name='Spieler 2'),
),
migrations.AlterField(
model_name='game',
name='player3',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Spieler 3'),
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT,
related_name='+', to=settings.AUTH_USER_MODEL,
verbose_name='Spieler 3'),
),
migrations.AlterField(
model_name='game',
name='player4',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Spieler 4'),
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT,
related_name='+', to=settings.AUTH_USER_MODEL,
verbose_name='Spieler 4'),
),
migrations.AlterField(
model_name='game',
name='player5',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Spieler 5'),
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT,
related_name='+', to=settings.AUTH_USER_MODEL,
verbose_name='Spieler 5'),
),
migrations.AlterField(
model_name='game',
name='player6',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Spieler 6'),
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT,
related_name='+', to=settings.AUTH_USER_MODEL,
verbose_name='Spieler 6'),
),
migrations.AlterField(
model_name='ranking',
name='user',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL),
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT,
to=settings.AUTH_USER_MODEL),
),
]

View File

@@ -211,7 +211,8 @@ def update_maistar_ranking(sender, **kwargs):
"""
A Django signal hook to trigger a recalculation of the rankings as soon
as a Mai-Star game has been added, deleted, or modified.
:param sender: The callback function which will be connected to this signal. See Receiver functions for more information.
:param sender: The callback function which will be connected to this signal.
See Receiver functions for more information.
:param kwargs: """
instance = kwargs['instance']
for player in instance.player_list:

View File

@@ -1,6 +1,5 @@
"""To geneate a Sitemap with all events."""
from kasu.sitemaps import GenericSitemap
from django.utils import timezone
from django.urls import reverse
from events.models import Event

View File

@@ -5,12 +5,21 @@ from . import views
urlpatterns = [
path("", views.ListRankings.as_view()),
path('event/<int:event>/maistar/', views.ListGames.as_view(), name="maistar-game-list"),
path('event/<int:event>/maistar/add/', views.GameForm.as_view(), name="maistar-add-game"),
path('maistar/', views.ListRankings.as_view(), name="maistar-ranking"),
path('maistar/<int:season>/', views.ListRankings.as_view(), name="maistar-ranking"),
path('maistar/<int:game>/edit/', views.GameForm.as_view(), name="maistar-edit-game"),
path('maistar/<int:game>/delete/', views.DeleteGame.as_view(), name="maistar-delete-game"),
path('player/<slug:username>/maistar/', views.ListPlayerGames.as_view(), name="maistar-player-games"),
path('player/<slug:username>/maistar/<int:season>/', views.ListPlayerGames.as_view(), name="maistar-player-games"),
path('event/<int:event>/maistar/', views.ListGames.as_view(),
name="maistar-game-list"),
path('event/<int:event>/maistar/add/', views.GameForm.as_view(),
name="maistar-add-game"),
path('maistar/', views.ListRankings.as_view(),
name="maistar-ranking"),
path('maistar/<int:season>/', views.ListRankings.as_view(),
name="maistar-ranking"),
path('maistar/<int:game>/edit/', views.GameForm.as_view(),
name="maistar-edit-game"),
path('maistar/<int:game>/delete/', views.DeleteGame.as_view(),
name="maistar-delete-game"),
path('player/<slug:username>/maistar/', views.ListPlayerGames.as_view(),
name="maistar-player-games"),
path('player/<slug:username>/maistar/<int:season>/',
views.ListPlayerGames.as_view(),
name="maistar-player-games"),
]

View File

@@ -50,7 +50,7 @@ def clear_personal_data(modeladmin, request, queryset):
if not modeladmin.has_delete_permission(request):
raise PermissionDenied
for membership in queryset:
if membership.membership == False:
if membership.membership is False:
[setattr(membership, fieldname, None)
for fieldname in membership.nullable_personal_data]
[setattr(membership, fieldname, "")
@@ -61,11 +61,15 @@ def clear_personal_data(modeladmin, request, queryset):
membership.save()
cleared_memberships += 1
else:
modeladmin.message_user(request, _(
"Can't remove personal data from active member %s.") % membership.username, messages.ERROR)
modeladmin.message_user(
request,
_("Can't remove personal data from %s.") % membership.username,
messages.ERROR)
if cleared_memberships > 0:
modeladmin.message_user(request, _(
"Cleared %d personal data profiles.") % cleared_memberships, messages.INFO)
modeladmin.message_user(
request,
_("Cleared %d personal data profiles.") % cleared_memberships,
messages.INFO)
clear_personal_data.short_description = _("Clear personal Data")
@@ -99,7 +103,7 @@ class MembershipAdmin(UserAdmin):
'confirmed',
'last_login',
)
list_editable = ('confirmed', )
list_editable = ('confirmed',)
list_display_links = ('username',)
fieldsets = (
(None, {'fields': (('username', 'password'), 'gender', 'avatar',

View File

@@ -27,17 +27,22 @@ class Migration(migrations.Migration):
max_length=128, verbose_name='password')),
('last_login', models.DateTimeField(
null=True, verbose_name='last login', blank=True)),
('is_superuser', models.BooleanField(default=False,
help_text='Designates that this user has all permissions without explicitly assigning them.',
('is_superuser', models.BooleanField(
default=False,
help_text="Designates that this user has all permissions " +
"without explicitly assigning them.",
verbose_name='superuser status')),
('username', models.CharField(error_messages={
'unique': 'A user with that username already exists.'},
max_length=30, validators=[
django.core.validators.RegexValidator(
'^[\\w.@+-]+$',
'Enter a valid username. This value may contain only letters, numbers and @/./+/-/_ characters.',
"^[\\w.@+-]+$",
"Enter a valid username. " +
"This value may contain only letters, " +
"numbers and @/./+/-/_ characters.",
'invalid')],
help_text='Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only.',
help_text="Required. 30 characters or fewer. " +
"Letters, digits and @/./+/-/_ only.",
unique=True,
verbose_name='username')),
('first_name', models.CharField(max_length=30,
@@ -49,12 +54,13 @@ class Migration(migrations.Migration):
('email', models.EmailField(max_length=254,
verbose_name='email address',
blank=True)),
('is_staff', models.BooleanField(default=False,
help_text='Designates whether the user can log into this admin site.',
('is_staff', models.BooleanField(
default=False,
help_text='this user can log into the admin site.',
verbose_name='staff status')),
('is_active', models.BooleanField(
default=True,
help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.',
help_text='Unselect this instead of deleting accounts.',
verbose_name='active')),
('date_joined', models.DateTimeField(
default=django.utils.timezone.now,
@@ -68,8 +74,10 @@ class Migration(migrations.Migration):
('avatar', models.ImageField(storage=utils.OverwriteStorage(
), null=True, upload_to=membership.models.get_upload_path,
blank=True)),
('membership', models.BooleanField(default=False,
help_text='Ja, ich bin mit den Statuen einverstanden und m\xf6chte Mitglied werden.',
('membership', models.BooleanField(
default=False,
help_text="Ja, ich bin mit den Statuen einverstanden " +
"und m\xf6chte Mitglied werden.",
verbose_name='Mitgliedschaft')),
('birthday', models.DateField(null=True,
verbose_name='Geburtstag',
@@ -93,17 +101,20 @@ class Migration(migrations.Migration):
('paid_until', models.DateField(null=True,
verbose_name='Bezahlt bis',
blank=True)),
('confirmed', models.BooleanField(default=False,
('confirmed', models.BooleanField(
default=False,
help_text='Diese Person hat ihre Mitgliedschaft bezahlt',
verbose_name='Best\xe4tigt')),
('comment', models.TextField(blank=True)),
('groups', models.ManyToManyField(related_query_name='user',
('groups', models.ManyToManyField(
related_query_name='user',
related_name='user_set',
to='auth.Group', blank=True,
help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.',
help_text="The groups this user belongs to. ",
verbose_name='groups')),
('user_permissions',
models.ManyToManyField(related_query_name='user',
models.ManyToManyField(
related_query_name='user',
related_name='user_set',
to='auth.Permission',
blank=True,

View File

@@ -2,7 +2,6 @@
from __future__ import unicode_literals
from django.db import migrations
from django.db import models
import django.contrib.auth.models

View File

@@ -2,7 +2,6 @@
from __future__ import unicode_literals
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):

View File

@@ -2,7 +2,6 @@
from __future__ import unicode_literals
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):

View File

@@ -2,7 +2,6 @@
from __future__ import unicode_literals
from django.db import migrations
from django.db import models
import membership.models
import utils
import easy_thumbnails.fields

View File

@@ -5,7 +5,6 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('membership', '0005_auto_20150901_2204'),
]
@@ -14,7 +13,12 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='membership',
name='gender',
field=models.CharField(blank=True, max_length=1, null=True, verbose_name='Geschlecht', choices=[
field=models.CharField(
blank=True,
max_length=1,
null=True,
verbose_name='Geschlecht',
choices=[
(b'm', 'M\xe4nnlich'), (b'f', 'Weiblich')]),
),
]

View File

@@ -7,7 +7,6 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('membership', '0006_auto_20160916_1759'),
]
@@ -16,11 +15,19 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='membership',
name='gender',
field=models.CharField(blank=True, choices=[('m', 'Male'), ('f', 'Female')], max_length=1, null=True, verbose_name='Geschlecht'),
field=models.CharField(
blank=True, choices=[('m', 'Male'), ('f', 'Female')], max_length=1,
null=True, verbose_name='Geschlecht'),
),
migrations.AlterField(
model_name='membership',
name='username',
field=models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username'),
field=models.CharField(
error_messages={'unique': 'A user with that username already exists.'},
help_text="Required. 150 characters or fewer. " +
"Letters, digits and @/./+/-/_ only.",
max_length=150, unique=True,
validators=[django.contrib.auth.validators.UnicodeUsernameValidator()],
verbose_name='username'),
),
]

View File

@@ -4,7 +4,6 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('membership', '0007_auto_20171115_0653'),
]
@@ -13,6 +12,7 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='membership',
name='last_name',
field=models.CharField(blank=True, max_length=150, verbose_name='last name'),
field=models.CharField(blank=True, max_length=150,
verbose_name='last name'),
),
]

View File

@@ -4,7 +4,6 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('membership', '0008_auto_20190106_1954'),
]
@@ -13,6 +12,7 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='membership',
name='first_name',
field=models.CharField(blank=True, max_length=150, verbose_name='first name'),
field=models.CharField(blank=True, max_length=150,
verbose_name='first name'),
),
]

View File

@@ -12,17 +12,29 @@ urlpatterns = [
path("", views.MembershipDetail.as_view()),
path('activate/<str:activation_key>', views.ActivateRegistration.as_view(),
name='membership-activate-registration'),
path('activation_sent/', views.ActivationSent.as_view(), name="membership-registration-complete"),
path('login/', auth_views.LoginView.as_view(), name='login'),
path('logout/', auth_views.LogoutView.as_view(), name='logout'),
path('password_change/', auth_views.PasswordChangeView.as_view(), name='password_change'),
path('password_change/done/', auth_views.PasswordChangeDoneView.as_view(), name='password_change_done'),
path('password_reset/', auth_views.PasswordResetView.as_view(), name='password_reset'),
path('password_reset/done/', auth_views.PasswordResetDoneView.as_view(), name='password_reset_done'),
path('register/', views.RegisterForm.as_view(), name="membership-register"),
path('reset/<uuid:uidb64>/<str:token>/', auth_views.PasswordResetConfirmView.as_view(),
path('activation_sent/', views.ActivationSent.as_view(),
name="membership-registration-complete"),
path('login/', auth_views.LoginView.as_view(),
name='login'),
path('logout/', auth_views.LogoutView.as_view(),
name='logout'),
path('password_change/', auth_views.PasswordChangeView.as_view(),
name='password_change'),
path('password_change/done/', auth_views.PasswordChangeDoneView.as_view(),
name='password_change_done'),
path('password_reset/', auth_views.PasswordResetView.as_view(),
name='password_reset'),
path('password_reset/done/', auth_views.PasswordResetDoneView.as_view(),
name='password_reset_done'),
path('register/', views.RegisterForm.as_view(),
name="membership-register"),
path('reset/<uuid:uidb64>/<str:token>/',
auth_views.PasswordResetConfirmView.as_view(),
name='password_reset_confirm'),
path('reset/done/', auth_views.PasswordResetCompleteView.as_view(), name='password_reset_complete'),
path('<slug:username>/', views.MembershipDetail.as_view(), name='membership-details'),
path('<slug:username>/edit/', views.EditMembership.as_view(), name="membership-edit")
path('reset/done/', auth_views.PasswordResetCompleteView.as_view(),
name='password_reset_complete'),
path('<slug:username>/', views.MembershipDetail.as_view(),
name='membership-details'),
path('<slug:username>/edit/', views.EditMembership.as_view(),
name="membership-edit")
]

View File

@@ -6,10 +6,8 @@ Created on 28.09.2011
from django.core.files.storage import FileSystemStorage
from django.utils.translation import gettext as _
from .countries import COUNTRIES
from .html_cleaner import HtmlCleaner
from .massmailer import MassMailer
from .countries import COUNTRIES # noqa: F401
CLEANER = HtmlCleaner()
STATUS_REJECTED, STATUS_WAITING, STATUS_PUBLISHED = -1, 0, 1