Compare commits
160 Commits
riichi_201
...
kyu_change
| Author | SHA1 | Date | |
|---|---|---|---|
| 06785a3e49 | |||
| 4c00211432 | |||
| c62d2ee010 | |||
| ef00fc25f7 | |||
| fbfabb982f | |||
| 3efc4335bb | |||
|
|
e3daccafb1 | ||
|
|
1f4b978fd2 | ||
| 18d7f8a926 | |||
| 2885ef9d5c | |||
| 3f403b3f52 | |||
| 0d3c47d8b3 | |||
| 95f5e0b920 | |||
| b12203911e | |||
| a733130b65 | |||
| 483e6f215d | |||
| 2bdf8c9692 | |||
| 36e24b7da8 | |||
| 79a5cdb868 | |||
| 5ed8976074 | |||
| 12930c2ec6 | |||
| e792da7459 | |||
| b01dc33cb4 | |||
| 1bdce47375 | |||
| bb7d4c8a08 | |||
| a3ac722acf | |||
| 1313d96e8f | |||
| f2836baae5 | |||
| d67719cc17 | |||
| 12773463a6 | |||
| a8536fc776 | |||
| ba4620705f | |||
| 4db5c09387 | |||
| 40d2120d7e | |||
| 0768641184 | |||
| f7e9585932 | |||
| fae5f30cfa | |||
| 99ceb54db1 | |||
| e95ad8bf0a | |||
| f841c1736e | |||
| 4b68f62929 | |||
| 436a77d036 | |||
| fc8daaaf25 | |||
| a10b2706c3 | |||
| c3d213934e | |||
| afc471d27f | |||
| baa9660b7c | |||
| 1d18356c8c | |||
| 3dcd1aeffa | |||
| 5a32dbf0af | |||
| 5affdb0f5c | |||
| 65b8208987 | |||
| 9f0126be54 | |||
| 4f61b1e73b | |||
| 0f71bb5360 | |||
| df4d8c83a6 | |||
| 3e64f4d757 | |||
| f2533273e9 | |||
| 121167f1fe | |||
| 595341a53b | |||
| ac9b3e06c0 | |||
| af46768e7d | |||
| 9fdf725702 | |||
| 10bb990539 | |||
| 2f5f834bba | |||
| 90cefd8739 | |||
| 722c155c17 | |||
| a4c4f96c06 | |||
| 3b162fc59c | |||
| 19bbb5a226 | |||
| e9e997e38d | |||
| 3a3c8ec0c5 | |||
| aa85d3fd94 | |||
| 4aab611026 | |||
| 432673a967 | |||
| d5995bc612 | |||
| 877715f613 | |||
| 3ef947f128 | |||
| 1d2fb44250 | |||
| 28f7292c9d | |||
| 3af8e64f1f | |||
| 7b631230da | |||
| 8ddbe03ff8 | |||
| 6804319c28 | |||
| 0a793b7954 | |||
| a2df81d62e | |||
| 4b0a5c9c82 | |||
| afd163298c | |||
| 6796b58d4c | |||
| cce6ac6014 | |||
| 192721452e | |||
| 10c27784ee | |||
| 8ab99ec039 | |||
| 1fdf88c6d2 | |||
| b20b988e5d | |||
| cf0e5e778c | |||
| c7b714c41b | |||
| 4bd017ec4f | |||
| f51155cfac | |||
| 52ec7d42b7 | |||
| 1315bc4225 | |||
| d62f549a30 | |||
| 97749bfd2e | |||
| 84880281c6 | |||
| cffbd30d7e | |||
| 3a611ca9da | |||
| 68c484afc9 | |||
| 92470514c4 | |||
| d33e5fc8c6 | |||
| bb110da5a2 | |||
| 35a51091bf | |||
| c0c48f950a | |||
| d9e0d5596c | |||
| fa6a81c710 | |||
| a3c02ae73a | |||
| e6f2528a0e | |||
| 638ec96c25 | |||
| 34d327f183 | |||
| 002eb40ea5 | |||
| d97c9db539 | |||
| 7ef69849a4 | |||
| 8719c2377a | |||
| abeb86d48f | |||
| 42a6ebedf9 | |||
| b3ab9798b5 | |||
| ce218080b2 | |||
| 63e099b7c5 | |||
| a26a91c360 | |||
| cf0bbb4c8f | |||
| 321531c160 | |||
| 5437b7b8de | |||
| 10bdaaa98c | |||
| 9b4ab374c6 | |||
| ae87414584 | |||
| 120b4ea17f | |||
| fcb15c7e7e | |||
| 299418ee62 | |||
| e5f0d7f6fe | |||
| 53974dcd48 | |||
| 222dd060b1 | |||
| bbe16b2d13 | |||
| ba44e97e9a | |||
| 8595959872 | |||
| 9b0967adc8 | |||
| ac78dc3d75 | |||
| 57b7d5a84b | |||
| 6b37aa84b0 | |||
|
|
0c7bd466c7 | ||
| 0bdd409dc2 | |||
|
|
9c4ec20394 | ||
|
|
6f1512906d | ||
|
|
12c9a6e0e9 | ||
|
|
8cac20dd2b | ||
|
|
b1586efbab | ||
|
|
088efe2f39 | ||
|
|
b9ec418e5e | ||
|
|
836eee983d | ||
|
|
79eaeb34ad | ||
|
|
bafbf38612 | ||
|
|
b96b485b61 |
2
.coafile
2
.coafile
@@ -5,4 +5,4 @@ language = python
|
|||||||
bears = PEP8Bear,PyLintBear,PyUnusedCodeBear
|
bears = PEP8Bear,PyLintBear,PyUnusedCodeBear
|
||||||
use_spaces = True
|
use_spaces = True
|
||||||
pylint_cli_options = --load-plugins pylint_django
|
pylint_cli_options = --load-plugins pylint_django
|
||||||
pylint_disable = E1101,R0201,R0901,R0903
|
#pylint_disable = E1101,R0201,R0901,R0903
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -71,3 +71,4 @@ backup/
|
|||||||
.[a-zA-Z]*
|
.[a-zA-Z]*
|
||||||
local_settings.py
|
local_settings.py
|
||||||
sample.xlsx
|
sample.xlsx
|
||||||
|
venv/
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ module.exports = function(grunt) {
|
|||||||
options: {
|
options: {
|
||||||
paths: ['src/kasu/static/less'],
|
paths: ['src/kasu/static/less'],
|
||||||
compress: false,
|
compress: false,
|
||||||
optimization:9,
|
optimization: 9,
|
||||||
ieCompat: false,
|
ieCompat: false,
|
||||||
},
|
},
|
||||||
kasu: {
|
kasu: {
|
||||||
@@ -21,9 +21,10 @@ module.exports = function(grunt) {
|
|||||||
report: 'min'
|
report: 'min'
|
||||||
},
|
},
|
||||||
kasu: {
|
kasu: {
|
||||||
src: 'static/css/kasu.css',
|
files: {
|
||||||
dest: 'static/css/kasu.css'
|
'src/kasu/static/css/kasu.min.css': ['src/kasu/static/css/kasu.css'],
|
||||||
}
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
styles: {
|
styles: {
|
||||||
|
|||||||
80
Makefile
Normal file
80
Makefile
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
ASSETS=requirements static
|
||||||
|
DEV_REQUIREMENTS=requirements/development.txt
|
||||||
|
DJANGO_SETTINGS_MODULE="kasu.settings"
|
||||||
|
EXCLUDE_FILES=*.pyc
|
||||||
|
PROJECT_PATH=$(CURDIR)
|
||||||
|
PYTHON=${VENV_PATH}/bin/python3
|
||||||
|
REQUIREMENTS=requirements/base.txt
|
||||||
|
SRC_PATH=${PROJECT_PATH}/src
|
||||||
|
MANAGE_PY=${PYTHON} -Wa ${SRC_PATH}/manage.py
|
||||||
|
SSH_LOGIN=kasu@kasu.at
|
||||||
|
VENV_PATH=$(PROJECT_PATH)/venv
|
||||||
|
|
||||||
|
.PHONY: clean venv
|
||||||
|
|
||||||
|
all: cleanup migrate testserver
|
||||||
|
|
||||||
|
venv: $(VENV_PATH)/bin/activate
|
||||||
|
$(VENV_PATH)/bin/activate:
|
||||||
|
@test -d $(VENV_PATH) || python3 -m venv --clear --system-site-packages $(VENV_PATH)
|
||||||
|
|
||||||
|
dev-requirements: venv ${DEV_REQUIREMENTS}
|
||||||
|
${PYTHON} -m pip install -qU pip
|
||||||
|
${PYTHON} -m pip install -qUr ${DEV_REQUIREMENTS}
|
||||||
|
|
||||||
|
requirements: venv ${REQUIREMENTS}
|
||||||
|
${PYTHON} -m pip install -qU pip
|
||||||
|
${PYTHON} -m pip install -qUr ${REQUIREMENTS}
|
||||||
|
|
||||||
|
grunt:
|
||||||
|
-grunt
|
||||||
|
|
||||||
|
requirements_remote:
|
||||||
|
@echo "Installing requirements"
|
||||||
|
ssh ${SSH_LOGIN} "virtualenv/bin/pip install -qUr ${REQUIREMENTS}"
|
||||||
|
|
||||||
|
sync_assets:
|
||||||
|
@echo "Syncing project assets ..."
|
||||||
|
rsync -qr --copy-links --delete ${ASSETS} ${SSH_LOGIN}:~/
|
||||||
|
|
||||||
|
sync_src:
|
||||||
|
@echo "Syncing Sourcecode ..."
|
||||||
|
find . -name EXCLUDE_FILES -exec rm -rf {} \;
|
||||||
|
rsync -qr --copy-links --delete ${SRC_PATH} ${SSH_LOGIN}:~/ --exclude 'src/kasu/local_settings.py'
|
||||||
|
|
||||||
|
restart_remote:
|
||||||
|
@echo "Rebuild and reload django..."
|
||||||
|
ssh ${SSH_LOGIN} "~/virtualenv/bin/python ~/src/manage.py collectstatic -l --noinput -v0"
|
||||||
|
ssh ${SSH_LOGIN} "~/init/kasu restart"
|
||||||
|
|
||||||
|
sync: sync_assets requirements_remote sync_src restart_remote
|
||||||
|
|
||||||
|
testserver: venv
|
||||||
|
${MANAGE_PY} runserver 127.0.0.1:8000
|
||||||
|
|
||||||
|
messages: venv
|
||||||
|
@echo "aktualisiere Übersetzungen..."
|
||||||
|
@(for d in ${SRC_PATH}/*; do \
|
||||||
|
test -d $$d/locale && cd $$d && ${VENV_PATH}/bin/django-admin makemessages -l de;\
|
||||||
|
done)
|
||||||
|
${MANAGE_PY} compilemessages -v0
|
||||||
|
|
||||||
|
cleanup-pyc:
|
||||||
|
@echo "lösche den Python Compiler Cache..."
|
||||||
|
find ${SRC_PATH} -name ${EXCLUDE_FILES} -exec rm -rf {} \;
|
||||||
|
|
||||||
|
collectstatic: venv
|
||||||
|
@echo "aktualisiere Statics"
|
||||||
|
${MANAGE_PY} collectstatic --noinput -c -v0
|
||||||
|
|
||||||
|
thumbnails: venv
|
||||||
|
@echo "Erstelle Vorschaubilder"
|
||||||
|
${MANAGE_PY} thumbnail_cleanup
|
||||||
|
|
||||||
|
cleanup: requirements messages cleanup-pyc collectstatic thumbnails
|
||||||
|
|
||||||
|
migrate: venv
|
||||||
|
${MANAGE_PY} migrate
|
||||||
|
|
||||||
|
migrations: venv
|
||||||
|
${MANAGE_PY} makemigrations
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
source .virtualenv/bin/activate
|
|
||||||
echo "aktualisiere Übersetzungen..."
|
|
||||||
cd src
|
|
||||||
unset DJANGO_SETTINGS_MODULE
|
|
||||||
for dir in *
|
|
||||||
do
|
|
||||||
if [ -d ${dir}/locale ]
|
|
||||||
echo "Übersetze $dir"
|
|
||||||
then
|
|
||||||
echo -n "$dir: "
|
|
||||||
cd ${dir}
|
|
||||||
django-admin.py makemessages -l de
|
|
||||||
cd ..
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
sleep 5s
|
|
||||||
export DJANGO_SETTINGS_MODULE="kasu.settings.production"
|
|
||||||
./manage.py compilemessages
|
|
||||||
|
|
||||||
echo "lösche den Python Compiler Cache..."
|
|
||||||
find . -name "*.pyc" -exec rm -rf {} \;
|
|
||||||
echo "Aktualisiere Statics"
|
|
||||||
./manage.py collectstatic --noinput -c
|
|
||||||
echo "Erstelle Vorschaubilder"
|
|
||||||
./manage.py generateimages
|
|
||||||
touch kasu/wsgi.py
|
|
||||||
23
bin/sync.sh
23
bin/sync.sh
@@ -1,23 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
SSH_LOGIN="kasu@s21.wservices.ch"
|
|
||||||
SYNC_ASSESTS="requirements static"
|
|
||||||
SYNC_SOURCECODE="src"
|
|
||||||
EXCLUDE_FILES="*.pyc"
|
|
||||||
|
|
||||||
grunt
|
|
||||||
|
|
||||||
echo "Syncing project assets ..."
|
|
||||||
rsync -r --copy-links --delete ${SYNC_ASSESTS} ${SSH_LOGIN}:~/
|
|
||||||
|
|
||||||
echo "Installing dependecies"
|
|
||||||
ssh ${SSH_LOGIN} "virtualenv/bin/pip install --upgrade -r requirements/base.txt"
|
|
||||||
|
|
||||||
echo "Syncing Sourcecode ..."
|
|
||||||
find . -name "*.pyc" -exec rm -rf {} \;
|
|
||||||
rsync -r --copy-links --delete ${SYNC_SOURCECODE} ${SSH_LOGIN}:~/ --exclude 'src/kasu/local_settings.py'
|
|
||||||
|
|
||||||
echo "Rebuild and reload django..."
|
|
||||||
ssh ${SSH_LOGIN} "rm src/kasu/settings/development.*"
|
|
||||||
ssh ${SSH_LOGIN} "~/virtualenv/bin/python ~/src/manage.py collectstatic -l --noinput -v1"
|
|
||||||
ssh ${SSH_LOGIN} "~/init/kasu restart"
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
export DJANGO_SETTINGS_MODULE=kasu.settings
|
|
||||||
source .virtualenv/bin/activate
|
|
||||||
./manage.py runserver 0.0.0.0:8000
|
|
||||||
|
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
"grunt": ">=0.4.5",
|
"grunt": ">=0.4.5",
|
||||||
"grunt-contrib-less": ">=1.0.1",
|
"grunt-contrib-less": ">=1.0.1",
|
||||||
"grunt-contrib-watch": ">=0.6.1",
|
"grunt-contrib-watch": ">=0.6.1",
|
||||||
"grunt-more-css": ">=0.1.0"
|
"grunt-more-css": "^0.1.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ckeditor-dev": "git://github.com/ckeditor/ckeditor-dev.git"
|
"ckeditor-dev": "git://github.com/ckeditor/ckeditor-dev.git"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
beautifulsoup4
|
beautifulsoup4
|
||||||
django < 2.0
|
django < 5.0
|
||||||
django-appconf
|
django-appconf
|
||||||
django-ckeditor
|
django-ckeditor
|
||||||
django-contrib-comments
|
django-contrib-comments
|
||||||
@@ -8,14 +8,13 @@ django-compressor
|
|||||||
django-extra-views
|
django-extra-views
|
||||||
django-markdown
|
django-markdown
|
||||||
django-recaptcha
|
django-recaptcha
|
||||||
easy-thumbnails
|
easy_thumbnails[svg]
|
||||||
icalendar
|
icalendar
|
||||||
|
openpyxl
|
||||||
markdown
|
markdown
|
||||||
pillow
|
pillow
|
||||||
psycopg2
|
psycopg2-binary
|
||||||
PyJWT
|
PyJWT
|
||||||
pytz
|
pytz
|
||||||
requests
|
requests
|
||||||
requests-oauthlib
|
requests-oauthlib
|
||||||
social-auth-app-django
|
|
||||||
social-auth-core
|
|
||||||
|
|||||||
@@ -4,5 +4,5 @@ django-rosetta
|
|||||||
sqlparse
|
sqlparse
|
||||||
|
|
||||||
# Code Linting
|
# Code Linting
|
||||||
coala-bears
|
pylint>=2.0
|
||||||
pylint-django
|
pylint-django
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
|
|
||||||
from . import models
|
from . import models
|
||||||
|
from utils import STATUS_PUBLISHED
|
||||||
|
|
||||||
|
|
||||||
def content_menus(request):
|
def content_menus(request):
|
||||||
@@ -18,9 +19,9 @@ def content_menus(request):
|
|||||||
:param request: a Django request object
|
:param request: a Django request object
|
||||||
:return: a dict with the template variables mentioned above
|
:return: a dict with the template variables mentioned above
|
||||||
"""
|
"""
|
||||||
current_page = None
|
current_page: models.Page = models.Page.objects.get(slug='index')
|
||||||
current_top_page = None
|
current_top_page: models.Page = models.Page.objects.get(slug='index')
|
||||||
current_path = request.path_info[1:request.path_info.rfind('.')]
|
current_path: str = request.path_info[1:request.path_info.rfind('.')]
|
||||||
|
|
||||||
# erzeuge das Top-Level Menü
|
# erzeuge das Top-Level Menü
|
||||||
top_level_pages = cache.get('top_level_pages')
|
top_level_pages = cache.get('top_level_pages')
|
||||||
@@ -50,7 +51,7 @@ def content_menus(request):
|
|||||||
break
|
break
|
||||||
current_path = current_path[0:current_path.rfind('.')]
|
current_path = current_path[0:current_path.rfind('.')]
|
||||||
|
|
||||||
return {'top_menu_items': top_level_pages,
|
return {'top_menu_items': top_level_pages.filter(status=STATUS_PUBLISHED),
|
||||||
'current_top_page': current_top_page,
|
'current_top_page': current_top_page,
|
||||||
'current_path': current_path,
|
'current_path': current_path,
|
||||||
'current_page': current_page}
|
'current_page': current_page}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import django_comments as comments
|
|||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.syndication.views import Feed
|
from django.contrib.syndication.views import Feed
|
||||||
from django.utils.feedgenerator import Rss201rev2Feed
|
from django.utils.feedgenerator import Rss201rev2Feed
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import gettext as _
|
||||||
|
|
||||||
from content.models import Article
|
from content.models import Article
|
||||||
|
|
||||||
@@ -11,15 +11,15 @@ MAX_ARTICLE_ITEMS = 10 # Maximum count of articles in the news RSS feed.
|
|||||||
MAX_COMMENT_ITEMS = 40 # Maximum count of comments in the comments RSS feed.
|
MAX_COMMENT_ITEMS = 40 # Maximum count of comments in the comments RSS feed.
|
||||||
|
|
||||||
|
|
||||||
# Start ignoring PyLintBear (R0201)
|
# noinspection PyMethodMayBeStatic
|
||||||
class LatestNews(Feed):
|
class LatestNews(Feed):
|
||||||
""" An Feed with the latest news from this site """
|
""" An Feed with the latest news from this site """
|
||||||
link = "http://www.kasu.at/"
|
|
||||||
description = _("Current news from Kasu")
|
description = _("Current news from Kasu")
|
||||||
title = "Kasu - traditonelle asiatische Spielkultur"
|
link = "http://www.kasu.at/"
|
||||||
|
title = _("Current news from Kasu")
|
||||||
feed_type = Rss201rev2Feed
|
feed_type = Rss201rev2Feed
|
||||||
|
|
||||||
def items(self):
|
def items(self) -> object:
|
||||||
"""get the newest published news articles for the feed."""
|
"""get the newest published news articles for the feed."""
|
||||||
return Article.objects.published()[:MAX_ARTICLE_ITEMS]
|
return Article.objects.published()[:MAX_ARTICLE_ITEMS]
|
||||||
|
|
||||||
@@ -78,5 +78,3 @@ class LatestComments(Feed):
|
|||||||
'user_name': item.user_name,
|
'user_name': item.user_name,
|
||||||
'content_object': item.content_object
|
'content_object': item.content_object
|
||||||
}
|
}
|
||||||
|
|
||||||
# Stop ignoring
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ Created on 04.10.2011
|
|||||||
"""
|
"""
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.template.defaultfilters import slugify
|
from django.template.defaultfilters import slugify
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import gettext as _
|
||||||
|
|
||||||
from . import models
|
from . import models
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -8,271 +8,259 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: kasu.content\n"
|
"Project-Id-Version: kasu.content\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2017-06-19 22:46+0200\n"
|
"POT-Creation-Date: 2023-08-07 20:38+0200\n"
|
||||||
"PO-Revision-Date: 2016-09-28 00:24+0200\n"
|
"PO-Revision-Date: 2018-01-12 15:25+0105\n"
|
||||||
"Last-Translator: Christian Berg <xeniac@posteo.at>\n"
|
"Last-Translator: b'Christian Berg <kasu@xendynastie.at>'\n"
|
||||||
"Language-Team: Deutsch <>\n"
|
"Language-Team: Deutsch <>\n"
|
||||||
"Language: de\n"
|
"Language: de\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
"X-Translated-Using: django-rosetta 0.7.2\n"
|
|
||||||
"X-Generator: Poedit 1.8.9\n"
|
"X-Generator: Poedit 1.8.9\n"
|
||||||
|
"X-Translated-Using: django-rosetta 0.7.14\n"
|
||||||
|
|
||||||
#: content/feeds.py:16
|
#: feeds.py:17 feeds.py:19
|
||||||
msgid "Current news from Kasu"
|
msgid "Current news from Kasu"
|
||||||
msgstr "Aktuelle Nachrichten von Kasu"
|
msgstr "Aktuelle Nachrichten von Kasu"
|
||||||
|
|
||||||
#: content/feeds.py:43
|
#: feeds.py:51
|
||||||
msgid "Latest comments on kasu.at"
|
msgid "Latest comments on kasu.at"
|
||||||
msgstr "Neueste Kommentare auf Kasu.at "
|
msgstr "Neueste Kommentare auf Kasu.at "
|
||||||
|
|
||||||
#: content/feeds.py:44
|
#: feeds.py:52
|
||||||
msgid "Kasu - latest comments"
|
msgid "Kasu - latest comments"
|
||||||
msgstr "Kasu - neue Kommentare"
|
msgstr "Kasu - neue Kommentare"
|
||||||
|
|
||||||
#: content/forms.py:52 content/models.py:308
|
#: forms.py:57 models.py:320
|
||||||
msgid "Please upload a PDF-File to this PDF-Page."
|
msgid "Please upload a PDF-File to this PDF-Page."
|
||||||
msgstr "Bitte eine PDF Datei für diese PDF Seite hochladen."
|
msgstr "Bitte eine PDF Datei für diese PDF Seite hochladen."
|
||||||
|
|
||||||
#: content/models.py:62
|
#: models.py:76
|
||||||
msgid "Headline"
|
msgid "Headline"
|
||||||
msgstr "Schlagzeile"
|
msgstr "Schlagzeile"
|
||||||
|
|
||||||
#: content/models.py:64
|
#: models.py:78
|
||||||
msgid "Content"
|
msgid "Content"
|
||||||
msgstr "Inhalt"
|
msgstr "Inhalt"
|
||||||
|
|
||||||
#: content/models.py:66 content/models.py:137
|
#: models.py:82 models.py:151 templates/content/article_detail.html:28
|
||||||
#: content/templates/content/article_detail.html:25
|
|
||||||
msgid "Category"
|
msgid "Category"
|
||||||
msgstr "Kategorie"
|
msgstr "Kategorie"
|
||||||
|
|
||||||
#: content/models.py:67 content/models.py:130
|
#: models.py:83 models.py:144
|
||||||
msgid "Image"
|
msgid "Image"
|
||||||
msgstr "Bild"
|
msgstr "Bild"
|
||||||
|
|
||||||
#: content/models.py:69 content/models.py:132
|
#: models.py:85 models.py:146
|
||||||
msgid "Slug"
|
msgid "Slug"
|
||||||
msgstr "Slug"
|
msgstr "Slug"
|
||||||
|
|
||||||
#: content/models.py:71 content/templates/content/article_detail.html:23
|
#: models.py:88 templates/content/article_detail.html:21
|
||||||
msgid "Author"
|
msgid "Author"
|
||||||
msgstr "Autor"
|
msgstr "Autor"
|
||||||
|
|
||||||
#: content/models.py:72
|
#: models.py:89
|
||||||
msgid "Status"
|
msgid "Status"
|
||||||
msgstr "Status"
|
msgstr "Status"
|
||||||
|
|
||||||
#: content/models.py:74
|
#: models.py:91
|
||||||
msgid "Created"
|
msgid "Created"
|
||||||
msgstr "Erstellt"
|
msgstr "Erstellt"
|
||||||
|
|
||||||
#: content/models.py:75
|
#: models.py:92
|
||||||
msgid "Modified"
|
msgid "Modified"
|
||||||
msgstr "Bearbeitet"
|
msgstr "Bearbeitet"
|
||||||
|
|
||||||
#: content/models.py:80
|
#: models.py:97
|
||||||
msgid "Article"
|
msgid "Article"
|
||||||
msgstr "Artikel"
|
msgstr "Artikel"
|
||||||
|
|
||||||
#: content/models.py:81
|
#: models.py:98
|
||||||
msgid "Articles"
|
msgid "Articles"
|
||||||
msgstr "Artikel"
|
msgstr "Artikel"
|
||||||
|
|
||||||
#: content/models.py:126 content/models.py:127
|
#: models.py:140 models.py:141
|
||||||
msgid "Name"
|
msgid "Name"
|
||||||
msgstr "Name"
|
msgstr "Name"
|
||||||
|
|
||||||
#: content/models.py:128 content/models.py:129
|
#: models.py:142 models.py:143
|
||||||
msgid "Description"
|
msgid "Description"
|
||||||
msgstr "Beschreibung"
|
msgstr "Beschreibung"
|
||||||
|
|
||||||
#: content/models.py:138
|
#: models.py:152
|
||||||
msgid "Categories"
|
msgid "Categories"
|
||||||
msgstr "Kategorien"
|
msgstr "Kategorien"
|
||||||
|
|
||||||
#: content/models.py:169 content/models.py:175
|
#: models.py:184 models.py:190
|
||||||
msgid "The short name for the menu-entry of this page"
|
msgid "The short name for the menu-entry of this page"
|
||||||
msgstr "Ein kurzer Name für den Menüeintrag"
|
msgstr "Ein kurzer Name für den Menüeintrag"
|
||||||
|
|
||||||
#: content/models.py:180 content/models.py:185
|
#: models.py:195 models.py:200
|
||||||
msgid "The page title as you'd like it to be seen by the public"
|
msgid "The page title as you'd like it to be seen by the public"
|
||||||
msgstr ""
|
msgstr "Der Seitentitel der öffentlich angezeigt werden soll"
|
||||||
|
|
||||||
#: content/models.py:187
|
#: models.py:202
|
||||||
msgid "slug"
|
msgid "slug"
|
||||||
msgstr "Slug"
|
msgstr "Slug"
|
||||||
|
|
||||||
#: content/models.py:190
|
#: models.py:205
|
||||||
msgid ""
|
msgid ""
|
||||||
"The name of the page as it will appear in URLs e.g http://domain.com/blog/"
|
"The name of the page as it will appear in URLs e.g http://domain.com/blog/"
|
||||||
"[my-slug]/"
|
"[my-slug]/"
|
||||||
msgstr ""
|
msgstr "Wie die Seite in der URL aufscheint also http://domain.com/blog/[slug]"
|
||||||
|
|
||||||
#: content/models.py:199
|
#: models.py:214
|
||||||
msgid "Path"
|
msgid "Path"
|
||||||
msgstr "Pfad"
|
msgstr "Pfad"
|
||||||
|
|
||||||
#: content/models.py:211
|
#: models.py:226
|
||||||
msgid "Position"
|
msgid "Position"
|
||||||
msgstr "Position"
|
msgstr "Position"
|
||||||
|
|
||||||
#: content/models.py:216
|
#: models.py:231
|
||||||
msgid "status"
|
msgid "status"
|
||||||
msgstr "Status"
|
msgstr "Status"
|
||||||
|
|
||||||
#: content/models.py:219 content/models.py:221
|
#: models.py:234 models.py:236
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Description"
|
|
||||||
msgid "search description"
|
msgid "search description"
|
||||||
msgstr "Beschreibung"
|
msgstr "Beschreibung für Suchfunktion"
|
||||||
|
|
||||||
#: content/models.py:224
|
#: models.py:239
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Content"
|
|
||||||
msgid "content type"
|
msgid "content type"
|
||||||
msgstr "Inhalt"
|
msgstr "Inhaltstyp"
|
||||||
|
|
||||||
#: content/models.py:229
|
#: models.py:244
|
||||||
msgid "enable comments"
|
msgid "enable comments"
|
||||||
msgstr "Kommentare möglich"
|
msgstr "Kommentare möglich"
|
||||||
|
|
||||||
#: content/models.py:234
|
#: models.py:249
|
||||||
msgid "Template"
|
msgid "Template"
|
||||||
msgstr "Vorlage"
|
msgstr "Vorlage"
|
||||||
|
|
||||||
#: content/models.py:242
|
#: models.py:257
|
||||||
#, fuzzy
|
|
||||||
#| msgid "created on"
|
|
||||||
msgid "first created at"
|
msgid "first created at"
|
||||||
msgstr "erstellt am"
|
msgstr "erstellt am"
|
||||||
|
|
||||||
#: content/models.py:247
|
#: models.py:262
|
||||||
msgid "latest updated at"
|
msgid "latest updated at"
|
||||||
msgstr ""
|
msgstr "letzte Aktualisierung am"
|
||||||
|
|
||||||
#: content/models.py:322
|
#: models.py:333
|
||||||
msgid "Page"
|
msgid "Page"
|
||||||
msgstr "Seite"
|
msgstr "Seite"
|
||||||
|
|
||||||
#: content/models.py:323
|
#: models.py:334
|
||||||
msgid "Pages"
|
msgid "Pages"
|
||||||
msgstr "Seiten"
|
msgstr "Seiten"
|
||||||
|
|
||||||
#: content/templates/content/article_archive.html:5
|
#: templates/content/article_archive.html:5
|
||||||
#: content/templates/content/article_archive.html:20
|
#: templates/content/article_archive.html:20
|
||||||
msgid "Article Archive"
|
msgid "Article Archive"
|
||||||
msgstr "Nachrichtenarchiv"
|
msgstr "Nachrichtenarchiv"
|
||||||
|
|
||||||
#: content/templates/content/article_archive.html:35
|
#: templates/content/article_archive.html:35
|
||||||
#: content/templates/content/article_archive_month.html:5
|
#: templates/content/article_archive_month.html:5
|
||||||
#: content/templates/content/article_archive_year.html:7
|
#: templates/content/article_archive_year.html:7
|
||||||
msgid "Archive"
|
msgid "Archive"
|
||||||
msgstr "Archiv"
|
msgstr "Archiv"
|
||||||
|
|
||||||
#: content/templates/content/article_archive.html:56
|
#: templates/content/article_archive.html:56
|
||||||
msgid "All Categories"
|
msgid "All Categories"
|
||||||
msgstr "Alle Kategorien"
|
msgstr "Alle Kategorien"
|
||||||
|
|
||||||
#: content/templates/content/article_archive.html:71
|
#: templates/content/article_archive.html:71
|
||||||
msgid "created on"
|
msgid "created on"
|
||||||
msgstr "erstellt am"
|
msgstr "erstellt am"
|
||||||
|
|
||||||
#: content/templates/content/article_archive.html:73
|
#: templates/content/article_archive.html:73
|
||||||
msgid "by"
|
msgid "by"
|
||||||
msgstr "von"
|
msgstr "von"
|
||||||
|
|
||||||
#: content/templates/content/article_archive.html:74
|
#: templates/content/article_archive.html:74
|
||||||
#: content/templates/content/article_archive.html:75
|
#: templates/content/article_archive.html:75
|
||||||
msgid "comments"
|
msgid "comments"
|
||||||
msgstr "Kommentare"
|
msgstr "Kommentare"
|
||||||
|
|
||||||
#: content/templates/content/article_archive.html:81
|
#: templates/content/article_archive.html:81
|
||||||
msgid "Read More"
|
msgid "Read More"
|
||||||
msgstr "Mehr lesen"
|
msgstr "Mehr lesen"
|
||||||
|
|
||||||
#: content/templates/content/article_archive.html:86
|
#: templates/content/article_archive.html:86
|
||||||
msgid "We're sorry. Your search yielded no results."
|
msgid "We're sorry. Your search yielded no results."
|
||||||
msgstr "Es tut uns leid. Deine Suche ergab keine Treffer."
|
msgstr "Es tut uns leid. Deine Suche ergab keine Treffer."
|
||||||
|
|
||||||
#: content/templates/content/article_archive.html:104
|
#: templates/content/article_archive.html:104
|
||||||
msgid "Add Article"
|
msgid "Add Article"
|
||||||
msgstr "neuer Artikel "
|
msgstr "neuer Artikel "
|
||||||
|
|
||||||
#: content/templates/content/article_archive_month.html:7
|
#: templates/content/article_archive_month.html:7
|
||||||
msgid "back"
|
msgid "back"
|
||||||
msgstr "Zurück"
|
msgstr "Zurück"
|
||||||
|
|
||||||
#: content/templates/content/article_detail.html:24
|
#: templates/content/article_detail.html:25
|
||||||
msgid "Created on"
|
msgid "Created on"
|
||||||
msgstr "Erstellt am"
|
msgstr "Erstellt am"
|
||||||
|
|
||||||
#: content/templates/content/article_detail.html:36
|
#: templates/content/article_detail.html:39
|
||||||
msgid "share on"
|
msgid "share on"
|
||||||
msgstr "Teile auf"
|
msgstr "Teile auf"
|
||||||
|
|
||||||
#: content/templates/content/article_detail.html:51
|
#: templates/content/article_detail.html:48 views.py:160
|
||||||
#: content/templates/content/article_form.html:20 content/views.py:138
|
|
||||||
msgid "Edit Article"
|
msgid "Edit Article"
|
||||||
msgstr "Artikel bearbeiten"
|
msgstr "Artikel bearbeiten"
|
||||||
|
|
||||||
#: content/templates/content/article_form.html:20 content/views.py:139
|
#: templates/content/article_form.html:24
|
||||||
msgid "Create Article"
|
#: templates/content/article_form.html:31 templates/content/page_form.html:42
|
||||||
msgstr "Artikel erstellen"
|
#: templates/content/page_form.html:49
|
||||||
|
|
||||||
#: content/templates/content/article_form.html:25
|
|
||||||
#: content/templates/content/page_form.html:49
|
|
||||||
#: content/templates/content/page_form.html:56
|
|
||||||
msgid "German"
|
msgid "German"
|
||||||
msgstr "Deutsch"
|
msgstr "Deutsch"
|
||||||
|
|
||||||
#: content/templates/content/article_form.html:26
|
#: templates/content/article_form.html:25
|
||||||
#: content/templates/content/page_form.html:50
|
#: templates/content/article_form.html:39 templates/content/page_form.html:43
|
||||||
#: content/templates/content/page_form.html:64
|
#: templates/content/page_form.html:57
|
||||||
msgid "English"
|
msgid "English"
|
||||||
msgstr "Englisch"
|
msgstr "Englisch"
|
||||||
|
|
||||||
#: content/templates/content/article_form.html:45
|
#: templates/content/article_form.html:47 templates/content/page_form.html:66
|
||||||
#: content/templates/content/page_form.html:73
|
|
||||||
msgid "reset"
|
msgid "reset"
|
||||||
msgstr "Zurücksetzen"
|
msgstr "Zurücksetzen"
|
||||||
|
|
||||||
#: content/templates/content/article_form.html:46
|
#: templates/content/article_form.html:48 templates/content/page_form.html:67
|
||||||
#: content/templates/content/page_form.html:74
|
|
||||||
msgid "save"
|
msgid "save"
|
||||||
msgstr "Speichern"
|
msgstr "Speichern"
|
||||||
|
|
||||||
#: content/templates/content/page_form.html:5
|
#: templates/content/page_form.html:5 templates/content/page_form.html:35
|
||||||
#: content/templates/content/page_form.html:42
|
|
||||||
msgid "Edit Page"
|
msgid "Edit Page"
|
||||||
msgstr "Seite bearbeiten"
|
msgstr "Seite bearbeiten"
|
||||||
|
|
||||||
#: content/templates/content/page_form.html:5
|
#: templates/content/page_form.html:5 templates/content/page_form.html:19
|
||||||
#: content/templates/content/page_form.html:28
|
#: templates/content/page_form.html:35
|
||||||
#: content/templates/content/page_form.html:42
|
|
||||||
msgid "Add Page"
|
msgid "Add Page"
|
||||||
msgstr "Seite hinzufügen"
|
msgstr "Seite hinzufügen"
|
||||||
|
|
||||||
#: content/templates/content/page_form.html:27
|
#: templates/content/page_form.html:18
|
||||||
msgid "Edit"
|
msgid "Edit"
|
||||||
msgstr "Bearbeiten"
|
msgstr "Bearbeiten"
|
||||||
|
|
||||||
#: content/templates/content/page_form.html:44
|
#: templates/content/page_form.html:37
|
||||||
msgid "HTML Specific"
|
msgid "HTML Specific"
|
||||||
msgstr "HTML spezifisch"
|
msgstr "HTML spezifisch"
|
||||||
|
|
||||||
#: content/views.py:35
|
#: views.py:53
|
||||||
msgid "This Category does not exist."
|
msgid "This Category does not exist."
|
||||||
msgstr "Diese Kategorie existiert nicht."
|
msgstr "Diese Kategorie existiert nicht."
|
||||||
|
|
||||||
#: content/views.py:205
|
#: views.py:161
|
||||||
|
msgid "Create Article"
|
||||||
|
msgstr "Artikel erstellen"
|
||||||
|
|
||||||
|
#: views.py:241
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "No Page found matching the Path %s"
|
msgid "No Page found matching the Path %s"
|
||||||
msgstr "Keine Seite unter dem Pfad %s gefunden"
|
msgstr "Keine Seite unter dem Pfad %s gefunden"
|
||||||
|
|
||||||
#: content/views.py:219
|
#: views.py:270
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "No PDF Document found matching the Path %s"
|
msgid "No PDF Document found matching the Path %s"
|
||||||
msgstr "Kein PDF Dokument unter dem Pfad %s gefunden."
|
msgstr "Kein PDF Dokument unter dem Pfad %s gefunden."
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import migrations
|
from django.db import migrations
|
||||||
from django.db import models
|
|
||||||
import ckeditor.fields
|
import ckeditor.fields
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ from django.db import migrations, models
|
|||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
('content', '0005_auto_20161012_2236'),
|
('content', '0005_auto_20161012_2236'),
|
||||||
]
|
]
|
||||||
@@ -16,52 +15,68 @@ class Migration(migrations.Migration):
|
|||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='article',
|
model_name='article',
|
||||||
name='content_de',
|
name='content_de',
|
||||||
field=ckeditor_uploader.fields.RichTextUploadingField(verbose_name='Inhalt'),
|
field=ckeditor_uploader.fields.RichTextUploadingField(
|
||||||
|
verbose_name='Inhalt'),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='article',
|
model_name='article',
|
||||||
name='content_en',
|
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(
|
migrations.AlterField(
|
||||||
model_name='article',
|
model_name='article',
|
||||||
name='headline_en',
|
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(
|
migrations.AlterField(
|
||||||
model_name='article',
|
model_name='article',
|
||||||
name='image',
|
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(
|
migrations.AlterField(
|
||||||
model_name='article',
|
model_name='article',
|
||||||
name='slug',
|
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(
|
migrations.AlterField(
|
||||||
model_name='category',
|
model_name='category',
|
||||||
name='image',
|
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(
|
migrations.AlterField(
|
||||||
model_name='page',
|
model_name='page',
|
||||||
name='content_de',
|
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(
|
migrations.AlterField(
|
||||||
model_name='page',
|
model_name='page',
|
||||||
name='content_en',
|
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(
|
migrations.AlterField(
|
||||||
model_name='page',
|
model_name='page',
|
||||||
name='menu_name_de',
|
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(
|
migrations.AlterField(
|
||||||
model_name='page',
|
model_name='page',
|
||||||
name='menu_name_en',
|
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(
|
migrations.AlterField(
|
||||||
model_name='page',
|
model_name='page',
|
||||||
@@ -76,16 +91,22 @@ class Migration(migrations.Migration):
|
|||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='page',
|
model_name='page',
|
||||||
name='template',
|
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(
|
migrations.AlterField(
|
||||||
model_name='page',
|
model_name='page',
|
||||||
name='title_de',
|
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(
|
migrations.AlterField(
|
||||||
model_name='page',
|
model_name='page',
|
||||||
name='title_en',
|
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'),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import django.db.models.deletion
|
|||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
('content', '0006_auto_20171115_0653'),
|
('content', '0006_auto_20171115_0653'),
|
||||||
]
|
]
|
||||||
@@ -17,11 +16,15 @@ class Migration(migrations.Migration):
|
|||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='article',
|
model_name='article',
|
||||||
name='author',
|
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(
|
migrations.AlterField(
|
||||||
model_name='article',
|
model_name='article',
|
||||||
name='category',
|
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'),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|||||||
74
src/content/migrations/0008_auto_20190106_1954.py
Normal file
74
src/content/migrations/0008_auto_20190106_1954.py
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
# Generated by Django 2.1.5 on 2019-01-06 18:54
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
('content', '0007_auto_20171214_1215'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='article',
|
||||||
|
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'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='page',
|
||||||
|
name='date_modified',
|
||||||
|
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'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='page',
|
||||||
|
name='description_en',
|
||||||
|
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'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='page',
|
||||||
|
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'),
|
||||||
|
),
|
||||||
|
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'),
|
||||||
|
),
|
||||||
|
]
|
||||||
18
src/content/migrations/0009_alter_page_id.py
Normal file
18
src/content/migrations/0009_alter_page_id.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 4.2.2 on 2023-06-11 09:26
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('content', '0008_auto_20190106_1954'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='page',
|
||||||
|
name='id',
|
||||||
|
field=models.AutoField(primary_key=True, serialize=False),
|
||||||
|
),
|
||||||
|
]
|
||||||
20
src/content/migrations/0010_alter_page_parent.py
Normal file
20
src/content/migrations/0010_alter_page_parent.py
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# Generated by Django 4.2.2 on 2023-06-11 13:41
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
('content', '0009_alter_page_id'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
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'),
|
||||||
|
),
|
||||||
|
]
|
||||||
19
src/content/migrations/0011_alter_page_id.py
Normal file
19
src/content/migrations/0011_alter_page_id.py
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# Generated by Django 4.2.2 on 2023-07-19 18:11
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
('content', '0010_alter_page_parent'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='page',
|
||||||
|
name='id',
|
||||||
|
field=models.AutoField(
|
||||||
|
auto_created=True, primary_key=True, serialize=False,
|
||||||
|
verbose_name='ID'),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -8,7 +8,7 @@ from django.template.defaultfilters import slugify
|
|||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.utils.safestring import mark_safe
|
from django.utils.safestring import mark_safe
|
||||||
from django.utils.translation import get_language, ugettext as _
|
from django.utils.translation import get_language, gettext as _
|
||||||
|
|
||||||
from utils import STATUS_CHOICES, STATUS_WAITING, STATUS_PUBLISHED, CLEANER
|
from utils import STATUS_CHOICES, STATUS_WAITING, STATUS_PUBLISHED, CLEANER
|
||||||
|
|
||||||
@@ -111,6 +111,7 @@ class Article(models.Model):
|
|||||||
"""Returns the headline of this article."""
|
"""Returns the headline of this article."""
|
||||||
return self.headline
|
return self.headline
|
||||||
|
|
||||||
|
# noinspection PyUnresolvedReferences
|
||||||
@property
|
@property
|
||||||
def get_image(self):
|
def get_image(self):
|
||||||
"""Return the article image, or the category image if unset."""
|
"""Return the article image, or the category image if unset."""
|
||||||
@@ -169,6 +170,7 @@ class Category(models.Model):
|
|||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection PyUnresolvedReferences
|
||||||
class Page(models.Model):
|
class Page(models.Model):
|
||||||
"""A page on this homepage. It can have a "static" HTML page, the URL of a
|
"""A page on this homepage. It can have a "static" HTML page, the URL of a
|
||||||
dynamic Django view, or a PDF document.
|
dynamic Django view, or a PDF document.
|
||||||
@@ -216,7 +218,7 @@ class Page(models.Model):
|
|||||||
blank=True,
|
blank=True,
|
||||||
null=True,
|
null=True,
|
||||||
related_name='subpages',
|
related_name='subpages',
|
||||||
on_delete=models.SET_NULL
|
on_delete=models.CASCADE
|
||||||
)
|
)
|
||||||
position = models.PositiveSmallIntegerField(
|
position = models.PositiveSmallIntegerField(
|
||||||
blank=True,
|
blank=True,
|
||||||
@@ -317,12 +319,12 @@ class Page(models.Model):
|
|||||||
raise ValidationError(
|
raise ValidationError(
|
||||||
_(u'Please upload a PDF-File to this PDF-Page.'))
|
_(u'Please upload a PDF-File to this PDF-Page.'))
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self) -> str:
|
||||||
"""Return the path with an extension that matches the content type.
|
"""Return the path with an extension that matches the content type.
|
||||||
It's useful for an user to match the URL to the contenttype.
|
It's useful for a user to match the URL to the contenttype.
|
||||||
|
|
||||||
:return: sting with the absolute URL of this page."""
|
:return: string with the absolute URL of this page."""
|
||||||
return '/' + self.path + CONTENT_TYPE_EXTENSIONS[self.content_type]
|
return '/' + str(self.path) + CONTENT_TYPE_EXTENSIONS[self.content_type]
|
||||||
|
|
||||||
class Meta(object):
|
class Meta(object):
|
||||||
"""Set default ordering and an unique priamry key to avoid dupes."""
|
"""Set default ordering and an unique priamry key to avoid dupes."""
|
||||||
|
|||||||
@@ -4,26 +4,22 @@ Created on 03.10.2011
|
|||||||
|
|
||||||
@author: christian
|
@author: christian
|
||||||
"""
|
"""
|
||||||
from django.conf.urls import url
|
from django.urls import path
|
||||||
|
from . import views
|
||||||
from .views import ArticleArchiveIndex, ArticleForm, ArticleYearArchive, \
|
|
||||||
ArticleMonthArchive, ArticleDetail
|
|
||||||
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^$', ArticleArchiveIndex.as_view(), name='article-archive'),
|
path("", views.ArticleArchiveIndex.as_view(), name='article-archive'),
|
||||||
url(r'^add/$', ArticleForm.as_view(), name='add-article'),
|
path('add/', views.ArticleForm.as_view(), name='add-article'),
|
||||||
url(r'^edit/(?P<pk>[\d]+)/$', ArticleForm.as_view(), name='edit-article'),
|
path('edit/<int:pk>/', views.ArticleForm.as_view(), name='edit-article'),
|
||||||
url(r'^(?P<year>[\d]{4})/$', ArticleYearArchive.as_view(),
|
path('<int:year>/', views.ArticleYearArchive.as_view(), name='article-archive'),
|
||||||
|
path('<int:year>/<int:month>/', views.ArticleMonthArchive.as_view(),
|
||||||
name='article-archive'),
|
name='article-archive'),
|
||||||
url(r'^(?P<year>[\d]{4})/(?P<month>[\d]+)/$', ArticleMonthArchive.as_view(),
|
path('<int:year>/<int:month>/<slug:slug>/', views.ArticleDetail.as_view(),
|
||||||
|
name='show-article'),
|
||||||
|
path('<slug:category>/', views.ArticleArchiveIndex.as_view(),
|
||||||
name='article-archive'),
|
name='article-archive'),
|
||||||
url(r'^(?P<year>[\d]{4})/(?P<month>[\d]+)/(?P<slug>[\-\d\w]+)/$',
|
path('<slug:category>/<int:year>/', views.ArticleYearArchive.as_view(),
|
||||||
ArticleDetail.as_view(), name='show-article'),
|
name='article-archive'),
|
||||||
url(r'^(?P<category>[\-\d\w]+)/$', ArticleArchiveIndex.as_view(),
|
path('<slug:category>/<int:year>/<int:month>/', views.ArticleMonthArchive.as_view(),
|
||||||
name='article-archive'),
|
name='article-archive'),
|
||||||
url(r'^(?P<category>[\-\d\w]+)/(?P<year>[\d]{4})/$',
|
|
||||||
ArticleYearArchive.as_view(), name='article-archive'),
|
|
||||||
url(r'^(?P<category>[\-\d\w]+)/(?P<year>[\d]{4})/(?P<month>[\d]+)/$',
|
|
||||||
ArticleMonthArchive.as_view(), name='article-archive'),
|
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ class ArticleSitemap(GenericSitemap):
|
|||||||
min_priority = 0.25
|
min_priority = 0.25
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def items():
|
def items(**kwargs):
|
||||||
"""only add published articles to the sitemap"""
|
"""only add published articles to the sitemap"""
|
||||||
return Article.objects.published()
|
return Article.objects.published()
|
||||||
|
|
||||||
@@ -18,6 +18,6 @@ class PageSitemap(GenericSitemap):
|
|||||||
min_priority = 0.5
|
min_priority = 0.5
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def items():
|
def items(**kwargs):
|
||||||
"""add all pages to the sitemap."""
|
"""add all pages to the sitemap."""
|
||||||
return Page.objects.all()
|
return Page.objects.all()
|
||||||
|
|||||||
@@ -53,10 +53,10 @@
|
|||||||
{% block navigation %}
|
{% block navigation %}
|
||||||
<ul id="navigation">
|
<ul id="navigation">
|
||||||
<li><a href="{{current_top_page.get_absolute_url}}"
|
<li><a href="{{current_top_page.get_absolute_url}}"
|
||||||
{% if not active_category %} class="active" {% endif %}>{% trans 'All Categories' %}</a></li>
|
class="active">{% trans 'All Categories' %}</a></li>
|
||||||
{% for category in categories %}
|
{% for category in categories %}
|
||||||
<li><a href="{% url 'article-archive' category=category.slug %}"
|
<li><a href="{% url 'article-archive' category=category.slug %}"
|
||||||
{% ifequal category.slug active_category.slug %} class="active"{% endifequal %}>{{ category.name }}</a></li>
|
class="active">{{ category.name }}</a></li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@@ -69,7 +69,7 @@
|
|||||||
<h3><a href="{{article.get_absolute_url}}">{{article.headline}}</a></h3>
|
<h3><a href="{{article.get_absolute_url}}">{{article.headline}}</a></h3>
|
||||||
<ul class="info">
|
<ul class="info">
|
||||||
<li><span class="fa fa-calendar-o" title="{% trans 'created on' %}"></span> <time
|
<li><span class="fa fa-calendar-o" title="{% trans 'created on' %}"></span> <time
|
||||||
datetime="{{article.date_created|date:'c'}}">{{ article.date_created|date }}</time></li>
|
datetime="{{article.date_created|date:'Y-m-d\TH:i:sO'}}">{{ article.date_created|date }}</time></li>
|
||||||
<li><span class="fa fa-user" title="{% trans 'by' %}"></span> {{ article.author }}</li>
|
<li><span class="fa fa-user" title="{% trans 'by' %}"></span> {{ article.author }}</li>
|
||||||
<li><span class="fa fa-comments" title="{% trans 'comments' %}"></span> <a
|
<li><span class="fa fa-comments" title="{% trans 'comments' %}"></span> <a
|
||||||
href="{{article.get_absolute_url}}#comments" >{{comment_count}} {% trans "comments" %}</a></li>
|
href="{{article.get_absolute_url}}#comments" >{{comment_count}} {% trans "comments" %}</a></li>
|
||||||
|
|||||||
@@ -1,18 +1,16 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "base.html" %}{% load i18n comments thumbnail %}
|
||||||
{% load i18n comments thumbnail %}
|
|
||||||
|
|
||||||
{% block title %}{{ article.headline }}{% endblock %}
|
{% block title %}{{ article.headline }}{% endblock %}
|
||||||
|
|
||||||
{% block description %}{{article.content|striptags|truncatewords:16}}{% endblock %}
|
{% block description %}{{article.content|striptags|truncatewords:16}}{% endblock %}
|
||||||
|
|
||||||
{% block opengraph %}
|
{% block opengraph %}
|
||||||
<meta property="og:type" content="article" />
|
<meta property="og:type" content="article"/>
|
||||||
<meta property="og:title" content="{{ article.headline|force_escape }}" />
|
<meta property="og:title" content="{{ article.headline|force_escape }}"/>
|
||||||
<meta property="og:url" content="http://www.kasu.at{{ article.get_absolute_url }}" />
|
<meta property="og:url" content="http://www.kasu.at{{ article.get_absolute_url }}"/>
|
||||||
<meta property="og:image" content="http://www.kasu.at{{article.get_image|thumbnail_url:'article'}}" />
|
<meta property="og:image" content="http://www.kasu.at{{article.get_image|thumbnail_url:'article'}}"/>
|
||||||
<meta property="og:description" content="{{article.content|striptags|truncatewords:25|force_escape}}" />
|
<meta property="og:description" content="{{article.content|striptags|truncatewords:25|force_escape}}"/>
|
||||||
<link rel="image_src" type="image/jpeg" href="{{article.get_image|thumbnail_url:'article'}}" />
|
<link rel="image_src" type="image/jpeg" href="{{article.get_image|thumbnail_url:'article'}}"/>{% endblock %}
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block itemscope %}itemscope itemtype="http://schema.org/Article"{% endblock %}
|
{% block itemscope %}itemscope itemtype="http://schema.org/Article"{% endblock %}
|
||||||
|
|
||||||
@@ -20,34 +18,31 @@
|
|||||||
<h1 itemprop="name">{{article.headline}}</h1>
|
<h1 itemprop="name">{{article.headline}}</h1>
|
||||||
<div id="teaser_text">
|
<div id="teaser_text">
|
||||||
<ul class="info">
|
<ul class="info">
|
||||||
<li><span class="fa fa-user"></span> <strong>{% trans 'Author' %}:</strong> <a href="{% url 'membership-details' article.author %}" itemprop="author">{{article.author}}</a></li>
|
<li><span class="fa fa-user"></span> <strong>{% trans 'Author' %}:</strong>
|
||||||
<li><span class="fa fa-calendar-o"></span> <strong>{% trans 'Created on' %}: </strong><time datetime="{{article.date_created|date:'Y-m-d H:i'}}">{{ article.date_created|date:'DATE_FORMAT' }}</time></li>
|
<a href="{% url 'membership-details' article.author %}" itemprop="author">{{article.author}}</a>
|
||||||
<li><span class="fa fa-tag"></span> <strong>{% trans "Category"%}: </strong><a href="{{ article.category.get_absolute_url }}" itemprop="articleSection">{{article.category.name}}</a></li>
|
</li>
|
||||||
|
<li><span class="fa fa-calendar-o"></span>
|
||||||
|
<strong>{% trans 'Created on' %}:</strong>
|
||||||
|
<time datetime="{{article.date_created|date:'Y-m-d\TH:i:sO'}}">{{ article.date_created|date:'DATE_FORMAT' }}</time>
|
||||||
|
</li>
|
||||||
|
<li><span class="fa fa-tag"></span> <strong>{% trans "Category"%}:</strong>
|
||||||
|
<a href="{{ article.category.get_absolute_url }}" itemprop="articleSection">{{article.category.name}}</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>{% endblock %}
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block maincontent %}
|
{% block maincontent %}
|
||||||
<div itemprop="articleBody" class="grid_12">
|
<div itemprop="articleBody" class="grid_12">
|
||||||
<img alt="{{article.category.name}}" src="{{article.get_image|thumbnail_url:'article'}}" class="posting_image" itemprop="image"/>
|
<img alt="{{article.category.name}}" src="{{article.get_image|thumbnail_url:'article'}}" class="posting_image" itemprop="image"/> {{ article.content }}
|
||||||
{{ article.content }}
|
|
||||||
</div>
|
</div>
|
||||||
<p class="right">
|
<p class="right">
|
||||||
<strong>{% trans 'share on' %}:</strong>
|
<strong>{% trans 'share on' %}:</strong>
|
||||||
<a class="button" href="https://plus.google.com/share?url=http%3A%2F%2Fwww.kasu.at{{article.get_absolute_url|urlencode}}"
|
<a class="button" href="https://plus.google.com/share?url=http%3A%2F%2Fwww.kasu.at{{article.get_absolute_url|urlencode}}" onclick="javascript:window.open(this.href,'', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="fa fa-google-plus"></span> Google+</a>
|
||||||
onclick="javascript:window.open(this.href,'', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="fa fa-google-plus"></span> Google+</a>
|
|
||||||
<a class="button" href="https://twitter.com/share?url=http%3A%2F%2Fwww.kasu.at{{article.get_absolute_url|urlencode}}" target='_blank'><span class="fa fa-twitter"></span> Twitter</a>
|
<a class="button" href="https://twitter.com/share?url=http%3A%2F%2Fwww.kasu.at{{article.get_absolute_url|urlencode}}" target='_blank'><span class="fa fa-twitter"></span> Twitter</a>
|
||||||
<a class="button" href="http://facebook.com/sharer.php?u=http%3A%2F%2Fwww.kasu.at{{article.get_absolute_url|urlencode}}?t={{article.headline|urlencode}}" target="_blank"><span class="fa fa-facebook"></span> Facebook</a>
|
<a class="button" href="http://facebook.com/sharer.php?u=http%3A%2F%2Fwww.kasu.at{{article.get_absolute_url|urlencode}}?t={{article.headline|urlencode}}" target="_blank"><span class="fa fa-facebook"></span> Facebook</a>
|
||||||
</p>
|
</p>{% endblock %}
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block comments%}
|
{% block comments%}{% render_comment_list for article %}{% render_comment_form for article %}{% endblock %}
|
||||||
{% render_comment_list for article %}
|
|
||||||
{% render_comment_form for article %}
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block buttonbar %}
|
{% block buttonbar %}{% if perms.content.change_article %}
|
||||||
{% if perms.content.change_article %}
|
<a href="{% url 'edit-article' article.id %}" class="button"><span class="fa fa-pencil"></span> {% trans "Edit Article" %}</a>{% endif %}{% endblock %}
|
||||||
<a href="{% url 'edit-article' article.id %}" class="button"><span class="fa fa-pencil"></span> {% trans "Edit Article" %}</a>
|
|
||||||
{% endif %}
|
|
||||||
{% endblock %}
|
|
||||||
|
|||||||
@@ -9,51 +9,39 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block maincontent %}
|
{% block maincontent %}
|
||||||
|
{% get_fieldset "category, image" from form as fieldset_common %}
|
||||||
|
{% get_fieldset "headline_de" from form as fieldset_de %}
|
||||||
|
{% get_fieldset "headline_en" from form as fieldset_en %}
|
||||||
|
|
||||||
<form action="" method="post" enctype="multipart/form-data">
|
<form action="" method="post" enctype="multipart/form-data">
|
||||||
{{ form.media }} {% csrf_token %}
|
{{ form.media }} {% csrf_token %}
|
||||||
|
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<div>
|
{% with fieldset_common as form %}{% include "form.html" %}{% endwith %}
|
||||||
<label for="id_category" class="field_name {{ form.category.css_classes }}">{{ form.category.label}}</label>
|
|
||||||
{{ form.category }}
|
|
||||||
{% if form.category.help_text %}<p class="help_text">{{form.category.help_text}}</p>{% endif %}
|
|
||||||
{% if form.category.errors %}{{ form.category.errors }}{% endif %}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label for="id_image" class="field_name {{ form.image.css_classes }}">{{ form.image.label}}</label>
|
|
||||||
{{ form.image }}
|
|
||||||
{% if form.image.help_text %}<p class="help_text">{{form.image.help_text}}</p>{% endif %}
|
|
||||||
{% if form.image.errors %}{{ form.image.errors }}{% endif %}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<ul class="tabs grid_12">
|
<ul class="tabs">
|
||||||
<li><a href="#de">{% trans "German" %}</a></li>
|
<li><a href="#de">{% trans "German" %}</a></li>
|
||||||
<li><a href="#en">{% trans "English" %}</a></li>
|
<li><a href="#en">{% trans "English" %}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<label for="id_{{ form.headline_de.html_name }}" class="fieldname {{ form.headline_de.css_classes }}">
|
|
||||||
{{ form.headline_de.label }}</label>
|
|
||||||
<p class="grid_10">{{ form.headline_de }}</p>
|
|
||||||
|
|
||||||
<div class="tab_container">
|
<div class="tab_container">
|
||||||
<div id="de" class="tab_content">
|
<section id="de" class="tab_content">
|
||||||
<fieldset>
|
<fieldset class="grid_12">
|
||||||
<legend>Deutsch</legend>
|
<legend>{% trans "German" %}</legend>
|
||||||
<label for="id_{{ form.headline_de.html_name }}" class="fieldname {{ form.headline_de.css_classes }}">
|
{% with fieldset_de as form %}{% include "form.html" %}{% endwith %}
|
||||||
{{ form.headline_de.label }}</label>
|
|
||||||
<p class="grid_10">{{ form.headline_de }}</p>
|
|
||||||
</fieldset>
|
</fieldset>
|
||||||
{{ form.content_de }}
|
<br>
|
||||||
</div>
|
{{form.content_de}}
|
||||||
<div id="en" class="tab_content">
|
</section>
|
||||||
<h3 class="grid_12">English</h3>
|
<section id="en" class="tab_content">
|
||||||
<label for="id_{{ form.headline_en.html_name }}" class="grid_2 {{ form.headline_en.css_classes }}">
|
<fieldset class="grid_12">
|
||||||
{{ form.headline_en.label }}</label>
|
<legend>{% trans "English" %}</legend>
|
||||||
<p class="grid_10">{{ form.headline_en }}</p>
|
{% with fieldset_en as form %}{% include "form.html" %}{% endwith %}
|
||||||
<p> </p>
|
</fieldset>
|
||||||
{{ form.content_en }}
|
<br>
|
||||||
</div>
|
{{form.content_en}}
|
||||||
|
</section>
|
||||||
</div>
|
</div>
|
||||||
<p class="buttonbar">
|
<p class="buttonbar">
|
||||||
<button type="reset"><span class="fa fa-undo"></span> {% trans 'reset' %}</button>
|
<button type="reset"><span class="fa fa-undo"></span> {% trans 'reset' %}</button>
|
||||||
|
|||||||
@@ -1,66 +0,0 @@
|
|||||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>{% block title %}{{page.title}}{% endblock %}</title>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
|
||||||
<style>
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Amerika Sans';
|
|
||||||
src: url('{{ STATIC_ROOT }}/fonts/amerika_sans.ttf');
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Philosopher';
|
|
||||||
src: url('{{ STATIC_ROOT }}/fonts/philosopher-regular.ttf');
|
|
||||||
font-weight: normal;
|
|
||||||
font-style: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1,h2,h3,h4,h5,h6 {
|
|
||||||
font-family: 'Amerika Sans', Helvetica;
|
|
||||||
font-variant: small-caps;
|
|
||||||
font-weight: bold;
|
|
||||||
margin: 0.5em 0 0.2em 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
font-family: Philosopher;
|
|
||||||
font-size: 12pt;
|
|
||||||
}
|
|
||||||
|
|
||||||
#page_header {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
@page {
|
|
||||||
margin-right: 0;
|
|
||||||
margin-bottom: 0;
|
|
||||||
margin-top: 35mm;
|
|
||||||
margin-left: 2cm;
|
|
||||||
@frame header {
|
|
||||||
-pdf-frame-content : page_header;
|
|
||||||
top: 0;
|
|
||||||
margin: 5mm;
|
|
||||||
height: 4cm;
|
|
||||||
}
|
|
||||||
@frame footer {
|
|
||||||
-pdf-frame-content: page_footer;
|
|
||||||
bottom: 0cm;
|
|
||||||
height: 2cm;
|
|
||||||
margin: 5mm;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>{{ page.title }}</h1>
|
|
||||||
{{ page.content }}
|
|
||||||
<div id="page_header">
|
|
||||||
<img src="{{STATIC_ROOT}}/img/logo.png" alt="Kasu">
|
|
||||||
</div>
|
|
||||||
<div id="page_footer">
|
|
||||||
{{ page.title }} Seite:
|
|
||||||
<pdf:pagenumber />
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -5,7 +5,7 @@ from csp.decorators import csp_update
|
|||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.auth.mixins import PermissionRequiredMixin
|
from django.contrib.auth.mixins import PermissionRequiredMixin
|
||||||
from django.http import HttpResponse, Http404
|
from django.http import HttpResponse, Http404
|
||||||
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, forms
|
from . import models, forms
|
||||||
@@ -19,7 +19,7 @@ class WYSIWYGEditorMixin(PermissionRequiredMixin):
|
|||||||
|
|
||||||
@csp_update(SCRIPT_SRC="'unsafe-eval'")
|
@csp_update(SCRIPT_SRC="'unsafe-eval'")
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
"""Add "unsafe-eval" to the Content-Secuirty-Policy HTTP Headers for the
|
"""Add "unsafe-eval" to the Content-Security-Policy HTTP Headers for the
|
||||||
WYSIWYG Editor.
|
WYSIWYG Editor.
|
||||||
|
|
||||||
:param request: the HTTP Request Object
|
:param request: the HTTP Request Object
|
||||||
@@ -40,7 +40,7 @@ class ArticleArchiveMixin(object):
|
|||||||
Filter the queryset by category if one has been specified in the URL
|
Filter the queryset by category if one has been specified in the URL
|
||||||
|
|
||||||
:param queryset: an model.Article.objects Queryset
|
:param queryset: an model.Article.objects Queryset
|
||||||
:return: an model.Article.objects Queryset filterd by category
|
:return: an model.Article.objects Queryset filtered by category
|
||||||
"""
|
"""
|
||||||
|
|
||||||
category_slug = self.kwargs.get('category')
|
category_slug = self.kwargs.get('category')
|
||||||
@@ -90,7 +90,7 @@ class ArticleArchiveIndex(ArticleArchiveMixin, generic.ArchiveIndexView):
|
|||||||
|
|
||||||
class ArticleYearArchive(ArticleArchiveMixin, generic.YearArchiveView):
|
class ArticleYearArchive(ArticleArchiveMixin, generic.YearArchiveView):
|
||||||
"""
|
"""
|
||||||
Displays the Articles filterd by a specific year
|
Displays the Articles filtered by a specific year
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = models.Article.objects.filter(status=models.STATUS_PUBLISHED)
|
queryset = models.Article.objects.filter(status=models.STATUS_PUBLISHED)
|
||||||
@@ -113,7 +113,7 @@ class ArticleYearArchive(ArticleArchiveMixin, generic.YearArchiveView):
|
|||||||
|
|
||||||
class ArticleMonthArchive(ArticleArchiveMixin, generic.MonthArchiveView):
|
class ArticleMonthArchive(ArticleArchiveMixin, generic.MonthArchiveView):
|
||||||
"""
|
"""
|
||||||
Displays the Articles filterd by a specific month
|
Displays the Articles filtered by a specific month
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = models.Article.objects.filter(status=models.STATUS_PUBLISHED)
|
queryset = models.Article.objects.filter(status=models.STATUS_PUBLISHED)
|
||||||
@@ -139,7 +139,11 @@ class ArticleDetail(generic.DetailView):
|
|||||||
Render the news Article, but only if it got published.
|
Render the news Article, but only if it got published.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
queryset = models.Article.objects.filter(status=models.STATUS_PUBLISHED)
|
queryset = models.Article.objects.filter(status=models.STATUS_PUBLISHED)
|
||||||
|
queryset = queryset.filter(date_created__year=self.kwargs['year'])
|
||||||
|
queryset = queryset.filter(date_created__month=self.kwargs['month'])
|
||||||
|
return queryset
|
||||||
|
|
||||||
|
|
||||||
class ArticleForm(WYSIWYGEditorMixin, generic.UpdateView):
|
class ArticleForm(WYSIWYGEditorMixin, generic.UpdateView):
|
||||||
@@ -170,7 +174,7 @@ class ArticleForm(WYSIWYGEditorMixin, generic.UpdateView):
|
|||||||
|
|
||||||
|
|
||||||
class PageAddForm(WYSIWYGEditorMixin, generic.CreateView):
|
class PageAddForm(WYSIWYGEditorMixin, generic.CreateView):
|
||||||
""" Renders an Form to create a new page for users with conforming
|
""" Renders a Form to create a new page for users with conforming
|
||||||
permissions."""
|
permissions."""
|
||||||
|
|
||||||
form_class = forms.PageForm
|
form_class = forms.PageForm
|
||||||
@@ -179,6 +183,7 @@ class PageAddForm(WYSIWYGEditorMixin, generic.CreateView):
|
|||||||
|
|
||||||
def get_initial(self):
|
def get_initial(self):
|
||||||
"""Try to get the path of the parent page as initial data."""
|
"""Try to get the path of the parent page as initial data."""
|
||||||
|
if self.kwargs['path']:
|
||||||
path = os.path.splitext(self.kwargs['path'])[0]
|
path = os.path.splitext(self.kwargs['path'])[0]
|
||||||
if path.startswith('/'):
|
if path.startswith('/'):
|
||||||
path = path[1:]
|
path = path[1:]
|
||||||
@@ -186,10 +191,12 @@ class PageAddForm(WYSIWYGEditorMixin, generic.CreateView):
|
|||||||
path = path[:-1]
|
path = path[:-1]
|
||||||
parent = models.Page.objects.get(path=path)
|
parent = models.Page.objects.get(path=path)
|
||||||
return {'parent': parent}
|
return {'parent': parent}
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
class PageEditForm(WYSIWYGEditorMixin, generic.UpdateView):
|
class PageEditForm(WYSIWYGEditorMixin, generic.UpdateView):
|
||||||
"""Renders an Form to edit a page for users with conforming permissions."""
|
"""Renders a Form to edit a page for users with conforming permissions."""
|
||||||
|
|
||||||
form_class = forms.PageForm
|
form_class = forms.PageForm
|
||||||
model = models.Page
|
model = models.Page
|
||||||
@@ -198,13 +205,14 @@ class PageEditForm(WYSIWYGEditorMixin, generic.UpdateView):
|
|||||||
def get_object(self, queryset=None):
|
def get_object(self, queryset=None):
|
||||||
""" Get the path from the URL and fetch the corresponding page.
|
""" Get the path from the URL and fetch the corresponding page.
|
||||||
|
|
||||||
First get the path wihout fileextentsion leading or trailing slashes,
|
First get the path without file extension leading or trailing slashes,
|
||||||
then search in the database if such a page exists.
|
then search in the database if such a page exists.
|
||||||
|
|
||||||
:param queryset: Get the single item from this filtered queryset.
|
:param queryset: Get the single item from this filtered queryset.
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
path = os.path.splitext(self.kwargs['path'])[0]
|
path = self.kwargs['path'] or 'index.html'
|
||||||
|
path = os.path.splitext(path)[0]
|
||||||
queryset = queryset or self.get_queryset()
|
queryset = queryset or self.get_queryset()
|
||||||
if path.startswith('/'):
|
if path.startswith('/'):
|
||||||
path = path[1:]
|
path = path[1:]
|
||||||
@@ -266,9 +274,9 @@ class PagePdf(generic.DeleteView):
|
|||||||
def render_to_response(self, context, **response_kwargs):
|
def render_to_response(self, context, **response_kwargs):
|
||||||
"""Stream the PDF File to the client and set the right content headers.
|
"""Stream the PDF File to the client and set the right content headers.
|
||||||
|
|
||||||
:param context: useless only for compatility
|
:param context: useless only for compatibility
|
||||||
:param response_kwargs: will be added to the HttpResponse kwargs.
|
:param response_kwargs: will be added to the HttpResponse kwargs.
|
||||||
:return: an HTTPResponse with PDF Content or an Http404 exception
|
:return: an HTTPResponse with PDF Content or a Http404 exception
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
with open(self.object.pdf_file.path, 'rb') as pdf_file:
|
with open(self.object.pdf_file.path, 'rb') as pdf_file:
|
||||||
@@ -278,8 +286,8 @@ class PagePdf(generic.DeleteView):
|
|||||||
**response_kwargs
|
**response_kwargs
|
||||||
)
|
)
|
||||||
return response
|
return response
|
||||||
except:
|
except FileExistsError:
|
||||||
raise Http404('File not Found %s.pdf' % self.kwargs['path'])
|
raise Http404('File %s.pdf not found' % self.kwargs['path'])
|
||||||
|
|
||||||
|
|
||||||
class StartPage(generic.TemplateView):
|
class StartPage(generic.TemplateView):
|
||||||
@@ -287,7 +295,7 @@ class StartPage(generic.TemplateView):
|
|||||||
template_name = 'index.html'
|
template_name = 'index.html'
|
||||||
|
|
||||||
def get_context_data(self):
|
def get_context_data(self):
|
||||||
""" Adds recent ariticles and recent comments to the context.
|
""" Adds recent articles and recent comments to the context.
|
||||||
|
|
||||||
:return: array() with the context data
|
:return: array() with the context data
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
"""Django admin interface for the event app.
|
"""Django admin interface for the event app.
|
||||||
|
|
||||||
It's the best way to add eventseries, or edit/delete events."""
|
It's the best way to add event-series, or edit/delete events."""
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
|
|
||||||
@@ -8,7 +8,7 @@ from events.models import Event, Photo, Location
|
|||||||
|
|
||||||
|
|
||||||
class EventInline(admin.TabularInline):
|
class EventInline(admin.TabularInline):
|
||||||
"""To list events of an eventseries below the 'master event'"""
|
"""To list events of an event-series below the 'master event'"""
|
||||||
model = Event
|
model = Event
|
||||||
fields = ('name', 'start', 'end')
|
fields = ('name', 'start', 'end')
|
||||||
verbose_name_plural = _('Event Series')
|
verbose_name_plural = _('Event Series')
|
||||||
|
|||||||
@@ -1,20 +1,20 @@
|
|||||||
""" Content processor to display upcoming events on every page you want. """
|
""" Content processor to display upcoming events on every page you want. """
|
||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
|
from django.http import HttpRequest
|
||||||
from .models import Event
|
from .models import Event
|
||||||
|
|
||||||
|
|
||||||
def events_overview(request): # Ignore PyLintBear (W0613)
|
def events_overview(request: HttpRequest) -> dict[str, Event]:
|
||||||
"""
|
"""
|
||||||
Adds event information as variables to the template context on every page.
|
Adds event information as variables to the template context on every page.
|
||||||
|
|
||||||
For speed reasons everything will be cached for an hour. the following
|
For speed reasons everything will be cached for an hour. the following
|
||||||
variables will be added to the template context:
|
variables will be added to the template context:
|
||||||
* current_event: If an event is running at this moment, the correspondi
|
* current_event: object for the currently running event.
|
||||||
event object.
|
|
||||||
* next_event: the next event that is upcoming.
|
* next_event: the next event that is upcoming.
|
||||||
* upcoming_events: the next 3 events that are upcoming.
|
* upcoming_events: the next 3 events that are upcoming.
|
||||||
|
|
||||||
:param request: An Django HTTPRequest object
|
:param request: a Django HTTPRequest object
|
||||||
:return: dict() with the new context variables
|
:return: dict() with the new context variables
|
||||||
"""
|
"""
|
||||||
current_event = cache.get('current_event', False)
|
current_event = cache.get('current_event', False)
|
||||||
|
|||||||
@@ -1,27 +1,42 @@
|
|||||||
"""Django Forms to administrate the event content on the frontend."""
|
"""Django Forms to administrate the event content on the frontend."""
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import gettext as _
|
||||||
|
|
||||||
from . import models
|
from . import models
|
||||||
|
|
||||||
|
|
||||||
|
class ClearableMultipleFileInput(forms.widgets.ClearableFileInput):
|
||||||
|
allow_multiple_selected = True
|
||||||
|
accept = "image/jpg"
|
||||||
|
|
||||||
|
|
||||||
|
class MultipleFileField(forms.FileField):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
kwargs.setdefault("widget", ClearableMultipleFileInput())
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
def clean(self, data, initial=None):
|
||||||
|
single_file_clean = super().clean
|
||||||
|
if isinstance(data, (list, tuple)):
|
||||||
|
result = [single_file_clean(d, initial) for d in data]
|
||||||
|
else:
|
||||||
|
result = single_file_clean(data, initial)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
class PhotoUploadForm(forms.Form):
|
class PhotoUploadForm(forms.Form):
|
||||||
"""Form to upload multiple photos to a single event."""
|
"""Form to upload multiple photos to a single event.
|
||||||
|
TODO: Check multiple upload
|
||||||
|
"""
|
||||||
error_css_class = 'error'
|
error_css_class = 'error'
|
||||||
required_css_class = 'required'
|
required_css_class = 'required'
|
||||||
photographer = forms.ModelChoiceField(get_user_model().objects.all(),
|
photographer = forms.ModelChoiceField(get_user_model().objects.all(),
|
||||||
required=True, )
|
required=True, )
|
||||||
event = forms.ModelChoiceField(models.Event.objects.all(), required=True, )
|
event = forms.ModelChoiceField(models.Event.objects.all(), required=True, )
|
||||||
upload = forms.FileField(
|
upload = MultipleFileField(
|
||||||
label=_('Images'),
|
label=_('Images'),
|
||||||
required=True,
|
required=True,
|
||||||
widget=forms.widgets.ClearableFileInput(
|
|
||||||
attrs={
|
|
||||||
'multiple': 'multiple',
|
|
||||||
'accept': "image/gif,image/png,image/jpeg"
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,17 @@
|
|||||||
""" urls for the event gallery part of the events app. """
|
from django.urls import path
|
||||||
from django.conf.urls import url
|
|
||||||
|
|
||||||
from . import views
|
from . import views
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^$', views.EventGallery.as_view(), name='event-gallery'),
|
path("", views.EventGallery.as_view(), name='event-gallery'),
|
||||||
url(r'^(?P<event>[\d]+)/$', views.EventPhotoList.as_view(),
|
path('<int:event>/', views.EventPhotoList.as_view(),
|
||||||
name='event-photo-list'),
|
name='event-photo-list'),
|
||||||
url(r'^(?P<event>[\d]+)/upload/$', views.EventPhotoUpload.as_view(),
|
path('<int:event>/upload/', views.EventPhotoUpload.as_view(),
|
||||||
name='event-photo-upload'),
|
name='event-photo-upload'),
|
||||||
url(r'^(?P<event>[\d]+)/(?P<pk>[\d]+)/$', views.EventPhoto.as_view(),
|
path('<int:event>/<int:pk>/', views.EventPhoto.as_view(),
|
||||||
name='event-photo'),
|
name='event-photo'),
|
||||||
url(r'^delete/(?P<pk>[\d]+)/$', views.DeleteEventPhoto.as_view(),
|
path('delete/<int:pk>/', views.DeleteEventPhoto.as_view(),
|
||||||
name='delete-event-photo'),
|
name='delete-event-photo'),
|
||||||
url(r'^upload/$', views.EventPhotoUpload.as_view(),
|
path('upload/', views.EventPhotoUpload.as_view(),
|
||||||
name='event-photo-upload'),
|
name='event-photo-upload'),
|
||||||
]
|
]
|
||||||
|
|||||||
Binary file not shown.
@@ -7,9 +7,9 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: kasu.events\n"
|
"Project-Id-Version: kasu.events\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2017-06-19 22:46+0200\n"
|
"POT-Creation-Date: 2023-08-07 20:38+0200\n"
|
||||||
"PO-Revision-Date: 2016-09-28 00:24+0200\n"
|
"PO-Revision-Date: 2018-01-12 15:25+0105\n"
|
||||||
"Last-Translator: Christian Berg <xeniac@posteo.at>\n"
|
"Last-Translator: b'Christian Berg <kasu@xendynastie.at>'\n"
|
||||||
"Language-Team: Kasu <verein@kasu.at>\n"
|
"Language-Team: Kasu <verein@kasu.at>\n"
|
||||||
"Language: de\n"
|
"Language: de\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
@@ -17,60 +17,60 @@ msgstr ""
|
|||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
"X-Generator: Poedit 1.8.9\n"
|
"X-Generator: Poedit 1.8.9\n"
|
||||||
"X-Translated-Using: django-rosetta 0.7.6\n"
|
"X-Translated-Using: django-rosetta 0.7.14\n"
|
||||||
|
|
||||||
#: events/admin.py:14 events/models.py:82
|
#: admin.py:14 models.py:83
|
||||||
msgid "Event Series"
|
msgid "Event Series"
|
||||||
msgstr "Veranstaltungsreihen"
|
msgstr "Veranstaltungsreihen"
|
||||||
|
|
||||||
#: events/forms.py:18
|
#: forms.py:38
|
||||||
msgid "Images"
|
msgid "Images"
|
||||||
msgstr "Bilder"
|
msgstr "Bilder"
|
||||||
|
|
||||||
#: events/forms.py:46
|
#: forms.py:61
|
||||||
msgid "start"
|
msgid "start"
|
||||||
msgstr "Beginn"
|
msgstr "Beginn"
|
||||||
|
|
||||||
#: events/forms.py:50
|
#: forms.py:64
|
||||||
msgid "end"
|
msgid "end"
|
||||||
msgstr "Ende"
|
msgstr "Ende"
|
||||||
|
|
||||||
#: events/models.py:52 events/models.py:176 events/models.py:217
|
#: mixins.py:86
|
||||||
|
msgid "Event does not exist"
|
||||||
|
msgstr "Veranstaltung gibt es nicht"
|
||||||
|
|
||||||
|
#: models.py:53 models.py:177 models.py:218
|
||||||
msgid "Name"
|
msgid "Name"
|
||||||
msgstr "Name"
|
msgstr "Name"
|
||||||
|
|
||||||
#: events/models.py:53 events/models.py:177 events/models.py:225
|
#: models.py:54 models.py:178 models.py:226
|
||||||
msgid "Description"
|
msgid "Description"
|
||||||
msgstr "Beschreibung"
|
msgstr "Beschreibung"
|
||||||
|
|
||||||
#: events/models.py:55 events/templates/events/event_detail.html:29
|
#: models.py:56 templates/events/event_detail.html:29
|
||||||
#: events/templates/events/event_detail.html:87
|
#: templates/events/event_detail.html:87 templates/events/event_list.html:28
|
||||||
#: events/templates/events/event_list.html:28
|
|
||||||
#: events/templates/events/photo_upload.html:13
|
|
||||||
msgid "Start"
|
msgid "Start"
|
||||||
msgstr "Beginn"
|
msgstr "Beginn"
|
||||||
|
|
||||||
#: events/models.py:56 events/templates/events/event_detail.html:30
|
#: models.py:57 templates/events/event_detail.html:30
|
||||||
#: events/templates/events/event_detail.html:89
|
#: templates/events/event_detail.html:89
|
||||||
msgid "End"
|
msgid "End"
|
||||||
msgstr "Ende"
|
msgstr "Ende"
|
||||||
|
|
||||||
#: events/models.py:57 events/models.py:185
|
#: models.py:58 models.py:186 templates/events/event_detail.html:34
|
||||||
#: events/templates/events/event_detail.html:34
|
#: templates/events/event_detail.html:80 templates/events/event_detail.html:92
|
||||||
#: events/templates/events/event_detail.html:80
|
|
||||||
#: events/templates/events/event_detail.html:92
|
|
||||||
msgid "Homepage"
|
msgid "Homepage"
|
||||||
msgstr "Homepage"
|
msgstr "Homepage"
|
||||||
|
|
||||||
#: events/models.py:59 events/models.py:179 events/models.py:219
|
#: models.py:60 models.py:180 models.py:220
|
||||||
msgid "Image"
|
msgid "Image"
|
||||||
msgstr "Bild"
|
msgstr "Bild"
|
||||||
|
|
||||||
#: events/models.py:66
|
#: models.py:67
|
||||||
msgid "Mahjong Tournament"
|
msgid "Mahjong Tournament"
|
||||||
msgstr "Mahjong Turnier"
|
msgstr "Mahjong Turnier"
|
||||||
|
|
||||||
#: events/models.py:68
|
#: models.py:69
|
||||||
msgid ""
|
msgid ""
|
||||||
"This event is a tournament, different rules apply for the kyu "
|
"This event is a tournament, different rules apply for the kyu "
|
||||||
"ranking."
|
"ranking."
|
||||||
@@ -78,11 +78,11 @@ msgstr ""
|
|||||||
"Diese Veranstaltung ist ein Turnier, es gelten andere Regeln für das Kyu "
|
"Diese Veranstaltung ist ein Turnier, es gelten andere Regeln für das Kyu "
|
||||||
"Ranking."
|
"Ranking."
|
||||||
|
|
||||||
#: events/models.py:72
|
#: models.py:73
|
||||||
msgid "Mahjong Season"
|
msgid "Mahjong Season"
|
||||||
msgstr "Mahjong Saison"
|
msgstr "Mahjong Saison"
|
||||||
|
|
||||||
#: events/models.py:83
|
#: models.py:84
|
||||||
msgid ""
|
msgid ""
|
||||||
"Wenn dieser Event zu einer Veranstaltungsreihe gehört werden Ort, "
|
"Wenn dieser Event zu einer Veranstaltungsreihe gehört werden Ort, "
|
||||||
"Beschreibung, Bild und Homepage von dem hier angegebenen Event "
|
"Beschreibung, Bild und Homepage von dem hier angegebenen Event "
|
||||||
@@ -91,247 +91,223 @@ msgstr ""
|
|||||||
"Wenn dieser Termin zu einer Veranstaltungsreihe gehört werden Ort, "
|
"Wenn dieser Termin zu einer Veranstaltungsreihe gehört werden Ort, "
|
||||||
"Beschreibung, Bild und Homepage von dem hier angegebenen Event übernommen."
|
"Beschreibung, Bild und Homepage von dem hier angegebenen Event übernommen."
|
||||||
|
|
||||||
#: events/models.py:92 events/models.py:195 events/models.py:247
|
#: models.py:93 models.py:196 models.py:249
|
||||||
msgid "first created at"
|
msgid "first created at"
|
||||||
msgstr ""
|
msgstr "erstellt am"
|
||||||
|
|
||||||
#: events/models.py:97 events/models.py:200 events/models.py:252
|
#: models.py:98 models.py:201 models.py:254
|
||||||
msgid "latest updated at"
|
msgid "latest updated at"
|
||||||
msgstr ""
|
msgstr "letzte Aktualisierung am"
|
||||||
|
|
||||||
#: events/models.py:103
|
#: models.py:104
|
||||||
msgid "Event"
|
msgid "Event"
|
||||||
msgstr "Termin"
|
msgstr "Termin"
|
||||||
|
|
||||||
#: events/models.py:104
|
#: models.py:105
|
||||||
msgid "Events"
|
msgid "Events"
|
||||||
msgstr "Termine"
|
msgstr "Termine"
|
||||||
|
|
||||||
#: events/models.py:117
|
#: models.py:118
|
||||||
msgid "A event can't end before it had started"
|
msgid "A event can't end before it had started"
|
||||||
msgstr "Eine Veranstaltung kann nicht enden bevor sie begonnen hat"
|
msgstr "Eine Veranstaltung kann nicht enden bevor sie begonnen hat"
|
||||||
|
|
||||||
#: events/models.py:186
|
#: models.py:187
|
||||||
msgid "Postal Code"
|
msgid "Postal Code"
|
||||||
msgstr "Postleitzahl"
|
msgstr "Postleitzahl"
|
||||||
|
|
||||||
#: events/models.py:187
|
#: models.py:188
|
||||||
msgid "Street Address"
|
msgid "Street Address"
|
||||||
msgstr "Straße"
|
msgstr "Straße"
|
||||||
|
|
||||||
#: events/models.py:188
|
#: models.py:189
|
||||||
msgid "Locality"
|
msgid "Locality"
|
||||||
msgstr "Ort"
|
msgstr "Ort"
|
||||||
|
|
||||||
#: events/models.py:189
|
#: models.py:190
|
||||||
msgid "Country"
|
msgid "Country"
|
||||||
msgstr "Land"
|
msgstr "Land"
|
||||||
|
|
||||||
#: events/models.py:204
|
#: models.py:205
|
||||||
msgid "Venue"
|
msgid "Venue"
|
||||||
msgstr "Veranstaltungsort"
|
msgstr "Veranstaltungsort"
|
||||||
|
|
||||||
#: events/models.py:205
|
#: models.py:206
|
||||||
msgid "Venues"
|
msgid "Venues"
|
||||||
msgstr "Veranstaltungsorte"
|
msgstr "Veranstaltungsorte"
|
||||||
|
|
||||||
#: events/models.py:231
|
#: models.py:233
|
||||||
msgid "Startpage"
|
msgid "Startpage"
|
||||||
msgstr "Startseite"
|
msgstr "Startseite"
|
||||||
|
|
||||||
#: events/models.py:234
|
#: models.py:236
|
||||||
msgid "Display this Photo on the Startpage Teaser"
|
msgid "Display this Photo on the Startpage Teaser"
|
||||||
msgstr "Foto als Teaser auf der Startseite verwenden."
|
msgstr "Foto als Teaser auf der Startseite verwenden."
|
||||||
|
|
||||||
#: events/models.py:236
|
#: models.py:238
|
||||||
msgid "Published on"
|
msgid "Published on"
|
||||||
msgstr "Veröffentlicht am"
|
msgstr "Veröffentlicht am"
|
||||||
|
|
||||||
#: events/models.py:238
|
#: models.py:240
|
||||||
msgid "Number of views"
|
msgid "Number of views"
|
||||||
msgstr "Wie oft gesehen"
|
msgstr "Wie oft gesehen"
|
||||||
|
|
||||||
#: events/models.py:262 events/templates/events/event_archive.html:38
|
#: models.py:264 templates/events/event_archive.html:38
|
||||||
#: events/templates/events/event_list.html:18
|
#: templates/events/event_list.html:18
|
||||||
msgid "Event Image"
|
msgid "Event Image"
|
||||||
msgstr "Veranstaltungsbild"
|
msgstr "Veranstaltungsbild"
|
||||||
|
|
||||||
#: events/models.py:263
|
#: models.py:265
|
||||||
msgid "Event Images"
|
msgid "Event Images"
|
||||||
msgstr "Veranstaltungsbilder"
|
msgstr "Veranstaltungsbilder"
|
||||||
|
|
||||||
#: events/templates/events/event_archive.html:5
|
#: templates/events/event_archive.html:5 templates/events/event_archive.html:9
|
||||||
#: events/templates/events/event_archive.html:9
|
|
||||||
msgid "Event Archive"
|
msgid "Event Archive"
|
||||||
msgstr "Veranstaltungsarchiv"
|
msgstr "Veranstaltungsarchiv"
|
||||||
|
|
||||||
#: events/templates/events/event_archive.html:42
|
#: templates/events/event_archive.html:42 templates/events/event_detail.html:85
|
||||||
#: events/templates/events/event_detail.html:85
|
#: templates/events/event_list.html:22 templates/events/photo_detail.html:53
|
||||||
#: events/templates/events/event_list.html:22
|
|
||||||
#: events/templates/events/photo_detail.html:53
|
|
||||||
msgid "Date"
|
msgid "Date"
|
||||||
msgstr "Datum"
|
msgstr "Datum"
|
||||||
|
|
||||||
#: events/templates/events/event_archive.html:47
|
#: templates/events/event_archive.html:47
|
||||||
msgid "Time"
|
msgid "Time"
|
||||||
msgstr "Zeit"
|
msgstr "Zeit"
|
||||||
|
|
||||||
#: events/templates/events/event_archive.html:49
|
#: templates/events/event_archive.html:49
|
||||||
#: events/templates/events/photo_upload.html:16
|
|
||||||
msgid "from"
|
msgid "from"
|
||||||
msgstr "von"
|
msgstr "von"
|
||||||
|
|
||||||
#: events/templates/events/event_archive.html:49
|
#: templates/events/event_archive.html:49
|
||||||
#: events/templates/events/photo_upload.html:16
|
|
||||||
msgid "to"
|
msgid "to"
|
||||||
msgstr "bis"
|
msgstr "bis"
|
||||||
|
|
||||||
#: events/templates/events/event_archive.html:57
|
#: templates/events/event_archive.html:57 templates/events/event_detail.html:31
|
||||||
#: events/templates/events/event_detail.html:31
|
#: templates/events/event_detail.html:72 templates/events/event_list.html:32
|
||||||
#: events/templates/events/event_detail.html:72
|
|
||||||
#: events/templates/events/event_list.html:32
|
|
||||||
#: events/templates/events/photo_upload.html:23
|
|
||||||
msgid "Location"
|
msgid "Location"
|
||||||
msgstr "Ort"
|
msgstr "Ort"
|
||||||
|
|
||||||
#: events/templates/events/event_archive.html:58
|
#: templates/events/event_archive.html:58 templates/events/event_list.html:35
|
||||||
#: events/templates/events/event_list.html:35
|
|
||||||
#: events/templates/events/photo_upload.html:25
|
|
||||||
#: events/templates/events/photo_upload.html:26
|
|
||||||
msgid "Comments"
|
msgid "Comments"
|
||||||
msgstr "Kommentare"
|
msgstr "Kommentare"
|
||||||
|
|
||||||
#: events/templates/events/event_archive.html:59
|
#: templates/events/event_archive.html:59 templates/events/event_detail.html:36
|
||||||
#: events/templates/events/event_detail.html:36
|
#: templates/events/event_detail.html:48 templates/events/photo_list.html:4
|
||||||
#: events/templates/events/event_detail.html:48
|
|
||||||
#: events/templates/events/photo_upload.html:28
|
|
||||||
#: events/templates/events/photo_upload.html:29
|
|
||||||
msgid "Photos"
|
msgid "Photos"
|
||||||
msgstr "Fotos"
|
msgstr "Fotos"
|
||||||
|
|
||||||
#: events/templates/events/event_archive.html:60
|
#: templates/events/event_archive.html:60
|
||||||
#: events/templates/events/event_archive.html:61
|
#: templates/events/event_archive.html:61 templates/events/event_detail.html:35
|
||||||
#: events/templates/events/event_detail.html:35
|
#: templates/events/event_detail.html:51
|
||||||
#: events/templates/events/event_detail.html:51
|
|
||||||
msgid "Hanchans"
|
msgid "Hanchans"
|
||||||
msgstr "Hanchans"
|
msgstr "Hanchans"
|
||||||
|
|
||||||
#: events/templates/events/event_detail.html:37
|
#: templates/events/event_detail.html:37
|
||||||
msgid "tourney"
|
msgid "tourney"
|
||||||
msgstr "Turnier"
|
msgstr "Turnier"
|
||||||
|
|
||||||
#: events/templates/events/event_detail.html:37
|
#: templates/events/event_detail.html:37
|
||||||
msgid "other rules apply here"
|
msgid "other rules apply here"
|
||||||
msgstr "hier gelten andere Regeln"
|
msgstr "hier gelten andere Regeln"
|
||||||
|
|
||||||
#: events/templates/events/event_detail.html:45
|
#: templates/events/event_detail.html:45
|
||||||
msgid "Info"
|
msgid "Info"
|
||||||
msgstr "Info"
|
msgstr "Info"
|
||||||
|
|
||||||
#: events/templates/events/event_detail.html:54
|
#: templates/events/event_detail.html:54
|
||||||
msgid "Mai-Star Games"
|
msgid "Mai-Star Games"
|
||||||
msgstr "Mai-Star Spiele"
|
msgstr "Mai-Star Spiele"
|
||||||
|
|
||||||
#: events/templates/events/event_detail.html:57
|
#: templates/events/event_detail.html:57
|
||||||
msgid "Event Ranking"
|
msgid "Event Ranking"
|
||||||
msgstr "Veranstaltungs Wertung"
|
msgstr "Veranstaltungs Wertung"
|
||||||
|
|
||||||
#: events/templates/events/event_detail.html:100
|
#: templates/events/event_detail.html:100
|
||||||
msgid "Share on Facebook"
|
msgid "Share on Facebook"
|
||||||
msgstr "Auf Facebook teilen"
|
msgstr "Auf Facebook teilen"
|
||||||
|
|
||||||
#: events/templates/events/event_detail.html:104
|
#: templates/events/event_detail.html:104
|
||||||
msgid "Share on Google+"
|
msgid "Share on Google+"
|
||||||
msgstr "Auf Google+ teilen"
|
msgstr "Auf Google+ teilen"
|
||||||
|
|
||||||
#: events/templates/events/event_detail.html:109
|
#: templates/events/event_detail.html:109
|
||||||
msgid "Share on Twitter"
|
msgid "Share on Twitter"
|
||||||
msgstr "Auf Twitter teilen"
|
msgstr "Auf Twitter teilen"
|
||||||
|
|
||||||
#: events/templates/events/event_detail.html:113
|
#: templates/events/event_detail.html:113
|
||||||
msgid "Show on Google Maps"
|
msgid "Show on Google Maps"
|
||||||
msgstr "Auf Google Maps zeigen"
|
msgstr "Auf Google Maps zeigen"
|
||||||
|
|
||||||
#: events/templates/events/event_detail.html:127
|
#: templates/events/event_detail.html:127 templates/events/event_form.html:9
|
||||||
#: events/templates/events/event_form.html:9 events/views.py:104
|
#: views.py:61
|
||||||
msgid "Edit Event"
|
msgid "Edit Event"
|
||||||
msgstr "Termin bearbeiten"
|
msgstr "Termin bearbeiten"
|
||||||
|
|
||||||
#: events/templates/events/event_detail.html:131
|
#: templates/events/event_detail.html:131
|
||||||
msgid "Add Dates"
|
msgid "Add Dates"
|
||||||
msgstr "Termine hinzufügen"
|
msgstr "Termine hinzufügen"
|
||||||
|
|
||||||
#: events/templates/events/event_form.html:9
|
#: templates/events/event_form.html:9 templates/events/page.html:9 views.py:61
|
||||||
#: events/templates/events/page.html:9 events/views.py:106
|
|
||||||
msgid "Add Event"
|
msgid "Add Event"
|
||||||
msgstr "Neuer Termin"
|
msgstr "Neuer Termin"
|
||||||
|
|
||||||
#: events/templates/events/event_form.html:18
|
#: templates/events/event_form.html:18 templates/events/photo_list.html:35
|
||||||
#: events/templates/events/photo_list.html:35
|
|
||||||
msgid "reset"
|
msgid "reset"
|
||||||
msgstr "Zurücksetzen"
|
msgstr "Zurücksetzen"
|
||||||
|
|
||||||
#: events/templates/events/event_form.html:19
|
#: templates/events/event_form.html:19
|
||||||
#: events/templates/events/eventseries_form.html:25
|
#: templates/events/eventseries_form.html:25
|
||||||
msgid "save"
|
msgid "save"
|
||||||
msgstr "Speichern"
|
msgstr "Speichern"
|
||||||
|
|
||||||
#: events/templates/events/event_list.html:4
|
#: templates/events/event_list.html:4 templates/events/event_list.html:5
|
||||||
#: events/templates/events/event_list.html:5
|
|
||||||
msgid "Upcoming Events"
|
msgid "Upcoming Events"
|
||||||
msgstr "Bevorstehende Veranstaltungen"
|
msgstr "Bevorstehende Veranstaltungen"
|
||||||
|
|
||||||
#: events/templates/events/eventseries_form.html:24
|
#: templates/events/eventseries_form.html:24
|
||||||
msgid "back"
|
msgid "back"
|
||||||
msgstr "Zurück"
|
msgstr "Zurück"
|
||||||
|
|
||||||
#: events/templates/events/photo_confirm_delete.html:17
|
#: templates/events/photo_confirm_delete.html:17
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Abbrechen"
|
msgstr "Abbrechen"
|
||||||
|
|
||||||
#: events/templates/events/photo_confirm_delete.html:21
|
#: templates/events/photo_confirm_delete.html:21
|
||||||
#: events/templates/events/photo_list.html:21
|
#: templates/events/photo_list.html:21
|
||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr "Löschen"
|
msgstr "Löschen"
|
||||||
|
|
||||||
#: events/templates/events/photo_detail.html:44
|
#: templates/events/photo_detail.html:44
|
||||||
msgid "previous"
|
msgid "previous"
|
||||||
msgstr "Zurück"
|
msgstr "Zurück"
|
||||||
|
|
||||||
#: events/templates/events/photo_detail.html:52
|
#: templates/events/photo_detail.html:52
|
||||||
msgid "Photographer"
|
msgid "Photographer"
|
||||||
msgstr "Fotograf"
|
msgstr "Fotograf"
|
||||||
|
|
||||||
#: events/templates/events/photo_detail.html:58
|
#: templates/events/photo_detail.html:58
|
||||||
msgid "share on"
|
msgid "share on"
|
||||||
msgstr "Teile auf"
|
msgstr "Teile auf"
|
||||||
|
|
||||||
#: events/templates/events/photo_detail.html:81
|
#: templates/events/photo_detail.html:78
|
||||||
msgid "download"
|
msgid "download"
|
||||||
msgstr "Herunterladen"
|
msgstr "Herunterladen"
|
||||||
|
|
||||||
#: events/templates/events/photo_detail.html:82
|
#: templates/events/photo_detail.html:79
|
||||||
msgid "Rotate counter clockwise"
|
msgid "Rotate counter clockwise"
|
||||||
msgstr "mit dem Uhrzeiger drehen"
|
msgstr "mit dem Uhrzeiger drehen"
|
||||||
|
|
||||||
#: events/templates/events/photo_detail.html:83
|
#: templates/events/photo_detail.html:80
|
||||||
msgid "Rotate clockwise"
|
msgid "Rotate clockwise"
|
||||||
msgstr "gegen den Uhrzeiger drehen"
|
msgstr "gegen den Uhrzeiger drehen"
|
||||||
|
|
||||||
#: events/templates/events/photo_detail.html:84
|
#: templates/events/photo_detail.html:81
|
||||||
msgid "Save"
|
msgid "Save"
|
||||||
msgstr "Speichern"
|
msgstr "Speichern"
|
||||||
|
|
||||||
#: events/templates/events/photo_list.html:36
|
#: templates/events/photo_list.html:36 templates/events/photo_upload.html:13
|
||||||
#: events/templates/events/photo_upload.html:35
|
|
||||||
#: events/templates/events/photo_upload.html:49
|
|
||||||
msgid "Upload"
|
msgid "Upload"
|
||||||
msgstr "Hochladen"
|
msgstr "Hochladen"
|
||||||
|
|
||||||
#: events/views.py:203
|
|
||||||
msgid "Event does not exist"
|
|
||||||
msgstr "Veranstaltung gibt es nicht"
|
|
||||||
|
|
||||||
#~ msgid " Edit"
|
#~ msgid " Edit"
|
||||||
#~ msgstr "Bearbeiten"
|
#~ msgstr "Bearbeiten"
|
||||||
|
|
||||||
|
|||||||
@@ -29,16 +29,21 @@ class Migration(migrations.Migration):
|
|||||||
('image', models.ImageField(storage=utils.OverwriteStorage(
|
('image', models.ImageField(storage=utils.OverwriteStorage(
|
||||||
), upload_to=events.models.get_upload_path, null=True,
|
), upload_to=events.models.get_upload_path, null=True,
|
||||||
verbose_name='Bild', blank=True)),
|
verbose_name='Bild', blank=True)),
|
||||||
('is_tournament', models.BooleanField(default=False,
|
('is_tournament', models.BooleanField(
|
||||||
help_text='Diese Veranstaltung ist ein Turnier, es gelten andere Regeln f\xfcr das Kyu Ranking.',
|
default=False,
|
||||||
|
help_text='Diese Veranstaltung ist ein Turnier, ' +
|
||||||
|
'es gelten andere Regeln f\xfcr das Kyu Ranking.',
|
||||||
verbose_name='Turnier')),
|
verbose_name='Turnier')),
|
||||||
('photo_count', models.PositiveIntegerField(
|
('photo_count', models.PositiveIntegerField(
|
||||||
default=0, editable=False)),
|
default=0, editable=False)),
|
||||||
('event_series',
|
('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',
|
editable=False, to='events.Event',
|
||||||
blank=True,
|
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,
|
null=True,
|
||||||
verbose_name='Veranstaltungsreihen')),
|
verbose_name='Veranstaltungsreihen')),
|
||||||
],
|
],
|
||||||
@@ -67,21 +72,19 @@ class Migration(migrations.Migration):
|
|||||||
max_length=127, verbose_name='Stra\xdfe')),
|
max_length=127, verbose_name='Stra\xdfe')),
|
||||||
('locality',
|
('locality',
|
||||||
models.CharField(max_length=127, verbose_name='Ort')),
|
models.CharField(max_length=127, verbose_name='Ort')),
|
||||||
('country', models.CharField(max_length=2, verbose_name='Land',
|
('country', models.CharField(
|
||||||
choices=[(b'GB',
|
max_length=2, verbose_name='Land',
|
||||||
'Vereinigtes K\xf6nigreich'),
|
choices=[(b'GB', 'Vereinigtes K\xf6nigreich'),
|
||||||
(b'AF', 'Afghanistan'),
|
(b'AF', 'Afghanistan'),
|
||||||
(b'AX', 'Aland Islands'),
|
(b'AX', 'Aland Islands'),
|
||||||
(b'AL', 'Albanien'),
|
(b'AL', 'Albanien'),
|
||||||
(b'DZ', 'Algerien'), (
|
(b'DZ', 'Algerien'),
|
||||||
b'AS',
|
(b'AS', 'Amerikanisch-Samoa'),
|
||||||
'Amerikanisch-Samoa'),
|
|
||||||
(b'AD', 'Andorra'),
|
(b'AD', 'Andorra'),
|
||||||
(b'AO', 'Angola'),
|
(b'AO', 'Angola'),
|
||||||
(b'AI', 'Anguilla'),
|
(b'AI', 'Anguilla'),
|
||||||
(b'AQ', 'Antarktika'), (
|
(b'AQ', 'Antarktika'),
|
||||||
b'AG',
|
(b'AG', 'Antigua und Barbuda'),
|
||||||
'Antigua und Barbuda'),
|
|
||||||
(b'AR', 'Argentinien'),
|
(b'AR', 'Argentinien'),
|
||||||
(b'AM', 'Armenien'),
|
(b'AM', 'Armenien'),
|
||||||
(b'AW', 'Aruba'),
|
(b'AW', 'Aruba'),
|
||||||
@@ -91,24 +94,20 @@ class Migration(migrations.Migration):
|
|||||||
(b'BS', 'Bahamas'),
|
(b'BS', 'Bahamas'),
|
||||||
(b'BH', 'Bahrein'),
|
(b'BH', 'Bahrein'),
|
||||||
(b'BD', 'Bangladesch'),
|
(b'BD', 'Bangladesch'),
|
||||||
(b'BB', 'Barbados'), (
|
(b'BB', 'Barbados'),
|
||||||
b'BY',
|
(b'BY', 'Wei\xdfrussland'),
|
||||||
'Wei\xdfrussland'),
|
|
||||||
(b'BE', 'Belgien'),
|
(b'BE', 'Belgien'),
|
||||||
(b'BZ', 'Belize'),
|
(b'BZ', 'Belize'),
|
||||||
(b'BJ', 'Benin'),
|
(b'BJ', 'Benin'),
|
||||||
(b'BM', 'Bermuda'),
|
(b'BM', 'Bermuda'),
|
||||||
(b'BT', 'Bhutan'),
|
(b'BT', 'Bhutan'),
|
||||||
(b'BO', 'Bolivien'), (
|
(b'BO', 'Bolivien'),
|
||||||
b'BA',
|
(b'BA', 'Bosnien und Herzegowina'),
|
||||||
'Bosnien und Herzegowina'),
|
|
||||||
(b'BW', 'Botswana'),
|
(b'BW', 'Botswana'),
|
||||||
(b'BV', 'Bouvet Island'),
|
(b'BV', 'Bouvet Island'),
|
||||||
(b'BR', 'Brasilien'), (
|
(b'BR', 'Brasilien'),
|
||||||
b'IO',
|
(b'IO', 'British Indian Ocean Territory'),
|
||||||
'British Indian Ocean Territory'),
|
(b'BN', 'Brunei Darussalam'),
|
||||||
(b'BN',
|
|
||||||
'Brunei Darussalam'),
|
|
||||||
(b'BG', 'Bulgarien'),
|
(b'BG', 'Bulgarien'),
|
||||||
(b'BF', 'Burkina Faso'),
|
(b'BF', 'Burkina Faso'),
|
||||||
(b'BI', 'Burundi'),
|
(b'BI', 'Burundi'),
|
||||||
@@ -117,51 +116,42 @@ class Migration(migrations.Migration):
|
|||||||
(b'CA', 'Kanada'),
|
(b'CA', 'Kanada'),
|
||||||
(b'CV', 'Cape Verde'),
|
(b'CV', 'Cape Verde'),
|
||||||
(b'KY', 'Cayman Islands'),
|
(b'KY', 'Cayman Islands'),
|
||||||
(b'CF',
|
(b'CF', 'Zentralafrikanische Republik'),
|
||||||
'Zentralafrikanische Republik'),
|
|
||||||
(b'TD', 'Tschad'),
|
(b'TD', 'Tschad'),
|
||||||
(b'CL', 'Chile'),
|
(b'CL', 'Chile'),
|
||||||
(b'CN', 'China'), (b'CX',
|
(b'CN', 'China'),
|
||||||
'Christmas Island'),
|
(b'CX', 'Christmas Island'),
|
||||||
(b'CC',
|
(b'CC', 'Cocos (Keeling) Islands'),
|
||||||
'Cocos (Keeling) Islands'),
|
|
||||||
(b'CO', 'Kolumbien'),
|
(b'CO', 'Kolumbien'),
|
||||||
(b'KM', 'Komoren'),
|
(b'KM', 'Komoren'),
|
||||||
(b'CG', 'Kongo'), (b'CD',
|
(b'CG', 'Kongo'),
|
||||||
'Kongo, Demokratische Republik'),
|
(b'CD', 'Kongo, Demokratische Republik'),
|
||||||
(b'CK', 'Cook-Inseln'),
|
(b'CK', 'Cook-Inseln'),
|
||||||
(b'CR', 'Costa Rica'),
|
(b'CR', 'Costa Rica'),
|
||||||
(b'CI', "Cote d'Ivoire"),
|
(b'CI', "Cote d'Ivoire"),
|
||||||
(b'HR', 'Kroatien'),
|
(b'HR', 'Kroatien'),
|
||||||
(b'CU', 'Kuba'),
|
(b'CU', 'Kuba'),
|
||||||
(b'CY', 'Zypern'), (b'CZ',
|
(b'CY', 'Zypern'),
|
||||||
'Tschechische Republik'),
|
(b'CZ', 'Tschechische Republik'),
|
||||||
(b'DK', 'D\xe4nemark'),
|
(b'DK', 'D\xe4nemark'),
|
||||||
(b'DJ', 'Dschibuti'),
|
(b'DJ', 'Dschibuti'),
|
||||||
(b'DM', 'Dominica'), (
|
(b'DM', 'Dominica'),
|
||||||
b'DO',
|
(b'DO', 'Dominikanische Republik'),
|
||||||
'Dominikanische Republik'),
|
|
||||||
(b'EC', 'Ecuador'),
|
(b'EC', 'Ecuador'),
|
||||||
(b'EG', '\xc4gypten'),
|
(b'EG', '\xc4gypten'),
|
||||||
(b'SV', 'El Salvador'), (
|
(b'SV', 'El Salvador'),
|
||||||
b'GQ',
|
(b'GQ', '\xc4quatorial-Guinea'),
|
||||||
'\xc4quatorial-Guinea'),
|
|
||||||
(b'ER', 'Eritrea'),
|
(b'ER', 'Eritrea'),
|
||||||
(b'EE', 'Estland'),
|
(b'EE', 'Estland'),
|
||||||
(b'ET', '\xc4thiopien'), (
|
(b'ET', '\xc4thiopien'),
|
||||||
b'FK',
|
(b'FK', 'Falklandinseln (Malvinas)'),
|
||||||
'Falklandinseln (Malvinas)'),
|
(b'FO', 'F\xe4r\xf6er-Inseln'),
|
||||||
(b'FO',
|
|
||||||
'F\xe4r\xf6er-Inseln'),
|
|
||||||
(b'FJ', 'Fidschi'),
|
(b'FJ', 'Fidschi'),
|
||||||
(b'FI', 'Finnland'),
|
(b'FI', 'Finnland'),
|
||||||
(b'FR', 'Frankreich'), (
|
(b'FR', 'Frankreich'),
|
||||||
b'GF',
|
(b'GF', 'Franz\xf6sisch-Guayana'),
|
||||||
'Franz\xf6sisch-Guayana'),
|
(b'PF', 'Franz\xf6sisch-Polynesien'),
|
||||||
(b'PF',
|
(b'TF', 'Franz\xf6sisch S\xfcdliche Territorien'),
|
||||||
'Franz\xf6sisch-Polynesien'),
|
|
||||||
(b'TF',
|
|
||||||
'Franz\xf6sisch S\xfcdliche Territorien'),
|
|
||||||
(b'GA', 'Gabun'),
|
(b'GA', 'Gabun'),
|
||||||
(b'GM', 'Gambia'),
|
(b'GM', 'Gambia'),
|
||||||
(b'GE', 'Georgia'),
|
(b'GE', 'Georgia'),
|
||||||
@@ -178,18 +168,16 @@ class Migration(migrations.Migration):
|
|||||||
(b'GN', 'Guinea'),
|
(b'GN', 'Guinea'),
|
||||||
(b'GW', 'Guinea-Bissau'),
|
(b'GW', 'Guinea-Bissau'),
|
||||||
(b'GY', 'Guyana'),
|
(b'GY', 'Guyana'),
|
||||||
(b'HT', 'Haiti'), (b'HM',
|
(b'HT', 'Haiti'),
|
||||||
'Heard und McDonald Inseln'),
|
(b'HM', 'Heard und McDonald Inseln'),
|
||||||
(b'VA',
|
(b'VA', 'Heiliger Stuhl (Vatikanstadt)'),
|
||||||
'Heiliger Stuhl (Vatikanstadt)'),
|
|
||||||
(b'HN', 'Honduras'),
|
(b'HN', 'Honduras'),
|
||||||
(b'HK', 'Hongkong'),
|
(b'HK', 'Hongkong'),
|
||||||
(b'HU', 'Ungarn'),
|
(b'HU', 'Ungarn'),
|
||||||
(b'IS', 'Island'),
|
(b'IS', 'Island'),
|
||||||
(b'IN', 'Indien'),
|
(b'IN', 'Indien'),
|
||||||
(b'ID', 'Indonesien'), (
|
(b'ID', 'Indonesien'),
|
||||||
b'IR',
|
(b'IR', 'Iran, Islamische Republik'),
|
||||||
'Iran, Islamische Republik'),
|
|
||||||
(b'IQ', 'Irak'),
|
(b'IQ', 'Irak'),
|
||||||
(b'IE', 'Irland'),
|
(b'IE', 'Irland'),
|
||||||
(b'IM', 'Isle of Man'),
|
(b'IM', 'Isle of Man'),
|
||||||
@@ -201,39 +189,36 @@ class Migration(migrations.Migration):
|
|||||||
(b'JO', 'Jordan'),
|
(b'JO', 'Jordan'),
|
||||||
(b'KZ', 'Kasachstan'),
|
(b'KZ', 'Kasachstan'),
|
||||||
(b'KE', 'Kenia'),
|
(b'KE', 'Kenia'),
|
||||||
(b'KI', 'Kiribati'), (
|
(b'KI', 'Kiribati'),
|
||||||
b'KP',
|
(b'KP', 'Korea, Demokratische Volksrepublik'),
|
||||||
'Korea, Demokratische Volksrepublik'),
|
(b'KR', 'Korea, Republik'),
|
||||||
(
|
|
||||||
b'KR',
|
|
||||||
'Korea, Republik'),
|
|
||||||
(b'KW', 'Kuwait'),
|
(b'KW', 'Kuwait'),
|
||||||
(b'KG', 'Kirgisistan'), (
|
(b'KG', 'Kirgisistan'),
|
||||||
b'LA',
|
(b'LA', 'Lao Demokratischen Volksrepublik'),
|
||||||
'Lao Demokratischen Volksrepublik'),
|
|
||||||
(b'LV', 'Lettland'),
|
(b'LV', 'Lettland'),
|
||||||
(b'LB', 'Libanon'), (
|
(b'LB', 'Libanon'),
|
||||||
b'LS', 'Lesotho'),
|
(b'LS', 'Lesotho'),
|
||||||
(b'LR', 'Liberia'),
|
(b'LR', 'Liberia'),
|
||||||
(b'LY', 'Libyen'),
|
(b'LY', 'Libyen'),
|
||||||
(b'LI', 'Liechtenstein'),
|
(b'LI', 'Liechtenstein'),
|
||||||
(b'LT', 'Litauen'),
|
(b'LT', 'Litauen'),
|
||||||
(b'LU', 'Luxemburg'),
|
(b'LU', 'Luxemburg'),
|
||||||
(b'MO', 'Macao'), (b'MK',
|
(b'MO', 'Macao'),
|
||||||
|
(b'MK',
|
||||||
'Mazedonien, die ehemalige jugoslawische Republik'),
|
'Mazedonien, die ehemalige jugoslawische Republik'),
|
||||||
(b'MG', 'Madagaskar'),
|
(b'MG', 'Madagaskar'),
|
||||||
(b'MW', 'Malawi'),
|
(b'MW', 'Malawi'),
|
||||||
(b'MY', 'Malaysia'),
|
(b'MY', 'Malaysia'),
|
||||||
(b'MV', 'Malediven'),
|
(b'MV', 'Malediven'),
|
||||||
(b'ML', 'Mali'),
|
(b'ML', 'Mali'),
|
||||||
(b'MT', 'Malta'), (b'MH',
|
(b'MT', 'Malta'),
|
||||||
'Marshall Islands'),
|
(b'MH', 'Marshall Islands'),
|
||||||
(b'MQ', 'Martinique'),
|
(b'MQ', 'Martinique'),
|
||||||
(b'MR', 'Mauretanien'),
|
(b'MR', 'Mauretanien'),
|
||||||
(b'MU', 'Mauritius'),
|
(b'MU', 'Mauritius'),
|
||||||
(b'YT', 'Mayotte'),
|
(b'YT', 'Mayotte'),
|
||||||
(b'MX', 'Mexiko'), (b'FM',
|
(b'MX', 'Mexiko'),
|
||||||
'Mikronesien, F\xf6derierte Staaten von'),
|
(b'FM', 'Mikronesien, F\xf6derierte Staaten von'),
|
||||||
(b'MD', 'Moldawien'),
|
(b'MD', 'Moldawien'),
|
||||||
(b'MC', 'Monaco'),
|
(b'MC', 'Monaco'),
|
||||||
(b'MN', 'Mongolei'),
|
(b'MN', 'Mongolei'),
|
||||||
@@ -245,9 +230,8 @@ class Migration(migrations.Migration):
|
|||||||
(b'NA', 'Namibia'),
|
(b'NA', 'Namibia'),
|
||||||
(b'NR', 'Nauru'),
|
(b'NR', 'Nauru'),
|
||||||
(b'NP', 'Nepal'),
|
(b'NP', 'Nepal'),
|
||||||
(b'NL', 'Niederlande'), (
|
(b'NL', 'Niederlande'),
|
||||||
b'AN',
|
(b'AN', 'Niederl\xe4ndische Antillen'),
|
||||||
'Niederl\xe4ndische Antillen'),
|
|
||||||
(b'NC', 'Neukaledonien'),
|
(b'NC', 'Neukaledonien'),
|
||||||
(b'NZ', 'New Zealand'),
|
(b'NZ', 'New Zealand'),
|
||||||
(b'NI', 'Nicaragua'),
|
(b'NI', 'Nicaragua'),
|
||||||
@@ -260,11 +244,10 @@ class Migration(migrations.Migration):
|
|||||||
(b'NO', 'Norwegen'),
|
(b'NO', 'Norwegen'),
|
||||||
(b'OM', 'Oman'),
|
(b'OM', 'Oman'),
|
||||||
(b'PK', 'Pakistan'),
|
(b'PK', 'Pakistan'),
|
||||||
(b'PW', 'Palau'), (b'PS',
|
(b'PW', 'Palau'),
|
||||||
'Pal\xe4stinensische Autonomiegebiete'),
|
(b'PS', 'Pal\xe4stinensische Autonomiegebiete'),
|
||||||
(b'PA', 'Panama'), (
|
(b'PA', 'Panama'),
|
||||||
b'PG',
|
(b'PG', 'Papua-Neuguinea'),
|
||||||
'Papua-Neuguinea'),
|
|
||||||
(b'PY', 'Paraguay'),
|
(b'PY', 'Paraguay'),
|
||||||
(b'PE', 'Peru'),
|
(b'PE', 'Peru'),
|
||||||
(b'PH', 'Philippinen'),
|
(b'PH', 'Philippinen'),
|
||||||
@@ -272,26 +255,21 @@ class Migration(migrations.Migration):
|
|||||||
(b'PL', 'Polen'),
|
(b'PL', 'Polen'),
|
||||||
(b'PT', 'Portugal'),
|
(b'PT', 'Portugal'),
|
||||||
(b'PR', 'Puerto Rico'),
|
(b'PR', 'Puerto Rico'),
|
||||||
(b'QA', 'Katar'), (b'RE',
|
(b'QA', 'Katar'),
|
||||||
'Wiedervereinigung'),
|
(b'RE', 'Wiedervereinigung'),
|
||||||
(b'RO', 'Rum\xe4nien'), (
|
(b'RO', 'Rum\xe4nien'),
|
||||||
b'RU',
|
(b'RU', 'Russischen F\xf6deration'),
|
||||||
'Russischen F\xf6deration'),
|
(b'RW', 'Ruanda'),
|
||||||
(b'RW', 'Ruanda'), (b'BL',
|
(b'BL', 'Saint Barthelemy'),
|
||||||
'Saint Barthelemy'),
|
(b'SH', 'Saint Helena'),
|
||||||
(b'SH', 'Saint Helena'), (
|
(b'KN', 'Saint Kitts und Nevis'),
|
||||||
b'KN',
|
|
||||||
'Saint Kitts und Nevis'),
|
|
||||||
(b'LC', 'Santa Lucia'),
|
(b'LC', 'Santa Lucia'),
|
||||||
(b'MF', 'Santa Martin'), (
|
(b'MF', 'Santa Martin'),
|
||||||
b'PM',
|
(b'PM', 'Saint Pierre und Miquelon'),
|
||||||
'Saint Pierre und Miquelon'),
|
(b'VC', 'Saint Vincent und die Grenadinen'),
|
||||||
(b'VC',
|
|
||||||
'Saint Vincent und die Grenadinen'),
|
|
||||||
(b'WS', 'Samoa'),
|
(b'WS', 'Samoa'),
|
||||||
(b'SM', 'San Marino'), (
|
(b'SM', 'San Marino'),
|
||||||
b'ST',
|
(b'ST', 'Sao Tome und Principe'),
|
||||||
'Sao Tome und Principe'),
|
|
||||||
(b'SA', 'Saudi-Arabien'),
|
(b'SA', 'Saudi-Arabien'),
|
||||||
(b'SN', 'Senegal'),
|
(b'SN', 'Senegal'),
|
||||||
(b'RS', 'Serbien'),
|
(b'RS', 'Serbien'),
|
||||||
@@ -302,56 +280,46 @@ class Migration(migrations.Migration):
|
|||||||
(b'SI', 'Slowenien'),
|
(b'SI', 'Slowenien'),
|
||||||
(b'SB', 'Salomon-Inseln'),
|
(b'SB', 'Salomon-Inseln'),
|
||||||
(b'SO', 'Somalia'),
|
(b'SO', 'Somalia'),
|
||||||
(b'ZA', 'S\xfcdafrika'), (
|
(b'ZA', 'S\xfcdafrika'),
|
||||||
b'GS',
|
(b'GS',
|
||||||
'S\xfcdgeorgien und die S\xfcdlichen Sandwichinseln'),
|
'S\xfcdgeorgien und die S\xfcdlichen Sandwichinseln'),
|
||||||
(b'ES', 'Spanien'),
|
(b'ES', 'Spanien'),
|
||||||
(b'LK', 'Sri Lanka'),
|
(b'LK', 'Sri Lanka'),
|
||||||
(b'SD', 'Sudan'),
|
(b'SD', 'Sudan'),
|
||||||
(b'SR', 'Suriname'), (
|
(b'SR', 'Suriname'),
|
||||||
b'SJ',
|
(b'SJ', 'Svalbard und Jan Mayen'),
|
||||||
'Svalbard und Jan Mayen'),
|
|
||||||
(b'SZ', 'Swaziland'),
|
(b'SZ', 'Swaziland'),
|
||||||
(b'SE', 'Schweden'),
|
(b'SE', 'Schweden'),
|
||||||
(b'CH', 'Schweiz'), (
|
(b'CH', 'Schweiz'),
|
||||||
b'SY',
|
(b'SY', 'Arabische Republik Syrien'),
|
||||||
'Arabische Republik Syrien'),
|
|
||||||
(b'TW',
|
(b'TW',
|
||||||
'Taiwan, Province of China'),
|
'Taiwan, Province of China'),
|
||||||
(b'TJ', 'Tadschikistan'),
|
(b'TJ', 'Tadschikistan'),
|
||||||
(b'TZ',
|
(b'TZ', 'Tansania, Vereinigte Republik'),
|
||||||
'Tansania, Vereinigte Republik'),
|
|
||||||
(b'TH', 'Thailand'),
|
(b'TH', 'Thailand'),
|
||||||
(b'TL', 'Timor-Leste'),
|
(b'TL', 'Timor-Leste'),
|
||||||
(b'TG', 'Togo'),
|
(b'TG', 'Togo'),
|
||||||
(b'TK', 'Tokelau'),
|
(b'TK', 'Tokelau'),
|
||||||
(b'TO', 'Tonga'), (b'TT',
|
(b'TO', 'Tonga'),
|
||||||
'Trinidad und Tobago'),
|
(b'TT', 'Trinidad und Tobago'),
|
||||||
(b'TN', 'Tunesien'),
|
(b'TN', 'Tunesien'),
|
||||||
(b'TR', 'T\xfcrkei'),
|
(b'TR', 'T\xfcrkei'),
|
||||||
(b'TM', 'Turkmenistan'), (
|
(b'TM', 'Turkmenistan'),
|
||||||
b'TC',
|
(b'TC', 'Turks-und Caicosinseln'),
|
||||||
'Turks-und Caicosinseln'),
|
|
||||||
(b'TV', 'Tuvalu'),
|
(b'TV', 'Tuvalu'),
|
||||||
(b'UG', 'Uganda'),
|
(b'UG', 'Uganda'),
|
||||||
(b'UA', 'Ukraine'), (
|
(b'UA', 'Ukraine'),
|
||||||
b'AE',
|
(b'AE', 'Vereinigte Arabische Emirate'),
|
||||||
'Vereinigte Arabische Emirate'),
|
(b'US', 'Vereinigte Staaten'),
|
||||||
(b'US',
|
(b'UM', 'United States Minor Outlying Islands'),
|
||||||
'Vereinigte Staaten'), (
|
|
||||||
b'UM',
|
|
||||||
'United States Minor Outlying Islands'),
|
|
||||||
(b'UY', 'Uruguay'),
|
(b'UY', 'Uruguay'),
|
||||||
(b'UZ', 'Usbekistan'),
|
(b'UZ', 'Usbekistan'),
|
||||||
(b'VU', 'Vanuatu'),
|
(b'VU', 'Vanuatu'),
|
||||||
(b'VE', 'Venezuela'),
|
(b'VE', 'Venezuela'),
|
||||||
(b'VN', 'Vietnam'), (
|
(b'VN', 'Vietnam'),
|
||||||
b'VG',
|
(b'VG', 'Virgin Islands, British'),
|
||||||
'Virgin Islands, British'),
|
(b'VI', 'Virgin Islands, US'),
|
||||||
(b'VI',
|
(b'WF', 'Wallis und Futuna'),
|
||||||
'Virgin Islands, US'), (
|
|
||||||
b'WF',
|
|
||||||
'Wallis und Futuna'),
|
|
||||||
(b'EH', 'Westsahara'),
|
(b'EH', 'Westsahara'),
|
||||||
(b'YE', 'Jemen'),
|
(b'YE', 'Jemen'),
|
||||||
(b'ZM', 'Sambia'),
|
(b'ZM', 'Sambia'),
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ from django.db import models, migrations
|
|||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
('events', '0001_initial'),
|
('events', '0001_initial'),
|
||||||
]
|
]
|
||||||
@@ -25,6 +24,9 @@ class Migration(migrations.Migration):
|
|||||||
model_name='event',
|
model_name='event',
|
||||||
name='mahjong_tournament',
|
name='mahjong_tournament',
|
||||||
field=models.BooleanField(
|
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'),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ from django.db import models, migrations
|
|||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
('events', '0002_auto_20150818_2139'),
|
('events', '0002_auto_20150818_2139'),
|
||||||
]
|
]
|
||||||
@@ -15,6 +14,9 @@ class Migration(migrations.Migration):
|
|||||||
model_name='event',
|
model_name='event',
|
||||||
name='mahjong_tournament',
|
name='mahjong_tournament',
|
||||||
field=models.BooleanField(
|
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'),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -32,12 +32,14 @@ class Migration(migrations.Migration):
|
|||||||
('description', models.TextField(max_length=300,
|
('description', models.TextField(max_length=300,
|
||||||
verbose_name='Beschreibung',
|
verbose_name='Beschreibung',
|
||||||
blank=True)),
|
blank=True)),
|
||||||
('on_startpage', models.BooleanField(default=False,
|
('on_startpage', models.BooleanField(
|
||||||
|
default=False,
|
||||||
help_text='Display this Photo on the Startpage Teaser',
|
help_text='Display this Photo on the Startpage Teaser',
|
||||||
verbose_name='Startpage')),
|
verbose_name='Startpage')),
|
||||||
('created_date',
|
('created_date',
|
||||||
models.DateTimeField(verbose_name='Published on')),
|
models.DateTimeField(verbose_name='Published on')),
|
||||||
('views', models.PositiveIntegerField(default=0,
|
('views', models.PositiveIntegerField(
|
||||||
|
default=0,
|
||||||
verbose_name='Number of views',
|
verbose_name='Number of views',
|
||||||
editable=False)),
|
editable=False)),
|
||||||
],
|
],
|
||||||
@@ -67,7 +69,9 @@ class Migration(migrations.Migration):
|
|||||||
field=models.ForeignKey(
|
field=models.ForeignKey(
|
||||||
on_delete=django.db.models.deletion.SET_NULL, blank=True,
|
on_delete=django.db.models.deletion.SET_NULL, blank=True,
|
||||||
to='events.Event',
|
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'),
|
null=True, verbose_name='Veranstaltungsreihen'),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ from django.db import models, migrations
|
|||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
('events', '0004_auto_20150901_2204'),
|
('events', '0004_auto_20150901_2204'),
|
||||||
]
|
]
|
||||||
@@ -15,6 +14,7 @@ class Migration(migrations.Migration):
|
|||||||
model_name='photo',
|
model_name='photo',
|
||||||
name='on_startpage',
|
name='on_startpage',
|
||||||
field=models.BooleanField(
|
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'),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ from django.db import migrations, models
|
|||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
('events', '0005_auto_20150907_2021'),
|
('events', '0005_auto_20150907_2021'),
|
||||||
]
|
]
|
||||||
@@ -14,7 +13,8 @@ class Migration(migrations.Migration):
|
|||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='photo',
|
name='photo',
|
||||||
options={'ordering': ['created_date'], 'get_latest_by': 'created_date',
|
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(
|
migrations.AlterField(
|
||||||
model_name='event',
|
model_name='event',
|
||||||
@@ -31,7 +31,9 @@ class Migration(migrations.Migration):
|
|||||||
model_name='photo',
|
model_name='photo',
|
||||||
name='on_startpage',
|
name='on_startpage',
|
||||||
field=models.BooleanField(
|
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(
|
migrations.AlterField(
|
||||||
model_name='photo',
|
model_name='photo',
|
||||||
|
|||||||
@@ -3,11 +3,10 @@ from __future__ import unicode_literals
|
|||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
import datetime
|
import datetime
|
||||||
from django.utils.timezone import utc
|
from datetime import timezone
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
('events', '0006_auto_20160916_1800'),
|
('events', '0006_auto_20160916_1800'),
|
||||||
]
|
]
|
||||||
@@ -17,39 +16,45 @@ class Migration(migrations.Migration):
|
|||||||
model_name='event',
|
model_name='event',
|
||||||
name='date_created',
|
name='date_created',
|
||||||
field=models.DateTimeField(
|
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(
|
migrations.AddField(
|
||||||
model_name='event',
|
model_name='event',
|
||||||
name='date_modified',
|
name='date_modified',
|
||||||
field=models.DateTimeField(default=datetime.datetime(
|
field=models.DateTimeField(default=datetime.datetime(
|
||||||
2016, 10, 12, 20, 24, 39, 910492, tzinfo=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,
|
preserve_default=False,
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='location',
|
model_name='location',
|
||||||
name='date_created',
|
name='date_created',
|
||||||
field=models.DateTimeField(
|
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(
|
migrations.AddField(
|
||||||
model_name='location',
|
model_name='location',
|
||||||
name='date_modified',
|
name='date_modified',
|
||||||
field=models.DateTimeField(default=datetime.datetime(
|
field=models.DateTimeField(default=datetime.datetime(
|
||||||
2016, 10, 12, 20, 24, 44, 566305, tzinfo=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,
|
preserve_default=False,
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='photo',
|
model_name='photo',
|
||||||
name='date_created',
|
name='date_created',
|
||||||
field=models.DateTimeField(
|
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(
|
migrations.AddField(
|
||||||
model_name='photo',
|
model_name='photo',
|
||||||
name='date_modified',
|
name='date_modified',
|
||||||
field=models.DateTimeField(default=datetime.datetime(
|
field=models.DateTimeField(default=datetime.datetime(
|
||||||
2016, 10, 12, 20, 24, 50, 509970, tzinfo=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,
|
preserve_default=False,
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -8,7 +8,6 @@ import django.db.models.deletion
|
|||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
('events', '0008_auto_20171115_0653'),
|
('events', '0008_auto_20171115_0653'),
|
||||||
]
|
]
|
||||||
@@ -17,16 +16,19 @@ class Migration(migrations.Migration):
|
|||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='event',
|
model_name='event',
|
||||||
name='location',
|
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(
|
migrations.AlterField(
|
||||||
model_name='photo',
|
model_name='photo',
|
||||||
name='event',
|
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(
|
migrations.AlterField(
|
||||||
model_name='photo',
|
model_name='photo',
|
||||||
name='photographer',
|
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),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|||||||
158
src/events/migrations/0010_auto_20190106_1954.py
Normal file
158
src/events/migrations/0010_auto_20190106_1954.py
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
# Generated by Django 2.1.5 on 2019-01-06 18:54
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
('events', '0009_auto_20171214_1215'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='event',
|
||||||
|
name='date_created',
|
||||||
|
field=models.DateTimeField(auto_now_add=True, db_index=True, null=True,
|
||||||
|
verbose_name='erstellt am'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='event',
|
||||||
|
name='date_modified',
|
||||||
|
field=models.DateTimeField(auto_now=True,
|
||||||
|
verbose_name='letzte Aktualisierung am'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='location',
|
||||||
|
name='country',
|
||||||
|
field=models.CharField(
|
||||||
|
choices=[('GB', 'United Kingdom'), ('AF', 'Afghanistan'),
|
||||||
|
('AX', 'Aland Islands'), ('AL', 'Albania'), ('DZ', 'Algeria'),
|
||||||
|
('AS', 'American Samoa'), ('AD', 'Andorra'), ('AO', 'Angola'),
|
||||||
|
('AI', 'Anguilla'), ('AQ', 'Antarctica'),
|
||||||
|
('AG', 'Antigua and Barbuda'), ('AR', 'Argentina'),
|
||||||
|
('AM', 'Armenia'), ('AW', 'Aruba'), ('AU', 'Australia'),
|
||||||
|
('AT', 'Austria'), ('AZ', 'Azerbaijan'), ('BS', 'Bahamas'),
|
||||||
|
('BH', 'Bahrain'), ('BD', 'Bangladesh'), ('BB', 'Barbados'),
|
||||||
|
('BY', 'Belarus'), ('BE', 'Belgium'), ('BZ', 'Belize'),
|
||||||
|
('BJ', 'Benin'), ('BM', 'Bermuda'), ('BT', 'Bhutan'),
|
||||||
|
('BO', 'Bolivia'), ('BA', 'Bosnia and Herzegovina'),
|
||||||
|
('BW', 'Botswana'), ('BV', 'Bouvet Island'), ('BR', 'Brazil'),
|
||||||
|
('IO', 'British Indian Ocean Territory'),
|
||||||
|
('BN', 'Brunei Darussalam'), ('BG', 'Bulgaria'),
|
||||||
|
('BF', 'Burkina Faso'), ('BI', 'Burundi'), ('KH', 'Cambodia'),
|
||||||
|
('CM', 'Cameroon'), ('CA', 'Canada'), ('CV', 'Cape Verde'),
|
||||||
|
('KY', 'Cayman Islands'), ('CF', 'Central African Republic'),
|
||||||
|
('TD', 'Chad'), ('CL', 'Chile'), ('CN', 'China'),
|
||||||
|
('CX', 'Christmas Island'), ('CC', 'Cocos (Keeling) Islands'),
|
||||||
|
('CO', 'Colombia'), ('KM', 'Comoros'), ('CG', 'Congo'),
|
||||||
|
('CD', 'Congo, The Democratic Republic of the'),
|
||||||
|
('CK', 'Cook Islands'), ('CR', 'Costa Rica'),
|
||||||
|
('CI', "Cote d'Ivoire"), ('HR', 'Croatia'), ('CU', 'Cuba'),
|
||||||
|
('CY', 'Cyprus'), ('CZ', 'Czech Republic'), ('DK', 'Denmark'),
|
||||||
|
('DJ', 'Djibouti'), ('DM', 'Dominica'),
|
||||||
|
('DO', 'Dominican Republic'), ('EC', 'Ecuador'),
|
||||||
|
('EG', 'Egypt'), ('SV', 'El Salvador'),
|
||||||
|
('GQ', 'Equatorial Guinea'), ('ER', 'Eritrea'),
|
||||||
|
('EE', 'Estonia'), ('ET', 'Ethiopia'),
|
||||||
|
('FK', 'Falkland Islands (Malvinas)'), ('FO', 'Faroe Islands'),
|
||||||
|
('FJ', 'Fiji'), ('FI', 'Finland'), ('FR', 'France'),
|
||||||
|
('GF', 'French Guiana'), ('PF', 'French Polynesia'),
|
||||||
|
('TF', 'French Southern Territories'), ('GA', 'Gabon'),
|
||||||
|
('GM', 'Gambia'), ('GE', 'Georgia'), ('DE', 'Germany'),
|
||||||
|
('GH', 'Ghana'), ('GI', 'Gibraltar'), ('GR', 'Greece'),
|
||||||
|
('GL', 'Greenland'), ('GD', 'Grenada'), ('GP', 'Guadeloupe'),
|
||||||
|
('GU', 'Guam'), ('GT', 'Guatemala'), ('GG', 'Guernsey'),
|
||||||
|
('GN', 'Guinea'), ('GW', 'Guinea-Bissau'), ('GY', 'Guyana'),
|
||||||
|
('HT', 'Haiti'), ('HM', 'Heard Island and McDonald Islands'),
|
||||||
|
('VA', 'Holy See (Vatican City State)'), ('HN', 'Honduras'),
|
||||||
|
('HK', 'Hong Kong'), ('HU', 'Hungary'), ('IS', 'Iceland'),
|
||||||
|
('IN', 'India'), ('ID', 'Indonesia'),
|
||||||
|
('IR', 'Iran, Islamic Republic of'), ('IQ', 'Iraq'),
|
||||||
|
('IE', 'Ireland'), ('IM', 'Isle of Man'), ('IL', 'Israel'),
|
||||||
|
('IT', 'Italy'), ('JM', 'Jamaica'), ('JP', 'Japan'),
|
||||||
|
('JE', 'Jersey'), ('JO', 'Jordan'), ('KZ', 'Kazakhstan'),
|
||||||
|
('KE', 'Kenya'), ('KI', 'Kiribati'),
|
||||||
|
('KP', "Korea, Democratic People's Republic of"),
|
||||||
|
('KR', 'Korea, Republic of'), ('KW', 'Kuwait'),
|
||||||
|
('KG', 'Kyrgyzstan'),
|
||||||
|
('LA', "Lao People's Democratic Republic"), ('LV', 'Latvia'),
|
||||||
|
('LB', 'Lebanon'), ('LS', 'Lesotho'), ('LR', 'Liberia'),
|
||||||
|
('LY', 'Libyan Arab Jamahiriya'), ('LI', 'Liechtenstein'),
|
||||||
|
('LT', 'Lithuania'), ('LU', 'Luxembourg'), ('MO', 'Macao'),
|
||||||
|
('MK', 'Macedonia, The Former Yugoslav Republic of'),
|
||||||
|
('MG', 'Madagascar'), ('MW', 'Malawi'), ('MY', 'Malaysia'),
|
||||||
|
('MV', 'Maldives'), ('ML', 'Mali'), ('MT', 'Malta'),
|
||||||
|
('MH', 'Marshall Islands'), ('MQ', 'Martinique'),
|
||||||
|
('MR', 'Mauritania'), ('MU', 'Mauritius'), ('YT', 'Mayotte'),
|
||||||
|
('MX', 'Mexico'), ('FM', 'Micronesia, Federated States of'),
|
||||||
|
('MD', 'Moldova'), ('MC', 'Monaco'), ('MN', 'Mongolia'),
|
||||||
|
('ME', 'Montenegro'), ('MS', 'Montserrat'), ('MA', 'Morocco'),
|
||||||
|
('MZ', 'Mozambique'), ('MM', 'Myanmar'), ('NA', 'Namibia'),
|
||||||
|
('NR', 'Nauru'), ('NP', 'Nepal'), ('NL', 'Netherlands'),
|
||||||
|
('AN', 'Netherlands Antilles'), ('NC', 'New Caledonia'),
|
||||||
|
('NZ', 'New Zealand'), ('NI', 'Nicaragua'), ('NE', 'Niger'),
|
||||||
|
('NG', 'Nigeria'), ('NU', 'Niue'), ('NF', 'Norfolk Island'),
|
||||||
|
('MP', 'Northern Mariana Islands'), ('NO', 'Norway'),
|
||||||
|
('OM', 'Oman'), ('PK', 'Pakistan'), ('PW', 'Palau'),
|
||||||
|
('PS', 'Palestinian Territory, Occupied'), ('PA', 'Panama'),
|
||||||
|
('PG', 'Papua New Guinea'), ('PY', 'Paraguay'), ('PE', 'Peru'),
|
||||||
|
('PH', 'Philippines'), ('PN', 'Pitcairn'), ('PL', 'Poland'),
|
||||||
|
('PT', 'Portugal'), ('PR', 'Puerto Rico'), ('QA', 'Qatar'),
|
||||||
|
('RE', 'Reunion'), ('RO', 'Romania'),
|
||||||
|
('RU', 'Russian Federation'), ('RW', 'Rwanda'),
|
||||||
|
('BL', 'Saint Barthelemy'), ('SH', 'Saint Helena'),
|
||||||
|
('KN', 'Saint Kitts and Nevis'), ('LC', 'Saint Lucia'),
|
||||||
|
('MF', 'Saint Martin'), ('PM', 'Saint Pierre and Miquelon'),
|
||||||
|
('VC', 'Saint Vincent and the Grenadines'), ('WS', 'Samoa'),
|
||||||
|
('SM', 'San Marino'), ('ST', 'Sao Tome and Principe'),
|
||||||
|
('SA', 'Saudi Arabia'), ('SN', 'Senegal'), ('RS', 'Serbia'),
|
||||||
|
('SC', 'Seychelles'), ('SL', 'Sierra Leone'),
|
||||||
|
('SG', 'Singapore'), ('SK', 'Slovakia'), ('SI', 'Slovenia'),
|
||||||
|
('SB', 'Solomon Islands'), ('SO', 'Somalia'),
|
||||||
|
('ZA', 'South Africa'),
|
||||||
|
('GS', 'South Georgia and the South Sandwich Islands'),
|
||||||
|
('ES', 'Spain'), ('LK', 'Sri Lanka'), ('SD', 'Sudan'),
|
||||||
|
('SR', 'Suriname'), ('SJ', 'Svalbard and Jan Mayen'),
|
||||||
|
('SZ', 'Swaziland'), ('SE', 'Sweden'), ('CH', 'Switzerland'),
|
||||||
|
('SY', 'Syrian Arab Republic'),
|
||||||
|
('TW', 'Taiwan, Province of China'), ('TJ', 'Tajikistan'),
|
||||||
|
('TZ', 'Tanzania, United Republic of'), ('TH', 'Thailand'),
|
||||||
|
('TL', 'Timor-Leste'), ('TG', 'Togo'), ('TK', 'Tokelau'),
|
||||||
|
('TO', 'Tonga'), ('TT', 'Trinidad and Tobago'),
|
||||||
|
('TN', 'Tunisia'), ('TR', 'Turkey'), ('TM', 'Turkmenistan'),
|
||||||
|
('TC', 'Turks and Caicos Islands'), ('TV', 'Tuvalu'),
|
||||||
|
('UG', 'Uganda'), ('UA', 'Ukraine'),
|
||||||
|
('AE', 'United Arab Emirates'), ('US', 'United States'),
|
||||||
|
('UM', 'United States Minor Outlying Islands'),
|
||||||
|
('UY', 'Uruguay'), ('UZ', 'Uzbekistan'), ('VU', 'Vanuatu'),
|
||||||
|
('VE', 'Venezuela'), ('VN', 'Viet Nam'),
|
||||||
|
('VG', 'Virgin Islands, British'),
|
||||||
|
('VI', 'Virgin Islands, U.S.'), ('WF', 'Wallis and Futuna'),
|
||||||
|
('EH', 'Western Sahara'), ('YE', 'Yemen'), ('ZM', 'Zambia'),
|
||||||
|
('ZW', 'Zimbabwe')], max_length=2, verbose_name='Land'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='location',
|
||||||
|
name='date_created',
|
||||||
|
field=models.DateTimeField(auto_now_add=True, db_index=True, null=True,
|
||||||
|
verbose_name='erstellt am'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='location',
|
||||||
|
name='date_modified',
|
||||||
|
field=models.DateTimeField(auto_now=True,
|
||||||
|
verbose_name='letzte Aktualisierung am'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='photo',
|
||||||
|
name='date_created',
|
||||||
|
field=models.DateTimeField(auto_now_add=True, db_index=True, null=True,
|
||||||
|
verbose_name='erstellt am'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='photo',
|
||||||
|
name='date_modified',
|
||||||
|
field=models.DateTimeField(auto_now=True,
|
||||||
|
verbose_name='letzte Aktualisierung am'),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -1,5 +1,9 @@
|
|||||||
"""Mixins for Events."""
|
"""Mixins for Events."""
|
||||||
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
|
from django.db.models import Q
|
||||||
from django.http import Http404
|
from django.http import Http404
|
||||||
|
from django.shortcuts import get_object_or_404
|
||||||
|
from django.utils.translation import gettext as _
|
||||||
|
|
||||||
from . import models
|
from . import models
|
||||||
|
|
||||||
@@ -29,17 +33,19 @@ class EventDetailMixin(object):
|
|||||||
event = None
|
event = None
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
"""Add self.event or the related event of self.object to the template
|
"""Adds this or the related event of the given object to the
|
||||||
context.
|
template context.
|
||||||
|
|
||||||
:return: TemplateContext object"""
|
:return: TemplateContext object"""
|
||||||
context = super(EventDetailMixin, self).get_context_data(**kwargs)
|
context = super(EventDetailMixin, self).get_context_data(**kwargs)
|
||||||
if hasattr(self, 'event') and self.event:
|
if getattr(self, 'event'):
|
||||||
context['event'] = self.event
|
context['event'] = self.event
|
||||||
elif hasattr(self, 'object') and isinstance(self.object, models.Event):
|
elif isinstance(getattr(self, 'object'), models.Event):
|
||||||
context['event'] = self.object
|
context['event'] = self.object
|
||||||
elif hasattr(self, 'object') and hasattr(self.object, 'event'):
|
elif getattr(getattr(self, 'object'), 'event'):
|
||||||
context['event'] = self.object.event
|
context['event'] = self.object.event
|
||||||
|
else:
|
||||||
|
raise ImproperlyConfigured("No Event in Context!")
|
||||||
return context
|
return context
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
@@ -49,12 +55,33 @@ class EventDetailMixin(object):
|
|||||||
:return: a django QuerySets
|
:return: a django QuerySets
|
||||||
"""
|
"""
|
||||||
if self.model == models.Event:
|
if self.model == models.Event:
|
||||||
self.event = models.Event.objects.get(pk=self.kwargs['pk'])
|
self.event = get_object_or_404(models.Event, pk=self.kwargs['pk'])
|
||||||
queryset = self.model.objects.all()
|
queryset = self.model._default_manager.all()
|
||||||
else:
|
elif self.kwargs.get('event'):
|
||||||
try:
|
self.event = get_object_or_404(
|
||||||
self.event = models.Event.objects.get(pk=self.kwargs['event'])
|
models.Event,
|
||||||
|
pk=self.kwargs['event'])
|
||||||
queryset = self.model.objects.filter(event=self.event)
|
queryset = self.model.objects.filter(event=self.event)
|
||||||
|
elif self.model:
|
||||||
|
queryset = self.model._default_manager.all()
|
||||||
|
else:
|
||||||
|
raise ImproperlyConfigured(
|
||||||
|
"%(cls)s is missing a QuerySet. Define "
|
||||||
|
"%(cls)s.model, %(cls)s.queryset, or override "
|
||||||
|
"%(cls)s.get_queryset()." % {
|
||||||
|
'cls': self.__class__.__name__
|
||||||
|
})
|
||||||
|
return queryset.prefetch_related()
|
||||||
|
|
||||||
|
|
||||||
|
class EventPhotoMixin(EventDetailMixin):
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
try:
|
||||||
|
self.event = models.Event.objects.get(id=self.kwargs['event'])
|
||||||
|
return models.Photo.objects.filter(
|
||||||
|
Q(event=self.event) |
|
||||||
|
Q(event__event_series=self.event)
|
||||||
|
)
|
||||||
except models.Event.DoesNotExist:
|
except models.Event.DoesNotExist:
|
||||||
raise Http404(_('Event does not exist'))
|
raise Http404(_('Event does not exist'))
|
||||||
return queryset.prefetch_related()
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
"""Models to solitary events, events series with an location and photos."""
|
"""Models to solitary events, events series with a location and photos."""
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from ckeditor.fields import RichTextField
|
from ckeditor.fields import RichTextField
|
||||||
@@ -9,21 +9,22 @@ from django.db.models import Q
|
|||||||
from django.template.defaultfilters import slugify
|
from django.template.defaultfilters import slugify
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.timezone import now
|
from django.utils.timezone import now
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import gettext as _
|
||||||
from easy_thumbnails.fields import ThumbnailerImageField
|
from easy_thumbnails.fields import ThumbnailerImageField
|
||||||
|
|
||||||
from utils import COUNTRIES, OverwriteStorage
|
from utils import COUNTRIES, OverwriteStorage
|
||||||
from .managers import EventManager
|
from .managers import EventManager
|
||||||
|
|
||||||
|
|
||||||
def get_upload_path(instance, filename):
|
def get_upload_path(instance: models.Model, filename: str) -> str:
|
||||||
"""
|
"""
|
||||||
Generates the desired file path and filename for an uploaded Image.
|
Generates the desired file path and filename for an uploaded Image.
|
||||||
With this function Django can save the uploaded images to subfolders that
|
With this function Django can save the uploaded images to a subfolder that
|
||||||
also have a meaning for humans.
|
also have a meaning for humans.
|
||||||
|
|
||||||
@param instance: an Django Object for which the Image has been uploaded.
|
@return: String: path for the image.
|
||||||
@type instance: a instace of an models.Model sub-class.
|
@param instance: a Django Object for which the Image has been uploaded.
|
||||||
|
@type instance: an instance of a models.Model subclass.
|
||||||
@param filename: The filename of the uploaded image.
|
@param filename: The filename of the uploaded image.
|
||||||
@type filename: String
|
@type filename: String
|
||||||
"""
|
"""
|
||||||
@@ -48,7 +49,7 @@ def get_upload_path(instance, filename):
|
|||||||
|
|
||||||
|
|
||||||
class Event(models.Model):
|
class Event(models.Model):
|
||||||
"""An Event that could be a tournament, a game session, or an convention."""
|
"""An Event that could be a tournament, a game session, or a convention."""
|
||||||
name = models.CharField(_('Name'), max_length=255)
|
name = models.CharField(_('Name'), max_length=255)
|
||||||
description = RichTextField(_("Description"), blank=True)
|
description = RichTextField(_("Description"), blank=True)
|
||||||
location = models.ForeignKey('Location', on_delete=models.PROTECT)
|
location = models.ForeignKey('Location', on_delete=models.PROTECT)
|
||||||
@@ -108,7 +109,7 @@ class Event(models.Model):
|
|||||||
try:
|
try:
|
||||||
return "%(name)s (%(date)s)" % {'name': self.name,
|
return "%(name)s (%(date)s)" % {'name': self.name,
|
||||||
'date': self.start.date()}
|
'date': self.start.date()}
|
||||||
except:
|
except AttributeError:
|
||||||
return "New Event Model"
|
return "New Event Model"
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
@@ -131,7 +132,7 @@ class Event(models.Model):
|
|||||||
'year': self.start.strftime('%Y'),
|
'year': self.start.strftime('%Y'),
|
||||||
'month': self.start.strftime('%m')
|
'month': self.start.strftime('%m')
|
||||||
}
|
}
|
||||||
return reverse('eventseries-form', kwargs=kwargs)
|
return reverse('event-series-form', kwargs=kwargs)
|
||||||
|
|
||||||
def get_edit_url(self):
|
def get_edit_url(self):
|
||||||
kwargs = {
|
kwargs = {
|
||||||
@@ -167,7 +168,7 @@ class Event(models.Model):
|
|||||||
self.photo_count = self.photo_set.count()
|
self.photo_count = self.photo_set.count()
|
||||||
super(Event, self).save(**kwargs)
|
super(Event, self).save(**kwargs)
|
||||||
|
|
||||||
# Update the Hanchans if necesery:
|
# Update the Hanchans if necessary:
|
||||||
for hanchan in self.hanchan_set.all():
|
for hanchan in self.hanchan_set.all():
|
||||||
hanchan.save()
|
hanchan.save()
|
||||||
|
|
||||||
@@ -267,7 +268,7 @@ class Photo(models.Model):
|
|||||||
return os.path.basename(self.image.name)
|
return os.path.basename(self.image.name)
|
||||||
|
|
||||||
def rotate(self, rotate):
|
def rotate(self, rotate):
|
||||||
# TODO: Eine vernüftigte Methode ohne viele Abhängigkeiten finden um
|
# TODO: Eine vernünftige Methode ohne viele Abhängigkeiten finden um
|
||||||
# die Bilder bei Bedarf zu drehen.
|
# die Bilder bei Bedarf zu drehen.
|
||||||
if rotate == 'clockwise':
|
if rotate == 'clockwise':
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
"""To geneate a Sitemap with all events."""
|
|
||||||
from kasu.sitemaps import GenericSitemap
|
from kasu.sitemaps import GenericSitemap
|
||||||
from django.utils import timezone
|
|
||||||
from .models import Event
|
from .models import Event
|
||||||
|
|
||||||
|
|
||||||
class EventSitemap(GenericSitemap):
|
class EventSitemap(GenericSitemap):
|
||||||
"""sitemap to help indexing all events on this site."""
|
"""sitemap to help indexing all events on this site."""
|
||||||
changefreq = "never"
|
changefreq: str = "never"
|
||||||
protocol = 'https'
|
protocol: str = 'https'
|
||||||
priority_field = 'start'
|
priority_field: str = 'start'
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def items():
|
def items(**kwargs) -> Event:
|
||||||
"""add all upcoming and archived events to the sitemap."""
|
"""add all upcoming and archived events to the sitemap.
|
||||||
|
@param **kwargs:
|
||||||
|
"""
|
||||||
return Event.objects.all()
|
return Event.objects.all()
|
||||||
|
|||||||
@@ -40,7 +40,7 @@
|
|||||||
<h4><a href="{{ event.get_absolute_url }}">{{ event.name }}</a></h4>
|
<h4><a href="{{ event.get_absolute_url }}">{{ event.name }}</a></h4>
|
||||||
<p>
|
<p>
|
||||||
<span class="fa fa-calendar-o" title="{% trans 'Date' %}" aria-label="{% trans 'Date' %}"></span>
|
<span class="fa fa-calendar-o" title="{% trans 'Date' %}" aria-label="{% trans 'Date' %}"></span>
|
||||||
<time datetime="{{event.start|date:'c'}}">
|
<time datetime="{{event.start|date:'Y-m-d\TH:i:sO'}}">
|
||||||
{{ event.start|date:'D' }}
|
{{ event.start|date:'D' }}
|
||||||
{{ event.start|date:'SHORT_DATE_FORMAT' }} {{hanchan.start|time:'H:i'}}
|
{{ event.start|date:'SHORT_DATE_FORMAT' }} {{hanchan.start|time:'H:i'}}
|
||||||
</time>
|
</time>
|
||||||
@@ -52,13 +52,13 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>{{event.description|truncatewords_html:20|safe}}</p>
|
{{event.description|truncatewords_html:20|safe}}
|
||||||
<ul class="info">
|
<ul class="info">
|
||||||
<li><span class="fa fa-map-marker" title="{% trans 'Location' %}"></span> {{ event.location }}</li>
|
<li><span class="fa fa-map-marker" title="{% trans 'Location' %}"></span> {{ event.location }}</li>
|
||||||
<li><span class="fa fa-comments" title="{% trans 'Comments' %}"></span> <a href="{{event.get_absolute_url}}#comments">{{ comment_count }}</a></li>
|
<li><span class="fa fa-comments" title="{% trans 'Comments' %}"></span> <a href="{{event.get_absolute_url}}#comments">{{ comment_count }}</a></li>
|
||||||
<li><span class="fa fa-camera-retro" title="{% trans 'Photos' %}"></span> <a href="{% url 'event-photo-list' event.pk %}">{{ event.photo_count }}</a></li>
|
<li><span class="fa fa-camera-retro" title="{% trans 'Photos' %}"></span> <a href="{% url 'event-photo-list' event.pk %}">{{ event.photo_count }}</a></li>
|
||||||
<li><span class="fa fa-table" title="{% trans 'Hanchans' %}"></span> <a href="{% url 'event-hanchan-list' event.pk %}">{{ event.hanchan_set.count }}</a></li>
|
<li><span class="fa fa-table" title="{% trans 'Hanchans' %}"></span> <a href="{% url 'event-hanchan-list' event.pk %}">{{ event.hanchan_set.count }}</a></li>
|
||||||
<li><span class="fa fa-glass" title="{% trans 'Hanchans' %}"></span> <a href="{% url 'maistar-game-list' event.pk %}">{{ event.maistargame_set.count }}</a></li>
|
<li><span class="fa fa -glass" title="{% trans 'Hanchans' %}"></span> <a href="{% url 'maistar-game-list' event.pk %}">{{ event.maistargame_set.count }}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
{% if perms.events.change_event %}
|
{% if perms.events.change_event %}
|
||||||
<p class="right"><a href="{{ event.get_edit_url }}" class="button"><span class="fa fa-pencil"></span></a></p>
|
<p class="right"><a href="{{ event.get_edit_url }}" class="button"><span class="fa fa-pencil"></span></a></p>
|
||||||
@@ -66,4 +66,5 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
{% block form %}{% endblock %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
{% include "form.html" %}
|
{% include "form.html" %}
|
||||||
{% if event.id and event.event_set.count %}
|
{% if event.id and event.event_set.count %}
|
||||||
<p class="warning">
|
<p class="warning">
|
||||||
<strong>Achtung! Das ist eine Veranstaltungsreihe!</strong> Diese kann man im Moment nur im Admin-Interface vernünfig bearbeiten.<br />
|
<strong>Achtung! Das ist eine Veranstaltungsreihe!</strong> Diese kann man im Moment nur im Admin-Interface vernünftig bearbeiten.<br />
|
||||||
Du bearbeitest hier den "Hauptevent" der Reihe ({{event.event_set.count}}). Alle Änderungen (abgesehen von Name, Start und Ende) werden von den darauf folgendem Veranstaltungen übernommen.
|
Du bearbeitest hier den "Hauptevent" der Reihe ({{event.event_set.count}}). Alle Änderungen (abgesehen von Name, Start und Ende) werden von den darauf folgendem Veranstaltungen übernommen.
|
||||||
</p>
|
</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
<h4><a href="{{ event.get_absolute_url }}">{{ event.name }}</a></h4>
|
<h4><a href="{{ event.get_absolute_url }}">{{ event.name }}</a></h4>
|
||||||
<ul class="info">
|
<ul class="info">
|
||||||
<li><span class="fa fa-calendar-o" title="{% trans 'Date' %}" aria-label="{% trans 'Date' %}"></span>
|
<li><span class="fa fa-calendar-o" title="{% trans 'Date' %}" aria-label="{% trans 'Date' %}"></span>
|
||||||
<time datetime="{{event.start|date:'c'}}">
|
<time datetime="{{event.start|date:'Y-m-d\TH:i:sO'}}">
|
||||||
{{ event.start|date:'D' }}
|
{{ event.start|date:'D' }}
|
||||||
{{ event.start|date:'SHORT_DATE_FORMAT' }}
|
{{ event.start|date:'SHORT_DATE_FORMAT' }}
|
||||||
</time>
|
</time>
|
||||||
@@ -36,10 +36,9 @@
|
|||||||
<a href="{{event.get_absolute_url}}#comments">{{ comment_count }}</a>
|
<a href="{{event.get_absolute_url}}#comments">{{ comment_count }}</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p>{{event.description|truncatewords_html:25|safe}}</p>
|
{{event.description|truncatewords_html:25|safe}}
|
||||||
</div>
|
</div>
|
||||||
{% if forloop.counter|divisibleby:2 %}<br class="clear">{% endif %}
|
{% if forloop.counter|divisibleby:2 %}<br class="clear">{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% if page_obj.has_other_pages %}{% include 'paginator.html' %}{% endif %}
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<form action="" method="post" class="grid_12">
|
<form action="" method="post" class="grid_12">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<header>
|
<header>
|
||||||
<h1 class="grid_12">Dieses Photo wirklich löschen?</h1>
|
<h1 class="grid_12">Dieses Foto wirklich löschen?</h1>
|
||||||
</header>
|
</header>
|
||||||
<p>Sind Sie sicher, dass Sie das Bild “{{photo.name}}” löschen wollen?</p>
|
<p>Sind Sie sicher, dass Sie das Bild “{{photo.name}}” löschen wollen?</p>
|
||||||
<img src="{{photo.image|thumbnail_url:'display'}}" alt="{{photo.name}}" title="{{photo.name}}" class="grid_10 push_1"/>
|
<img src="{{photo.image|thumbnail_url:'display'}}" alt="{{photo.name}}" title="{{photo.name}}" class="grid_10 push_1"/>
|
||||||
|
|||||||
@@ -59,9 +59,6 @@ if ($('a.next').attr('href')) {
|
|||||||
<a class="button" href="http://facebook.com/sharer.php?u=http%3A%2F%2Fwww.kasu.at{{photo.get_absolute_url|urlencode}}" target="_blank" rel="nofollow">
|
<a class="button" href="http://facebook.com/sharer.php?u=http%3A%2F%2Fwww.kasu.at{{photo.get_absolute_url|urlencode}}" target="_blank" rel="nofollow">
|
||||||
<span class="fa fa-twitter"></span>Facebook
|
<span class="fa fa-twitter"></span>Facebook
|
||||||
</a>
|
</a>
|
||||||
<a class="button" href="https://m.google.com/app/plus/x/?v=compose&content={{photo.headline|urlencode}}+-+http%3A%2F%2Fwww.kasu.at/{{photo.get_absolute_url|urlencode}}" target="_blank" rel="nofollow">
|
|
||||||
<span class="fa fa-google-plus"></span> Google+
|
|
||||||
</a>
|
|
||||||
<a class="button" href="https://twitter.com/share?url=http%3A%2F%2Fwww.kasu.at/{{photo.get_absolute_url|urlencode}}" target='_blank' rel="nofollow">
|
<a class="button" href="https://twitter.com/share?url=http%3A%2F%2Fwww.kasu.at/{{photo.get_absolute_url|urlencode}}" target='_blank' rel="nofollow">
|
||||||
<span class="fa fa-twitter"></span> Twitter
|
<span class="fa fa-twitter"></span> Twitter
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -1,46 +1,10 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "events/event_archive.html" %}
|
||||||
{% load i18n comments thumbnail %}
|
{% load i18n comments thumbnail %}
|
||||||
|
|
||||||
{% block maincontent %}
|
{% block bottom %}
|
||||||
{% for event in event_list %}
|
|
||||||
{% get_comment_count for event as comment_count %}
|
|
||||||
{% ifchanged %}<h3 class="grid_12">{{ event.start|date:'F Y' }}</h3>{% endifchanged %}
|
|
||||||
<div style="float:left">
|
|
||||||
<a href="{% url 'event-photo-list' event.pk %}"><img src="{{ event.get_image|thumbnail_url:'thumbnail' }}" alt="" class="thumbnail"/></a>
|
|
||||||
<div class="grid_4" />
|
|
||||||
<h4><a href="{% url 'event-photo-list' event.pk %}">{{ event.name }}</a></h4>
|
|
||||||
<div class="info">
|
|
||||||
<span class="fa fa-calendar-o" title="{% trans 'Start' %}"></span>
|
|
||||||
{{ event.start|date }}
|
|
||||||
{% if event.end %}
|
|
||||||
{% trans "from" %} {{ event.start|time:'H:i' }} {% trans "to" %} {{ event.end|time:'H:i' }}
|
|
||||||
{% else %}
|
|
||||||
{{ event.start|time:'H:i' }}
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
{% if event.description %}<p>{{event.description}}</p>{% endif %}
|
|
||||||
<div class="info">
|
|
||||||
<span class="fa fa-map-marker" title="{% trans 'Location' %}"></span>
|
|
||||||
{{ event.location }}
|
|
||||||
<span class="fa fa-comments" title="{% trans 'Comments' %}"></span>
|
|
||||||
<a href="{{event.get_absolute_url}}#comments">{{ comment_count }} {% trans 'Comments' %}</a>
|
|
||||||
|
|
||||||
<span class="fa fa-camera-retro" title="{% trans 'Photos' %}"></span>
|
|
||||||
<a href="{% url 'event-photo-list' event.pk %}">{{ event.photo_count }} {% trans 'Photos' %}</a>
|
|
||||||
</div>
|
|
||||||
<p style="text-align:right">
|
|
||||||
{% if perms.events.add_photo %}
|
|
||||||
<a href="{% url 'event-photo-list' event.pk %}" class="button">
|
|
||||||
<span class="fa fa-cloud-upload"></span>
|
|
||||||
{%trans "Upload" %}</a>
|
|
||||||
{% endif %}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
<form method="post" enctype="multipart/form-data">
|
<form method="post" enctype="multipart/form-data">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<fieldset class="grid_8 push_2">
|
<fieldset id="bottom_buttonbar" class="grid_12">
|
||||||
<legend>Photos hochladen</legend>
|
<legend>Photos hochladen</legend>
|
||||||
{% include "form.html" %}
|
{% include "form.html" %}
|
||||||
<p class="buttonbar">
|
<p class="buttonbar">
|
||||||
@@ -52,5 +16,5 @@
|
|||||||
</fieldset>
|
</fieldset>
|
||||||
</form>
|
</form>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
{% block buttonbar %}
|
||||||
|
{% endblock %}
|
||||||
|
|||||||
@@ -1,20 +1,19 @@
|
|||||||
"""
|
"""
|
||||||
This file should test the functionality of the events app using the unittest
|
This file should test the functionality of the events app using the unittest
|
||||||
module. These will pass when you run "manage.py test".
|
module. These will pass when you run "manage.py test".
|
||||||
|
useful tests have to be written yet. sorry!
|
||||||
Usefull tests have to been written yet. sorry!
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
|
|
||||||
|
|
||||||
class EventTest(TestCase):
|
class EventTest(TestCase):
|
||||||
""" Here we should test the creation and modifiaction of Events. """
|
""" Here we should test the creation and modification of Events. """
|
||||||
|
|
||||||
|
|
||||||
class LocationTest(TestCase):
|
class LocationTest(TestCase):
|
||||||
""" Here we should test the creation and modifiaction of Locations. """
|
""" Here we should test the creation and modification of Locations. """
|
||||||
|
|
||||||
|
|
||||||
class PhotoTest(TestCase):
|
class PhotoTest(TestCase):
|
||||||
""" Here we should test the creation and modifiaction of Photos. """
|
""" Here we should test the creation and modification of Photos. """
|
||||||
|
|||||||
@@ -1,22 +1,21 @@
|
|||||||
"""URLS to access upcoming events and the event archive."""
|
"""URLS to access upcoming events and the event archive."""
|
||||||
from django.conf.urls import url
|
from django.urls import path
|
||||||
from django.views.generic import RedirectView
|
from django.views.generic import RedirectView
|
||||||
from . import views
|
from . import views
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^$', RedirectView.as_view(url='/events/upcoming/', permanent=True)),
|
path("", RedirectView.as_view(url='/events/upcoming/', permanent=True)),
|
||||||
url(r'^(?P<year>[\d]{4})/$', views.EventArchiveYear.as_view(),
|
path('<int:year>/', views.EventArchiveYear.as_view(), name='event-archive'),
|
||||||
|
path('<int:year>/<int:month>/', views.EventArchiveMonth.as_view(),
|
||||||
name='event-archive'),
|
name='event-archive'),
|
||||||
url(r'^(?P<year>[\d]{4})/(?P<month>[\d]+)/$',
|
path('<int:year>/<int:month>/<int:pk>/', views.EventDetail.as_view(),
|
||||||
views.EventArchiveMonth.as_view(),
|
name='event-detail'),
|
||||||
name='event-archive'),
|
path('<int:year>/<int:month>/<int:pk>/add_dates/',
|
||||||
url(r'^(?P<year>[\d]{4})/(?P<month>[\d]+)/(?P<pk>[\d]+)/$',
|
views.EventSeriesForm.as_view(),
|
||||||
views.EventDetail.as_view(), name='event-detail'),
|
name='event-series-form'),
|
||||||
url(r'^(?P<year>[\d]{4})/(?P<month>[\d]+)/(?P<pk>[\d]+)/add_dates/$',
|
path('<int:year>/<int:month>/<int:pk>/edit/', views.EventForm.as_view(),
|
||||||
views.EventSeriesForm.as_view(), name='eventseries-form'),
|
name='event-form'),
|
||||||
url(r'^(?P<year>[\d]{4})/(?P<month>[\d]+)/(?P<pk>[\d]+)/edit/$',
|
path('add/', views.EventForm.as_view(), name='event-form'),
|
||||||
views.EventForm.as_view(), name='event-form'),
|
path('archive/', views.EventArchiveIndex.as_view(), name='event-archive'),
|
||||||
url(r'^add/$', views.EventForm.as_view(), name='event-form'),
|
path('upcoming/', views.UpcomingEvents.as_view(), name='upcoming-events'),
|
||||||
url(r'^archive/$', views.EventArchiveIndex.as_view(), name='event-archive'),
|
|
||||||
url(r'^upcoming/$', views.UpcomingEvents.as_view(), name='upcoming-events'),
|
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -4,11 +4,10 @@ from datetime import timedelta
|
|||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django.contrib.auth.mixins import PermissionRequiredMixin
|
from django.contrib.auth.mixins import PermissionRequiredMixin
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.db.models import Q
|
from django.http import HttpResponse
|
||||||
from django.http import HttpResponse, Http404
|
from django.shortcuts import redirect, get_object_or_404
|
||||||
from django.shortcuts import redirect
|
|
||||||
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 django.views import generic
|
from django.views import generic
|
||||||
from extra_views import InlineFormSetView
|
from extra_views import InlineFormSetView
|
||||||
from icalendar import Calendar, Event
|
from icalendar import Calendar, Event
|
||||||
@@ -49,19 +48,16 @@ class EventDetail(mixins.EventDetailMixin, generic.DetailView):
|
|||||||
|
|
||||||
class EventForm(PermissionRequiredMixin, mixins.EventDetailMixin,
|
class EventForm(PermissionRequiredMixin, mixins.EventDetailMixin,
|
||||||
generic.UpdateView):
|
generic.UpdateView):
|
||||||
"""Frontend formular to add or edit a Event."""
|
"""Frontend formular to add or edit an Event."""
|
||||||
form_class = forms.EventForm
|
form_class = forms.EventForm
|
||||||
template_name = 'events/event_form.html'
|
template_name = 'events/event_form.html'
|
||||||
permission_required = 'events.add_event'
|
permission_required = 'events.add_event'
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
"""Dynamicle set the title to Add or Edit Event, depanding if an
|
"""sets the title to add or edit Event,
|
||||||
event ID was given, or not."""
|
depending on the fact if an event ID was given."""
|
||||||
context = super(EventForm, self).get_context_data(**kwargs)
|
context = super(EventForm, self).get_context_data(**kwargs)
|
||||||
if self.kwargs.get('pk'):
|
context['title'] = _("Edit Event") if self.kwargs.get('pk') else _("Add Event")
|
||||||
context['title'] = _("Edit Event")
|
|
||||||
else:
|
|
||||||
context['title'] = _("Add Event")
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
def get_object(self, queryset=None):
|
def get_object(self, queryset=None):
|
||||||
@@ -73,18 +69,22 @@ class EventForm(PermissionRequiredMixin, mixins.EventDetailMixin,
|
|||||||
|
|
||||||
|
|
||||||
class EventGallery(generic.ListView):
|
class EventGallery(generic.ListView):
|
||||||
"""Display a overview of all event photo albums."""
|
"""Display an overview of all event photo albums."""
|
||||||
template_name = 'events/photo_gallery.html'
|
template_name = 'events/photo_gallery.html'
|
||||||
|
paginate_by = 24
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
queryset = models.Event.objects.filter(
|
queryset = models.Event.objects.filter(
|
||||||
start__lt=timezone.now(),
|
start__lt=timezone.now(),
|
||||||
event_series__isnull=True,
|
event_series__isnull=True,
|
||||||
photo_count__gt=0
|
photo_count__gt=0
|
||||||
)
|
)
|
||||||
paginate_by = 12
|
queryset = queryset.order_by('-start')
|
||||||
|
return queryset
|
||||||
|
|
||||||
|
|
||||||
class EventListIcal(generic.View):
|
class EventListIcal(generic.View):
|
||||||
"""Generates an returns an iCal File with all upcoming events."""
|
"""Generates and returns an iCal File with all upcoming events."""
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
"""Add all upcoming events to an .ics file and send it."""
|
"""Add all upcoming events to an .ics file and send it."""
|
||||||
@@ -109,7 +109,7 @@ class EventListIcal(generic.View):
|
|||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
class EventPhoto(mixins.EventDetailMixin, generic.UpdateView):
|
class EventPhoto(mixins.EventPhotoMixin, generic.UpdateView):
|
||||||
"""Display the requested Photo and allows rotation if the user has change
|
"""Display the requested Photo and allows rotation if the user has change
|
||||||
permissions."""
|
permissions."""
|
||||||
form_class = forms.EditPhotoForm
|
form_class = forms.EditPhotoForm
|
||||||
@@ -126,8 +126,8 @@ class EventPhoto(mixins.EventDetailMixin, generic.UpdateView):
|
|||||||
return generic.UpdateView.post(self, request, *args, **kwargs)
|
return generic.UpdateView.post(self, request, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class EventPhotoList(mixins.EventDetailMixin, generic.ListView):
|
class EventPhotoList(mixins.EventPhotoMixin, generic.ListView):
|
||||||
"""List all Photos of the event or event series in an album."""
|
"""List all Photos of the event or event series."""
|
||||||
context_object_name = 'photo_list'
|
context_object_name = 'photo_list'
|
||||||
event = None
|
event = None
|
||||||
paginate_by = 36
|
paginate_by = 36
|
||||||
@@ -138,16 +138,6 @@ class EventPhotoList(mixins.EventDetailMixin, generic.ListView):
|
|||||||
initial={'event': self.event, 'photographer': self.request.user})
|
initial={'event': self.event, 'photographer': self.request.user})
|
||||||
return context
|
return context
|
||||||
|
|
||||||
def get_queryset(self):
|
|
||||||
try:
|
|
||||||
self.event = models.Event.objects.get(id=self.kwargs['event'])
|
|
||||||
return models.Photo.objects.filter(
|
|
||||||
Q(event=self.event) |
|
|
||||||
Q(event__event_series=self.event)
|
|
||||||
)
|
|
||||||
except models.Event.DoesNotExist:
|
|
||||||
raise Http404(_('Event does not exist'))
|
|
||||||
|
|
||||||
|
|
||||||
class EventPhotoUpload(mixins.EventDetailMixin, generic.FormView):
|
class EventPhotoUpload(mixins.EventDetailMixin, generic.FormView):
|
||||||
form_class = forms.PhotoUploadForm
|
form_class = forms.PhotoUploadForm
|
||||||
@@ -186,20 +176,21 @@ class EventSeriesForm(mixins.EventDetailMixin, PermissionRequiredMixin,
|
|||||||
InlineFormSetView):
|
InlineFormSetView):
|
||||||
model = models.Event
|
model = models.Event
|
||||||
inline_model = models.Event
|
inline_model = models.Event
|
||||||
fk_name = 'event_series'
|
|
||||||
fields = ('start', 'end')
|
fields = ('start', 'end')
|
||||||
form_class = forms.EventForm
|
form_class = forms.EventForm
|
||||||
extra = 3
|
factory_kwargs = {'extra': 3, 'fk_name': 'event_series'}
|
||||||
permission_required = 'events.add_event'
|
permission_required = 'events.add_event'
|
||||||
template_name = 'events/eventseries_form.html'
|
template_name = 'events/eventseries_form.html'
|
||||||
|
|
||||||
def get_object(self, queryset=None):
|
def get_object(self, queryset=None):
|
||||||
self.event = models.Event.objects.get(pk=self.kwargs['pk'])
|
self.event = get_object_or_404(models.Event, pk=self.kwargs['pk'])
|
||||||
if self.event.event_series:
|
if self.event.event_series:
|
||||||
self.event = self.event.event_series
|
self.event = self.event.event_series
|
||||||
return self.event
|
return self.event
|
||||||
|
|
||||||
|
|
||||||
class UpcomingEvents(generic.ListView):
|
class UpcomingEvents(generic.ListView):
|
||||||
queryset = models.Event.objects.upcoming(limit=None)
|
|
||||||
paginate_by = 16
|
paginate_by = 16
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return models.Event.objects.upcoming(limit=None)
|
||||||
|
|||||||
Binary file not shown.
@@ -7,9 +7,9 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: kasu.utils\n"
|
"Project-Id-Version: kasu.utils\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2017-06-19 22:46+0200\n"
|
"POT-Creation-Date: 2023-08-07 20:38+0200\n"
|
||||||
"PO-Revision-Date: 2016-09-28 00:24+0200\n"
|
"PO-Revision-Date: 2018-12-30 11:14+0105\n"
|
||||||
"Last-Translator: Christian Berg <xeniac.at@gmail.com>\n"
|
"Last-Translator: b' <kasu@xendynastie.at>'\n"
|
||||||
"Language-Team: Kasu <verein@kasu.at>\n"
|
"Language-Team: Kasu <verein@kasu.at>\n"
|
||||||
"Language: de\n"
|
"Language: de\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
@@ -17,183 +17,183 @@ msgstr ""
|
|||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
"X-Generator: Poedit 1.8.9\n"
|
"X-Generator: Poedit 1.8.9\n"
|
||||||
"X-Translated-Using: django-rosetta 0.7.6\n"
|
"X-Translated-Using: django-rosetta 0.9.0\n"
|
||||||
|
|
||||||
#: kasu/settings.py:153
|
#: settings.py:144
|
||||||
msgid "German"
|
msgid "German"
|
||||||
msgstr "Deutsch"
|
msgstr "Deutsch"
|
||||||
|
|
||||||
#: kasu/settings.py:153
|
#: settings.py:144
|
||||||
msgid "English"
|
msgid "English"
|
||||||
msgstr "Englisch"
|
msgstr "Englisch"
|
||||||
|
|
||||||
#: kasu/templates/404.html:8
|
#: templates/404.html:8
|
||||||
msgid "The page your requested does not exist on this server."
|
msgid "The page your requested does not exist on this server."
|
||||||
msgstr "Die angeforderte Seite existiert auf diesem Server nicht."
|
msgstr "Die angeforderte Seite existiert auf diesem Server nicht."
|
||||||
|
|
||||||
#: kasu/templates/base.html:22
|
#: templates/base.html:22
|
||||||
msgid "Current News"
|
msgid "Current News"
|
||||||
msgstr "Aktuelle Neuigkeiten"
|
msgstr "Aktuelle Neuigkeiten"
|
||||||
|
|
||||||
#: kasu/templates/base.html:24 kasu/templates/index.html:40
|
#: templates/base.html:24 templates/index.html:40
|
||||||
msgid "Recent Comments"
|
msgid "Recent Comments"
|
||||||
msgstr "Kürzliche Kommentare"
|
msgstr "Kürzliche Kommentare"
|
||||||
|
|
||||||
#: kasu/templates/base.html:45
|
#: templates/base.html:45
|
||||||
msgid "Menu"
|
msgid "Menu"
|
||||||
msgstr "Menü"
|
msgstr "Menü"
|
||||||
|
|
||||||
#: kasu/templates/base.html:69
|
#: templates/base.html:69
|
||||||
msgid "Current Event"
|
msgid "Current Event"
|
||||||
msgstr "Aktuelle Veranstaltung"
|
msgstr "Aktuelle Veranstaltung"
|
||||||
|
|
||||||
#: kasu/templates/base.html:72
|
#: templates/base.html:72
|
||||||
msgid "Since"
|
msgid "Since"
|
||||||
msgstr "seit"
|
msgstr "seit"
|
||||||
|
|
||||||
#: kasu/templates/base.html:73 kasu/templates/base.html:85
|
#: templates/base.html:73 templates/base.html:87
|
||||||
msgid "Start"
|
msgid "Start"
|
||||||
msgstr "Beginn"
|
msgstr "Beginn"
|
||||||
|
|
||||||
#: kasu/templates/base.html:76 kasu/templates/base.html:88
|
#: templates/base.html:76 templates/base.html:90
|
||||||
msgid "Location"
|
msgid "Location"
|
||||||
msgstr "Ort"
|
msgstr "Ort"
|
||||||
|
|
||||||
#: kasu/templates/base.html:79 kasu/templates/base.html:90
|
#: templates/base.html:81 templates/base.html:94
|
||||||
msgid "More Details"
|
msgid "More Details"
|
||||||
msgstr "Mehr Details"
|
msgstr "Mehr Details"
|
||||||
|
|
||||||
#: kasu/templates/base.html:81
|
#: templates/base.html:83
|
||||||
msgid "Next Event"
|
msgid "Next Event"
|
||||||
msgstr "Nächste Veranstaltung"
|
msgstr "Nächste Veranstaltung"
|
||||||
|
|
||||||
#: kasu/templates/base.html:84
|
#: templates/base.html:86
|
||||||
msgid "in"
|
msgid "in"
|
||||||
msgstr "in"
|
msgstr "in"
|
||||||
|
|
||||||
#: kasu/templates/base.html:93
|
#: templates/base.html:97
|
||||||
msgid "Upcoming events"
|
msgid "Upcoming events"
|
||||||
msgstr "Bevorstehende Veranstaltungen"
|
msgstr "Bevorstehende Veranstaltungen"
|
||||||
|
|
||||||
#: kasu/templates/base.html:143
|
#: templates/base.html:107
|
||||||
|
msgid "No events found"
|
||||||
|
msgstr "Keine Veranstaltungen gefunden"
|
||||||
|
|
||||||
|
#: templates/base.html:150
|
||||||
msgid "Add Subpage"
|
msgid "Add Subpage"
|
||||||
msgstr "Unterseite Hinzufügen"
|
msgstr "Unterseite Hinzufügen"
|
||||||
|
|
||||||
#: kasu/templates/base.html:148
|
#: templates/base.html:154
|
||||||
msgid "Edit Page"
|
msgid "Edit Page"
|
||||||
msgstr "Seite bearbeiten"
|
msgstr "Seite bearbeiten"
|
||||||
|
|
||||||
#: kasu/templates/base.html:156
|
#: templates/base.html:163
|
||||||
msgid "Imprint"
|
msgid "Imprint"
|
||||||
msgstr "Impressum"
|
msgstr "Impressum"
|
||||||
|
|
||||||
#: kasu/templates/base.html:157
|
#: templates/base.html:164
|
||||||
msgid "contact"
|
msgid "contact"
|
||||||
msgstr "Kontakt"
|
msgstr "Kontakt"
|
||||||
|
|
||||||
#: kasu/templates/base.html:162
|
#: templates/base.html:169
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr "Sprache"
|
msgstr "Sprache"
|
||||||
|
|
||||||
#: kasu/templates/base.html:171
|
#: templates/base.html:178
|
||||||
msgid "Go"
|
msgid "Go"
|
||||||
msgstr "Los"
|
msgstr "Los"
|
||||||
|
|
||||||
#: kasu/templates/base.html:176
|
#: templates/base.html:183
|
||||||
msgid "Logged in as"
|
msgid "Logged in as"
|
||||||
msgstr "Angemeldet als"
|
msgstr "Angemeldet als"
|
||||||
|
|
||||||
#: kasu/templates/base.html:178
|
#: templates/base.html:185
|
||||||
msgid "Admin"
|
msgid "Admin"
|
||||||
msgstr "Admin"
|
msgstr "Admin"
|
||||||
|
|
||||||
#: kasu/templates/base.html:179
|
#: templates/base.html:186
|
||||||
msgid "Logout"
|
msgid "Logout"
|
||||||
msgstr "Abmelden"
|
msgstr "Abmelden"
|
||||||
|
|
||||||
#: kasu/templates/base.html:181
|
#: templates/base.html:188
|
||||||
msgid "no user logged in"
|
msgid "no user logged in"
|
||||||
msgstr "Niemand angemeldet"
|
msgstr "Niemand angemeldet"
|
||||||
|
|
||||||
#: kasu/templates/base.html:182 kasu/templates/comments/form.html:43
|
#: templates/base.html:189 templates/comments/form.html:43
|
||||||
msgid "register"
|
msgid "register"
|
||||||
msgstr "Registrieren"
|
msgstr "Registrieren"
|
||||||
|
|
||||||
#: kasu/templates/base.html:183 kasu/templates/comments/form.html:44
|
#: templates/base.html:190 templates/comments/form.html:44
|
||||||
msgid "login"
|
msgid "login"
|
||||||
msgstr "anmelden"
|
msgstr "anmelden"
|
||||||
|
|
||||||
#: kasu/templates/base.html:185
|
#: templates/comments/form.html:5
|
||||||
msgid "Login with Facebook"
|
|
||||||
msgstr "über Facebook anmelden"
|
|
||||||
|
|
||||||
#: kasu/templates/base.html:187
|
|
||||||
msgid "Login with Twitter"
|
|
||||||
msgstr "über Twitter anmelden"
|
|
||||||
|
|
||||||
#: kasu/templates/base.html:189
|
|
||||||
msgid "Login with Google"
|
|
||||||
msgstr "über Google anmelden"
|
|
||||||
|
|
||||||
#: kasu/templates/comments/form.html:5
|
|
||||||
msgid "New Comment"
|
msgid "New Comment"
|
||||||
msgstr "Neuer Kommentar"
|
msgstr "Neuer Kommentar"
|
||||||
|
|
||||||
#: kasu/templates/comments/form.html:20
|
#: templates/comments/form.html:20
|
||||||
msgid "now"
|
msgid "now"
|
||||||
msgstr "Jetzt"
|
msgstr "Jetzt"
|
||||||
|
|
||||||
#: kasu/templates/comments/form.html:25
|
#: templates/comments/form.html:25
|
||||||
msgid "Preview"
|
msgid "Preview"
|
||||||
msgstr "Vorschau"
|
msgstr "Vorschau"
|
||||||
|
|
||||||
#: kasu/templates/comments/form.html:26
|
#: templates/comments/form.html:26
|
||||||
msgid "Post"
|
msgid "Post"
|
||||||
msgstr "Schreiben"
|
msgstr "Schreiben"
|
||||||
|
|
||||||
#: kasu/templates/comments/form.html:34
|
#: templates/comments/form.html:34
|
||||||
msgid "not logged in"
|
msgid "not logged in"
|
||||||
msgstr "Nicht angemeldet"
|
msgstr "Nicht angemeldet"
|
||||||
|
|
||||||
#: kasu/templates/comments/form.html:38
|
#: templates/comments/form.html:38
|
||||||
msgid "Register now, or Login to leave a comment here."
|
msgid "Register now, or Login to leave a comment here."
|
||||||
msgstr "Jetzt registrieren, oder anmelden um einen Kommentar zu schreiben."
|
msgstr "Jetzt registrieren, oder anmelden um einen Kommentar zu schreiben."
|
||||||
|
|
||||||
#: kasu/templates/comments/list.html:2 kasu/templates/index.html:25
|
#: templates/comments/list.html:2 templates/index.html:25
|
||||||
msgid "Comments"
|
msgid "Comments"
|
||||||
msgstr "Kommentare"
|
msgstr "Kommentare"
|
||||||
|
|
||||||
#: kasu/templates/comments/posted.html:4 kasu/templates/comments/posted.html:7
|
#: templates/comments/posted.html:4 templates/comments/posted.html:7
|
||||||
msgid "Thank you for your comment"
|
msgid "Thank you for your comment"
|
||||||
msgstr "Danke für deinen Kommentar."
|
msgstr "Danke für deinen Kommentar."
|
||||||
|
|
||||||
#: kasu/templates/comments/preview.html:4
|
#: templates/comments/preview.html:4 templates/comments/preview.html:6
|
||||||
#: kasu/templates/comments/preview.html:6
|
|
||||||
msgid "Preview your comment"
|
msgid "Preview your comment"
|
||||||
msgstr "Vorschau deines Kommentars"
|
msgstr "Vorschau deines Kommentars"
|
||||||
|
|
||||||
#: kasu/templates/comments/preview.html:10
|
#: templates/comments/preview.html:10
|
||||||
msgid "Please correct the error below"
|
msgid "Please correct the error below"
|
||||||
msgid_plural "Please correct the errors below"
|
msgid_plural "Please correct the errors below"
|
||||||
msgstr[0] "Bitte den Fehler weiter unten beheben"
|
msgstr[0] "Bitte den Fehler weiter unten beheben"
|
||||||
msgstr[1] "Bitte die Fehler weiter unten beheben"
|
msgstr[1] "Bitte die Fehler weiter unten beheben"
|
||||||
|
|
||||||
#: kasu/templates/index.html:4
|
#: templates/index.html:4
|
||||||
msgid "traditional Asian game culture"
|
msgid "traditional Asian game culture"
|
||||||
msgstr "traditionelle asiatische Spielkultur"
|
msgstr "traditionelle asiatische Spielkultur"
|
||||||
|
|
||||||
#: kasu/templates/index.html:33
|
#: templates/index.html:33
|
||||||
msgid "Read More"
|
msgid "Read More"
|
||||||
msgstr "Mehr lesen"
|
msgstr "Mehr lesen"
|
||||||
|
|
||||||
#: kasu/templates/index.html:47
|
#: templates/index.html:47
|
||||||
#, python-format
|
#, fuzzy, python-format
|
||||||
|
#| msgid ""
|
||||||
|
#| "\n"
|
||||||
|
#| " From <a href=\"%(user_link)s\">%(author)s</a> in\n"
|
||||||
|
#| " <a href=\"%(comment_link)s\">“%(object)s”</"
|
||||||
|
#| "a>\n"
|
||||||
|
#| " since\n"
|
||||||
|
#| " <time datetime=\"%(submit_date)s\">%(since)s</time>\n"
|
||||||
|
#| " "
|
||||||
msgid ""
|
msgid ""
|
||||||
"\n"
|
"\n"
|
||||||
" From <a href=\"%(user_link)s\">%(author)s</a> in\n"
|
" From <a href=\"%(user_link)s\">%(author)s</a> in\n"
|
||||||
" <a href=\"%(comment_link)s\">“%(object)s”</a>\n"
|
" <a href=\"%(comment_link)s\">“%(object)s”</a>\n"
|
||||||
" since\n"
|
" since\n"
|
||||||
" <time datetime=\"%(submit_date)s\">%(since)s</time>\n"
|
" <time "
|
||||||
|
"datetime=\"%(submit_date|date:'Y-m-d\\TH:i:sO')s\">%(since)s</time>\n"
|
||||||
" "
|
" "
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"\n"
|
"\n"
|
||||||
@@ -203,26 +203,35 @@ msgstr ""
|
|||||||
" <time datetime=\"%(submit_date)s\">%(since)s</time>\n"
|
" <time datetime=\"%(submit_date)s\">%(since)s</time>\n"
|
||||||
" "
|
" "
|
||||||
|
|
||||||
#: kasu/templates/index.html:59
|
#: templates/index.html:59
|
||||||
msgid "Kasu in the social network"
|
msgid "Kasu in the social network"
|
||||||
msgstr "Kasu im sozialem Netzwerk"
|
msgstr "Kasu im sozialem Netzwerk"
|
||||||
|
|
||||||
#: kasu/templates/index.html:62 kasu/templates/index.html:65
|
#: templates/index.html:62 templates/index.html:65
|
||||||
msgid "Visit us on"
|
msgid "Visit us on"
|
||||||
msgstr "Besuche uns auf"
|
msgstr "Besuche uns auf"
|
||||||
|
|
||||||
#: kasu/templates/index.html:74
|
#: templates/index.html:74
|
||||||
msgid "Add Article"
|
msgid "Add Article"
|
||||||
msgstr "Artikel hinzufügen"
|
msgstr "Artikel hinzufügen"
|
||||||
|
|
||||||
#: kasu/templates/paginator.html:8
|
#: templates/paginator.html:5 templates/paginator.html:7
|
||||||
msgid "Previous"
|
msgid "Previous"
|
||||||
msgstr "Vorherige"
|
msgstr "Vorherige"
|
||||||
|
|
||||||
#: kasu/templates/paginator.html:20
|
#: templates/paginator.html:17 templates/paginator.html:20
|
||||||
msgid "Next"
|
msgid "Next"
|
||||||
msgstr "Nächste"
|
msgstr "Nächste"
|
||||||
|
|
||||||
|
#~ msgid "Login with Facebook"
|
||||||
|
#~ msgstr "über Facebook anmelden"
|
||||||
|
|
||||||
|
#~ msgid "Login with Twitter"
|
||||||
|
#~ msgstr "über Twitter anmelden"
|
||||||
|
|
||||||
|
#~ msgid "Login with Google"
|
||||||
|
#~ msgstr "über Google anmelden"
|
||||||
|
|
||||||
#~ msgid "United Kingdom"
|
#~ msgid "United Kingdom"
|
||||||
#~ msgstr "Vereinigtes Königreich"
|
#~ msgstr "Vereinigtes Königreich"
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,6 @@ PREREQ_APPS = [
|
|||||||
'ckeditor',
|
'ckeditor',
|
||||||
'ckeditor_uploader',
|
'ckeditor_uploader',
|
||||||
'easy_thumbnails',
|
'easy_thumbnails',
|
||||||
'social_django',
|
|
||||||
]
|
]
|
||||||
PROJECT_APPS = [
|
PROJECT_APPS = [
|
||||||
'kasu',
|
'kasu',
|
||||||
@@ -69,17 +68,16 @@ CACHES = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Request Middleware
|
# Request Middleware
|
||||||
MIDDLEWARE_CLASSES = [
|
MIDDLEWARE = [
|
||||||
'csp.middleware.CSPMiddleware',
|
'csp.middleware.CSPMiddleware',
|
||||||
'django.middleware.security.SecurityMiddleware',
|
'django.middleware.security.SecurityMiddleware',
|
||||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||||
'django.middleware.common.CommonMiddleware',
|
'django.middleware.common.CommonMiddleware',
|
||||||
'django.middleware.csrf.CsrfViewMiddleware',
|
'django.middleware.csrf.CsrfViewMiddleware',
|
||||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||||
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
|
|
||||||
'django.middleware.locale.LocaleMiddleware',
|
|
||||||
'django.contrib.messages.middleware.MessageMiddleware',
|
'django.contrib.messages.middleware.MessageMiddleware',
|
||||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||||
|
'django.middleware.locale.LocaleMiddleware',
|
||||||
'utils.middleware.SetRemoteAddrFromForwardedFor',
|
'utils.middleware.SetRemoteAddrFromForwardedFor',
|
||||||
'mahjong_ranking.middleware.DenormalizationUpdateMiddleware',
|
'mahjong_ranking.middleware.DenormalizationUpdateMiddleware',
|
||||||
]
|
]
|
||||||
@@ -103,8 +101,6 @@ TEMPLATES = [
|
|||||||
'django.contrib.messages.context_processors.messages',
|
'django.contrib.messages.context_processors.messages',
|
||||||
'django.contrib.messages.context_processors.messages',
|
'django.contrib.messages.context_processors.messages',
|
||||||
'events.context_processors.events_overview',
|
'events.context_processors.events_overview',
|
||||||
'social_django.context_processors.backends',
|
|
||||||
'social_django.context_processors.login_redirect'
|
|
||||||
],
|
],
|
||||||
'loaders': [
|
'loaders': [
|
||||||
('django.template.loaders.cached.Loader', [
|
('django.template.loaders.cached.Loader', [
|
||||||
@@ -132,24 +128,14 @@ DEFAULT_FROM_EMAIL = ""
|
|||||||
# Login Settings
|
# Login Settings
|
||||||
ACCOUNT_ACTIVATION_DAYS = 5
|
ACCOUNT_ACTIVATION_DAYS = 5
|
||||||
AUTH_USER_MODEL = 'membership.Membership'
|
AUTH_USER_MODEL = 'membership.Membership'
|
||||||
AUTHENTICATION_BACKENDS = ('social_core.backends.facebook.FacebookOAuth2',
|
AUTHENTICATION_BACKENDS = ('django.contrib.auth.backends.ModelBackend',)
|
||||||
'social_core.backends.google.GoogleOAuth2',
|
|
||||||
'social_core.backends.twitter.TwitterOAuth',
|
|
||||||
'django.contrib.auth.backends.ModelBackend',)
|
|
||||||
LOGIN_URL = '/membership/login/'
|
LOGIN_URL = '/membership/login/'
|
||||||
LOGIN_ERROR_URL = '/membership/login/error/'
|
LOGIN_ERROR_URL = '/membership/login/error/'
|
||||||
LOGIN_REDIRECT_URL = '/users/'
|
LOGIN_REDIRECT_URL = '/users/'
|
||||||
SOCIAL_AUTH_CHANGE_SIGNAL_ONLY = False
|
|
||||||
SOCIAL_AUTH_ENABLED_BACKENDS = ('facebook-oauth2', 'google-oauth2', 'twitter')
|
|
||||||
SOCIAL_AUTH_NEW_USER_REDIRECT_URL = '/users/'
|
# Set the primarykey handing to old django style
|
||||||
SOCIAL_AUTH_SLUGIFY_USERNAMES = True
|
DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
|
||||||
SOCIAL_AUTH_FACEBOOK_KEY = ''
|
|
||||||
SOCIAL_AUTH_FACEBOOK_SECRET = ''
|
|
||||||
SOCIAL_AUTH_FACEBOOK_SCOPE = ['user_about_me', 'email']
|
|
||||||
SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = ''
|
|
||||||
SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = ''
|
|
||||||
SOCIAL_AUTH_TWITTER_KEY = ''
|
|
||||||
SOCIAL_AUTH_TWITTER_SECRET = ''
|
|
||||||
|
|
||||||
# Localization
|
# Localization
|
||||||
USE_I18N = True
|
USE_I18N = True
|
||||||
@@ -205,7 +191,8 @@ LOGGING = {
|
|||||||
},
|
},
|
||||||
'formatters': {
|
'formatters': {
|
||||||
'verbose': {
|
'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': {
|
'simple': {
|
||||||
'format': '%(levelname)s %(message)s'
|
'format': '%(levelname)s %(message)s'
|
||||||
@@ -289,7 +276,7 @@ KYU_RANKS = (
|
|||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from .local_settings import * # Ignore PyLintBear (W0401, W0614)
|
from .local_settings import * # noqa: F403
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|||||||
@@ -337,6 +337,10 @@ ul.tabs li.active a {
|
|||||||
ul.errorlist li {
|
ul.errorlist li {
|
||||||
color: #a40000;
|
color: #a40000;
|
||||||
}
|
}
|
||||||
|
input.error {
|
||||||
|
border-color: #a40000;
|
||||||
|
background-color: rgba(164, 0, 0, 0.25);
|
||||||
|
}
|
||||||
.game h2 {
|
.game h2 {
|
||||||
margin: 0.5em 0;
|
margin: 0.5em 0;
|
||||||
}
|
}
|
||||||
|
|||||||
231
src/kasu/static/js/jquery.formset.js
Normal file
231
src/kasu/static/js/jquery.formset.js
Normal file
@@ -0,0 +1,231 @@
|
|||||||
|
/**
|
||||||
|
* jQuery Formset 1.3-pre
|
||||||
|
* @author Stanislaus Madueke (stan DOT madueke AT gmail DOT com)
|
||||||
|
* @requires jQuery 1.2.6 or later
|
||||||
|
*
|
||||||
|
* Copyright (c) 2009, Stanislaus Madueke
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the New BSD License
|
||||||
|
* See: http://www.opensource.org/licenses/bsd-license.php
|
||||||
|
*/
|
||||||
|
;(function($) {
|
||||||
|
$.fn.formset = function(opts)
|
||||||
|
{
|
||||||
|
var options = $.extend({}, $.fn.formset.defaults, opts),
|
||||||
|
flatExtraClasses = options.extraClasses.join(' '),
|
||||||
|
totalForms = $('#id_' + options.prefix + '-TOTAL_FORMS'),
|
||||||
|
maxForms = $('#id_' + options.prefix + '-MAX_NUM_FORMS'),
|
||||||
|
minForms = $('#id_' + options.prefix + '-MIN_NUM_FORMS'),
|
||||||
|
childElementSelector = 'input,select,textarea,label,div',
|
||||||
|
$$ = $(this),
|
||||||
|
|
||||||
|
applyExtraClasses = function(row, ndx) {
|
||||||
|
if (options.extraClasses) {
|
||||||
|
row.removeClass(flatExtraClasses);
|
||||||
|
row.addClass(options.extraClasses[ndx % options.extraClasses.length]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
updateElementIndex = function(elem, prefix, ndx) {
|
||||||
|
var idRegex = new RegExp(prefix + '-(\\d+|__prefix__)-'),
|
||||||
|
replacement = prefix + '-' + ndx + '-';
|
||||||
|
if (elem.attr("for")) elem.attr("for", elem.attr("for").replace(idRegex, replacement));
|
||||||
|
if (elem.attr('id')) elem.attr('id', elem.attr('id').replace(idRegex, replacement));
|
||||||
|
if (elem.attr('name')) elem.attr('name', elem.attr('name').replace(idRegex, replacement));
|
||||||
|
},
|
||||||
|
|
||||||
|
hasChildElements = function(row) {
|
||||||
|
return row.find(childElementSelector).length > 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
showAddButton = function() {
|
||||||
|
return maxForms.length == 0 || // For Django versions pre 1.2
|
||||||
|
(maxForms.val() == '' || (maxForms.val() - totalForms.val() > 0));
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether delete link(s) can be displayed - when total forms > min forms
|
||||||
|
*/
|
||||||
|
showDeleteLinks = function() {
|
||||||
|
return minForms.length == 0 || // For Django versions pre 1.7
|
||||||
|
(minForms.val() == '' || (totalForms.val() - minForms.val() > 0));
|
||||||
|
},
|
||||||
|
|
||||||
|
insertDeleteLink = function(row) {
|
||||||
|
var delCssSelector = $.trim(options.deleteCssClass).replace(/\s+/g, '.'),
|
||||||
|
addCssSelector = $.trim(options.addCssClass).replace(/\s+/g, '.');
|
||||||
|
if (row.is('TR')) {
|
||||||
|
// If the forms are laid out in table rows, insert
|
||||||
|
// the remove button into the last table cell:
|
||||||
|
row.children(':last').append('<a class="' + options.deleteCssClass +'" href="javascript:void(0)">' + options.deleteText + '</a>');
|
||||||
|
} else if (row.is('UL') || row.is('OL')) {
|
||||||
|
// If they're laid out as an ordered/unordered list,
|
||||||
|
// insert an <li> after the last list item:
|
||||||
|
row.append('<li><a class="' + options.deleteCssClass + '" href="javascript:void(0)">' + options.deleteText +'</a></li>');
|
||||||
|
} else {
|
||||||
|
// Otherwise, just insert the remove button as the
|
||||||
|
// last child element of the form's container:
|
||||||
|
row.append('<a class="' + options.deleteCssClass + '" href="javascript:void(0)">' + options.deleteText +'</a>');
|
||||||
|
}
|
||||||
|
// Check if we're under the minimum number of forms - not to display delete link at rendering
|
||||||
|
if (!showDeleteLinks()){
|
||||||
|
row.find('a.' + delCssSelector).hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
row.find('a.' + delCssSelector).click(function() {
|
||||||
|
var row = $(this).parents('.' + options.formCssClass),
|
||||||
|
del = row.find('input:hidden[id $= "-DELETE"]'),
|
||||||
|
buttonRow = row.siblings("a." + addCssSelector + ', .' + options.formCssClass + '-add'),
|
||||||
|
forms;
|
||||||
|
if (del.length) {
|
||||||
|
// We're dealing with an inline formset.
|
||||||
|
// Rather than remove this form from the DOM, we'll mark it as deleted
|
||||||
|
// and hide it, then let Django handle the deleting:
|
||||||
|
del.val('on');
|
||||||
|
row.hide();
|
||||||
|
forms = $('.' + options.formCssClass).not(':hidden');
|
||||||
|
} else {
|
||||||
|
row.remove();
|
||||||
|
// Update the TOTAL_FORMS count:
|
||||||
|
forms = $('.' + options.formCssClass).not('.formset-custom-template');
|
||||||
|
totalForms.val(forms.length);
|
||||||
|
}
|
||||||
|
for (var i=0, formCount=forms.length; i<formCount; i++) {
|
||||||
|
// Apply `extraClasses` to form rows so they're nicely alternating:
|
||||||
|
applyExtraClasses(forms.eq(i), i);
|
||||||
|
if (!del.length) {
|
||||||
|
// Also update names and IDs for all child controls (if this isn't
|
||||||
|
// a delete-able inline formset) so they remain in sequence:
|
||||||
|
forms.eq(i).find(childElementSelector).each(function() {
|
||||||
|
updateElementIndex($(this), options.prefix, i);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Check if we've reached the minimum number of forms - hide all delete link(s)
|
||||||
|
if (!showDeleteLinks()){
|
||||||
|
$('a.' + delCssSelector).each(function(){$(this).hide();});
|
||||||
|
}
|
||||||
|
// Check if we need to show the add button:
|
||||||
|
if (buttonRow.is(':hidden') && showAddButton()) buttonRow.show();
|
||||||
|
// If a post-delete callback was provided, call it with the deleted form:
|
||||||
|
if (options.removed) options.removed(row);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
$$.each(function(i) {
|
||||||
|
var row = $(this),
|
||||||
|
del = row.find('input:checkbox[id $= "-DELETE"]');
|
||||||
|
if (del.length) {
|
||||||
|
// If you specify "can_delete = True" when creating an inline formset,
|
||||||
|
// Django adds a checkbox to each form in the formset.
|
||||||
|
// Replace the default checkbox with a hidden field:
|
||||||
|
if (del.is(':checked')) {
|
||||||
|
// If an inline formset containing deleted forms fails validation, make sure
|
||||||
|
// we keep the forms hidden (thanks for the bug report and suggested fix Mike)
|
||||||
|
del.before('<input type="hidden" name="' + del.attr('name') +'" id="' + del.attr('id') +'" value="on" />');
|
||||||
|
row.hide();
|
||||||
|
} else {
|
||||||
|
del.before('<input type="hidden" name="' + del.attr('name') +'" id="' + del.attr('id') +'" />');
|
||||||
|
}
|
||||||
|
// Hide any labels associated with the DELETE checkbox:
|
||||||
|
$('label[for="' + del.attr('id') + '"]').hide();
|
||||||
|
del.remove();
|
||||||
|
}
|
||||||
|
if (hasChildElements(row)) {
|
||||||
|
row.addClass(options.formCssClass);
|
||||||
|
if (row.is(':visible')) {
|
||||||
|
insertDeleteLink(row);
|
||||||
|
applyExtraClasses(row, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($$.length) {
|
||||||
|
var hideAddButton = !showAddButton(),
|
||||||
|
addButton, template;
|
||||||
|
if (options.formTemplate) {
|
||||||
|
// If a form template was specified, we'll clone it to generate new form instances:
|
||||||
|
template = (options.formTemplate instanceof $) ? options.formTemplate : $(options.formTemplate);
|
||||||
|
template.removeAttr('id').addClass(options.formCssClass + ' formset-custom-template');
|
||||||
|
template.find(childElementSelector).each(function() {
|
||||||
|
updateElementIndex($(this), options.prefix, '__prefix__');
|
||||||
|
});
|
||||||
|
insertDeleteLink(template);
|
||||||
|
} else {
|
||||||
|
// Otherwise, use the last form in the formset; this works much better if you've got
|
||||||
|
// extra (>= 1) forms (thnaks to justhamade for pointing this out):
|
||||||
|
template = $('.' + options.formCssClass + ':last').clone(true).removeAttr('id');
|
||||||
|
template.find('input:hidden[id $= "-DELETE"]').remove();
|
||||||
|
// Clear all cloned fields, except those the user wants to keep (thanks to brunogola for the suggestion):
|
||||||
|
template.find(childElementSelector).not(options.keepFieldValues).each(function() {
|
||||||
|
var elem = $(this);
|
||||||
|
// If this is a checkbox or radiobutton, uncheck it.
|
||||||
|
// This fixes Issue 1, reported by Wilson.Andrew.J:
|
||||||
|
if (elem.is('input:checkbox') || elem.is('input:radio')) {
|
||||||
|
elem.attr('checked', false);
|
||||||
|
} else {
|
||||||
|
elem.val('');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// FIXME: Perhaps using $.data would be a better idea?
|
||||||
|
options.formTemplate = template;
|
||||||
|
|
||||||
|
if ($$.is('TR')) {
|
||||||
|
// If forms are laid out as table rows, insert the
|
||||||
|
// "add" button in a new table row:
|
||||||
|
var numCols = $$.eq(0).children().length, // This is a bit of an assumption :|
|
||||||
|
buttonRow = $('<tr><td colspan="' + numCols + '"><a class="' + options.addCssClass + '" href="javascript:void(0)">' + options.addText + '</a></tr>')
|
||||||
|
.addClass(options.formCssClass + '-add');
|
||||||
|
$$.parent().append(buttonRow);
|
||||||
|
if (hideAddButton) buttonRow.hide();
|
||||||
|
addButton = buttonRow.find('a');
|
||||||
|
} else {
|
||||||
|
// Otherwise, insert it immediately after the last form:
|
||||||
|
$$.filter(':last').after('<a class="' + options.addCssClass + '" href="javascript:void(0)">' + options.addText + '</a>');
|
||||||
|
addButton = $$.filter(':last').next();
|
||||||
|
if (hideAddButton) addButton.hide();
|
||||||
|
}
|
||||||
|
addButton.click(function() {
|
||||||
|
var formCount = parseInt(totalForms.val()),
|
||||||
|
row = options.formTemplate.clone(true).removeClass('formset-custom-template'),
|
||||||
|
buttonRow = $($(this).parents('tr.' + options.formCssClass + '-add').get(0) || this),
|
||||||
|
delCssSelector = $.trim(options.deleteCssClass).replace(/\s+/g, '.');
|
||||||
|
applyExtraClasses(row, formCount);
|
||||||
|
row.insertBefore(buttonRow).show();
|
||||||
|
row.find(childElementSelector).each(function() {
|
||||||
|
updateElementIndex($(this), options.prefix, formCount);
|
||||||
|
});
|
||||||
|
totalForms.val(formCount + 1);
|
||||||
|
// Check if we're above the minimum allowed number of forms -> show all delete link(s)
|
||||||
|
if (showDeleteLinks()){
|
||||||
|
$('a.' + delCssSelector).each(function(){$(this).show();});
|
||||||
|
}
|
||||||
|
// Check if we've exceeded the maximum allowed number of forms:
|
||||||
|
if (!showAddButton()) buttonRow.hide();
|
||||||
|
// If a post-add callback was supplied, call it with the added form:
|
||||||
|
if (options.added) options.added(row);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return $$;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Setup plugin defaults */
|
||||||
|
$.fn.formset.defaults = {
|
||||||
|
prefix: 'form', // The form prefix for your django formset
|
||||||
|
formTemplate: null, // The jQuery selection cloned to generate new form instances
|
||||||
|
addText: 'add another', // Text for the add link
|
||||||
|
deleteText: 'remove', // Text for the delete link
|
||||||
|
addCssClass: 'add-row', // CSS class applied to the add link
|
||||||
|
deleteCssClass: 'delete-row', // CSS class applied to the delete link
|
||||||
|
formCssClass: 'dynamic-form', // CSS class applied to each form in a formset
|
||||||
|
extraClasses: [], // Additional CSS classes, which will be applied to each form in turn
|
||||||
|
keepFieldValues: '', // jQuery selector for fields whose values should be kept when the form is cloned
|
||||||
|
added: null, // Function called each time a new form is added
|
||||||
|
removed: null // Function called each time a form is deleted
|
||||||
|
};
|
||||||
|
})(jQuery);
|
||||||
@@ -4,9 +4,11 @@
|
|||||||
_paq.push(['trackPageView']);
|
_paq.push(['trackPageView']);
|
||||||
_paq.push(['enableLinkTracking']);
|
_paq.push(['enableLinkTracking']);
|
||||||
(function() {
|
(function() {
|
||||||
var u="//kasu.at/piwik/";
|
var u="/piwik/";
|
||||||
_paq.push(['setTrackerUrl', u+'piwik.php']);
|
_paq.push(['setTrackerUrl', u+'piwik.php']);
|
||||||
_paq.push(['setSiteId', '1']);
|
_paq.push(['setSiteId', '1']);
|
||||||
|
_paq.push(['disableCookies']);
|
||||||
|
_paq.push(['trackPageView']);
|
||||||
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
|
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
|
||||||
g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s);
|
g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s);
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -258,6 +258,7 @@ ul.tabs {
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
.error, ul.errorlist li {color: #a40000;}
|
.error, ul.errorlist li {color: #a40000;}
|
||||||
|
input.error {border-color:#a40000; background-color: rgba(164, 0, 0, 0.25);}
|
||||||
.game h2 {margin: 0.5em 0;}
|
.game h2 {margin: 0.5em 0;}
|
||||||
.grid_1,.grid_2,.grid_3,.grid_4,.grid_5,.grid_6,.grid_7,.grid_8,.grid_9,.grid_10,.grid_11,.grid_12
|
.grid_1,.grid_2,.grid_3,.grid_4,.grid_5,.grid_6,.grid_7,.grid_8,.grid_9,.grid_10,.grid_11,.grid_12
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -37,7 +37,7 @@
|
|||||||
{% block extra_head %}{% endblock %}
|
{% block extra_head %}{% endblock %}
|
||||||
<script src="{{ STATIC_URL }}js/piwik.js"></script>
|
<script src="{{ STATIC_URL }}js/piwik.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body id="body" {% block itemscope %}{% endblock %}>
|
<body id="body" itemscope>
|
||||||
<header id="siteheader">
|
<header id="siteheader">
|
||||||
<div id="sitelogo"><a href="/index.html">Kasu - traditionelle asiatische Spielkultur</a></div>
|
<div id="sitelogo"><a href="/index.html">Kasu - traditionelle asiatische Spielkultur</a></div>
|
||||||
<nav id="mainnav">
|
<nav id="mainnav">
|
||||||
@@ -46,12 +46,12 @@
|
|||||||
<ul class="main_menu">
|
<ul class="main_menu">
|
||||||
{% for item in top_menu_items %}
|
{% for item in top_menu_items %}
|
||||||
<li><a href="{{item.get_absolute_url}}" title="{{ item.title }}"
|
<li><a href="{{item.get_absolute_url}}" title="{{ item.title }}"
|
||||||
class="{%if item.active %}active{% endif %}">{{item.menu_name}}</a>
|
class="{% if item.active %}active{% endif %}">{{item.menu_name}}</a>
|
||||||
{% if item.subpages.all %}
|
{% if item.subpages.all %}
|
||||||
<ul class="main_dropdown">
|
<ul class="main_dropdown">
|
||||||
{% for subpage in item.subpages.all %}<li><a
|
{% for subpage in item.subpages.all %}<li><a
|
||||||
href="{{subpage.get_absolute_url}}"
|
href="{{subpage.get_absolute_url}}"
|
||||||
{% ifequal subpage current_page %}class="active"{% endifequal %}>{{subpage.menu_name}}</a></li>
|
>{{subpage.menu_name}}</a></li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@@ -71,21 +71,25 @@
|
|||||||
<ul class="fa-ul">
|
<ul class="fa-ul">
|
||||||
<li><span class="fa-li fa fa-clock-o"></span><strong>{% trans "Since" %}:</strong> {{current_event.start|timesince}}</li>
|
<li><span class="fa-li fa fa-clock-o"></span><strong>{% trans "Since" %}:</strong> {{current_event.start|timesince}}</li>
|
||||||
<li><span class="fa-li fa fa-calendar"></span><strong>{% trans "Start" %}:</strong>
|
<li><span class="fa-li fa fa-calendar"></span><strong>{% trans "Start" %}:</strong>
|
||||||
<time datetime="{{current_event.start|date:'c'}}">{{current_event.start|date:'DATETIME_FORMAT'}}</time>
|
<time datetime="{{current_event.start|date:'Y-m-d\TH:i:sO'}}">{{current_event.start|date:'DATETIME_FORMAT'}}</time>
|
||||||
|
</li>
|
||||||
|
<li><span class="fa-li fa fa-map-marker"></span><strong>{% trans "Location" %}:</strong> {{ current_event.location }}
|
||||||
|
- {{current_event.location.street_address}}, {{current_event.location.postal_code}} {{current_event.location.locality}}
|
||||||
</li>
|
</li>
|
||||||
<li><span class="fa-li fa fa-map-marker"></span><strong>{% trans "Location" %}:</strong> {{ current_event.location }}</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
<div class="right"><a class="button" href="{{current_event.get_absolute_url}}">
|
<div class="right"><a class="button" href="{{current_event.get_absolute_url}}">
|
||||||
{% trans "More Details" %} <span class="fa fa-arrow-right"></span></a></div>
|
{% trans "More Details" %} <span class="fa fa-arrow-right"></span></a></div>
|
||||||
{% else %}
|
{% elif next_event %}
|
||||||
<h2>{% trans "Next Event" %}</h2>
|
<h2>{% trans "Next Event" %}</h2>
|
||||||
<h3>{{ next_event.name}}</h3>
|
<h3>{{ next_event.name}}</h3>
|
||||||
<ul class="fa-ul">
|
<ul class="fa-ul">
|
||||||
<li><span class="fa-li fa fa-clock-o"></span><strong>{% trans "in" %}:</strong> {{next_event.start|timeuntil}}</li>
|
<li><span class="fa-li fa fa-clock-o"></span><strong>{% trans "in" %}:</strong> {{next_event.start|timeuntil}}</li>
|
||||||
<li><span class="fa-li fa fa-calendar"></span><strong>{% trans "Start" %}:</strong>
|
<li><span class="fa-li fa fa-calendar"></span><strong>{% trans "Start" %}:</strong>
|
||||||
<time datetime="{{next_event.start|date:'c'}}">{{next_event.start|date:'DATETIME_FORMAT' }}</time>
|
<time datetime="{{next_event.start|date:'Y-m-d\TH:i:sO'}}">{{next_event.start|date:'DATETIME_FORMAT' }}</time>
|
||||||
|
</li>
|
||||||
|
<li><span class="fa-li fa fa-map-marker"></span><strong>{% trans "Location" %}:</strong> {{ next_event.location }}
|
||||||
|
- {{next_event.location.street_address}}, {{next_event.location.postal_code}} {{next_event.location.locality}}
|
||||||
</li>
|
</li>
|
||||||
<li><span class="fa-li fa fa-map-marker"></span><strong>{% trans "Location" %}:</strong> {{ next_event.location }}</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
<div class="right"><a class="button" href="{{next_event.get_absolute_url}}">{% trans "More Details" %}
|
<div class="right"><a class="button" href="{{next_event.get_absolute_url}}">{% trans "More Details" %}
|
||||||
<span class="fa fa-arrow-right"></span></a></div>
|
<span class="fa fa-arrow-right"></span></a></div>
|
||||||
@@ -97,8 +101,10 @@
|
|||||||
{% for event in upcoming_events %}
|
{% for event in upcoming_events %}
|
||||||
<li><span class="fa-li fa fa-calendar-o"></span>
|
<li><span class="fa-li fa fa-calendar-o"></span>
|
||||||
<a href="{{ event.get_absolute_url}}">
|
<a href="{{ event.get_absolute_url}}">
|
||||||
<time datetime="{{event.start|date:'c'}}">{{event.start|date:'D d. M:'}}</time>
|
<time datetime="{{event.start|date:'Y-m-d\TH:i:sO'}}">{{event.start|date:'D d. M:'}}</time>
|
||||||
{{event.name}}</a></li>
|
{{event.name}}</a></li>
|
||||||
|
{% empty %}
|
||||||
|
<li>{% trans 'No events found' %}.</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@@ -110,9 +116,9 @@
|
|||||||
{% block navigation %}{% if current_top_page.subpages.count %}
|
{% block navigation %}{% if current_top_page.subpages.count %}
|
||||||
<ul id="navigation">
|
<ul id="navigation">
|
||||||
<li><a href="{{current_top_page.get_absolute_url}}"
|
<li><a href="{{current_top_page.get_absolute_url}}"
|
||||||
class="{% ifequal current_page current_top_page %}{% endifequal %}">{{current_top_page.menu_name}}</a></li>
|
class="{% if current_page == current_top_page %}{% endif %}">{{current_top_page.menu_name}}</a></li>
|
||||||
{% for subpage in current_top_page.subpages.all %}
|
{% for subpage in current_top_page.subpages.all %}
|
||||||
<li><a href="{{subpage.get_absolute_url}}" class="{% ifequal subpage current_page %}active{% endifequal %}">{{subpage.menu_name}}</a>
|
<li><a href="{{subpage.get_absolute_url}}" class="{% if subpage == current_page %}active{% endif %}">{{subpage.menu_name}}</a>
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% block additional_nav_elements %}{% endblock %}
|
{% block additional_nav_elements %}{% endblock %}
|
||||||
@@ -136,20 +142,21 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block comments %}{% endblock %}
|
{% block comments %}{% endblock %}
|
||||||
<br class="clear"/>
|
<br class="clear"/>
|
||||||
<p id="bottom_buttonbar" class="buttonbar">
|
{% block bottom %}
|
||||||
|
<div id="bottom_buttonbar" class="buttonbar">
|
||||||
{% block buttonbar %}
|
{% block buttonbar %}
|
||||||
{% if current_page and perms.content.add_page %}
|
{% if current_page and perms.content.add_page %}
|
||||||
<a href="{% url 'add-page' current_page.path %}" class="button"><span class="fa fa-plus"></span>
|
<a href="{% url 'add-page' current_page.path %}" class="button"><span class="fa fa-plus"></span>
|
||||||
{% trans "Add Subpage" %}</a>
|
{% trans "Add Subpage" %}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if current_page and perms.content.change_page %}
|
{% if current_page and perms.content.change_page %}
|
||||||
<a href="{% url 'edit-page' current_page.path %}" class="button"><span class="fa fa-pencil"></span>
|
<a href="{% url 'edit-page' current_page.path %}" class="button"><span class="fa fa-pencil"></span>
|
||||||
{% trans "Edit Page" %}</a>
|
{% trans "Edit Page" %}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% block additional_buttonbar %}{% endblock %}
|
{% block additional_buttonbar %}{% endblock %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
</p>
|
</div>
|
||||||
|
{% endblock %}
|
||||||
</main>
|
</main>
|
||||||
<footer id="footer">
|
<footer id="footer">
|
||||||
<p><strong>Herausgeber:</strong> Verein Kasu - traditionelle asiatische Spielkultur (<a
|
<p><strong>Herausgeber:</strong> Verein Kasu - traditionelle asiatische Spielkultur (<a
|
||||||
@@ -163,8 +170,8 @@
|
|||||||
<select name="language" id="language">
|
<select name="language" id="language">
|
||||||
{% get_language_info_list for LANGUAGES as languages %}
|
{% get_language_info_list for LANGUAGES as languages %}
|
||||||
{% for language in languages %}
|
{% for language in languages %}
|
||||||
<option value="{{language.code}}" {% ifequal language.code LANGUAGE_CODE %}
|
<option value="{{language.code}}"
|
||||||
selected="selected" {% endifequal %}>{{ language.name_local }} ({{ language.code }})
|
selected="selected">{{ language.name_local }} ({{ language.code }})
|
||||||
</option>
|
</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
@@ -181,12 +188,6 @@
|
|||||||
{% trans "no user logged in" %} -
|
{% trans "no user logged in" %} -
|
||||||
<a rel="nofollow" href="{% url 'membership-register' %}">{% trans "register" %}</a>
|
<a rel="nofollow" href="{% url 'membership-register' %}">{% trans "register" %}</a>
|
||||||
<a rel="nofollow" href="{% url 'login' %}?next={{ request.path_info }}">{% trans "login" %}</a>
|
<a rel="nofollow" href="{% url 'login' %}?next={{ request.path_info }}">{% trans "login" %}</a>
|
||||||
<a rel="nofollow" href="{% url 'social:begin' 'facebook' %}" class="fa fa-facebook"
|
|
||||||
title="{% trans 'Login with Facebook' %}" aria-label="{% trans 'Login with Facebook' %}"></a>
|
|
||||||
<a rel="nofollow" href="{% url 'social:begin' 'twitter' %}" class="fa fa-twitter"
|
|
||||||
title="{% trans 'Login with Twitter' %}" aria-label="{% trans 'Login with Twitter' %}"></a>
|
|
||||||
<a rel="nofollow" href="{% url 'social:begin' 'google-oauth2' %}" class="fa fa-google"
|
|
||||||
title="{% trans 'Login with Google' %}" aria-label="{% trans 'Login with Google' %}"></a>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</nav>
|
</nav>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<header class="comment_header">
|
<header class="comment_header">
|
||||||
<h3><a href="{{ comment.user.get_profile.get_absolute_url }}" class="user">{{comment.user}}</a></h3>
|
<h3><a href="{{ comment.user.get_profile.get_absolute_url }}" class="user">{{comment.user}}</a></h3>
|
||||||
<time datetime="{{comment.submit_date|date:'Y-m-d'}}" class="submit_date">{{comment.submit_date|timesince}}</time>
|
<time datetime="{{comment.submit_date|date:'Y-m-d\TH:i:sO'}}" class="submit_date">{{comment.submit_date|timesince}}</time>
|
||||||
</header>
|
</header>
|
||||||
<div class="comment_text">{{comment.comment}}</div>
|
<div class="comment_text">{{comment.comment}}</div>
|
||||||
</article>
|
</article>
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<header class="comment_header">
|
<header class="comment_header">
|
||||||
<a href="{{ user.get_profile.get_absolute_url }}" class="user">{{comment.user}}</a>
|
<a href="{{ user.get_profile.get_absolute_url }}" class="user">{{comment.user}}</a>
|
||||||
<div class="submit_date"><time time="{% now 'c' %}">{% now 'DATETIME_FORMAT' %}</time></div>
|
<div class="submit_date"><time>{% now 'DATETIME_FORMAT' %}</time></div>
|
||||||
</header>
|
</header>
|
||||||
<div class="comment_text">{{comment}}</div>
|
<div class="comment_text">{{comment}}</div>
|
||||||
</article>
|
</article>
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
<input type="{{ type|default:'text' }}" name="{{ widget.name }}"{% if widget.value != None %} value="{{ widget.value|stringformat:'s' }}"{% endif %}{% include "django/forms/widgets/attrs.html" %} />
|
<input type="{{ type|default:'text' }}" name="{{ widget.name }}"
|
||||||
|
value="{{ widget.value|stringformat:'s' }}" "django/forms/widgets/attrs.html" %} />
|
||||||
|
|||||||
@@ -2,11 +2,11 @@
|
|||||||
{% for hidden in form.hidden_fields %}{{ hidden }}{% endfor %}
|
{% for hidden in form.hidden_fields %}{{ hidden }}{% endfor %}
|
||||||
{% for field in form.visible_fields %}
|
{% for field in form.visible_fields %}
|
||||||
<div>
|
<div>
|
||||||
<label {% if field.html_name != 'recaptcha' %} for="id_{{ field.html_name}}" {% endif %}
|
<label for="id_{{ field.html_name}}"
|
||||||
class="field_name {{ field.css_classes }}">{{ field.label}}</label>
|
class="field_name {{ field.css_classes }}">{{ field.label}}</label>
|
||||||
{{ field }}
|
{{ field }}
|
||||||
{% if field.help_text and not field.field.widget.input_type %}
|
{% if field.field.widget.input_type == 'checkbox' %}
|
||||||
{{field.help_text}}
|
<label for="id_{{field.name}}">{{field.help_text|safe}}</label>
|
||||||
{% elif field.help_text %}
|
{% elif field.help_text %}
|
||||||
<p class="help_text">{{field.help_text}}</p>
|
<p class="help_text">{{field.help_text}}</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<h2><a href="{{article.get_absolute_url}}">{{article.headline}}</a></h2>
|
<h2><a href="{{article.get_absolute_url}}">{{article.headline}}</a></h2>
|
||||||
<ul class="info">
|
<ul class="info">
|
||||||
<li><span class="fa fa-calendar"></span>
|
<li><span class="fa fa-calendar"></span>
|
||||||
<time datetime="{{article.date_created|date:'Y-m-d H:i'}}">{{ article.date_created|date:'DATE_FORMAT' }}</time>
|
<time datetime="{{article.date_created|date:'Y-m-d\TH:i:sO'}}">{{ article.date_created|date:'DATE_FORMAT' }}</time>
|
||||||
</li>
|
</li>
|
||||||
<li><span class="fa fa-user"></span> {{ article.author }}
|
<li><span class="fa fa-user"></span> {{ article.author }}
|
||||||
</li>
|
</li>
|
||||||
@@ -48,7 +48,7 @@
|
|||||||
From <a href="{{user_link}}">{{author}}</a> in
|
From <a href="{{user_link}}">{{author}}</a> in
|
||||||
<a href="{{comment_link}}">“{{object}}”</a>
|
<a href="{{comment_link}}">“{{object}}”</a>
|
||||||
since
|
since
|
||||||
<time datetime="{{submit_date}}">{{since}}</time>
|
<time datetime="{{submit_date|date:'Y-m-d\TH:i:sO'}}">{{since}}</time>
|
||||||
{% endblocktrans %}
|
{% endblocktrans %}
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|||||||
@@ -1,22 +1,22 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
<nav class="grid_12 pagination">
|
<nav class="grid_12 pagination">
|
||||||
<a {% if page_obj.has_previous %}
|
{% if page_obj.has_previous %}
|
||||||
class="previous" href="?page={{ page_obj.previous_page_number }}"
|
<a class="previous" href="?page={{ page_obj.previous_page_number }}"><span class="fa fa-arrow-left"></span>
|
||||||
|
{% trans "Previous" %}</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
class="previous disabled"
|
<a class="previous disabled"><span class="fa fa-arrow-left"></span>{% trans "Previous" %}</a>
|
||||||
{% endif %}>
|
{% endif %}
|
||||||
<span class="fa fa-arrow-left"></span>{% trans "Previous" %}
|
|
||||||
</a>
|
|
||||||
|
|
||||||
{% for page in paginator.page_range %}
|
{% for page in paginator.page_range %}
|
||||||
<a {% ifequal page_obj.number page %}class="active"{% else %}href="?page={{page}}"{% endifequal %}>{{page}}</a>
|
{% if page_obj.number == page %}
|
||||||
{% endfor %}
|
<a class="active">{{page}}</a>
|
||||||
|
|
||||||
<a {% if page_obj.has_next %}
|
|
||||||
class="next" href="?page={{ page_obj.next_page_number }}"
|
|
||||||
{% else %}
|
{% else %}
|
||||||
class="next disabled"
|
<a href="?page={{page}}">{{page}}</a>
|
||||||
{% endif %}>
|
{% endif %}
|
||||||
{% trans "Next" %} <span class="fa fa-arrow-right"></span>
|
{% endfor %}
|
||||||
</a>
|
{% if page_obj.has_next %}
|
||||||
|
<a class="next" href="?page={{ page_obj.next_page_number }}">{% trans "Next" %}
|
||||||
|
<span class="fa fa-arrow-right"></span></a>
|
||||||
|
{% else %}
|
||||||
|
<a class="next disabled">{% trans "Next" %} <span class="fa fa-arrow-right"></span></a>
|
||||||
|
{% endif %}
|
||||||
</nav>
|
</nav>
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
""" the main URL config that imports many URL configs from the applications. """
|
""" the main URL config that imports many URL configs from the applications. """
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.conf.urls import include, url
|
from django.urls import include, path
|
||||||
from django.conf.urls.static import static
|
from django.conf.urls.static import static
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.contrib.sitemaps.views import sitemap
|
from django.contrib.sitemaps.views import sitemap
|
||||||
@@ -10,59 +10,55 @@ from content import views, feeds
|
|||||||
from content.sitemaps import ArticleSitemap, PageSitemap
|
from content.sitemaps import ArticleSitemap, PageSitemap
|
||||||
from events.sitemaps import EventSitemap
|
from events.sitemaps import EventSitemap
|
||||||
from events.views import EventListIcal
|
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
|
from membership.views import MembershipDetail
|
||||||
|
|
||||||
admin.autodiscover()
|
admin.autodiscover()
|
||||||
|
# register_converter('path')
|
||||||
|
|
||||||
sitemaps = {
|
sitemaps = {
|
||||||
'event_rankings': EventRankingSitemap,
|
'event_rankings': mahjong_ranking.sitemaps.EventRankingSitemap,
|
||||||
'event_hanchans': EventHanchanSitemap,
|
'event_hanchans': mahjong_ranking.sitemaps.EventHanchanSitemap,
|
||||||
'mahjong_seasons': MajongSeasonSitemap,
|
'mahjong_seasons': mahjong_ranking.sitemaps.MahjongSeasonSitemap,
|
||||||
'maistar_games': MaistarGamesSitemap,
|
'maistar_games': maistar_ranking.sitemaps.MaistarGamesSitemap,
|
||||||
'articles': ArticleSitemap,
|
'articles': ArticleSitemap,
|
||||||
'events': EventSitemap,
|
'events': EventSitemap,
|
||||||
'pages': PageSitemap,
|
'pages': PageSitemap,
|
||||||
}
|
}
|
||||||
|
|
||||||
urlpatterns = [ # Ignore PyLintBear (C0103)
|
urlpatterns = [ # Ignore PyLintBear (C0103)
|
||||||
url(r'^$', views.StartPage.as_view()),
|
path("", views.StartPage.as_view(), name="index"),
|
||||||
url(r'^404/$', TemplateView.as_view(template_name='404.html')),
|
path('index.html', views.StartPage.as_view()),
|
||||||
url(r'^add_page/(?P<path>[\+\.\-\d\w\/]+)/$',
|
path('404/', TemplateView.as_view(template_name='404.html'), name="404"),
|
||||||
views.PageAddForm.as_view(), name='add-page'),
|
path('admin/doc/', include('django.contrib.admindocs.urls'), name="django-docs"),
|
||||||
url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
|
path('admin/', admin.site.urls, name="django-admin"),
|
||||||
url(r'^admin/', admin.site.urls),
|
path('ckeditor/', include('ckeditor_uploader.urls')),
|
||||||
url(r'^ckeditor/', include('ckeditor_uploader.urls')),
|
path('comments/', include('django_comments.urls')),
|
||||||
url(r'^comments/', include('django_comments.urls')),
|
path('events/', include('events.urls')),
|
||||||
url(r'^edit_page/(?P<path>[\+\.\-\d\w\/]+)/$',
|
path('events.ics', EventListIcal.as_view(), name='events-ical'),
|
||||||
views.PageEditForm.as_view(), name='edit-page'),
|
path('feeds/latest/', feeds.LatestNews(), name='feed-latest-news'),
|
||||||
url(r'^events/', include('events.urls')),
|
path('feeds/comments/', feeds.LatestComments(), name='feed-latest-comments'),
|
||||||
url(r'^events.ics$', EventListIcal.as_view(), name='events-ical'),
|
path('gallery/', include('events.gallery_urls')),
|
||||||
url(r'^feeds/latest/$', feeds.LatestNews(), name='feed-latest-news'),
|
path('google25dabc1a49a9ef03.html',
|
||||||
url(r'^feeds/comments/$', feeds.LatestComments(),
|
TemplateView.as_view(template_name='google25dabc1a49a9ef03.html')),
|
||||||
name='feed-latest-comments'),
|
path('i18n/', include('django.conf.urls.i18n'), name='start-page'),
|
||||||
url(r'^gallery/', include('events.gallery_urls')),
|
path('manifest.json', TemplateView.as_view(template_name='manifest.json')),
|
||||||
url(r'^google25dabc1a49a9ef03.html$', TemplateView.as_view(
|
path('membership/', include('membership.urls')),
|
||||||
template_name='google25dabc1a49a9ef03.html')),
|
path('news/', include('content.news_urls')),
|
||||||
url(r'^i18n/', include('django.conf.urls.i18n'), name='start-page'),
|
path('ranking/', include('mahjong_ranking.urls')),
|
||||||
url(r'^index.html$', views.StartPage.as_view()),
|
path('ranking/', include('maistar_ranking.urls')),
|
||||||
url(r'^manifest.json$',
|
path('robots.txt', TemplateView.as_view(template_name='robots.txt')),
|
||||||
TemplateView.as_view(template_name='manifest.json')),
|
path('users/', MembershipDetail.as_view(), name='membership-details'),
|
||||||
url(r'^membership/', include('membership.urls')),
|
path('users/<slug:username>/',
|
||||||
url(r'^news/', include('content.news_urls')),
|
|
||||||
url(r'^ranking/', include('mahjong_ranking.urls')),
|
|
||||||
url(r'^ranking/', include('maistar_ranking.urls')),
|
|
||||||
url(r'^sitemap\.xml$', sitemap, {
|
|
||||||
'sitemaps': sitemaps}, name='django.contrib.sitemaps.views.sitemap'),
|
|
||||||
url(r'^robots.txt$', TemplateView.as_view(template_name='robots.txt')),
|
|
||||||
url(r'^users/$', MembershipDetail.as_view(), name='membership-details'),
|
|
||||||
url(r'^users/(?P<username>[\-\.\d\w]+)/$',
|
|
||||||
MembershipDetail.as_view(), name='membership-details'),
|
MembershipDetail.as_view(), name='membership-details'),
|
||||||
url(r'^(?P<path>[\-\d\w\/]+)\.html$',
|
path('add_page/<path:path>', views.PageAddForm.as_view(), name='add-page'),
|
||||||
views.PageHtml.as_view(), name='view-page'),
|
path('edit_page/<path:path>', views.PageEditForm.as_view(), name='edit-page'),
|
||||||
url(r'^(?P<path>[\-\d\w\/]+)\.pdf$', views.PagePdf.as_view()),
|
path('<path:path>.html', views.PageHtml.as_view(), name='view-page'),
|
||||||
url('', include('social_django.urls', namespace='social'))
|
path('<path:path>.pdf', views.PagePdf.as_view()),
|
||||||
|
path('sitemap.xml', sitemap, {'sitemaps': sitemaps},
|
||||||
|
name='django.contrib.sitemaps.views.sitemap'),
|
||||||
]
|
]
|
||||||
|
|
||||||
if settings.DEBUG:
|
if settings.DEBUG:
|
||||||
@@ -71,8 +67,8 @@ if settings.DEBUG:
|
|||||||
urlpatterns += static(settings.STATIC_URL,
|
urlpatterns += static(settings.STATIC_URL,
|
||||||
document_root=settings.STATIC_ROOT)
|
document_root=settings.STATIC_ROOT)
|
||||||
if 'rosetta' in settings.INSTALLED_APPS:
|
if 'rosetta' in settings.INSTALLED_APPS:
|
||||||
urlpatterns += [url(r'^rosetta/', include('rosetta.urls'))]
|
urlpatterns += [path("rosetta/", include('rosetta.urls'))]
|
||||||
if 'debug_toolbar' in settings.INSTALLED_APPS:
|
if 'debug_toolbar' in settings.INSTALLED_APPS:
|
||||||
import debug_toolbar
|
import debug_toolbar
|
||||||
|
|
||||||
urlpatterns += [url(r'^__debug__/', include(debug_toolbar.urls)), ]
|
urlpatterns += [path('__debug__/', include(debug_toolbar.urls)), ]
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
""" Script to start Django as an WSGI Application.
|
""" Script to start Django as an WSGI Application.
|
||||||
|
|
||||||
src_path and virtpy_path are host dependet variables.
|
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 os
|
||||||
import sys
|
import sys
|
||||||
@@ -14,8 +14,8 @@ if VENV_PATH not in sys.path:
|
|||||||
if SOURCE_PATH not in sys.path:
|
if SOURCE_PATH not in sys.path:
|
||||||
sys.path.append(SOURCE_PATH)
|
sys.path.append(SOURCE_PATH)
|
||||||
|
|
||||||
from django.core.wsgi import get_wsgi_application # Ignore PyLintBear (C0413) # Ignore PyLintBear (C0413)
|
from django.core.wsgi import get_wsgi_application # noqa: E402
|
||||||
|
|
||||||
os.environ['DJANGO_SETTINGS_MODULE'] = 'kasu.settings'
|
os.environ['DJANGO_SETTINGS_MODULE'] = 'kasu.settings'
|
||||||
|
|
||||||
application = get_wsgi_application() # Ignore PyLintBear (C0103) # Ignore PyLintBear (C0103)
|
application = get_wsgi_application()
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
"""
|
"""
|
||||||
Helper to generate XLSX Spreadsheets in an uniform way.
|
Helper to generate XLSX Spreadsheets in an uniform way.
|
||||||
"""
|
"""
|
||||||
|
import datetime
|
||||||
from datetime import date
|
from datetime import date
|
||||||
|
|
||||||
import openpyxl
|
import openpyxl
|
||||||
@@ -61,13 +62,15 @@ def getattr_recursive(obj, attr_string):
|
|||||||
|
|
||||||
:param obj: a python object.
|
:param obj: a python object.
|
||||||
:param attr_string: the desired attribute of the 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('.')
|
attr_list = attr_string.split('.')
|
||||||
return_value = None
|
return_value = None
|
||||||
for attr in attr_list:
|
for attr in attr_list:
|
||||||
return_value = getattr(obj, attr)
|
return_value = getattr(obj, attr)
|
||||||
obj = return_value
|
obj = return_value
|
||||||
|
if isinstance(return_value, datetime.datetime):
|
||||||
|
return_value = return_value.replace(tzinfo=None)
|
||||||
return return_value
|
return return_value
|
||||||
|
|
||||||
|
|
||||||
@@ -80,7 +83,8 @@ class Workbook(object):
|
|||||||
:rtype: object
|
:rtype: object
|
||||||
"""
|
"""
|
||||||
self.workbook = openpyxl.Workbook()
|
self.workbook = openpyxl.Workbook()
|
||||||
[self.workbook.add_named_style(style) for style in XLSX_STYLES.values()]
|
[self.workbook.add_named_style(style)
|
||||||
|
for style in XLSX_STYLES.values()]
|
||||||
[self.workbook.remove(sheet) for sheet in self.workbook.worksheets]
|
[self.workbook.remove(sheet) for sheet in self.workbook.worksheets]
|
||||||
|
|
||||||
def generate_sheet(self, title, columns_settings, object_list,
|
def generate_sheet(self, title, columns_settings, object_list,
|
||||||
@@ -135,7 +139,8 @@ class Workbook(object):
|
|||||||
|
|
||||||
# write table footer
|
# write table footer
|
||||||
for column, settings in enumerate(columns_settings, 1):
|
for column, settings in enumerate(columns_settings, 1):
|
||||||
cell = ws.cell(column=column, row=row, value=settings.get('footer'))
|
cell = ws.cell(column=column, row=row,
|
||||||
|
value=settings.get('footer'))
|
||||||
cell.style = settings['style']
|
cell.style = settings['style']
|
||||||
row += 1
|
row += 1
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
""" Adds management of the mahong ranking system to the admin interface. """
|
""" Adds management of the mahjong ranking system to the admin interface. """
|
||||||
|
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import gettext as _
|
||||||
|
|
||||||
from . import models, set_dirty
|
from . import models, set_dirty
|
||||||
|
|
||||||
@@ -21,6 +21,8 @@ def recalculate(modeladmin, request, queryset): # Ignore PyLintBear (W0613)
|
|||||||
for ladder_ranking in queryset:
|
for ladder_ranking in queryset:
|
||||||
set_dirty(user=ladder_ranking.user_id,
|
set_dirty(user=ladder_ranking.user_id,
|
||||||
season=ladder_ranking.season)
|
season=ladder_ranking.season)
|
||||||
|
|
||||||
|
|
||||||
recalculate.short_description = _("Recalculate")
|
recalculate.short_description = _("Recalculate")
|
||||||
|
|
||||||
|
|
||||||
@@ -34,14 +36,14 @@ def confirm(modeladmin, request, queryset): # Ignore PyLintBear (W0613)
|
|||||||
confirm.short_description = _("Confirm")
|
confirm.short_description = _("Confirm")
|
||||||
|
|
||||||
|
|
||||||
def unconfirm(modeladmin, request, queryset): # Ignore PyLintBear (W0613)
|
def reject(modeladmin, request, queryset): # Ignore PyLintBear (W0613)
|
||||||
"""An admin action to quickly set selected hanchans to unconfirmed. """
|
"""An admin action to quickly set selected hanchans to unconfirmed. """
|
||||||
for hanchan in queryset:
|
for hanchan in queryset:
|
||||||
hanchan.confirmed = False
|
hanchan.confirmed = False
|
||||||
hanchan.save()
|
hanchan.save()
|
||||||
|
|
||||||
|
|
||||||
unconfirm.short_description = _('Set unconfirmed')
|
reject.short_description = _('Reject')
|
||||||
|
|
||||||
|
|
||||||
class EventRankingAdmin(admin.ModelAdmin):
|
class EventRankingAdmin(admin.ModelAdmin):
|
||||||
@@ -55,7 +57,7 @@ class EventRankingAdmin(admin.ModelAdmin):
|
|||||||
|
|
||||||
class HanchanAdmin(admin.ModelAdmin):
|
class HanchanAdmin(admin.ModelAdmin):
|
||||||
""" To administrate the stored Hanchans. """
|
""" To administrate the stored Hanchans. """
|
||||||
actions = [recalculate, confirm, unconfirm]
|
actions = [recalculate, confirm, reject]
|
||||||
date_hierarchy = 'start'
|
date_hierarchy = 'start'
|
||||||
list_filter = ('season', 'event', 'confirmed')
|
list_filter = ('season', 'event', 'confirmed')
|
||||||
search_fields = ('player_names',)
|
search_fields = ('player_names',)
|
||||||
|
|||||||
@@ -5,10 +5,11 @@ Created on 04.10.2011
|
|||||||
|
|
||||||
@author: christian
|
@author: christian
|
||||||
"""
|
"""
|
||||||
from django.contrib.auth import get_user_model
|
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.utils.translation import ugettext as _
|
from django.contrib.auth import get_user_model
|
||||||
|
from django.utils.translation import gettext as _
|
||||||
|
|
||||||
|
from events.models import Event
|
||||||
from . import models
|
from . import models
|
||||||
|
|
||||||
USER_MODEL = get_user_model()
|
USER_MODEL = get_user_model()
|
||||||
@@ -47,14 +48,31 @@ class HanchanForm(forms.ModelForm):
|
|||||||
self.fields[player_input_score].widget.attrs['type'] = 'number'
|
self.fields[player_input_score].widget.attrs['type'] = 'number'
|
||||||
self.fields[player].queryset = player_queryset
|
self.fields[player].queryset = player_queryset
|
||||||
|
|
||||||
|
def is_valid(self):
|
||||||
|
ret = forms.Form.is_valid(self)
|
||||||
|
for field, errors in self.errors.items():
|
||||||
|
message = ", ".join(set(errors))
|
||||||
|
print(type(field), type(errors))
|
||||||
|
self.fields[field].widget.attrs.update({
|
||||||
|
'class': self.fields[field].widget.attrs.get('class', '') + ' error',
|
||||||
|
'title': message
|
||||||
|
})
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
class HanchanAdminForm(HanchanForm):
|
class HanchanAdminForm(HanchanForm):
|
||||||
""" Extends the HanchanForm for users with admin privileges.
|
""" Extends the HanchanForm for users with admin privileges.
|
||||||
|
|
||||||
They are allowed to confirm/unconfirm Hanchans, this could be userful if
|
They are allowed to confirm/unconfirm Hanchans, this could be userful if
|
||||||
one games smells fishy and needs the opinion of an referee."""
|
one games smells fishy and needs the opinion of a referee."""
|
||||||
|
|
||||||
class Meta(object):
|
class Meta(object):
|
||||||
""" Extend the formfields to add the confirmed checkbox. """
|
""" Extend the formfields to add the confirmed checkbox. """
|
||||||
model = models.Hanchan
|
model = models.Hanchan
|
||||||
fields = HanchanForm.Meta.fields + ('confirmed',)
|
fields = HanchanForm.Meta.fields + ('confirmed',)
|
||||||
|
|
||||||
|
|
||||||
|
HanchanFormset = forms.inlineformset_factory(Event, models.Hanchan,
|
||||||
|
form=HanchanForm,
|
||||||
|
extra=1,
|
||||||
|
can_delete=True)
|
||||||
|
|||||||
Binary file not shown.
@@ -7,9 +7,9 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: kasu.mahjong_ranking\n"
|
"Project-Id-Version: kasu.mahjong_ranking\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2017-06-19 22:46+0200\n"
|
"POT-Creation-Date: 2023-08-07 20:38+0200\n"
|
||||||
"PO-Revision-Date: 2016-09-28 00:24+0200\n"
|
"PO-Revision-Date: 2018-05-08 00:20+0105\n"
|
||||||
"Last-Translator: Christian Berg <xeniac.at@gmail.com>\n"
|
"Last-Translator: b'Christian Berg <kasu@xendynastie.at>'\n"
|
||||||
"Language-Team: Kasu <verein@kasu.at>\n"
|
"Language-Team: Kasu <verein@kasu.at>\n"
|
||||||
"Language: de\n"
|
"Language: de\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
@@ -17,381 +17,388 @@ msgstr ""
|
|||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
"X-Generator: Poedit 1.8.9\n"
|
"X-Generator: Poedit 1.8.9\n"
|
||||||
"X-Translated-Using: django-rosetta 0.7.6\n"
|
"X-Translated-Using: django-rosetta 0.8.1\n"
|
||||||
|
|
||||||
#: mahjong_ranking/admin.py:26
|
#: admin.py:26
|
||||||
msgid "Recalculate"
|
msgid "Recalculate"
|
||||||
msgstr "Neuberechnen"
|
msgstr "Neuberechnen"
|
||||||
|
|
||||||
#: mahjong_ranking/admin.py:36
|
#: admin.py:36
|
||||||
msgid "Confirm"
|
msgid "Confirm"
|
||||||
msgstr "Bestätigen"
|
msgstr "Bestätigen"
|
||||||
|
|
||||||
#: mahjong_ranking/admin.py:46
|
#: admin.py:46
|
||||||
msgid "Set unconfirmed"
|
msgid "Reject"
|
||||||
msgstr "Als unbestätigt markieren"
|
msgstr ""
|
||||||
|
|
||||||
#: mahjong_ranking/forms.py:21
|
#: forms.py:22
|
||||||
msgid "start"
|
msgid "start"
|
||||||
msgstr "Beginn"
|
msgstr "Beginn"
|
||||||
|
|
||||||
#: mahjong_ranking/models.py:89
|
#: models.py:93 templates/mahjong_ranking/player_dan_score.html:14
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/player_dan_score.html:14
|
#: templates/mahjong_ranking/player_invalid_score.html:13
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/player_invalid_score.html:13
|
#: templates/mahjong_ranking/player_kyu_score.html:15
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/player_kyu_score.html:15
|
#: templates/mahjong_ranking/player_ladder_score.html:15
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/player_ladder_score.html:15
|
#: templates/mahjong_ranking/seasonranking_list.html:10
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/seasonranking_list.html:10
|
|
||||||
msgid "Start"
|
msgid "Start"
|
||||||
msgstr "Beginn"
|
msgstr "Beginn"
|
||||||
|
|
||||||
#: mahjong_ranking/models.py:90
|
#: models.py:94
|
||||||
msgid "This is crucial to get the right Hanchans that scores"
|
msgid "This is crucial to get the right Hanchans that scores"
|
||||||
msgstr "Wichtig damit die richtigen Hanchans in die Wertung kommen."
|
msgstr "Wichtig damit die richtigen Hanchans in die Wertung kommen."
|
||||||
|
|
||||||
#: mahjong_ranking/models.py:97
|
#: models.py:101
|
||||||
msgid "Player 1"
|
msgid "Player 1"
|
||||||
msgstr "Spieler 1"
|
msgstr "Spieler 1"
|
||||||
|
|
||||||
#: mahjong_ranking/models.py:98 mahjong_ranking/models.py:100
|
#: models.py:102 models.py:104 models.py:121 models.py:123 models.py:140
|
||||||
#: mahjong_ranking/models.py:117 mahjong_ranking/models.py:119
|
#: models.py:142 models.py:159 models.py:161
|
||||||
#: mahjong_ranking/models.py:136 mahjong_ranking/models.py:138
|
#: templates/mahjong_ranking/eventhanchan_list.html:19
|
||||||
#: mahjong_ranking/models.py:155 mahjong_ranking/models.py:157
|
#: templates/mahjong_ranking/eventranking_list.html:21
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/eventhanchan_list.html:19
|
#: templates/mahjong_ranking/hanchan_confirm_delete.html:16
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/eventranking_list.html:21
|
#: templates/mahjong_ranking/hanchan_form.html:19
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/hanchan_confirm_delete.html:16
|
#: templates/mahjong_ranking/kyudanranking_list.html:30
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/hanchan_form.html:19
|
#: templates/mahjong_ranking/seasonranking_list.html:31
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/kyudanranking_list.html:35
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/seasonranking_list.html:32
|
|
||||||
msgid "Score"
|
msgid "Score"
|
||||||
msgstr "Punkte"
|
msgstr "Punkte"
|
||||||
|
|
||||||
#: mahjong_ranking/models.py:110 mahjong_ranking/models.py:129
|
#: models.py:114 models.py:133 models.py:152 models.py:171 models.py:173
|
||||||
#: mahjong_ranking/models.py:148 mahjong_ranking/models.py:167
|
#: templates/mahjong_ranking/hanchan_form.html:20
|
||||||
#: mahjong_ranking/models.py:169
|
#: templates/mahjong_ranking/player_dan_score.html:18
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/hanchan_form.html:20
|
#: templates/mahjong_ranking/player_invalid_score.html:17
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/player_dan_score.html:18
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/player_invalid_score.html:17
|
|
||||||
msgid "Comment"
|
msgid "Comment"
|
||||||
msgstr "Kommentar"
|
msgstr "Kommentar"
|
||||||
|
|
||||||
#: mahjong_ranking/models.py:116
|
#: models.py:120
|
||||||
msgid "Player 2"
|
msgid "Player 2"
|
||||||
msgstr "Spieler 2"
|
msgstr "Spieler 2"
|
||||||
|
|
||||||
#: mahjong_ranking/models.py:135
|
#: models.py:139
|
||||||
msgid "Player 3"
|
msgid "Player 3"
|
||||||
msgstr "Spieler 3"
|
msgstr "Spieler 3"
|
||||||
|
|
||||||
#: mahjong_ranking/models.py:154
|
#: models.py:158
|
||||||
msgid "Player 4"
|
msgid "Player 4"
|
||||||
msgstr "Spieler 4"
|
msgstr "Spieler 4"
|
||||||
|
|
||||||
#: mahjong_ranking/models.py:170
|
#: models.py:175
|
||||||
msgid "Has been Confirmed"
|
msgid "Has been Confirmed"
|
||||||
msgstr "Wurde bestätigt"
|
msgstr "Wurde bestätigt"
|
||||||
|
|
||||||
#: mahjong_ranking/models.py:172
|
#: models.py:176
|
||||||
msgid "Only valid and confirmed Hanchans will be counted in the rating."
|
msgid "Only valid and confirmed Hanchans will be counted in the rating."
|
||||||
msgstr "Nur gültige und bestätigte Hanchans kommen in die Wertung."
|
msgstr "Nur gültige und bestätigte Hanchans kommen in die Wertung."
|
||||||
|
|
||||||
#: mahjong_ranking/models.py:177 mahjong_ranking/models.py:576
|
#: models.py:181 models.py:619 templates/mahjong_ranking/ladder_redbox.html:29
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/ladder_redbox.html:29
|
#: templates/mahjong_ranking/player_ladder_score.html:63
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/player_ladder_score.html:63
|
|
||||||
msgid "Season"
|
msgid "Season"
|
||||||
msgstr "Saison"
|
msgstr "Saison"
|
||||||
|
|
||||||
#: mahjong_ranking/models.py:182
|
#: models.py:186
|
||||||
msgid "Hanchan"
|
msgid "Hanchan"
|
||||||
msgstr "Hanchan"
|
msgstr "Hanchan"
|
||||||
|
|
||||||
#: mahjong_ranking/models.py:183
|
#: models.py:187 templates/mahjong_ranking/eventranking_list.html:17
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/eventranking_list.html:17
|
|
||||||
msgid "Hanchans"
|
msgid "Hanchans"
|
||||||
msgstr "Hanchans"
|
msgstr "Hanchans"
|
||||||
|
|
||||||
#: mahjong_ranking/models.py:186
|
#: models.py:190
|
||||||
msgid "Hanchan from {0:%Y-%m-%d} at {0:%H:%M} with {1}"
|
msgid "Hanchan from {0:%Y-%m-%d} at {0:%H:%M} with {1}"
|
||||||
msgstr "Hanchan vom {0:%Y-%m-%d} um {0:%H:%M} mit {1}"
|
msgstr "Hanchan vom {0:%Y-%m-%d} um {0:%H:%M} mit {1}"
|
||||||
|
|
||||||
#: mahjong_ranking/models.py:213
|
#: models.py:217
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%s can't attend the same game multiple times"
|
msgid "%s can't attend the same game multiple times"
|
||||||
msgstr "%s kann an einem Spiel nicht mehrfach teilnehmen."
|
msgstr "%s kann an einem Spiel nicht mehrfach teilnehmen."
|
||||||
|
|
||||||
#: mahjong_ranking/models.py:221
|
#: models.py:225
|
||||||
msgid "Games in the future may not be added, Dr. Brown"
|
msgid "Games in the future may not be added, Dr. Brown"
|
||||||
msgstr "Spiele aus der Zukunft dürfen noch nicht erfasst werden. Dr. Brown."
|
msgstr "Spiele aus der Zukunft dürfen noch nicht erfasst werden. Dr. Brown."
|
||||||
|
|
||||||
#: mahjong_ranking/models.py:223
|
#: models.py:227
|
||||||
msgid "Only games during the event are allowed"
|
msgid "Only games during the event are allowed"
|
||||||
msgstr "Nur Spiele während der Veranstaltung zählen."
|
msgstr "Nur Spiele während der Veranstaltung zählen."
|
||||||
|
|
||||||
#: mahjong_ranking/models.py:226
|
#: models.py:230
|
||||||
msgid "Gamescore is lower then 100.000 Pt."
|
msgid "Gamescore is lower then 100.000 Pt."
|
||||||
msgstr "Spielstand ist weniger als 100.000 Punkte"
|
msgstr "Spielstand ist weniger als 100.000 Punkte"
|
||||||
|
|
||||||
#: mahjong_ranking/models.py:228
|
#: models.py:232
|
||||||
msgid "Gamescore is over 100.000 Pt."
|
msgid "Gamescore is over 100.000 Pt."
|
||||||
msgstr "Spielstand ist über 100.000 Punkte."
|
msgstr "Spielstand ist über 100.000 Punkte."
|
||||||
|
|
||||||
#: mahjong_ranking/models.py:352
|
#: models.py:367
|
||||||
msgid "Kyū/Dan Ranking"
|
msgid "Kyū/Dan Ranking"
|
||||||
msgstr "Kyū/Dan Wertung"
|
msgstr "Kyū/Dan Wertung"
|
||||||
|
|
||||||
#: mahjong_ranking/models.py:353
|
#: models.py:368
|
||||||
msgid "Kyū/Dan Rankings"
|
msgid "Kyū/Dan Rankings"
|
||||||
msgstr "Kyū/Dan Wertungen"
|
msgstr "Kyū/Dan Wertungen"
|
||||||
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/eventhanchan_list.html:7
|
#: templates/mahjong_ranking/eventhanchan_form.html:11
|
||||||
msgid "Played Hanchans"
|
#: templates/mahjong_ranking/eventhanchan_list.html:55
|
||||||
msgstr "Gespielte Hanchans"
|
msgid "Edit Hanchans"
|
||||||
|
msgstr "Hanchans bearbeiten"
|
||||||
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/eventhanchan_list.html:18
|
#: templates/mahjong_ranking/eventhanchan_form.html:49
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/hanchan_confirm_delete.html:15
|
#: templates/mahjong_ranking/hanchan_form.html:58
|
||||||
msgid "Place"
|
|
||||||
msgstr "Platz"
|
|
||||||
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/eventhanchan_list.html:21
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/hanchan_confirm_delete.html:18
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/player_dan_score.html:17
|
|
||||||
msgid "Dan Points"
|
|
||||||
msgstr "Dan Punkte"
|
|
||||||
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/eventhanchan_list.html:23
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/hanchan_confirm_delete.html:20
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/player_invalid_score.html:16
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/player_kyu_score.html:18
|
|
||||||
msgid "Kyu Points"
|
|
||||||
msgstr "Kyu Punkte"
|
|
||||||
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/eventhanchan_list.html:37
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/hanchan_confirm_delete.html:4
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/hanchan_confirm_delete.html:33
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/player_dan_score.html:44
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/player_invalid_score.html:33
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/player_kyu_score.html:41
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/player_ladder_score.html:52
|
|
||||||
msgid "Delete Hanchan"
|
|
||||||
msgstr "Hanchan löschen"
|
|
||||||
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/eventhanchan_list.html:43
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/hanchan_form.html:4
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/hanchan_form.html:14
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/player_dan_score.html:47
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/player_invalid_score.html:36
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/player_kyu_score.html:44
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/player_ladder_score.html:55
|
|
||||||
msgid "Edit Hanchan"
|
|
||||||
msgstr "Hanchan bearbeiten"
|
|
||||||
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/eventhanchan_list.html:48
|
|
||||||
msgid "No Hanchan has been added to this event yet."
|
|
||||||
msgstr "Für diese Veranstaltung wurde noch keine Hanchan eingetragen."
|
|
||||||
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/eventhanchan_list.html:54
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/eventranking_list.html:51
|
|
||||||
msgid "Edit Event"
|
|
||||||
msgstr "Veranstaltung bearbeiten"
|
|
||||||
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/eventhanchan_list.html:55
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/eventranking_list.html:52
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/hanchan_form.html:4
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/hanchan_form.html:14
|
|
||||||
msgid "Add Hanchan"
|
|
||||||
msgstr "Hanchan hinzufügen"
|
|
||||||
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/eventranking_list.html:4
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/eventranking_list.html:5
|
|
||||||
msgid "Tournament Ranking"
|
|
||||||
msgstr "Turnierwertung"
|
|
||||||
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/eventranking_list.html:12
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/kyudanranking_list.html:30
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/seasonranking_list.html:23
|
|
||||||
msgid "Rank"
|
|
||||||
msgstr "Rang"
|
|
||||||
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/eventranking_list.html:13
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/kyudanranking_list.html:17
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/seasonranking_list.html:24
|
|
||||||
msgid "Avatar"
|
|
||||||
msgstr "Avatar"
|
|
||||||
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/eventranking_list.html:14
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/kyudanranking_list.html:20
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/seasonranking_list.html:25
|
|
||||||
msgid "Nickname"
|
|
||||||
msgstr "Spitzname"
|
|
||||||
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/eventranking_list.html:15
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/seasonranking_list.html:26
|
|
||||||
msgid "Name"
|
|
||||||
msgstr "Name"
|
|
||||||
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/eventranking_list.html:16
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/seasonranking_list.html:27
|
|
||||||
msgid "Average"
|
|
||||||
msgstr "Durchschnitt"
|
|
||||||
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/eventranking_list.html:20
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/player_dan_score.html:15
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/player_invalid_score.html:15
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/player_kyu_score.html:16
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/player_ladder_score.html:16
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/seasonranking_list.html:31
|
|
||||||
msgid "Placement"
|
|
||||||
msgstr "Platzierung"
|
|
||||||
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/eventranking_list.html:22
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/seasonranking_list.html:33
|
|
||||||
msgid "count"
|
|
||||||
msgstr "Anzahl"
|
|
||||||
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/eventranking_list.html:23
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/seasonranking_list.html:34
|
|
||||||
msgid "good"
|
|
||||||
msgstr "gut"
|
|
||||||
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/eventranking_list.html:24
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/seasonranking_list.html:35
|
|
||||||
msgid "won"
|
|
||||||
msgstr "gewonnen"
|
|
||||||
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/hanchan_confirm_delete.html:39
|
|
||||||
msgid "Cancel"
|
|
||||||
msgstr "Abbruch"
|
|
||||||
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/hanchan_confirm_delete.html:40
|
|
||||||
msgid "Delete"
|
|
||||||
msgstr "Löschen"
|
|
||||||
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/hanchan_form.html:18
|
|
||||||
msgid "Player"
|
|
||||||
msgstr "Spieler"
|
|
||||||
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/hanchan_form.html:58
|
|
||||||
msgid "Total"
|
msgid "Total"
|
||||||
msgstr "Total"
|
msgstr "Total"
|
||||||
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/hanchan_form.html:71
|
#: templates/mahjong_ranking/eventhanchan_form.html:51
|
||||||
|
msgid "Difference"
|
||||||
|
msgstr "Unterschied"
|
||||||
|
|
||||||
|
#: templates/mahjong_ranking/eventhanchan_form.html:103
|
||||||
|
#: templates/mahjong_ranking/eventhanchan_list.html:56
|
||||||
|
#: templates/mahjong_ranking/eventranking_list.html:52
|
||||||
|
#: templates/mahjong_ranking/hanchan_form.html:4
|
||||||
|
#: templates/mahjong_ranking/hanchan_form.html:14
|
||||||
|
msgid "Add Hanchan"
|
||||||
|
msgstr "Hanchan hinzufügen"
|
||||||
|
|
||||||
|
#: templates/mahjong_ranking/eventhanchan_form.html:105
|
||||||
|
#: templates/mahjong_ranking/eventhanchan_list.html:37
|
||||||
|
#: templates/mahjong_ranking/hanchan_confirm_delete.html:4
|
||||||
|
#: templates/mahjong_ranking/hanchan_confirm_delete.html:33
|
||||||
|
#: templates/mahjong_ranking/player_dan_score.html:44
|
||||||
|
#: templates/mahjong_ranking/player_invalid_score.html:33
|
||||||
|
#: templates/mahjong_ranking/player_kyu_score.html:41
|
||||||
|
#: templates/mahjong_ranking/player_ladder_score.html:52
|
||||||
|
msgid "Delete Hanchan"
|
||||||
|
msgstr "Hanchan löschen"
|
||||||
|
|
||||||
|
#: templates/mahjong_ranking/eventhanchan_form.html:118
|
||||||
|
#: templates/mahjong_ranking/hanchan_form.html:71
|
||||||
msgid "back"
|
msgid "back"
|
||||||
msgstr "Zurück"
|
msgstr "Zurück"
|
||||||
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/hanchan_form.html:72
|
#: templates/mahjong_ranking/eventhanchan_form.html:119
|
||||||
|
#: templates/mahjong_ranking/hanchan_form.html:72
|
||||||
msgid "save"
|
msgid "save"
|
||||||
msgstr "Speichern"
|
msgstr "Speichern"
|
||||||
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/kyudanranking_list.html:4
|
#: templates/mahjong_ranking/eventhanchan_list.html:7
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/kyudanranking_list.html:9
|
msgid "Played Hanchans"
|
||||||
msgid "Player List"
|
msgstr "Gespielte Hanchans"
|
||||||
msgstr "Spieler Liste"
|
|
||||||
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/kyudanranking_list.html:25
|
#: templates/mahjong_ranking/eventhanchan_list.html:18
|
||||||
msgid "Full Name"
|
#: templates/mahjong_ranking/hanchan_confirm_delete.html:15
|
||||||
msgstr "Voller Name"
|
msgid "Place"
|
||||||
|
msgstr "Platz"
|
||||||
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/kyudanranking_list.html:40
|
#: templates/mahjong_ranking/eventhanchan_list.html:21
|
||||||
|
#: templates/mahjong_ranking/hanchan_confirm_delete.html:18
|
||||||
|
#: templates/mahjong_ranking/player_dan_score.html:17
|
||||||
|
msgid "Dan Points"
|
||||||
|
msgstr "Dan Punkte"
|
||||||
|
|
||||||
|
#: templates/mahjong_ranking/eventhanchan_list.html:23
|
||||||
|
#: templates/mahjong_ranking/hanchan_confirm_delete.html:20
|
||||||
|
#: templates/mahjong_ranking/player_invalid_score.html:16
|
||||||
|
#: templates/mahjong_ranking/player_kyu_score.html:18
|
||||||
|
msgid "Kyu Points"
|
||||||
|
msgstr "Kyu Punkte"
|
||||||
|
|
||||||
|
#: templates/mahjong_ranking/eventhanchan_list.html:43
|
||||||
|
#: templates/mahjong_ranking/hanchan_form.html:4
|
||||||
|
#: templates/mahjong_ranking/hanchan_form.html:14
|
||||||
|
#: templates/mahjong_ranking/player_dan_score.html:47
|
||||||
|
#: templates/mahjong_ranking/player_invalid_score.html:36
|
||||||
|
#: templates/mahjong_ranking/player_kyu_score.html:44
|
||||||
|
#: templates/mahjong_ranking/player_ladder_score.html:55
|
||||||
|
msgid "Edit Hanchan"
|
||||||
|
msgstr "Hanchan bearbeiten"
|
||||||
|
|
||||||
|
#: templates/mahjong_ranking/eventhanchan_list.html:48
|
||||||
|
msgid "No Hanchan has been added to this event yet."
|
||||||
|
msgstr "Für diese Veranstaltung wurde noch keine Hanchan eingetragen."
|
||||||
|
|
||||||
|
#: templates/mahjong_ranking/eventhanchan_list.html:54
|
||||||
|
#: templates/mahjong_ranking/eventranking_list.html:51
|
||||||
|
msgid "Edit Event"
|
||||||
|
msgstr "Veranstaltung bearbeiten"
|
||||||
|
|
||||||
|
#: templates/mahjong_ranking/eventranking_list.html:4
|
||||||
|
#: templates/mahjong_ranking/eventranking_list.html:5
|
||||||
|
msgid "Tournament Ranking"
|
||||||
|
msgstr "Turnierwertung"
|
||||||
|
|
||||||
|
#: templates/mahjong_ranking/eventranking_list.html:12
|
||||||
|
#: templates/mahjong_ranking/kyudanranking_list.html:25
|
||||||
|
#: templates/mahjong_ranking/seasonranking_list.html:23
|
||||||
|
msgid "Rank"
|
||||||
|
msgstr "Rang"
|
||||||
|
|
||||||
|
#: templates/mahjong_ranking/eventranking_list.html:13
|
||||||
|
#: templates/mahjong_ranking/kyudanranking_list.html:17
|
||||||
|
#: templates/mahjong_ranking/seasonranking_list.html:24
|
||||||
|
msgid "Avatar"
|
||||||
|
msgstr "Avatar"
|
||||||
|
|
||||||
|
#: templates/mahjong_ranking/eventranking_list.html:14
|
||||||
|
#: templates/mahjong_ranking/kyudanranking_list.html:20
|
||||||
|
#: templates/mahjong_ranking/seasonranking_list.html:25
|
||||||
|
msgid "Nickname"
|
||||||
|
msgstr "Spitzname"
|
||||||
|
|
||||||
|
#: templates/mahjong_ranking/eventranking_list.html:15
|
||||||
|
msgid "Name"
|
||||||
|
msgstr "Name"
|
||||||
|
|
||||||
|
#: templates/mahjong_ranking/eventranking_list.html:16
|
||||||
|
#: templates/mahjong_ranking/seasonranking_list.html:26
|
||||||
|
msgid "Average"
|
||||||
|
msgstr "Durchschnitt"
|
||||||
|
|
||||||
|
#: templates/mahjong_ranking/eventranking_list.html:20
|
||||||
|
#: templates/mahjong_ranking/player_dan_score.html:15
|
||||||
|
#: templates/mahjong_ranking/player_invalid_score.html:15
|
||||||
|
#: templates/mahjong_ranking/player_kyu_score.html:16
|
||||||
|
#: templates/mahjong_ranking/player_ladder_score.html:16
|
||||||
|
#: templates/mahjong_ranking/seasonranking_list.html:30
|
||||||
|
msgid "Placement"
|
||||||
|
msgstr "Platzierung"
|
||||||
|
|
||||||
|
#: templates/mahjong_ranking/eventranking_list.html:22
|
||||||
|
#: templates/mahjong_ranking/seasonranking_list.html:32
|
||||||
|
msgid "count"
|
||||||
|
msgstr "Anzahl"
|
||||||
|
|
||||||
|
#: templates/mahjong_ranking/eventranking_list.html:23
|
||||||
|
#: templates/mahjong_ranking/seasonranking_list.html:33
|
||||||
|
msgid "good"
|
||||||
|
msgstr "gut"
|
||||||
|
|
||||||
|
#: templates/mahjong_ranking/eventranking_list.html:24
|
||||||
|
#: templates/mahjong_ranking/seasonranking_list.html:34
|
||||||
|
msgid "won"
|
||||||
|
msgstr "gewonnen"
|
||||||
|
|
||||||
|
#: templates/mahjong_ranking/hanchan_confirm_delete.html:39
|
||||||
|
msgid "Cancel"
|
||||||
|
msgstr "Abbruch"
|
||||||
|
|
||||||
|
#: templates/mahjong_ranking/hanchan_confirm_delete.html:40
|
||||||
|
msgid "Delete"
|
||||||
|
msgstr "Löschen"
|
||||||
|
|
||||||
|
#: templates/mahjong_ranking/hanchan_form.html:18
|
||||||
|
msgid "Player"
|
||||||
|
msgstr "Spieler"
|
||||||
|
|
||||||
|
#: templates/mahjong_ranking/kyudanranking_list.html:4
|
||||||
|
#: templates/mahjong_ranking/kyudanranking_list.html:9
|
||||||
|
msgid "Players list"
|
||||||
|
msgstr "Spielerliste"
|
||||||
|
|
||||||
|
#: templates/mahjong_ranking/kyudanranking_list.html:35
|
||||||
msgid "Games Total"
|
msgid "Games Total"
|
||||||
msgstr "Spiele total"
|
msgstr "Spiele total"
|
||||||
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/ladder_redbox.html:3
|
#: templates/mahjong_ranking/ladder_redbox.html:3
|
||||||
msgid "Latest Hanchans"
|
msgid "Latest Hanchans"
|
||||||
msgstr "Letzten Hanchans"
|
msgstr "Letzten Hanchans"
|
||||||
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/ladder_redbox.html:15
|
#: templates/mahjong_ranking/ladder_redbox.html:15
|
||||||
msgid "Latest Events"
|
msgid "Latest Events"
|
||||||
msgstr "Letzte Veranstaltungen"
|
msgstr "Letzte Veranstaltungen"
|
||||||
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/ladder_redbox.html:27
|
#: templates/mahjong_ranking/ladder_redbox.html:27
|
||||||
msgid "Ladder Archive"
|
msgid "Ladder Archive"
|
||||||
msgstr "Ladder Archiv"
|
msgstr "Ladder Archiv"
|
||||||
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/player_dan_score.html:4
|
#: templates/mahjong_ranking/player_dan_score.html:4
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/player_dan_score.html:5
|
#: templates/mahjong_ranking/player_dan_score.html:5
|
||||||
msgid "Dan Score for"
|
msgid "Dan Score for"
|
||||||
msgstr "Dan Wertung für"
|
msgstr "Dan Wertung für"
|
||||||
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/player_dan_score.html:8
|
#: templates/mahjong_ranking/player_dan_score.html:8
|
||||||
msgid "Hanchans that apply to the Dan Score"
|
msgid "Hanchans that apply to the Dan Score"
|
||||||
msgstr "Hanchans welche zur Dan Wertung zählen"
|
msgstr "Hanchans welche zur Dan Wertung zählen"
|
||||||
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/player_dan_score.html:12
|
#: templates/mahjong_ranking/player_dan_score.html:12
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/player_kyu_score.html:13
|
#: templates/mahjong_ranking/player_kyu_score.html:13
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/player_ladder_score.html:13
|
#: templates/mahjong_ranking/player_ladder_score.html:13
|
||||||
msgid "Date"
|
msgid "Date"
|
||||||
msgstr "Datum"
|
msgstr "Datum"
|
||||||
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/player_dan_score.html:13
|
#: templates/mahjong_ranking/player_dan_score.html:13
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/player_invalid_score.html:12
|
#: templates/mahjong_ranking/player_invalid_score.html:12
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/player_kyu_score.html:14
|
#: templates/mahjong_ranking/player_kyu_score.html:14
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/player_ladder_score.html:14
|
#: templates/mahjong_ranking/player_ladder_score.html:14
|
||||||
msgid "Event"
|
msgid "Event"
|
||||||
msgstr "Veranstaltung"
|
msgstr "Veranstaltung"
|
||||||
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/player_dan_score.html:16
|
#: templates/mahjong_ranking/player_dan_score.html:16
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/player_invalid_score.html:14
|
#: templates/mahjong_ranking/player_invalid_score.html:14
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/player_kyu_score.html:17
|
#: templates/mahjong_ranking/player_kyu_score.html:17
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/player_ladder_score.html:17
|
#: templates/mahjong_ranking/player_ladder_score.html:17
|
||||||
msgid "Players"
|
msgid "Players"
|
||||||
msgstr "Spieler"
|
msgstr "Spieler"
|
||||||
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/player_invalid_score.html:4
|
#: templates/mahjong_ranking/player_invalid_score.html:4
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/player_invalid_score.html:6
|
#: templates/mahjong_ranking/player_invalid_score.html:6
|
||||||
msgid "Unconfirmed Hanchans from"
|
msgid "Unconfirmed Hanchans from"
|
||||||
msgstr "Nicht bestätigte Hanchans von"
|
msgstr "Nicht bestätigte Hanchans von"
|
||||||
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/player_invalid_score.html:9
|
#: templates/mahjong_ranking/player_invalid_score.html:9
|
||||||
msgid "Invalid hanchans with"
|
msgid "Invalid hanchans with"
|
||||||
msgstr "Ungültige Hanchans mit"
|
msgstr "Ungültige Hanchans mit"
|
||||||
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/player_kyu_score.html:4
|
#: templates/mahjong_ranking/player_kyu_score.html:4
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/player_kyu_score.html:6
|
#: templates/mahjong_ranking/player_kyu_score.html:6
|
||||||
msgid "Kyu Score for"
|
msgid "Kyu Score for"
|
||||||
msgstr "Kyu Wertung für"
|
msgstr "Kyu Wertung für"
|
||||||
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/player_kyu_score.html:9
|
#: templates/mahjong_ranking/player_kyu_score.html:9
|
||||||
msgid "Hanchans that apply to the Kyu Score"
|
msgid "Hanchans that apply to the Kyu Score"
|
||||||
msgstr "Hanchans welche zur Kyu Wertung zählen"
|
msgstr "Hanchans welche zur Kyu Wertung zählen"
|
||||||
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/player_ladder_score.html:4
|
#: templates/mahjong_ranking/player_ladder_score.html:4
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/player_ladder_score.html:5
|
#: templates/mahjong_ranking/player_ladder_score.html:5
|
||||||
msgid "Ladder Score for"
|
msgid "Ladder Score for"
|
||||||
msgstr "Ladder Wertung für"
|
msgstr "Ladder Wertung für"
|
||||||
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/player_ladder_score.html:8
|
#: templates/mahjong_ranking/player_ladder_score.html:8
|
||||||
msgid "Hanchans that apply to the Ladder Score"
|
msgid "Hanchans that apply to the Ladder Score"
|
||||||
msgstr "Hanchans welche in der Ladder zählen"
|
msgstr "Hanchans welche in der Ladder zählen"
|
||||||
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/player_ladder_score.html:71
|
#: templates/mahjong_ranking/player_ladder_score.html:71
|
||||||
msgid "Go"
|
msgid "Go"
|
||||||
msgstr "Los"
|
msgstr "Los"
|
||||||
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/seasonranking_list.html:11
|
#: templates/mahjong_ranking/seasonranking_list.html:11
|
||||||
msgid "End"
|
msgid "End"
|
||||||
msgstr "Ende"
|
msgstr "Ende"
|
||||||
|
|
||||||
#: mahjong_ranking/templates/mahjong_ranking/seasonranking_list.html:12
|
#: templates/mahjong_ranking/seasonranking_list.html:12
|
||||||
msgid "Participants"
|
msgid "Participants"
|
||||||
msgstr "Teilnehmer"
|
msgstr "Teilnehmer"
|
||||||
|
|
||||||
#: mahjong_ranking/views.py:98
|
#: views.py:116
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%s has been updated successfully."
|
msgid "%s has been updated successfully."
|
||||||
msgstr "%s wurde erfolgreich aktualisiert."
|
msgstr "%s wurde erfolgreich aktualisiert."
|
||||||
|
|
||||||
#: mahjong_ranking/views.py:101
|
#: views.py:119
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%s has been added successfully. You can now add a new one."
|
msgid "%s has been added successfully. You can now add a new one."
|
||||||
msgstr "%s wurde erfolgreich hinzugefügt. Du kannst eine neue eintragen."
|
msgstr "%s wurde erfolgreich hinzugefügt. Du kannst eine neue eintragen."
|
||||||
|
|
||||||
#: mahjong_ranking/views.py:119 mahjong_ranking/views.py:135
|
#: views.py:222
|
||||||
msgid "Event does not exist"
|
|
||||||
msgstr "Veranstaltung existiert nicht"
|
|
||||||
|
|
||||||
#: mahjong_ranking/views.py:199
|
|
||||||
msgid "No user found matching the name {}"
|
msgid "No user found matching the name {}"
|
||||||
msgstr "Kein Benutzer mit dem Namen %s gefunden"
|
msgstr "Kein Benutzer mit dem Namen %s gefunden"
|
||||||
|
|
||||||
|
#~ msgid "Set unconfirmed"
|
||||||
|
#~ msgstr "Als unbestätigt markieren"
|
||||||
|
|
||||||
|
#~ msgid "Full Name"
|
||||||
|
#~ msgstr "Voller Name"
|
||||||
|
|
||||||
|
#~ msgid "Event does not exist"
|
||||||
|
#~ msgstr "Veranstaltung existiert nicht"
|
||||||
|
|
||||||
#~ msgid "It's not allowed to enter future games."
|
#~ msgid "It's not allowed to enter future games."
|
||||||
#~ msgstr "Spiele in der Zukunft sind nicht erlaubt."
|
#~ msgstr "Spiele in der Zukunft sind nicht erlaubt."
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
"""Export Mahjong Rankings as excel files."""
|
"""Export Mahjong Rankings as Excel files."""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from datetime import date, time, datetime
|
from datetime import date, time, datetime
|
||||||
|
|||||||
58
src/mahjong_ranking/management/commands/fixateranking.py
Normal file
58
src/mahjong_ranking/management/commands/fixateranking.py
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
"""
|
||||||
|
Recalculates all Kyu/Dan Rankings until the given date
|
||||||
|
and writes them to the legacy fields.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from django.core.management.base import BaseCommand
|
||||||
|
from datetime import datetime, date, time
|
||||||
|
from mahjong_ranking import models
|
||||||
|
from django.utils.dateparse import parse_date
|
||||||
|
from django.utils import timezone
|
||||||
|
|
||||||
|
LEGACY_ATTRIBUTES = (
|
||||||
|
"dan",
|
||||||
|
"dan_points",
|
||||||
|
"max_dan_points",
|
||||||
|
"kyu",
|
||||||
|
"kyu_points",
|
||||||
|
"hanchan_count",
|
||||||
|
"good_hanchans",
|
||||||
|
"won_hanchans"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class Command(BaseCommand):
|
||||||
|
help = "Recalculates all Kyu/Dan Rankings until the given date " + \
|
||||||
|
"and writes them to the legacy fields."
|
||||||
|
|
||||||
|
|
||||||
|
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.')
|
||||||
|
parser.add_argument('-u', '--until', nargs='?', type=parse_date,
|
||||||
|
metavar='YYYY-MM-DD',
|
||||||
|
help='Only use Hanchans until the given date.')
|
||||||
|
|
||||||
|
|
||||||
|
def handle(self, *args, **options):
|
||||||
|
since = options.get('since', None)
|
||||||
|
until = options.get('until', None)
|
||||||
|
if isinstance(since, date):
|
||||||
|
since = datetime.combine(since, time(0, 0, 0))
|
||||||
|
since = timezone.make_aware(since)
|
||||||
|
if isinstance(until, date):
|
||||||
|
until = datetime.combine(until, time(23, 59, 59))
|
||||||
|
until = timezone.make_aware(until)
|
||||||
|
models.KyuDanRanking.objects.update(since=since, until=until, force_recalc=True)
|
||||||
|
# write the updated values to the legacy fields
|
||||||
|
for ranking in models.KyuDanRanking.objects.all():
|
||||||
|
print(ranking)
|
||||||
|
for attribute in LEGACY_ATTRIBUTES:
|
||||||
|
setattr(ranking, f"legacy_{attribute}", getattr(ranking, attribute))
|
||||||
|
value = getattr(ranking, attribute)
|
||||||
|
legacy_value = getattr(ranking, f"legacy_{attribute}")
|
||||||
|
print(f"{attribute}: {value}, legacy_{attribute}: {legacy_value}")
|
||||||
|
ranking.legacy_date = until.date()
|
||||||
|
print(f"legacy_date: {ranking.legacy_date}")
|
||||||
|
ranking.save()
|
||||||
@@ -3,13 +3,15 @@ Rest all dan points to 0 at a given date.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from datetime import date, datetime, time
|
from datetime import datetime
|
||||||
|
from datetime import time
|
||||||
from mahjong_ranking import models
|
from mahjong_ranking import models
|
||||||
from django.utils.dateparse import parse_date
|
from django.utils.dateparse import parse_date
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
""" Recalculate all Kyu/Dan Rankings """
|
""" reset every dan player to 1st dan with 0 points. """
|
||||||
|
|
||||||
help = "reset every dan player to 1st dan with 0 points."
|
help = "reset every dan player to 1st dan with 0 points."
|
||||||
|
|
||||||
@@ -17,12 +19,13 @@ class Command(BaseCommand):
|
|||||||
parser.add_argument('reset_date', type=parse_date)
|
parser.add_argument('reset_date', type=parse_date)
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
legacy_attrs = [ key for key in models.KyuDanRanking.__dict__.keys()
|
legacy_attrs = [key for key in models.KyuDanRanking.__dict__.keys()
|
||||||
if key.startswith('legacy') ]
|
if key.startswith('legacy')]
|
||||||
legacy_attrs.remove('legacy_date')
|
legacy_attrs.remove('legacy_date')
|
||||||
reset_date = timezone.make_aware(datetime.combine(
|
reset_date = timezone.make_aware(datetime.combine(
|
||||||
options.get('reset_date'), time(23, 59, 59)))
|
options.get('reset_date'), time(23, 59, 59)))
|
||||||
models.KyuDanRanking.objects.update(until=reset_date, force_recalc=True)
|
models.KyuDanRanking.objects.update(
|
||||||
|
until=reset_date, force_recalc=True)
|
||||||
for ranking in models.KyuDanRanking.objects.filter(dan__gt=0):
|
for ranking in models.KyuDanRanking.objects.filter(dan__gt=0):
|
||||||
print(ranking)
|
print(ranking)
|
||||||
ranking.dan = 1
|
ranking.dan = 1
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ class HanchanManager(models.Manager):
|
|||||||
hanchans = hanchans.filter(start__lte=until)
|
hanchans = hanchans.filter(start__lte=until)
|
||||||
return hanchans
|
return hanchans
|
||||||
|
|
||||||
def dan_hanchans(self, user, since = None, **filter_args):
|
def dan_hanchans(self, user, since=None, **filter_args):
|
||||||
""" Return all Hanchans where a specific user has participated and had
|
""" Return all Hanchans where a specific user has participated and had
|
||||||
gain dan points and make his gamestats availabale.
|
gain dan points and make his gamestats availabale.
|
||||||
|
|
||||||
@@ -53,7 +53,7 @@ class HanchanManager(models.Manager):
|
|||||||
[hanchan.get_playerdata(user) for hanchan in queryset]
|
[hanchan.get_playerdata(user) for hanchan in queryset]
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
def kyu_hanchans(self, user, since = None, **filter_args):
|
def kyu_hanchans(self, user, since=None, **filter_args):
|
||||||
""" Return all Hanchans where a specific user has participated and had
|
""" Return all Hanchans where a specific user has participated and had
|
||||||
gain kyū points and make his gamestats availabale.
|
gain kyū points and make his gamestats availabale.
|
||||||
|
|
||||||
@@ -74,11 +74,13 @@ class HanchanManager(models.Manager):
|
|||||||
[hanchan.get_playerdata(user) for hanchan in queryset]
|
[hanchan.get_playerdata(user) for hanchan in queryset]
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
def season_hanchans(self, user=None, season=None, until=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.
|
"""Return all Hanchans that belong to a given or the current season.
|
||||||
|
|
||||||
:param user: Only return Hanchans where this user participated.
|
:param user: Only return Hanchans where this user participated.
|
||||||
:param season: the year of the wanted season, current year if None.
|
:param season: the year of the wanted season, current year if None.
|
||||||
|
:param until: only return hanchans played until the given date.
|
||||||
:return: QuerySet Object
|
:return: QuerySet Object
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
@@ -92,6 +94,7 @@ class HanchanManager(models.Manager):
|
|||||||
|
|
||||||
:param user: Return Hanchans where this user participated.
|
:param user: Return Hanchans where this user participated.
|
||||||
:param since: only return Hanchans played since the given datetime
|
:param since: only return Hanchans played since the given datetime
|
||||||
|
:param until: only return hanchans played until the given date.
|
||||||
:param filter_args: To add specific arguments to the Django filter.
|
:param filter_args: To add specific arguments to the Django filter.
|
||||||
:return: a QuerySet Object
|
:return: a QuerySet Object
|
||||||
"""
|
"""
|
||||||
@@ -199,10 +202,8 @@ class SeasonRankingManager(models.Manager):
|
|||||||
class KyuDanRankingManager(models.Manager):
|
class KyuDanRankingManager(models.Manager):
|
||||||
def json_data(self):
|
def json_data(self):
|
||||||
""" Get all Rankings for a given Season and return them as a list of
|
""" Get all Rankings for a given Season and return them as a list of
|
||||||
dict objects, suitable for JSON exports and other processings.
|
dict objects, suitable for JSON exports and other processing.
|
||||||
|
:return: a list() of dict() objects suitable for JSON export.
|
||||||
:param season: Season that should be exported, current season if empty
|
|
||||||
:return: a list() of dict() objects suiteable for JSON export.
|
|
||||||
"""
|
"""
|
||||||
json_data = list()
|
json_data = list()
|
||||||
values = self.all()
|
values = self.all()
|
||||||
@@ -237,8 +238,9 @@ class KyuDanRankingManager(models.Manager):
|
|||||||
|
|
||||||
def update(self, since=None, until=None, force_recalc=False):
|
def update(self, since=None, until=None, force_recalc=False):
|
||||||
old_attr = {'dan': None, 'dan_points': None,
|
old_attr = {'dan': None, 'dan_points': None,
|
||||||
'kyu': None, 'kyu_points': None, 'won_hanchans': None,
|
'kyu': None, 'kyu_points': None,
|
||||||
'good_hanchans': None, 'hanchan_count': None}
|
'won_hanchans': None, 'good_hanchans': None,
|
||||||
|
'hanchan_count': None}
|
||||||
for ranking in self.all():
|
for ranking in self.all():
|
||||||
old_attr = {attr: getattr(ranking, attr) for attr in
|
old_attr = {attr: getattr(ranking, attr) for attr in
|
||||||
old_attr.keys()}
|
old_attr.keys()}
|
||||||
@@ -247,7 +249,8 @@ class KyuDanRankingManager(models.Manager):
|
|||||||
for attr, old_value in old_attr.items():
|
for attr, old_value in old_attr.items():
|
||||||
if getattr(ranking, attr) != old_value:
|
if getattr(ranking, attr) != old_value:
|
||||||
LOGGER.warning(
|
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,
|
{'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)}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,12 +1,26 @@
|
|||||||
"""Middleware to defer slow denormalization at the end of a request."""
|
"""Middleware to defer slow denormalization at the end of a request."""
|
||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
|
|
||||||
from mahjong_ranking import models
|
from mahjong_ranking import models
|
||||||
from . import LOGGER
|
from . import LOGGER
|
||||||
|
|
||||||
|
|
||||||
class DenormalizationUpdateMiddleware(object): # Ignore PyLintBear (R0903)
|
class DenormalizationUpdateMiddleware:
|
||||||
"""To recalculate everything in the queues at the end of a POST request."""
|
"""To recalculate everything in the queues at the end of a POST request."""
|
||||||
|
|
||||||
|
def __init__(self, get_response=None):
|
||||||
|
self.get_response = get_response
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
def __call__(self, request):
|
||||||
|
response = None
|
||||||
|
if hasattr(self, 'process_request'):
|
||||||
|
response = self.process_request(request)
|
||||||
|
response = response or self.get_response(request)
|
||||||
|
if hasattr(self, 'process_response'):
|
||||||
|
response = self.process_response(request, response)
|
||||||
|
return response
|
||||||
|
|
||||||
def process_response(self, request, response): # Ignore PyLintBear (R0201)
|
def process_response(self, request, response): # Ignore PyLintBear (R0201)
|
||||||
"""Check and process the recalculation queues on each POST request.
|
"""Check and process the recalculation queues on each POST request.
|
||||||
|
|
||||||
@@ -16,7 +30,6 @@ class DenormalizationUpdateMiddleware(object): # Ignore PyLintBear (R0903)
|
|||||||
"""
|
"""
|
||||||
event_queue = set()
|
event_queue = set()
|
||||||
season_queue = set()
|
season_queue = set()
|
||||||
|
|
||||||
if request.method != 'POST':
|
if request.method != 'POST':
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,8 @@ class Migration(migrations.Migration):
|
|||||||
serialize=False, auto_created=True,
|
serialize=False, auto_created=True,
|
||||||
primary_key=True)),
|
primary_key=True)),
|
||||||
('start', models.DateTimeField(
|
('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')),
|
verbose_name='Beginn')),
|
||||||
('player1_input_score',
|
('player1_input_score',
|
||||||
models.IntegerField(verbose_name='Punkte')),
|
models.IntegerField(verbose_name='Punkte')),
|
||||||
@@ -55,14 +56,14 @@ class Migration(migrations.Migration):
|
|||||||
null=True, editable=False, blank=True)),
|
null=True, editable=False, blank=True)),
|
||||||
('player1_bonus_points', models.SmallIntegerField(
|
('player1_bonus_points', models.SmallIntegerField(
|
||||||
null=True, editable=False, blank=True)),
|
null=True, editable=False, blank=True)),
|
||||||
('player1_comment', models.CharField(verbose_name='Anmerkung',
|
('player1_comment', models.CharField(verbose_name="Anmerkung",
|
||||||
max_length=255,
|
max_length=255,
|
||||||
editable=False,
|
editable=False,
|
||||||
blank=True)),
|
blank=True)),
|
||||||
('player2_input_score',
|
('player2_input_score',
|
||||||
models.IntegerField(verbose_name='Punkte')),
|
models.IntegerField(verbose_name="Punkte")),
|
||||||
('player2_game_score', models.PositiveIntegerField(
|
('player2_game_score', models.PositiveIntegerField(
|
||||||
default=0, verbose_name='Punkte', editable=False)),
|
default=0, verbose_name="Punkte", editable=False)),
|
||||||
('player2_placement', models.PositiveSmallIntegerField(
|
('player2_placement', models.PositiveSmallIntegerField(
|
||||||
default=0, editable=False)),
|
default=0, editable=False)),
|
||||||
('player2_kyu_points', models.SmallIntegerField(
|
('player2_kyu_points', models.SmallIntegerField(
|
||||||
@@ -111,7 +112,8 @@ class Migration(migrations.Migration):
|
|||||||
models.TextField(verbose_name='Anmerkung', blank=True)),
|
models.TextField(verbose_name='Anmerkung', blank=True)),
|
||||||
('confirmed', models.BooleanField(
|
('confirmed', models.BooleanField(
|
||||||
default=True,
|
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')),
|
verbose_name='Wurde best\xe4tigt')),
|
||||||
('player_names',
|
('player_names',
|
||||||
models.CharField(max_length=255, editable=False)),
|
models.CharField(max_length=255, editable=False)),
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ from django.db import migrations, models
|
|||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
('mahjong_ranking', '0004_auto_20170218_1947'),
|
('mahjong_ranking', '0004_auto_20170218_1947'),
|
||||||
]
|
]
|
||||||
@@ -14,7 +13,9 @@ class Migration(migrations.Migration):
|
|||||||
operations = [
|
operations = [
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='kyudanranking',
|
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(
|
migrations.AddField(
|
||||||
model_name='kyudanranking',
|
model_name='kyudanranking',
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import django.db.models.deletion
|
|||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
('mahjong_ranking', '0005_auto_20171115_0653'),
|
('mahjong_ranking', '0005_auto_20171115_0653'),
|
||||||
]
|
]
|
||||||
@@ -42,27 +41,40 @@ class Migration(migrations.Migration):
|
|||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='eventranking',
|
model_name='eventranking',
|
||||||
name='user',
|
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(
|
migrations.AlterField(
|
||||||
model_name='hanchan',
|
model_name='hanchan',
|
||||||
name='player1',
|
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(
|
migrations.AlterField(
|
||||||
model_name='hanchan',
|
model_name='hanchan',
|
||||||
name='player2',
|
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(
|
migrations.AlterField(
|
||||||
model_name='hanchan',
|
model_name='hanchan',
|
||||||
name='player3',
|
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(
|
migrations.AlterField(
|
||||||
model_name='hanchan',
|
model_name='hanchan',
|
||||||
name='player4',
|
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(
|
migrations.AlterField(
|
||||||
model_name='kyudanranking',
|
model_name='kyudanranking',
|
||||||
@@ -82,6 +94,7 @@ class Migration(migrations.Migration):
|
|||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='seasonranking',
|
model_name='seasonranking',
|
||||||
name='user',
|
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),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
# Generated by Django 4.2.2 on 2023-07-19 18:11
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
('mahjong_ranking', '0006_auto_20171214_1318'),
|
||||||
|
]
|
||||||
|
|
||||||
|
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'},
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='kyudanranking',
|
||||||
|
name='legacy_max_dan_points',
|
||||||
|
field=models.PositiveIntegerField(default=0),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -12,7 +12,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 as _
|
from django.utils.translation import gettext as _
|
||||||
|
|
||||||
from events.models import Event
|
from events.models import Event
|
||||||
from . import DAN_RANKS_DICT, LOGGER, set_dirty
|
from . import DAN_RANKS_DICT, LOGGER, set_dirty
|
||||||
@@ -29,7 +29,8 @@ class EventRanking(models.Model):
|
|||||||
Sie beschränken sich aber auf einen Event und werden nur dann angestossen,
|
Sie beschränken sich aber auf einen Event und werden nur dann angestossen,
|
||||||
wenn der Event als Turnier markiert wurde.
|
wenn der Event als Turnier markiert wurde.
|
||||||
"""
|
"""
|
||||||
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT)
|
user = models.ForeignKey(settings.AUTH_USER_MODEL,
|
||||||
|
on_delete=models.PROTECT)
|
||||||
event = models.ForeignKey(Event, on_delete=models.CASCADE)
|
event = models.ForeignKey(Event, on_delete=models.CASCADE)
|
||||||
placement = models.PositiveIntegerField(blank=True, null=True)
|
placement = models.PositiveIntegerField(blank=True, null=True)
|
||||||
avg_placement = models.FloatField(default=4)
|
avg_placement = models.FloatField(default=4)
|
||||||
@@ -46,11 +47,11 @@ class EventRanking(models.Model):
|
|||||||
|
|
||||||
def recalculate(self):
|
def recalculate(self):
|
||||||
"""
|
"""
|
||||||
Berechnet die durschnittliche Platzierung und Punkte, u.v.m. neu.
|
Berechnet die durchschnittliche Platzierung und Punkte, u.v.m. neu.
|
||||||
|
|
||||||
Diese Daten werden benötigt um die Platzierung zu erstellen. Sie
|
Diese Daten werden benötigt, um die Platzierung zu erstellen. Sie
|
||||||
können zwar sehr leicht errechnet werden, es macht trotzdem Sinn
|
können zwar sehr leicht errechnet werden, es macht trotzdem Sinn
|
||||||
sie zwischen zu speichern.
|
sie zwischenzuspeichern.
|
||||||
"""
|
"""
|
||||||
LOGGER.info(
|
LOGGER.info(
|
||||||
u'Recalculate EventRanking for Player %s in %s',
|
u'Recalculate EventRanking for Player %s in %s',
|
||||||
@@ -289,9 +290,8 @@ class Hanchan(models.Model):
|
|||||||
self.bonus_points = getattr(self, '%s_bonus_points' % player)
|
self.bonus_points = getattr(self, '%s_bonus_points' % player)
|
||||||
self.player_comment = getattr(self, '%s_comment' % player)
|
self.player_comment = getattr(self, '%s_comment' % player)
|
||||||
|
|
||||||
def update_playerdata(self, user, **kwargs):
|
def update_player_data(self, user, **kwargs):
|
||||||
"""i small workaround to access score, placement of a specific user
|
"""to access scores and placement of a specific user from templates"""
|
||||||
prominent from a in the user templates"""
|
|
||||||
for player in ('player1', 'player2', 'player3', 'player4'):
|
for player in ('player1', 'player2', 'player3', 'player4'):
|
||||||
if getattr(self, player) == user:
|
if getattr(self, player) == user:
|
||||||
setattr(self, '%s_input_score' % player, self.input_score)
|
setattr(self, '%s_input_score' % player, self.input_score)
|
||||||
@@ -348,6 +348,7 @@ class KyuDanRanking(models.Model):
|
|||||||
legacy_date = models.DateField(blank=True, null=True)
|
legacy_date = models.DateField(blank=True, null=True)
|
||||||
legacy_dan = models.PositiveSmallIntegerField(blank=True, null=True)
|
legacy_dan = models.PositiveSmallIntegerField(blank=True, null=True)
|
||||||
legacy_dan_points = models.PositiveIntegerField(blank=True, null=True)
|
legacy_dan_points = models.PositiveIntegerField(blank=True, null=True)
|
||||||
|
legacy_max_dan_points = models.PositiveIntegerField(default=0)
|
||||||
legacy_kyu = models.PositiveSmallIntegerField(blank=True, null=True)
|
legacy_kyu = models.PositiveSmallIntegerField(blank=True, null=True)
|
||||||
legacy_kyu_points = models.PositiveIntegerField(blank=True, null=True)
|
legacy_kyu_points = models.PositiveIntegerField(blank=True, null=True)
|
||||||
legacy_hanchan_count = models.PositiveIntegerField(blank=True, null=True)
|
legacy_hanchan_count = models.PositiveIntegerField(blank=True, null=True)
|
||||||
@@ -358,7 +359,10 @@ class KyuDanRanking(models.Model):
|
|||||||
objects = managers.KyuDanRankingManager()
|
objects = managers.KyuDanRankingManager()
|
||||||
|
|
||||||
class Meta(object):
|
class Meta(object):
|
||||||
ordering = ('-dan_points', 'dan', '-kyu_points')
|
ordering = (models.F("dan").desc(nulls_last=True),
|
||||||
|
'-dan_points', '-kyu_points',
|
||||||
|
'-won_hanchans', '-good_hanchans',
|
||||||
|
'-last_hanchan_date')
|
||||||
verbose_name = _(u'Kyū/Dan Ranking')
|
verbose_name = _(u'Kyū/Dan Ranking')
|
||||||
verbose_name_plural = _(u'Kyū/Dan Rankings')
|
verbose_name_plural = _(u'Kyū/Dan Rankings')
|
||||||
|
|
||||||
@@ -417,7 +421,7 @@ class KyuDanRanking(models.Model):
|
|||||||
|
|
||||||
def append_tournament_bonuspoints(self, hanchan):
|
def append_tournament_bonuspoints(self, hanchan):
|
||||||
"""
|
"""
|
||||||
Prüft ob es die letzte Hanchan in einem Turnier war. Wenn ja werden
|
Prüft, ob es die letzte Hanchan in einem Turnier war. Wenn ja, werden
|
||||||
bei Bedarf Bonuspunkte vergeben, falls der Spieler das Turnier
|
bei Bedarf Bonuspunkte vergeben, falls der Spieler das Turnier
|
||||||
gewonnen hat.
|
gewonnen hat.
|
||||||
:param hanchan: Ein Player Objekt
|
:param hanchan: Ein Player Objekt
|
||||||
@@ -428,7 +432,8 @@ class KyuDanRanking(models.Model):
|
|||||||
).order_by('-start')
|
).order_by('-start')
|
||||||
last_hanchan_this_event = hanchans_this_event[0]
|
last_hanchan_this_event = hanchans_this_event[0]
|
||||||
# Das braucht nur am Ende eines Turnieres gemacht werden.
|
# Das braucht nur am Ende eines Turnieres gemacht werden.
|
||||||
if hanchan != last_hanchan_this_event: return False
|
if hanchan != last_hanchan_this_event:
|
||||||
|
return False
|
||||||
event_ranking = EventRanking.objects.get(
|
event_ranking = EventRanking.objects.get(
|
||||||
user=self.user,
|
user=self.user,
|
||||||
event=hanchan.event
|
event=hanchan.event
|
||||||
@@ -439,8 +444,8 @@ class KyuDanRanking(models.Model):
|
|||||||
settings.TOURNAMENT_WIN_BONUSPOINTS)
|
settings.TOURNAMENT_WIN_BONUSPOINTS)
|
||||||
if event_ranking.avg_placement == 1:
|
if event_ranking.avg_placement == 1:
|
||||||
bonus_points += settings.TOURNAMENT_FLAWLESS_VICTORY_BONUSPOINTS
|
bonus_points += settings.TOURNAMENT_FLAWLESS_VICTORY_BONUSPOINTS
|
||||||
hanchan.player_comment += u'+{0:d} Pkt: alle Spiele des Turnieres gewonnen. '.format(
|
hanchan.player_comment += '+{0:d} Pkt: alle Spiele des Turnieres \
|
||||||
settings.TOURNAMENT_FLAWLESS_VICTORY_BONUSPOINTS)
|
gewonnen. '.format(settings.TOURNAMENT_FLAWLESS_VICTORY_BONUSPOINTS)
|
||||||
|
|
||||||
if bonus_points and self.dan:
|
if bonus_points and self.dan:
|
||||||
hanchan.dan_points += bonus_points
|
hanchan.dan_points += bonus_points
|
||||||
@@ -472,7 +477,7 @@ class KyuDanRanking(models.Model):
|
|||||||
# Setze alles auf die legacy Werte und berechne alles von neuem.
|
# Setze alles auf die legacy Werte und berechne alles von neuem.
|
||||||
self.dan = self.legacy_dan
|
self.dan = self.legacy_dan
|
||||||
self.dan_points = self.legacy_dan_points or 0
|
self.dan_points = self.legacy_dan_points or 0
|
||||||
self.max_dan_points = self.dan_points
|
self.max_dan_points = self.legacy_max_dan_points or 0
|
||||||
self.kyu = self.legacy_kyu
|
self.kyu = self.legacy_kyu
|
||||||
self.kyu_points = self.legacy_kyu_points or 0
|
self.kyu_points = self.legacy_kyu_points or 0
|
||||||
self.hanchan_count = self.legacy_hanchan_count or 0
|
self.hanchan_count = self.legacy_hanchan_count or 0
|
||||||
@@ -489,19 +494,27 @@ class KyuDanRanking(models.Model):
|
|||||||
since = timezone.make_aware(
|
since = timezone.make_aware(
|
||||||
datetime.combine(self.legacy_date, time(0, 0, 0))
|
datetime.combine(self.legacy_date, time(0, 0, 0))
|
||||||
)
|
)
|
||||||
LOGGER.info(
|
|
||||||
"recalculating Kyu/Dan points for %(user)s since %(since)s...",
|
|
||||||
{'user': self.user, 'since': str(since)}
|
|
||||||
)
|
|
||||||
if since:
|
if since:
|
||||||
valid_hanchans = valid_hanchans.filter(start__gt=since)
|
valid_hanchans = valid_hanchans.filter(start__gt=since)
|
||||||
|
else:
|
||||||
|
since = valid_hanchans.aggregate(since=models.Min("start"))["since"]
|
||||||
if until:
|
if until:
|
||||||
valid_hanchans = valid_hanchans.filter(start__lte=until)
|
valid_hanchans = valid_hanchans.filter(start__lte=until)
|
||||||
|
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} " +
|
||||||
|
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:
|
for hanchan in valid_hanchans:
|
||||||
self.hanchan_count += 1
|
self.hanchan_count += 1
|
||||||
|
LOGGER.info(
|
||||||
|
f"{self.user} Hanchan no. {self.hanchan_count} " +
|
||||||
|
f"from {hanchan.start}")
|
||||||
hanchan.get_playerdata(self.user)
|
hanchan.get_playerdata(self.user)
|
||||||
if since and hanchan.start < since:
|
if since and hanchan.start < since:
|
||||||
LOGGER.debug(hanchan, "<", since, "no recalc")
|
LOGGER.info(hanchan, "<", since, "no recalc")
|
||||||
self.dan_points += hanchan.dan_points or 0
|
self.dan_points += hanchan.dan_points or 0
|
||||||
self.kyu_points += hanchan.kyu_points or 0
|
self.kyu_points += hanchan.kyu_points or 0
|
||||||
self.update_rank()
|
self.update_rank()
|
||||||
@@ -513,7 +526,7 @@ class KyuDanRanking(models.Model):
|
|||||||
self.append_tournament_bonuspoints(hanchan)
|
self.append_tournament_bonuspoints(hanchan)
|
||||||
self.update_rank()
|
self.update_rank()
|
||||||
self.append_3_in_a_row_bonuspoints(hanchan)
|
self.append_3_in_a_row_bonuspoints(hanchan)
|
||||||
hanchan.update_playerdata(self.user)
|
hanchan.update_player_data(self.user)
|
||||||
hanchan.save(recalculate=False)
|
hanchan.save(recalculate=False)
|
||||||
self.won_hanchans += 1 if hanchan.placement == 1 else 0
|
self.won_hanchans += 1 if hanchan.placement == 1 else 0
|
||||||
self.good_hanchans += 1 if hanchan.placement == 2 else 0
|
self.good_hanchans += 1 if hanchan.placement == 2 else 0
|
||||||
@@ -524,7 +537,7 @@ class KyuDanRanking(models.Model):
|
|||||||
"""
|
"""
|
||||||
Berechne die Kyu bzw. Dan Punkte für eine Hanchan neu.
|
Berechne die Kyu bzw. Dan Punkte für eine Hanchan neu.
|
||||||
:type hanchan: Hanchan
|
:type hanchan: Hanchan
|
||||||
:param hanchan: Das Player Objekt das neuberechnet werden soll.
|
:param hanchan: das Player-Objekt, welches neu berechnet werden soll.
|
||||||
"""
|
"""
|
||||||
hanchan.kyu_points = None
|
hanchan.kyu_points = None
|
||||||
hanchan.dan_points = None
|
hanchan.dan_points = None
|
||||||
@@ -567,14 +580,16 @@ class KyuDanRanking(models.Model):
|
|||||||
# Only substract so much points that player has 0 Points:
|
# Only substract so much points that player has 0 Points:
|
||||||
if self.dan_points + hanchan.dan_points < 0:
|
if self.dan_points + hanchan.dan_points < 0:
|
||||||
hanchan.player_comment = 'Spieler unterschreitet 0 Punkte.' \
|
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)
|
hanchan.dan_points -= (self.dan_points + hanchan.dan_points)
|
||||||
self.dan_points += hanchan.dan_points
|
self.dan_points += hanchan.dan_points
|
||||||
else:
|
else:
|
||||||
# Only substract so much points that player has 0 Points:
|
# Only substract so much points that player has 0 Points:
|
||||||
if self.kyu_points + hanchan.kyu_points < 0:
|
if self.kyu_points + hanchan.kyu_points < 0:
|
||||||
hanchan.player_comment = 'Spieler unterschreitet 0 Punkte.' \
|
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)
|
hanchan.kyu_points -= (self.kyu_points + hanchan.kyu_points)
|
||||||
self.kyu_points += hanchan.kyu_points
|
self.kyu_points += hanchan.kyu_points
|
||||||
|
|
||||||
@@ -603,7 +618,8 @@ class KyuDanRanking(models.Model):
|
|||||||
|
|
||||||
|
|
||||||
class SeasonRanking(models.Model):
|
class SeasonRanking(models.Model):
|
||||||
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT)
|
user = models.ForeignKey(settings.AUTH_USER_MODEL,
|
||||||
|
on_delete=models.PROTECT)
|
||||||
season = models.PositiveSmallIntegerField(_('Season'))
|
season = models.PositiveSmallIntegerField(_('Season'))
|
||||||
placement = models.PositiveIntegerField(blank=True, null=True)
|
placement = models.PositiveIntegerField(blank=True, null=True)
|
||||||
avg_placement = models.FloatField(blank=True, null=True)
|
avg_placement = models.FloatField(blank=True, null=True)
|
||||||
|
|||||||
@@ -11,38 +11,42 @@ from .models import SeasonRanking
|
|||||||
|
|
||||||
class EventRankingSitemap(GenericSitemap):
|
class EventRankingSitemap(GenericSitemap):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def items():
|
def items(**kwargs):
|
||||||
"""add all upcoming and archived events to the sitemap."""
|
"""add all upcoming and archived events to the sitemap.
|
||||||
|
@param **kwargs:
|
||||||
|
"""
|
||||||
return Event.objects.all().exclude(eventranking=None)
|
return Event.objects.all().exclude(eventranking=None)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def location(event):
|
def location(event, **kwargs):
|
||||||
return reverse('event-ranking', kwargs={'event': event.id})
|
return reverse('event-ranking', kwargs={'event': event.id})
|
||||||
|
|
||||||
|
|
||||||
class EventHanchanSitemap(GenericSitemap):
|
class EventHanchanSitemap(GenericSitemap):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def items():
|
def items(**kwargs):
|
||||||
"""add all upcoming and archived events to the sitemap."""
|
"""add all upcoming and archived events to the sitemap.
|
||||||
|
@param **kwargs:
|
||||||
|
"""
|
||||||
return Event.objects.all().exclude(eventranking=None)
|
return Event.objects.all().exclude(eventranking=None)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def location(event):
|
def location(event, **kwargs):
|
||||||
return reverse('event-hanchan-list', kwargs={'event': event.id})
|
return reverse('event-hanchan-list', kwargs={'event': event.id})
|
||||||
|
|
||||||
|
|
||||||
class MajongSeasonSitemap(Sitemap):
|
class MahjongSeasonSitemap(Sitemap):
|
||||||
priority = 0.5
|
priority = 0.5
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def items():
|
def items(**kwargs):
|
||||||
seasons = SeasonRanking.objects.all().distinct('season').order_by(
|
seasons = SeasonRanking.objects.all().distinct('season').order_by(
|
||||||
'season')
|
'season')
|
||||||
seasons = seasons.values_list('season', flat=True)
|
seasons = seasons.values_list('season', flat=True)
|
||||||
return seasons
|
return seasons
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def location(season):
|
def location(season, **kwargs):
|
||||||
return reverse('mahjong-ladder', kwargs={'season': season})
|
return reverse('mahjong-ladder', kwargs={'season': season})
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|||||||
120
src/mahjong_ranking/templates/mahjong_ranking/eventhanchan_form.html
Executable file
120
src/mahjong_ranking/templates/mahjong_ranking/eventhanchan_form.html
Executable file
@@ -0,0 +1,120 @@
|
|||||||
|
{% extends "events/event_detail.html" %}{% load i18n humanize thumbnail %}
|
||||||
|
|
||||||
|
{% block title %}Hanchans: {{ event.name }}{% endblock %}
|
||||||
|
|
||||||
|
{% block extra_head %}
|
||||||
|
<script type="text/javascript" src="{{ STATIC_URL }}js/jquery.min.js"></script>
|
||||||
|
<script type="text/javascript" src="{{ STATIC_URL }}js/jquery.formset.js"></script>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block maincontent %}
|
||||||
|
<h2 class="grid_12">{% trans 'Edit Hanchans' %}</h2>
|
||||||
|
|
||||||
|
<form method="post" action="" id="eventhanchan_form">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ formset.management_form }}
|
||||||
|
|
||||||
|
{% for form in formset %}
|
||||||
|
<fieldset class="hanchan">
|
||||||
|
{% for hidden in form.hidden_fields %} {{ hidden }} {% endfor %}
|
||||||
|
<p>
|
||||||
|
<label for="{{ form.start.if_for_label }}" class="field_name {{ form.start.css_classes }}">{{ form.start.label }}:</label>
|
||||||
|
{{ form.start }}
|
||||||
|
{{ form.start.errors }}
|
||||||
|
</p>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>{{form.player1.label}}</th>
|
||||||
|
<th>{{form.player2.label}}</th>
|
||||||
|
<th>{{form.player3.label}}</th>
|
||||||
|
<th>{{form.player4.label}}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tr>
|
||||||
|
<td>{{ form.player1 }}</td>
|
||||||
|
<td>{{ form.player2 }}</td>
|
||||||
|
<td>{{ form.player3 }}</td>
|
||||||
|
<td>{{ form.player4 }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{{ form.player1_input_score }}</td>
|
||||||
|
<td>{{ form.player2_input_score }}</td>
|
||||||
|
<td>{{ form.player3_input_score }}</td>
|
||||||
|
<td>{{ form.player4_input_score }}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<label class="field_name {{ form.comment.css_classes }}">{% trans 'Total' %}:</label>
|
||||||
|
<input type="number" value="0" name="total_score" disabled>
|
||||||
|
<label>{% trans 'Difference' %}:</label>
|
||||||
|
<span class="difference"></span>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
<p><label for="id_{{ form.comment.html_name }}" class="field_name {{ form.comment.css_classes }}">{{ form.comment.label }}:</label>
|
||||||
|
{{ form.comment }}
|
||||||
|
{{ form.comment.errors }}
|
||||||
|
</p>
|
||||||
|
{% if form.instance.pk %}
|
||||||
|
<p>
|
||||||
|
<label for="id_{{ form.DELETE.html_name }}" class="field_name {{ form.DELETE.css_classes }}">{{ form.DELETE.label }}:</label>
|
||||||
|
{{ form.DELETE }} {{form.DELETE.help_text}}
|
||||||
|
{{ form.DELETE.errors }}
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
{% if form.non_field_errors %}
|
||||||
|
<p> {{ form.non_field_errors }}</p>
|
||||||
|
{% endif %}
|
||||||
|
</fieldset>
|
||||||
|
{% endfor %}
|
||||||
|
</form>
|
||||||
|
<script type="text/javascript">
|
||||||
|
function autofill(row) {
|
||||||
|
row.find("input[id$='start_0']").val('{{ event.start|date:"SHORT_DATE_FORMAT"}}');
|
||||||
|
row.find("input[id$='start_1']").val('{{ event.start|time:'TIME_FORMAT'}}');
|
||||||
|
}
|
||||||
|
|
||||||
|
function recalculate_score(element) {
|
||||||
|
var difference = 100000
|
||||||
|
var total = 0;
|
||||||
|
score_fields = $(element).closest('fieldset').find('input[name$="input_score"]')
|
||||||
|
total_field = $(element).closest('fieldset').find('input[name$="total_score"]')
|
||||||
|
difference_field = $(element).closest('fieldset').find('span[class="difference"]')
|
||||||
|
score_fields.each(function() {total += Number($(this).val());});
|
||||||
|
total_field.val(total)
|
||||||
|
|
||||||
|
difference = 100000 - total
|
||||||
|
if (difference > 0) {
|
||||||
|
differnence_text = difference + ' offen'
|
||||||
|
} else if (difference < 0) {
|
||||||
|
differnence_text = (0 - difference) + ' zu viel'
|
||||||
|
} else {
|
||||||
|
differnence_text = 'Ok'
|
||||||
|
}
|
||||||
|
difference_field.text(differnence_text)
|
||||||
|
}
|
||||||
|
|
||||||
|
$(function() {
|
||||||
|
$('.hanchan').formset({
|
||||||
|
prefix: '{{ formset.prefix }}',
|
||||||
|
added: autofill,
|
||||||
|
addText: '<span class="fa fa-plus-circle"></span> {% trans 'Add Hanchan' %}',
|
||||||
|
addCssClass: 'button',
|
||||||
|
deleteText:'<span class="fa fa-trash"></span> {% trans 'Delete Hanchan' %}',
|
||||||
|
deleteCssClass: 'button'
|
||||||
|
});
|
||||||
|
})
|
||||||
|
$('input[name$="_input_score"]').change(function() {recalculate_score(this);});
|
||||||
|
$('input[name$="_input_score"]').keyup(function() {recalculate_score(this);});
|
||||||
|
$('input[name$="total_score"]').each(function() {recalculate_score(this);});
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block comments %}{% endblock %}
|
||||||
|
|
||||||
|
{% block buttonbar %}
|
||||||
|
<a class="button" href="{% url 'event-hanchan-list' event.pk %}"><span class="fa fa-undo"></span> {% trans 'back' %}</a>
|
||||||
|
<button type="submit" form="eventhanchan_form"><span class="fa fa-hdd-o"></span> {% trans 'save' %}</button>
|
||||||
|
{% endblock %}
|
||||||
@@ -52,6 +52,7 @@
|
|||||||
{% block buttonbar %}
|
{% block buttonbar %}
|
||||||
{% if perms.mahjong_ranking.add_hanchan %}
|
{% if perms.mahjong_ranking.add_hanchan %}
|
||||||
<a class="button" href="{{event.get_edit_url}}"><span class="fa fa-pencil"></span> {% trans 'Edit Event' %}</a>
|
<a class="button" href="{{event.get_edit_url}}"><span class="fa fa-pencil"></span> {% trans 'Edit Event' %}</a>
|
||||||
|
<a class="button" href="{% url 'event-hanchan-form' event.id %}"><span class="fa fa-pencil"></span> {% trans 'Edit Hanchans' %}</a>
|
||||||
<a class="button" href="{% url 'add-hanchan-form' event.id %}"><span class="fa fa-plus-circle"></span> {% trans 'Add Hanchan' %}</a>
|
<a class="button" href="{% url 'add-hanchan-form' event.id %}"><span class="fa fa-plus-circle"></span> {% trans 'Add Hanchan' %}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
<h3 class="grid_12" id="{{ hanchan.pk }}">{{hanchan.start|time:'H:i'}}: {{ hanchan.player_names }}</h3>
|
<h3 class="grid_12" id="{{ hanchan.pk }}">{{hanchan.start|time:'H:i'}}: {{ hanchan.player_names }}</h3>
|
||||||
{% for player in hanchan.player_list %}
|
{% for player in hanchan.player_list %}
|
||||||
<a class="grid_1" href="{% url 'player-ladder-score' player.user %}"><img
|
<a class="grid_1" href="{% url 'player-ladder-score' player.user %}"><img
|
||||||
src="{% thumbnail user.avatar|default:'unknown_profile.jpg' 'avatar' %}"
|
src="{% thumbnail player.user.avatar|default:'unknown_profile.jpg' 'avatar' %}"
|
||||||
width="70" height="70"
|
width="70" height="70"
|
||||||
class="avatar" alt="{{ player.user }}" title="{{ player.user }}"/></a>
|
class="avatar" alt="{{ player.user }}" title="{{ player.user }}"/></a>
|
||||||
<div class="grid_2">
|
<div class="grid_2">
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
<legend>{% trans "Delete Hanchan" %}</legend>
|
<legend>{% trans "Delete Hanchan" %}</legend>
|
||||||
{% include 'form.html' %}
|
{% include 'form.html' %}
|
||||||
<label class="field_name fa fa-exclamation-triangle fa-5x fa-pull-left" ></label>
|
<label class="field_name fa fa-exclamation-triangle fa-5x fa-pull-left" ></label>
|
||||||
<p>Bist du sicher dass du diese Hanchan und alle Ergebnisse und Wertungen welche sich hierauf beziehen löschen möchtest?</p>
|
<p>Bist du sicher, dass du diese Hanchan und alle Ergebnisse und Wertungen, welche sich hierauf beziehen löschen möchtest?</p>
|
||||||
<br class="clear">
|
<br class="clear">
|
||||||
<p class="buttonbar">
|
<p class="buttonbar">
|
||||||
<button type="button" onclick="window.history.back()"><span class="fa fa-close"></span> {% trans 'Cancel' %}</button>
|
<button type="button" onclick="window.history.back()"><span class="fa fa-close"></span> {% trans 'Cancel' %}</button>
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
{% extends "mahjong_ranking/page.html" %}
|
{% extends "mahjong_ranking/page.html" %}
|
||||||
{% load i18n thumbnail %}
|
{% load i18n thumbnail %}
|
||||||
|
|
||||||
{% block title %}{% trans 'Player List' %}{% endblock %}
|
{% block title %}{% trans 'Players list' %}{% endblock %}
|
||||||
{% block extra_head %}
|
{% block extra_head %}
|
||||||
<link rel="canonical" href="{% url 'kyudanranking-list' %}?page={{page_obj.number}}" />
|
<link rel="canonical" href="{% url 'kyudanranking-list' %}?page={{page_obj.number}}" />
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block teaser %}<h1>{% trans 'Player List' %}</h1>{% endblock %}
|
{% block teaser %}<h1>{% trans 'Players list' %}</h1>{% endblock %}
|
||||||
|
|
||||||
{% block redbox %}{% include 'mahjong_ranking/ladder_redbox.html' %}{% endblock %}
|
{% block redbox %}{% include 'mahjong_ranking/ladder_redbox.html' %}{% endblock %}
|
||||||
|
|
||||||
@@ -20,11 +20,6 @@
|
|||||||
{% trans 'Nickname' %}
|
{% trans 'Nickname' %}
|
||||||
<a href="{% url 'kyudanranking-list' order_by='-username' %}?page={{page_obj.number}}" class="fa fa-sort-desc" rel="nofollow"></a>
|
<a href="{% url 'kyudanranking-list' order_by='-username' %}?page={{page_obj.number}}" class="fa fa-sort-desc" rel="nofollow"></a>
|
||||||
</th>
|
</th>
|
||||||
<th>
|
|
||||||
<a href="{% url 'kyudanranking-list' order_by='+full_name'%}?page={{page_obj.number}}" class="fa fa-sort-asc" rel="nofollow"></a>
|
|
||||||
{% trans 'Full Name' %}
|
|
||||||
<a href="{% url 'kyudanranking-list' order_by='-full_name' %}?page={{page_obj.number}}" class="fa fa-sort-desc" rel="nofollow"></a>
|
|
||||||
</th>
|
|
||||||
<th>
|
<th>
|
||||||
<a href="{% url 'kyudanranking-list' order_by='+rank' %}?page={{page_obj.number}}" class="fa fa-sort-asc" rel="nofollow"></a>
|
<a href="{% url 'kyudanranking-list' order_by='+rank' %}?page={{page_obj.number}}" class="fa fa-sort-asc" rel="nofollow"></a>
|
||||||
{% trans 'Rank' %}
|
{% trans 'Rank' %}
|
||||||
@@ -51,7 +46,6 @@
|
|||||||
width="70" height="70" alt="" /></a>
|
width="70" height="70" alt="" /></a>
|
||||||
</td>
|
</td>
|
||||||
<td><a href="{{ ranking.get_absolute_url }}">{{ ranking.user }}</a></td>
|
<td><a href="{{ ranking.get_absolute_url }}">{{ ranking.user }}</a></td>
|
||||||
<td>{% if user.is_authenticated %}{{ranking.user.last_name}} {{ranking.user.first_name}}{% else %}---{% endif %}</td>
|
|
||||||
<td>{% if ranking.dan %} {{ranking.dan}}. Dan {% else %} {{ranking.kyu}} Kyu {% endif %}</td>
|
<td>{% if ranking.dan %} {{ranking.dan}}. Dan {% else %} {{ranking.kyu}} Kyu {% endif %}</td>
|
||||||
<td class="right">{% if ranking.dan %} {{ranking.dan_points}} {% else %} {{ranking.kyu_points}} {% endif %}</td>
|
<td class="right">{% if ranking.dan %} {{ranking.dan_points}} {% else %} {{ranking.kyu_points}} {% endif %}</td>
|
||||||
<td class="right">{{ranking.hanchan_count}}</td>
|
<td class="right">{{ranking.hanchan_count}}</td>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
{% for hanchan in latest_hanchan_list %}
|
{% for hanchan in latest_hanchan_list %}
|
||||||
<li><span class="fa-li fa fa-table"></span>
|
<li><span class="fa-li fa fa-table"></span>
|
||||||
<a href="{% url 'event-hanchan-list' hanchan.event_id %}">
|
<a href="{% url 'event-hanchan-list' hanchan.event_id %}">
|
||||||
<time datetime="{{ hanchan.start|date:'c' }}">{{ hanchan.start|date:'D' }}
|
<time datetime="{{ hanchan.start|date:'Y-m-d\TH:i:sO' }}">{{ hanchan.start|date:'D' }}
|
||||||
{{ hanchan.start|date:'SHORT_DATE_FORMAT' }} {{hanchan.start|time:'H:i'}}
|
{{ hanchan.start|date:'SHORT_DATE_FORMAT' }} {{hanchan.start|time:'H:i'}}
|
||||||
</time></a>:<br />
|
</time></a>:<br />
|
||||||
<small>{{hanchan.player_names}}</small>
|
<small>{{hanchan.player_names}}</small>
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
<li>
|
<li>
|
||||||
<span class="fa-li fa fa-calendar-o"></span>
|
<span class="fa-li fa fa-calendar-o"></span>
|
||||||
<a href="{% url 'event-hanchan-list' event.pk %}">
|
<a href="{% url 'event-hanchan-list' event.pk %}">
|
||||||
<time datetime="{{event.start|date:'c'}}">{{ event.start|date:'D' }} {{ event.start|date:'SHORT_DATE_FORMAT' }}</time>:
|
<time datetime="{{event.start|date:'Y-m-d\TH:i:sO'}}">{{ event.start|date:'D' }} {{ event.start|date:'SHORT_DATE_FORMAT' }}</time>:
|
||||||
{{event.name}}</a></li>
|
{{event.name}}</a></li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
{% for season_link in season_list%}
|
{% for season_link in season_list%}
|
||||||
<option
|
<option
|
||||||
value="{% url 'mahjong-ladder' season_link %}"
|
value="{% url 'mahjong-ladder' season_link %}"
|
||||||
{% ifequal season season_link %} selected="selected"{% endifequal %}>{{ season_link }}
|
selected="selected">{{ season_link }}
|
||||||
</option>
|
</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
|
|||||||
@@ -52,7 +52,7 @@
|
|||||||
</table>
|
</table>
|
||||||
|
|
||||||
{% if kyu_dan_ranking.legacy_date %}
|
{% if kyu_dan_ranking.legacy_date %}
|
||||||
<p><strong>Frühere Dan Punkte vom {{ kyu_dan_ranking.legacy_date|date }}:</strong> {{kyu_dan_ranking.legacy_dan_points }}</p>
|
<p><strong>Frühere Dan Punkte vom {{kyu_dan_ranking.legacy_date|date}}:</strong> {{kyu_dan_ranking.legacy_dan_points}}</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|||||||
@@ -64,7 +64,7 @@
|
|||||||
<select id="season" name="season" size="1">
|
<select id="season" name="season" size="1">
|
||||||
{% for season_link in season_list%}
|
{% for season_link in season_list%}
|
||||||
<option
|
<option
|
||||||
{% ifequal season season_link %} selected="selected"{% endifequal %}
|
selected="selected"
|
||||||
value="{{ season_link }}">{{ season_link }}</option>
|
value="{{ season_link }}">{{ season_link }}</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
@@ -75,5 +75,5 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block buttonbar %}
|
{% block buttonbar %}
|
||||||
<a href="?download=xlsx" class="button"><span class="fa fa-table"></span> Download</a>
|
<a href="?download=xlsx{% if season %}&season={{ season }}{% endif %}" class="button"><span class="fa fa-table"></span> Download</a>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@@ -23,7 +23,6 @@
|
|||||||
<th rowspan="2">{% trans "Rank" %}</th>
|
<th rowspan="2">{% trans "Rank" %}</th>
|
||||||
<th rowspan="2">{% trans "Avatar" %}</th>
|
<th rowspan="2">{% trans "Avatar" %}</th>
|
||||||
<th rowspan="2">{% trans "Nickname" %}</th>
|
<th rowspan="2">{% trans "Nickname" %}</th>
|
||||||
<th rowspan="2">{% trans "Name" %}</th>
|
|
||||||
<th colspan="2">{% trans 'Average' %}</th>
|
<th colspan="2">{% trans 'Average' %}</th>
|
||||||
<th colspan="3">Hanchans</th>
|
<th colspan="3">Hanchans</th>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -42,7 +41,6 @@
|
|||||||
src="{% thumbnail player.user.avatar|default:'unknown_profile.jpg' 'avatar' %}"
|
src="{% thumbnail player.user.avatar|default:'unknown_profile.jpg' 'avatar' %}"
|
||||||
width="70" height="70" class="avatar" alt=""/></a></td>
|
width="70" height="70" class="avatar" alt=""/></a></td>
|
||||||
<td><a href="{{ player.get_absolute_url }}?season={{season}}">{{player.user}}</a></td>
|
<td><a href="{{ player.get_absolute_url }}?season={{season}}">{{player.user}}</a></td>
|
||||||
<td>{% if user.is_authenticated %}{{player.user.last_name}} {{player.user.first_name}}{% else %}---{% endif %}</td>
|
|
||||||
<td class="center">{{player.avg_placement|floatformat:2 }}</td>
|
<td class="center">{{player.avg_placement|floatformat:2 }}</td>
|
||||||
<td class="right">{{player.avg_score|floatformat:0|intcomma }}</td>
|
<td class="right">{{player.avg_score|floatformat:0|intcomma }}</td>
|
||||||
<td class="right">{{player.hanchan_count}}</td>
|
<td class="right">{{player.hanchan_count}}</td>
|
||||||
@@ -51,8 +49,8 @@
|
|||||||
</tr>
|
</tr>
|
||||||
{% empty %}
|
{% empty %}
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="9">Leider hat es noch niemand in das Ranking geschafft.
|
<td colspan="8">Leider hat es noch niemand in das Ranking geschafft.
|
||||||
Ein Spieler wird erst ins Ranking genommen wenn er 5 Hanchans absolviert hat.
|
Spieler werden erst ins Ranking genommen, wenn sie 5 Hanchans absolviert haben.
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|||||||
@@ -97,7 +97,6 @@ class KyuDanTest(TestCase):
|
|||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
points[dan_kyu],
|
points[dan_kyu],
|
||||||
getattr(ranking, dan_kyu),
|
getattr(ranking, dan_kyu),
|
||||||
"{dan_kyu} for {player} won't compute! ranking: {ranking}, sum: {sum}".format(
|
f"{dan_kyu} for {ranking.user} won't compute! " +
|
||||||
dan_kyu=dan_kyu, player=ranking.user,
|
f"ranking: {ranking.dan_kyu}, sum: {points[dan_kyu]}"
|
||||||
ranking=getattr(ranking, dan_kyu), sum=points[dan_kyu])
|
|
||||||
)
|
)
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user