Velká revize stylů (a některých JS) #44
219 changed files with 499 additions and 809 deletions
12
.gitignore
vendored
12
.gitignore
vendored
|
@ -31,9 +31,15 @@ TODO
|
||||||
# reversion kvůli historii objektů v reversion
|
# reversion kvůli historii objektů v reversion
|
||||||
**/reversion
|
**/reversion
|
||||||
|
|
||||||
|
# dokumentace
|
||||||
|
docs/_build
|
||||||
|
docs/modules
|
||||||
|
|
||||||
|
# logy týracího skriptu (./checklinks.sh)
|
||||||
|
/wget.log.*
|
||||||
|
|
||||||
# pro lidi, co programují v nástrojích od JetBrains
|
# pro lidi, co programují v nástrojích od JetBrains
|
||||||
.idea
|
.idea
|
||||||
|
|
||||||
# dokumentace
|
# Mac users
|
||||||
docs/_build
|
.DS_Store
|
||||||
docs/modules
|
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
git hooks
|
|
||||||
=========
|
|
||||||
|
|
||||||
Kontrola stylu pythoních zdrojáků pomocí flake8. Kontrolujeme jen změny,
|
|
||||||
abychom nenutili lidi dělat nesouvisející úpravy, které by rozbíjely historii
|
|
||||||
(git blame).
|
|
||||||
|
|
||||||
pre-commit
|
|
||||||
----------
|
|
||||||
* kontrola změn před commitnutím
|
|
||||||
* instalace: lokálně zkopírovat do .git/hooks (musí být spustitelný)
|
|
||||||
|
|
||||||
update
|
|
||||||
------
|
|
||||||
* kontrola změn přicházejících s pushem
|
|
||||||
* instalace: na atreyi zkopírovat do /akce/MaM/MaMweb/mamweb.git/hooks
|
|
|
@ -1,30 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
#
|
|
||||||
# Git hook script to verify what is about to be committed.
|
|
||||||
# Checks that the changes don't introduce new flake8 errors.
|
|
||||||
|
|
||||||
TMPDIFF=`tempfile`
|
|
||||||
FLAKE8="`git rev-parse --show-toplevel`/bin/flake8"
|
|
||||||
|
|
||||||
status=0
|
|
||||||
|
|
||||||
# select only changed python files which are not migrations
|
|
||||||
changed=`git diff --cached --name-only | grep 'py$' | grep -v 'migrations/[0-9]'`
|
|
||||||
if [ -z $changed ] ; then
|
|
||||||
# Nothing to check. Note the exit is necessary -- we would not pass any
|
|
||||||
# paths to git diff below and it would output the diff unfiltered.
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
git diff --unified=1 --cached HEAD -- $changed > $TMPDIFF
|
|
||||||
|
|
||||||
# only do the check when there are some changes to be commited
|
|
||||||
# otherwise flake8 would hang waiting for input
|
|
||||||
if [ -s $TMPDIFF ] ; then
|
|
||||||
cat $TMPDIFF | $FLAKE8 --diff
|
|
||||||
status=$?
|
|
||||||
fi
|
|
||||||
|
|
||||||
rm -f $TMPDIFF
|
|
||||||
|
|
||||||
exit $status
|
|
|
@ -1,61 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# git update hook to check that pushed changes don't introduce new flake8
|
|
||||||
# errors
|
|
||||||
|
|
||||||
# --- Command line
|
|
||||||
refname="$1"
|
|
||||||
oldrev="$2"
|
|
||||||
newrev="$3"
|
|
||||||
|
|
||||||
# --- Safety check
|
|
||||||
if [ -z "$GIT_DIR" ]; then
|
|
||||||
echo "Don't run this script from the command line." >&2
|
|
||||||
echo " (if you want, you could supply GIT_DIR then run" >&2
|
|
||||||
echo " $0 <ref> <oldrev> <newrev>)" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then
|
|
||||||
echo "usage: $0 <ref> <oldrev> <newrev>" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
TMPDIR=`mktemp -d`
|
|
||||||
TMPDIFF=`tempfile`
|
|
||||||
|
|
||||||
[ $refname != "refs/heads/master" -a $refname != "refs/heads/stable" ] && exit 0
|
|
||||||
|
|
||||||
# select only changed python files which are not migrations
|
|
||||||
changed=`git diff --name-only $oldrev $newrev | grep 'py$' | grep -v 'migrations/[0-9]'`
|
|
||||||
if [ -z $changed ] ; then
|
|
||||||
# Nothing to check. Note the exit is necessary -- we would not pass any
|
|
||||||
# paths to git diff below and it would output the diff unfiltered.
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
git diff --unified=1 $oldrev $newrev -- $changed >${TMPDIFF}
|
|
||||||
|
|
||||||
# there is no working tree in bare git repository, so we recreate it for flake8
|
|
||||||
git archive $newrev | tar -x -C ${TMPDIR}
|
|
||||||
|
|
||||||
cd ${TMPDIR}
|
|
||||||
# report only errors on lines in diff
|
|
||||||
# (if threre was flake8 installed on atrey, we could just call flake8)
|
|
||||||
/akce/MaM/WWW/mamweb-test/bin/flake8 --diff <${TMPDIFF}
|
|
||||||
status=$?
|
|
||||||
if [ $status != 0 ] ; then
|
|
||||||
echo
|
|
||||||
echo -n "Změny, které se snažíte pushnout, obsahují kód v pythonu "
|
|
||||||
echo -n "nevyhovující flake8 (viz výše). Opravte je a zkuste to znovu. "
|
|
||||||
echo -n "Nezapomeňte, že můžete editovat historii (git commit --amend, "
|
|
||||||
echo -n "git rebase -i). Pokud byste chybu příště raději odhalili už při "
|
|
||||||
echo "commitu, zkopírujte si pre-commit hook z _git_hooks do .git/hooks."
|
|
||||||
echo
|
|
||||||
fi
|
|
||||||
|
|
||||||
rm -rf ${TMPDIR}
|
|
||||||
rm -f ${TMPDIFF}
|
|
||||||
|
|
||||||
exit $status
|
|
|
@ -1,8 +1,5 @@
|
||||||
"""
|
|
||||||
Soubor sloužící k pojmenování a jiným nastavením djangovské aplikace.
|
|
||||||
"""
|
|
||||||
from django.apps import AppConfig
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
class AesopConfig(AppConfig):
|
class AesopConfig(AppConfig):
|
||||||
name = 'aesop'
|
name = 'aesop'
|
||||||
|
verbose_name = 'Export do AESOPa'
|
||||||
|
|
|
@ -1,10 +1,3 @@
|
||||||
"""
|
|
||||||
Soubor sloužící jako „router“, tj. zde se definují url adresy a na co ukazují:
|
|
||||||
|
|
||||||
- ``aesop-export/mam-rocnik-<int:prvni_rok>.csv`` (seminar_export_rocnik) :class:`~aesop.views.ExportRocnikView`
|
|
||||||
- ``aesop-export/mam-sous-<str:datum_zacatku>.csv`` (seminar_export_sous) :class:`~aesop.views.ExportSousView`
|
|
||||||
- ``aesop-export/index.csv`` (seminar_export_index) :class:`~aesop.views.ExportIndexView`
|
|
||||||
"""
|
|
||||||
from django.urls import path
|
from django.urls import path
|
||||||
from aesop import views
|
from aesop import views
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
"""
|
|
||||||
Soubor sloužící k deklaraci jednotlivých „views“ (nejčastěji funkce beroucí request
|
|
||||||
a vracející :func:`django.shortcuts.render` respektive nějakou response, nebo
|
|
||||||
třídy většinou rozšiřující nějakou třídu z :mod:`django.views.generic`)
|
|
||||||
"""
|
|
||||||
import django
|
import django
|
||||||
from django.shortcuts import get_object_or_404
|
from django.shortcuts import get_object_or_404
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
"""
|
|
||||||
Soubor sloužící k pojmenování a jiným nastavením djangovské aplikace.
|
|
||||||
"""
|
|
||||||
from django.apps import AppConfig
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
class ApiConfig(AppConfig):
|
class ApiConfig(AppConfig):
|
||||||
name = 'api'
|
name = 'api'
|
||||||
|
verbose_name = 'Různá webová API'
|
||||||
|
|
12
api/urls.py
12
api/urls.py
|
@ -1,15 +1,3 @@
|
||||||
"""
|
|
||||||
Soubor sloužící jako „router“, tj. zde se definují url adresy a na co ukazují:
|
|
||||||
|
|
||||||
- ``api/expor/skoly/`` (export_skoly) :func:`~api.views.exports.exportSkolView`
|
|
||||||
- ``api/autocomplete/skola/`` (autocomplete_skola) :class:`~api.views.autocomplete.SkolaAutocomplete`
|
|
||||||
- ``api/autocomplete/resitel/`` (autocomplete_resitel) :class:`~api.views.autocomplete.ResitelAutocomplete`
|
|
||||||
- ``api/autocomplete/problem/odevzdatelny`` (autocomplete_problem_odevzdatelny) :class:`~api.views.autocomplete.OdevzdatelnyProblemAutocomplete`
|
|
||||||
|
|
||||||
Na autocomplete v3 čeká:
|
|
||||||
|
|
||||||
- ``autocomplete/organizatori/`` (seminar_autocomplete_organizator) :class:`~api.views.autocomplete.OrganizatorAutocomplete`
|
|
||||||
"""
|
|
||||||
from django.urls import path
|
from django.urls import path
|
||||||
from . import views
|
from . import views
|
||||||
from seminar.utils import org_required
|
from seminar.utils import org_required
|
||||||
|
|
|
@ -1,7 +1,2 @@
|
||||||
"""
|
|
||||||
Soubory sloužící k deklaraci jednotlivých „views“ (nejčastěji funkce beroucí request
|
|
||||||
a vracející :func:`django.shortcuts.render` respektive nějakou response, nebo
|
|
||||||
třídy většinou rozšiřující nějakou třídu z :mod:`django.views.generic`)
|
|
||||||
"""
|
|
||||||
from .autocomplete import *
|
from .autocomplete import *
|
||||||
from .exports import *
|
from .exports import *
|
||||||
|
|
|
@ -1079,5 +1079,29 @@
|
||||||
},
|
},
|
||||||
"model": "sitetree.treeitem",
|
"model": "sitetree.treeitem",
|
||||||
"pk": 53
|
"pk": 53
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fields": {
|
||||||
|
"access_guest": false,
|
||||||
|
"access_loggedin": false,
|
||||||
|
"access_perm_type": 1,
|
||||||
|
"access_permissions": [],
|
||||||
|
"access_restricted": true,
|
||||||
|
"alias": null,
|
||||||
|
"description": "",
|
||||||
|
"hidden": false,
|
||||||
|
"hint": "",
|
||||||
|
"inbreadcrumbs": true,
|
||||||
|
"inmenu": true,
|
||||||
|
"insitetree": true,
|
||||||
|
"parent": 20,
|
||||||
|
"sort_order": 54,
|
||||||
|
"title": "Export do abstraktů sousu {{ soustredeni.id }}",
|
||||||
|
"tree": 1,
|
||||||
|
"url": "seminar_soustredeni_abstrakty soustredeni.id",
|
||||||
|
"urlaspattern": true
|
||||||
|
},
|
||||||
|
"model": "sitetree.treeitem",
|
||||||
|
"pk": 54
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -331,22 +331,22 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"codename": "add_novinky",
|
"codename": "add_novinky",
|
||||||
"ct_app_label": "seminar",
|
"ct_app_label": "novinky",
|
||||||
"ct_model": "novinky"
|
"ct_model": "novinky"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"codename": "change_novinky",
|
"codename": "change_novinky",
|
||||||
"ct_app_label": "seminar",
|
"ct_app_label": "novinky",
|
||||||
"ct_model": "novinky"
|
"ct_model": "novinky"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"codename": "delete_novinky",
|
"codename": "delete_novinky",
|
||||||
"ct_app_label": "seminar",
|
"ct_app_label": "novinky",
|
||||||
"ct_model": "novinky"
|
"ct_model": "novinky"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"codename": "view_novinky",
|
"codename": "view_novinky",
|
||||||
"ct_app_label": "seminar",
|
"ct_app_label": "novinky",
|
||||||
"ct_model": "novinky"
|
"ct_model": "novinky"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,12 +9,6 @@ static
|
||||||
------
|
------
|
||||||
Složka, kam django nakopíruje všechno ze složek static a pak na to z templatů / kódu jde ukazovat pomocí ``static``.
|
Složka, kam django nakopíruje všechno ze složek static a pak na to z templatů / kódu jde ukazovat pomocí ``static``.
|
||||||
|
|
||||||
_git_hooks
|
|
||||||
----------
|
|
||||||
Hooky do gitu pro kontrolu Pythoního stylu. Především ``flake8``.
|
|
||||||
|
|
||||||
Zbylo tu z minulosti mamwebu.
|
|
||||||
|
|
||||||
data
|
data
|
||||||
----
|
----
|
||||||
Obsahuje data, která patří do databáze, ale jsou přímo součástí webu jako
|
Obsahuje data, která patří do databáze, ale jsou přímo součástí webu jako
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
FIXME přepsat do rst, přidat i další věci a případně přesunout na wiki
|
||||||
Přidání obrázků do odměn:
|
Přidání obrázků do odměn:
|
||||||
admin -> flatpage odměn -> ikona přidat obrázek
|
admin -> flatpage odměn -> ikona přidat obrázek
|
||||||
záložka odeslat, vybrat obrázek, odeslat
|
záložka odeslat, vybrat obrázek, odeslat
|
25
galerie/TODO
25
galerie/TODO
|
@ -1,25 +0,0 @@
|
||||||
========
|
|
||||||
| TODO |
|
|
||||||
|======|
|
|
||||||
|
|
||||||
Aktualni
|
|
||||||
* co s titulni fotkou
|
|
||||||
* do CSS
|
|
||||||
* nahledy
|
|
||||||
* nastylovat tabulku s nahledy
|
|
||||||
* komentare uz na nahledy?
|
|
||||||
* detail
|
|
||||||
* nahledy pred a po
|
|
||||||
* opravit prechodove sipky
|
|
||||||
* vyrobit prechodove sipky ve M&M-stylu
|
|
||||||
|
|
||||||
Dlouhodobe
|
|
||||||
* sipky na prechazeni mezi fotkami
|
|
||||||
* hromadne PRIDANI fotek do jiz existujici galerie
|
|
||||||
|
|
||||||
Fylozoficke
|
|
||||||
* zvolit velikosti velke a male fotky
|
|
||||||
* je potreba i jine razeni nez automaticky podle casu nebo staci podgalerie?
|
|
||||||
* napr. dve hry na dvou ruznych mistech ve stejny cas
|
|
||||||
* fotky od ucastniku ze hry (skupinky se pohybuji ve stejny cas, ale maji sled fotek) -- nestaci to pripadne vrazit do podgalerii?
|
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
#coding: utf-8
|
|
||||||
|
|
||||||
from galerie.models import Obrazek, Galerie
|
from galerie.models import Obrazek, Galerie
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponseRedirect
|
||||||
|
|
|
@ -1,47 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
from autocomplete_light import shortcuts as autocomplete_light
|
|
||||||
|
|
||||||
from .models import Obrazek, Galerie
|
|
||||||
from .views import cesta_od_korene
|
|
||||||
|
|
||||||
|
|
||||||
class ObrazekAutocomplete(autocomplete_light.AutocompleteModelBase):
|
|
||||||
|
|
||||||
model = Obrazek
|
|
||||||
search_fields = ['nazev', 'popis']
|
|
||||||
split_words = True
|
|
||||||
limit_choices = 15
|
|
||||||
attrs = {
|
|
||||||
# This will set the input placeholder attribute:
|
|
||||||
'placeholder': u'Obrázek',
|
|
||||||
# This will set the yourlabs.Autocomplete.minimumCharacters
|
|
||||||
# options, the naming conversion is handled by jQuery
|
|
||||||
'data-autocomplete-minimum-characters': 1,
|
|
||||||
}
|
|
||||||
|
|
||||||
choice_html_format = '''
|
|
||||||
<span class="block" data-value="{}">
|
|
||||||
<span class="block">
|
|
||||||
{}
|
|
||||||
<span class="block">{}</span>
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
'''
|
|
||||||
|
|
||||||
def choice_label(self, obrazek):
|
|
||||||
cesta = "/".join(g.nazev for g in cesta_od_korene(obrazek.galerie))
|
|
||||||
popis = "{}<br>".format(obrazek.popis) if obrazek.popis else ""
|
|
||||||
return '{}<br>{}{}'.format(obrazek.nazev, popis, cesta)
|
|
||||||
|
|
||||||
def choice_html(self, obrazek):
|
|
||||||
"""Vrátí kus html i s obrázkem, které se pak ukazuje v nabídce"""
|
|
||||||
return self.choice_html_format.format(self.choice_value(obrazek),
|
|
||||||
obrazek.obrazek_maly_tag(), self.choice_label(obrazek))
|
|
||||||
|
|
||||||
widget_attrs={
|
|
||||||
'data-widget-maximum-values': 15,
|
|
||||||
'class': 'modern-style',
|
|
||||||
}
|
|
||||||
|
|
||||||
autocomplete_light.register(ObrazekAutocomplete)
|
|
|
@ -1,5 +1,3 @@
|
||||||
#coding: utf-8
|
|
||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
from seminar.models import Soustredeni
|
from seminar.models import Soustredeni
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import models, migrations
|
from django.db import models, migrations
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import models, migrations
|
from django.db import models, migrations
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import models, migrations
|
from django.db import models, migrations
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import models, migrations
|
from django.db import models, migrations
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import models, migrations
|
from django.db import models, migrations
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import models, migrations
|
from django.db import models, migrations
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import models, migrations
|
from django.db import models, migrations
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Generated by Django 1.11.20 on 2019-04-30 21:40
|
# Generated by Django 1.11.20 on 2019-04-30 21:40
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Generated by Django 1.11.21 on 2019-06-10 21:58
|
# Generated by Django 1.11.21 on 2019-06-10 21:58
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
# coding: utf-8
|
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
#from django.db.models import Q
|
#from django.db.models import Q
|
||||||
from imagekit.models import ImageSpecField
|
from imagekit.models import ImageSpecField
|
||||||
|
|
|
@ -1,12 +1,3 @@
|
||||||
"""
|
|
||||||
Soubor sloužící jako „router“, tj. zde se definují url adresy a na co ukazují:
|
|
||||||
|
|
||||||
- ``<int:pk>/`` :func:`~galerie.views.nahled`
|
|
||||||
- ``<int:pk>/<int:fotka>/`` :func:`~galerie.views.detail`
|
|
||||||
- ``<int:galerie>/new/`` :func:`~galerie.views.new_galerie`
|
|
||||||
- ``<int:galerie>/plus/<int:subgalerie>/`` :func:`~galerie.views.plus_galerie`
|
|
||||||
- ``<int:galerie>/minus/<int:subgalerie>/`` :func:`~galerie.views.minus_galerie`
|
|
||||||
"""
|
|
||||||
from django.urls import path
|
from django.urls import path
|
||||||
from seminar.utils import org_required
|
from seminar.utils import org_required
|
||||||
from . import views
|
from . import views
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
# coding: utf-8
|
|
||||||
|
|
||||||
import random
|
import random
|
||||||
|
|
||||||
from django.http import HttpResponse, Http404
|
from django.http import HttpResponse, Http404
|
||||||
|
|
|
@ -1,14 +1,3 @@
|
||||||
"""
|
|
||||||
Soubor sloužící k definici toho, co bude v adminu. Většinou pouhým zavoláním
|
|
||||||
funkce :func:`django.contrib.admin.site.register`, v případě, že chceme něco
|
|
||||||
upravit, tak jako třída rozšiřující :class:`django.contrib.admin.ModelAdmin`
|
|
||||||
s dekorátorem :func:`django.contrib.admin.register`.
|
|
||||||
|
|
||||||
Zde se definuje admin pro:
|
|
||||||
|
|
||||||
- :class:`~header_fotky.models.FotkaHeader`
|
|
||||||
- :class:`~header_fotky.models.FotkaUrlVazba`
|
|
||||||
"""
|
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.contrib.admin import ModelAdmin
|
from django.contrib.admin import ModelAdmin
|
||||||
import header_fotky.models as m
|
import header_fotky.models as m
|
||||||
|
@ -22,4 +11,4 @@ class FotkaPozadiAdmin(ModelAdmin):
|
||||||
readonly_fields = ['cas']
|
readonly_fields = ['cas']
|
||||||
|
|
||||||
admin.site.register(m.FotkaHeader, FotkaPozadiAdmin)
|
admin.site.register(m.FotkaHeader, FotkaPozadiAdmin)
|
||||||
admin.site.register(m.FotkaUrlVazba)
|
admin.site.register(m.FotkaUrlVazba)
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
"""
|
|
||||||
Soubor sloužící k pojmenování a jiným nastavením djangovské aplikace.
|
|
||||||
"""
|
|
||||||
from django.apps import AppConfig
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
class HeaderFotkyConfig(AppConfig):
|
class HeaderFotkyConfig(AppConfig):
|
||||||
name = 'header_fotky'
|
name = 'header_fotky'
|
||||||
|
verbose_name = 'Fotky v záhlaví'
|
||||||
|
|
|
@ -1,17 +1,3 @@
|
||||||
"""
|
|
||||||
Tento soubor slouží k definici databázového modelu.
|
|
||||||
|
|
||||||
Třídy rozšiřují většinou :class:`django.db.models.Model` a jejich atributy jsou
|
|
||||||
většinou sloupce v databázi (tj. nastaví se na hodnotu něčeho z :mod:`django.db.models`).
|
|
||||||
Na výběr jsou:
|
|
||||||
|
|
||||||
- :class:`django.db.models.TextField`
|
|
||||||
- :class:`django.db.models.ForeignKey`
|
|
||||||
- :class:`django.db.models.DateField`
|
|
||||||
- :class:`django.db.models.DateTimeField`
|
|
||||||
- :class:`django.db.models.ImageField`
|
|
||||||
- :class:`django.db.models.CharField`
|
|
||||||
"""
|
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
- korektura potrebuje reakci
|
|
||||||
+ komentáře fixně na username
|
|
||||||
- používat skutečné jméno?
|
|
||||||
- vyžádat pozornost autora obsahu
|
|
||||||
- zvednout upload limit na 5MB
|
|
||||||
- sbalit a rozbalit korekturu
|
|
||||||
- nahrávání jiných věcí než PDF - kontrolovat?
|
|
||||||
- stylování
|
|
||||||
- seznam PDF - co zobrazovat?
|
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,3 @@
|
||||||
"""
|
|
||||||
Soubor sloužící k definici toho, co bude v adminu. Většinou pouhým zavoláním
|
|
||||||
funkce :func:`django.contrib.admin.site.register`, v případě, že chceme něco
|
|
||||||
upravit, tak jako třída rozšiřující :class:`django.contrib.admin.ModelAdmin`
|
|
||||||
s dekorátorem :func:`django.contrib.admin.register`.
|
|
||||||
|
|
||||||
Zde se definuje admin pro:
|
|
||||||
|
|
||||||
- :class:`korektury.models.KorekturovanePDF`
|
|
||||||
"""
|
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from reversion.admin import VersionAdmin
|
from reversion.admin import VersionAdmin
|
||||||
from korektury.models import KorekturovanePDF
|
from korektury.models import KorekturovanePDF
|
||||||
|
@ -15,7 +5,6 @@ from korektury.models import KorekturovanePDF
|
||||||
from django.core.mail import EmailMessage
|
from django.core.mail import EmailMessage
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
|
||||||
# Register your models here.
|
|
||||||
class KorekturovanePDFAdmin(VersionAdmin):
|
class KorekturovanePDFAdmin(VersionAdmin):
|
||||||
"""
|
"""
|
||||||
nastaví čas vložení (:attr:`~koretkury.models.KorekturovanePDF.cas`) a počet
|
nastaví čas vložení (:attr:`~koretkury.models.KorekturovanePDF.cas`) a počet
|
||||||
|
|
|
@ -1,13 +1,3 @@
|
||||||
"""
|
|
||||||
Formuláře (:class:`django.forms.Form`) umožňují jednoduchou tvorbu formulářů,
|
|
||||||
které lze pak jednoduše dát do frontendu i zpracovat na backendu.
|
|
||||||
|
|
||||||
Pro přidání políčka do formuláře je potřeba
|
|
||||||
- mít v modelu tu položku, kterou chci upravovat
|
|
||||||
- přidat do views (prihlaskaView, resitelEditView)
|
|
||||||
- přidat do forms
|
|
||||||
- includovat do html
|
|
||||||
"""
|
|
||||||
from django import forms
|
from django import forms
|
||||||
|
|
||||||
class OpravaForm(forms.Form):
|
class OpravaForm(forms.Form):
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import models, migrations
|
from django.db import models, migrations
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import models, migrations
|
from django.db import models, migrations
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import models, migrations
|
from django.db import models, migrations
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import models, migrations
|
from django.db import models, migrations
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import models, migrations
|
from django.db import models, migrations
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import models, migrations
|
from django.db import models, migrations
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import models, migrations
|
from django.db import models, migrations
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import models, migrations
|
from django.db import models, migrations
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Generated by Django 1.11.20 on 2019-04-30 21:40
|
# Generated by Django 1.11.20 on 2019-04-30 21:40
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Generated by Django 1.11.21 on 2019-06-10 21:58
|
# Generated by Django 1.11.21 on 2019-06-10 21:58
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,3 @@
|
||||||
"""
|
|
||||||
Tento soubor slouží k definici databázového modelu.
|
|
||||||
|
|
||||||
Třídy rozšiřují většinou :class:`django.db.models.Model` a jejich atributy jsou
|
|
||||||
většinou sloupce v databázi (tj. nastaví se na hodnotu něčeho z :mod:`django.db.models`).
|
|
||||||
Na výběr jsou:
|
|
||||||
|
|
||||||
- :class:`django.db.models.TextField`
|
|
||||||
- :class:`django.db.models.ForeignKey`
|
|
||||||
- :class:`django.db.models.DateField`
|
|
||||||
- :class:`django.db.models.DateTimeField`
|
|
||||||
- :class:`django.db.models.ImageField`
|
|
||||||
- :class:`django.db.models.CharField`
|
|
||||||
"""
|
|
||||||
import os
|
import os
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
from django.test import TestCase
|
|
||||||
|
|
||||||
# Create your tests here.
|
|
|
@ -1,11 +1,3 @@
|
||||||
"""
|
|
||||||
Soubor sloužící jako „router“, tj. zde se definují url adresy a na co ukazují:
|
|
||||||
|
|
||||||
- ``korektury/`` (korektury_list) :class:`~korektury.views.KorekturySeskupeneListView`
|
|
||||||
- ``korektury/neseskupene/`` (korektury_neseskupene_list) :class:`~korektury.views.KorekturyAktualniListView`
|
|
||||||
- ``korektury/zastarale/`` (korektury_stare_list) :class:`~korektury.views.KorekturyZastaraleListView`
|
|
||||||
- ``korektury/<int:pdf>/`` (korektury) :class:`~korektury.views.KorekturyView`
|
|
||||||
"""
|
|
||||||
from django.urls import path
|
from django.urls import path
|
||||||
from seminar.utils import org_required
|
from seminar.utils import org_required
|
||||||
from . import views
|
from . import views
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
"""
|
|
||||||
Soubor sloužící k deklaraci jednotlivých „views“ (nejčastěji funkce beroucí request
|
|
||||||
a vracející :func:`django.shortcuts.render` respektive nějakou response, nebo
|
|
||||||
třídy většinou rozšiřující nějakou třídu z :mod:`django.views.generic`)
|
|
||||||
"""
|
|
||||||
from django.shortcuts import get_object_or_404, render
|
from django.shortcuts import get_object_or_404, render
|
||||||
from django.views import generic
|
from django.views import generic
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
@ -199,13 +194,6 @@ class KorekturyView(generic.TemplateView):
|
||||||
if email:
|
if email:
|
||||||
emails.discard(email)
|
emails.discard(email)
|
||||||
|
|
||||||
if not settings.POSLI_MAILOVOU_NOTIFIKACI:
|
|
||||||
print("Poslal bych upozornění na tyto adresy: ", " ".join(emails))
|
|
||||||
print("---- Upozornění:")
|
|
||||||
print(text)
|
|
||||||
print("---- Konec upozornění")
|
|
||||||
return
|
|
||||||
|
|
||||||
EmailMessage(
|
EmailMessage(
|
||||||
subject=subject,
|
subject=subject,
|
||||||
body=text,
|
body=text,
|
||||||
|
|
|
@ -7,5 +7,5 @@ make/install_web
|
||||||
ensure_venv
|
ensure_venv
|
||||||
./manage.py testdata
|
./manage.py testdata
|
||||||
./manage.py loaddata data/*
|
./manage.py loaddata data/*
|
||||||
make/sync_prod_flatpages
|
#make/sync_prod_flatpages
|
||||||
./manage.py load_org_permissions deploy_v2/admin_org_prava.json
|
./manage.py load_org_permissions deploy_v2/admin_org_prava.json
|
||||||
|
|
|
@ -42,8 +42,18 @@ def get_app_list(self, request, app_label=None):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
app_dict = self._build_app_dict(request, label=app_label)
|
app_dict = self._build_app_dict(request, label=app_label)
|
||||||
# Sort the apps alphabetically.
|
aplikace_nahore = [
|
||||||
app_list = sorted(app_dict.values(), key=lambda x: locale.strxfrm('!') if (x['name'] == "Seminar") else locale.strxfrm(x['name'].lower()))
|
'seminar',
|
||||||
|
'personalni',
|
||||||
|
'novinky',
|
||||||
|
'korektury',
|
||||||
|
'various',
|
||||||
|
'prednasky',
|
||||||
|
'soustredeni',
|
||||||
|
]
|
||||||
|
# Odhlášený admin má prázdný app_dict :-/
|
||||||
|
app_list = [app_dict[label] for label in aplikace_nahore if label in app_dict] + [app_dict[label] for label in app_dict if label not in aplikace_nahore]
|
||||||
|
|
||||||
|
|
||||||
# Sort the models alphabetically within each app.
|
# Sort the models alphabetically within each app.
|
||||||
for app in app_list:
|
for app in app_list:
|
||||||
|
|
|
@ -1,88 +0,0 @@
|
||||||
from datetime import datetime, date
|
|
||||||
|
|
||||||
from django.conf import settings
|
|
||||||
from django.http import HttpResponse, HttpResponseRedirect
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class LoggedInHintCookieMiddleware(object):
|
|
||||||
"""Middleware to securely help with 'logged-in' detection for dual HTTP/HTTPS sites.
|
|
||||||
|
|
||||||
On insecure requests: Checks for a (non-secure) cookie settings.LOGGED_IN_HINT_COOKIE_NAME
|
|
||||||
and if present, redirects to HTTPS (same adress).
|
|
||||||
Note this usually breaks non-GET (POST) requests.
|
|
||||||
|
|
||||||
On secure requests: Updates cookie settings.LOGGED_IN_HINT_COOKIE_NAME to reflect
|
|
||||||
whether an user is logged in in the current session (cookie set to 'True' or cleared).
|
|
||||||
The cookie is set to expire at the same time as the sessionid cookie.
|
|
||||||
|
|
||||||
By default, LOGGED_IN_HINT_COOKIE_NAME = 'logged_in_hint'.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
if hasattr(settings, 'LOGGED_IN_HINT_COOKIE_NAME'):
|
|
||||||
self.cookie_name = settings.LOGGED_IN_HINT_COOKIE_NAME
|
|
||||||
else: self.cookie_name = 'logged_in_hint'
|
|
||||||
self.cookie_value = 'True'
|
|
||||||
|
|
||||||
def cookie_correct(self, request):
|
|
||||||
return self.cookie_name in request.COOKIES and request.COOKIES[self.cookie_name] == self.cookie_value
|
|
||||||
|
|
||||||
def process_request(self, request):
|
|
||||||
if not request.is_secure():
|
|
||||||
if self.cookie_correct(request):
|
|
||||||
# redirect insecure (assuming http) requests with hint cookie to https
|
|
||||||
url = request.build_absolute_uri()
|
|
||||||
assert url[:5] == 'http:'
|
|
||||||
return HttpResponseRedirect('https:' + url[5:])
|
|
||||||
return None
|
|
||||||
|
|
||||||
def process_response(self, request, response):
|
|
||||||
if request.is_secure():
|
|
||||||
# assuming full session info (as the conn. is secure)
|
|
||||||
try:
|
|
||||||
user = request.user
|
|
||||||
except AttributeError: # no user - ajax or other special request
|
|
||||||
return response
|
|
||||||
if user.is_authenticated():
|
|
||||||
if not self.cookie_correct(request):
|
|
||||||
expiry = None if request.session.get_expire_at_browser_close() else request.session.get_expiry_date()
|
|
||||||
response.set_cookie(self.cookie_name, value=self.cookie_value, expires=expiry, secure=False)
|
|
||||||
else:
|
|
||||||
if self.cookie_name in request.COOKIES:
|
|
||||||
response.delete_cookie(self.cookie_name)
|
|
||||||
return response
|
|
||||||
|
|
||||||
|
|
||||||
class vzhled:
|
|
||||||
|
|
||||||
def process_request(self, request):
|
|
||||||
return None
|
|
||||||
|
|
||||||
def process_view(self, request, view_func, view_args, view_kwargs):
|
|
||||||
#print "====== process_request ======"
|
|
||||||
#print view_func
|
|
||||||
#print view_args
|
|
||||||
#print view_kwargs
|
|
||||||
#print "============================="
|
|
||||||
return None
|
|
||||||
|
|
||||||
def process_template_response(self, request, response):
|
|
||||||
hodin = datetime.now().hour
|
|
||||||
if (hodin <= 6) or (hodin >= 14): # TODO 20
|
|
||||||
response.context_data['noc'] = True
|
|
||||||
else:
|
|
||||||
response.context_data['noc'] = False
|
|
||||||
return response
|
|
||||||
|
|
||||||
def process_response(self, request, response):
|
|
||||||
#hodin = datetime.now().hour
|
|
||||||
#if (hodin <= 6) or (hodin >= 14): # TODO 20
|
|
||||||
#response.context_data['noc'] = True
|
|
||||||
#else:
|
|
||||||
#response.context_data['noc'] = False
|
|
||||||
return response
|
|
||||||
|
|
||||||
|
|
||||||
##def process_exception(request, exception):
|
|
||||||
#pass
|
|
|
@ -68,9 +68,6 @@ MIDDLEWARE = (
|
||||||
'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',
|
||||||
# FIXME: rozbilo se při přechodu na Django 2.0, nevím, jestli
|
|
||||||
# se to dá zahodit bez náhrady
|
|
||||||
# 'mamweb.middleware.LoggedInHintCookieMiddleware',
|
|
||||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||||
'django.contrib.messages.middleware.MessageMiddleware',
|
'django.contrib.messages.middleware.MessageMiddleware',
|
||||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||||
|
@ -149,6 +146,7 @@ INSTALLED_APPS = (
|
||||||
'treenode',
|
'treenode',
|
||||||
'vyroci',
|
'vyroci',
|
||||||
'sifrovacka',
|
'sifrovacka',
|
||||||
|
'novinky',
|
||||||
|
|
||||||
# Admin upravy:
|
# Admin upravy:
|
||||||
|
|
||||||
|
@ -344,10 +342,6 @@ KOREKTURY_IMG_DIR = os.path.join('korektury', 'img')
|
||||||
CISLO_IMG_DIR = os.path.join('cislo', 'img')
|
CISLO_IMG_DIR = os.path.join('cislo', 'img')
|
||||||
|
|
||||||
|
|
||||||
# E-MAIL NOTIFICATIONS
|
|
||||||
POSLI_MAILOVOU_NOTIFIKACI = False
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Logování chyb
|
# Logování chyb
|
||||||
class InvalidTemplateVariable(str):
|
class InvalidTemplateVariable(str):
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
import os.path
|
import os.path
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -70,5 +68,4 @@ LOGGING['handlers']['registration_error_log']['filename'] = '/home/mam-web/logs/
|
||||||
|
|
||||||
|
|
||||||
# E-MAIL NOTIFICATIONS
|
# E-MAIL NOTIFICATIONS
|
||||||
POSLI_MAILOVOU_NOTIFIKACI = True
|
|
||||||
LOCAL_TEST_PROD = "prod"
|
LOCAL_TEST_PROD = "prod"
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
import os.path
|
import os.path
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -74,7 +72,6 @@ LOGGING['handlers']['registration_error_log']['filename'] = '/home/mam-web/logs/
|
||||||
FILE_UPLOAD_PERMISSIONS = 0o440
|
FILE_UPLOAD_PERMISSIONS = 0o440
|
||||||
|
|
||||||
# Testování e-mailů
|
# Testování e-mailů
|
||||||
POSLI_MAILOVOU_NOTIFIKACI = True
|
|
||||||
EMAIL_BACKEND = 'various.mail_prefixer.PrefixingMailBackend'
|
EMAIL_BACKEND = 'various.mail_prefixer.PrefixingMailBackend'
|
||||||
# TODO Pouze na otestování testu… Zvolit konferu!
|
# TODO Pouze na otestování testu… Zvolit konferu!
|
||||||
# XXX: Je to pole, protože implementační detail backendu.
|
# XXX: Je to pole, protože implementační detail backendu.
|
||||||
|
|
|
@ -1,18 +1,5 @@
|
||||||
"""
|
"""
|
||||||
Soubor sloužící jako základní „router“, tj. zde se includují veškeré ostatní urls:
|
Soubor sloužící jako základní „router“, tj. zde se includují veškeré ostatní urls.
|
||||||
|
|
||||||
- ``admin/`` :mod:`django.contrib.admin.site.urls`
|
|
||||||
- ``ckeditor/`` :mod:`ckeditor_uploader.urls`
|
|
||||||
- :mod:`seminar.urls`
|
|
||||||
- :mod:`odevzdavatko.urls`
|
|
||||||
- :mod:`korektury.urls`
|
|
||||||
- :mod:`prednasky.urls`
|
|
||||||
- :mod:`soustredeni.urls`
|
|
||||||
- :mod:`personalni.urls`
|
|
||||||
- :mod:`various.autentizace.urls`
|
|
||||||
- :mod:`api.urls`
|
|
||||||
- :mod:`treenode.urls`
|
|
||||||
- :mod:`aesop.urls`
|
|
||||||
"""
|
"""
|
||||||
from django.urls import path, include
|
from django.urls import path, include
|
||||||
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
|
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
|
||||||
|
|
0
novinky/__init__.py
Normal file
0
novinky/__init__.py
Normal file
5
novinky/admin.py
Normal file
5
novinky/admin.py
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
from .models import Novinky
|
||||||
|
|
||||||
|
admin.site.register(Novinky)
|
5
novinky/apps.py
Normal file
5
novinky/apps.py
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
class NovinkyConfig(AppConfig):
|
||||||
|
name = 'novinky'
|
||||||
|
verbose_name = 'Novinky'
|
45
novinky/migrations/0001_initial.py
Normal file
45
novinky/migrations/0001_initial.py
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
# Generated by Django 4.2.13 on 2024-05-13 20:43
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
def nastav_nove_contenttypes(apps, schema_editor):
|
||||||
|
ContentType = apps.get_model('contenttypes', 'ContentType')
|
||||||
|
for m in ('novinka'):
|
||||||
|
oct = ContentType.objects.filter(app_label='seminar', model=m)
|
||||||
|
oct.update(app_label='novinky')
|
||||||
|
|
||||||
|
def nastav_stare_contenttypes(apps, schema_editor):
|
||||||
|
ContentType = apps.get_model('contenttypes', 'ContentType')
|
||||||
|
for m in ('novinka'):
|
||||||
|
nct = ContentType.objects.filter(app_label='novinky', model=m)
|
||||||
|
nct.update(app_label='seminar')
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
initial = True
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('seminar', '0127_unmanage_novinky'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RunPython(nastav_nove_contenttypes, nastav_stare_contenttypes),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Novinky',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('datum', models.DateField(auto_now_add=True)),
|
||||||
|
('text', models.TextField(blank=True, null=True, verbose_name='Text novinky')),
|
||||||
|
('obrazek', models.ImageField(blank=True, null=True, upload_to='image_novinky/%Y/%m/%d/', verbose_name='Obrázek')),
|
||||||
|
('autor', models.ForeignKey(to='personalni.organizator', verbose_name='Autor novinky', null=True, on_delete=models.SET_NULL)),
|
||||||
|
('zverejneno', models.BooleanField(default=False, verbose_name='Zveřejněno')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'Novinka',
|
||||||
|
'verbose_name_plural': 'Novinky',
|
||||||
|
'db_table': 'seminar_novinky',
|
||||||
|
'ordering': ['-datum'],
|
||||||
|
'managed': False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
18
novinky/migrations/0002_manage_novinky.py
Normal file
18
novinky/migrations/0002_manage_novinky.py
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 4.2.13 on 2024-05-13 20:58
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('novinky', '0001_initial'),
|
||||||
|
('seminar', '0128_delete_novinky'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='novinky',
|
||||||
|
options={'ordering': ['-datum'], 'verbose_name': 'Novinka', 'verbose_name_plural': 'Novinky'},
|
||||||
|
),
|
||||||
|
]
|
13
novinky/migrations/0003_novinky_post.py
Normal file
13
novinky/migrations/0003_novinky_post.py
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
# Generated by Django 4.2.13 on 2024-05-13 21:00
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('novinky', '0002_manage_novinky'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
]
|
0
novinky/migrations/__init__.py
Normal file
0
novinky/migrations/__init__.py
Normal file
|
@ -13,6 +13,7 @@ class Novinky(models.Model):
|
||||||
verbose_name = 'Novinka'
|
verbose_name = 'Novinka'
|
||||||
verbose_name_plural = 'Novinky'
|
verbose_name_plural = 'Novinky'
|
||||||
ordering = ['-datum']
|
ordering = ['-datum']
|
||||||
|
db_table = 'seminar_novinky'
|
||||||
|
|
||||||
datum = models.DateField(auto_now_add=True)
|
datum = models.DateField(auto_now_add=True)
|
||||||
|
|
0
novinky/views.py
Normal file
0
novinky/views.py
Normal file
|
@ -1,9 +1,3 @@
|
||||||
"""
|
|
||||||
Soubor sloužící k definici toho, co bude v adminu. Většinou pouhým zavoláním
|
|
||||||
funkce :func:`django.contrib.admin.site.register`, v případě, že chceme něco
|
|
||||||
upravit, tak jako třída rozšiřující :class:`django.contrib.admin.ModelAdmin`
|
|
||||||
s dekorátorem :func:`django.contrib.admin.register`.
|
|
||||||
"""
|
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django_reverse_admin import ReverseModelAdmin
|
from django_reverse_admin import ReverseModelAdmin
|
||||||
import seminar.models as m
|
import seminar.models as m
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
"""
|
|
||||||
Soubor sloužící k pojmenování a jiným nastavením djangovské aplikace.
|
|
||||||
"""
|
|
||||||
from django.apps import AppConfig
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
class OdevzdavatkoConfig(AppConfig):
|
class OdevzdavatkoConfig(AppConfig):
|
||||||
name = 'odevzdavatko'
|
name = 'odevzdavatko'
|
||||||
|
verbose_name = 'Odevzdávátko'
|
||||||
|
|
|
@ -1,17 +1,3 @@
|
||||||
"""
|
|
||||||
Soubor sloužící jako „router“, tj. zde se definují url adresy a na co ukazují:
|
|
||||||
|
|
||||||
- ``org/add_solution`` (seminar_vloz_reseni) :class:`~odevzdavatko.views.PosliReseniView`
|
|
||||||
- ``resitel/nahraj_reseni`` (seminar_nahraj_reseni) :class:`~odevzdavatko.views.NahrajReseniView`
|
|
||||||
- ``resitel/odevzdana_reseni/`` (seminar_resitel_odevzdana_reseni) :class:`~odevzdavatko.views.PrehledOdevzdanychReseni`
|
|
||||||
- ``org/reseni/`` (odevzdavatko_tabulka) :class:`~odevzdavatko.views.TabulkaOdevzdanychReseniView`
|
|
||||||
- ``org/reseni/rocnik/<int:rocnik>/`` (odevzdavatko_tabulka) :class:`~odevzdavatko.views.TabulkaOdevzdanychReseniView`
|
|
||||||
- ``org/reseni/<int:problem>/<int:resitel>/`` (odevzdavatko_reseni_resitele_k_problemu) :class:`~odevzdavatko.views.ReseniProblemuView`
|
|
||||||
- ``org/reseni/<int:pk>/`` (odevzdavatko_detail_reseni) :func:`~seminar.utils.viewMethodSwitch` + :class:`~odevzdavatko.views.DetailReseniView` + :func:`~odevzdavatko.views.hodnoceniReseniView`
|
|
||||||
- ``org/reseni/all`` :class:`~odevzdavatko.views.SeznamReseniView`
|
|
||||||
- ``org/reseni/akt`` :class:`~odevzdavatko.views.TabulkaOdevzdanychReseniView`
|
|
||||||
- ``resitel/reseni/<int:pk>`` (odevzdavatko_resitel_reseni) :class:`~odevzdavatko.views.ResitelReseniView`
|
|
||||||
"""
|
|
||||||
from django.urls import path
|
from django.urls import path
|
||||||
|
|
||||||
from seminar.utils import org_required, resitel_required, viewMethodSwitch, \
|
from seminar.utils import org_required, resitel_required, viewMethodSwitch, \
|
||||||
|
|
|
@ -504,7 +504,7 @@ class NahrajReseniView(LoginRequiredMixin, CreateView):
|
||||||
|
|
||||||
EmailMessage(
|
EmailMessage(
|
||||||
subject="Nové řešení k " + seznam_do_subjectu,
|
subject="Nové řešení k " + seznam_do_subjectu,
|
||||||
body=f"Řešitel{ '' if resitel.pohlavi_muz else 'ka' } { resitel } právě nahrál{'' if resitel.pohlavi_muz else 'a' } nové řešení k { seznam }.\n\nHurá do opravování: { self.object.absolute_url() }",
|
body=f"{resitel} posílá nové řešení k { seznam }.\n\nHurá do opravování: { self.object.absolute_url() }",
|
||||||
from_email="submitovatko@mam.mff.cuni.cz", # FIXME: Chceme to mít radši tady, nebo v nastavení?
|
from_email="submitovatko@mam.mff.cuni.cz", # FIXME: Chceme to mít radši tady, nebo v nastavení?
|
||||||
to=list(prijemci),
|
to=list(prijemci),
|
||||||
).send()
|
).send()
|
||||||
|
|
|
@ -5,10 +5,52 @@ from django.contrib.messages import WARNING, ERROR, SUCCESS
|
||||||
import seminar.models as m
|
import seminar.models as m
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
|
@admin.action(description="Sjednoť telefony")
|
||||||
|
def sjednot_telefony(admin, request, queryset):
|
||||||
|
for o in queryset:
|
||||||
|
if o.telefon == '':
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
telefon = int(o.telefon.replace(" ", "").replace("+", ""))
|
||||||
|
# 6 míst
|
||||||
|
if len(str(telefon)) == 9:
|
||||||
|
o.telefon = "+420 " + str(telefon)[0:3] + " " + str(telefon)[3:6] + " " + str(telefon)[6:9]
|
||||||
|
o.save()
|
||||||
|
# 12 míst
|
||||||
|
elif len(str(telefon)) == 12:
|
||||||
|
o.telefon = "+" + str(telefon)[0:3] + " " + str(telefon)[3:6] + " " + str(telefon)[6:9] + " " + str(telefon)[9:12]
|
||||||
|
o.save()
|
||||||
|
else:
|
||||||
|
raise ValueError
|
||||||
|
except:
|
||||||
|
admin.message_user(request, f"{o.jmeno} {o.prijmeni} (id: {o.id}) má divný telefon: {o.telefon}", level=ERROR)
|
||||||
|
admin.message_user(request, "Telefony sjednoceny.", level=SUCCESS)
|
||||||
|
|
||||||
|
# Tohle chceme umět použít i z ResitelAdmin
|
||||||
|
@admin.action(description="Udělej z vybraných osob organizátory")
|
||||||
|
def udelej_orgem(admin, request, queryset):
|
||||||
|
org_group = Group.objects.get(name='org')
|
||||||
|
uspesne_vytvoreni_orgove = 0
|
||||||
|
for o in queryset:
|
||||||
|
if m.Organizator.objects.filter(osoba=o).exists():
|
||||||
|
# Ref: https://docs.djangoproject.com/en/3.2/ref/contrib/admin/#django.contrib.admin.ModelAdmin.message_user
|
||||||
|
admin.message_user(request, f"Osoba {o} už je org, přeskakuji.", level=WARNING)
|
||||||
|
continue
|
||||||
|
user = o.user
|
||||||
|
if user is None:
|
||||||
|
admin.message_user(request, f"Osoba {o} nemá uživatele! Přeskakuji.", level=ERROR)
|
||||||
|
continue
|
||||||
|
user.groups.add(org_group)
|
||||||
|
user.is_staff = True
|
||||||
|
user.save()
|
||||||
|
org = m.Organizator.objects.create(osoba=o, organizuje_od=datetime.now())
|
||||||
|
org.save()
|
||||||
|
uspesne_vytvoreni_orgove += 1
|
||||||
|
admin.message_user(request, f'Úspěšně vytvořeno {uspesne_vytvoreni_orgove} orgů.', level=SUCCESS)
|
||||||
|
|
||||||
@admin.register(m.Osoba)
|
@admin.register(m.Osoba)
|
||||||
class OsobaAdmin(admin.ModelAdmin):
|
class OsobaAdmin(admin.ModelAdmin):
|
||||||
actions = ['synchronizuj_maily', 'udelej_orgem']
|
actions = ['synchronizuj_maily', udelej_orgem, sjednot_telefony]
|
||||||
search_fields = ['jmeno', 'prijmeni', 'prezdivka']
|
search_fields = ['jmeno', 'prijmeni', 'prezdivka']
|
||||||
|
|
||||||
def synchronizuj_maily(self, request, queryset):
|
def synchronizuj_maily(self, request, queryset):
|
||||||
|
@ -20,27 +62,6 @@ class OsobaAdmin(admin.ModelAdmin):
|
||||||
self.message_user(request, "E-maily synchronizovány.")
|
self.message_user(request, "E-maily synchronizovány.")
|
||||||
synchronizuj_maily.short_description = "Synchronizuj vybraným osobám e-maily do uživatelů"
|
synchronizuj_maily.short_description = "Synchronizuj vybraným osobám e-maily do uživatelů"
|
||||||
|
|
||||||
def udelej_orgem(self,request,queryset):
|
|
||||||
org_group = Group.objects.get(name='org')
|
|
||||||
uspesne_vytvoreni_orgove = 0
|
|
||||||
for o in queryset:
|
|
||||||
if m.Organizator.objects.filter(osoba=o).exists():
|
|
||||||
# Ref: https://docs.djangoproject.com/en/3.2/ref/contrib/admin/#django.contrib.admin.ModelAdmin.message_user
|
|
||||||
self.message_user(request, f"Osoba {o} už je org, přeskakuji.", level=WARNING)
|
|
||||||
continue
|
|
||||||
user = o.user
|
|
||||||
if user is None:
|
|
||||||
self.message_user(request, f"Osoba {o} nemá uživatele! Přeskakuji.", level=ERROR)
|
|
||||||
continue
|
|
||||||
user.groups.add(org_group)
|
|
||||||
user.is_staff = True
|
|
||||||
user.save()
|
|
||||||
org = m.Organizator.objects.create(osoba=o, organizuje_od=datetime.now())
|
|
||||||
org.save()
|
|
||||||
uspesne_vytvoreni_orgove += 1
|
|
||||||
self.message_user(request, f'Úspěšně vytvořeno {uspesne_vytvoreni_orgove} orgů.', level=SUCCESS)
|
|
||||||
udelej_orgem.short_description = "Udělej z vybraných osob organizátory"
|
|
||||||
|
|
||||||
class OsobaInline(admin.TabularInline):
|
class OsobaInline(admin.TabularInline):
|
||||||
model = m.Osoba
|
model = m.Osoba
|
||||||
|
|
||||||
|
@ -53,9 +74,16 @@ class OrganizatorAdmin(ReverseModelAdmin):
|
||||||
@admin.register(m.Resitel)
|
@admin.register(m.Resitel)
|
||||||
class ResitelAdmin(ReverseModelAdmin):
|
class ResitelAdmin(ReverseModelAdmin):
|
||||||
search_fields = ['osoba__jmeno', 'osoba__prijmeni', 'osoba__prezdivka']
|
search_fields = ['osoba__jmeno', 'osoba__prijmeni', 'osoba__prezdivka']
|
||||||
|
list_filter = ['zasilat', 'zasilat_cislo_papirove', 'zasilat_cislo_emailem', 'rok_maturity']
|
||||||
ordering = ('osoba__prijmeni', 'osoba__jmeno')
|
ordering = ('osoba__prijmeni', 'osoba__jmeno')
|
||||||
inline_type = 'stacked'
|
inline_type = 'stacked'
|
||||||
inline_reverse = ['osoba']
|
inline_reverse = ['osoba']
|
||||||
|
|
||||||
|
actions = ['udelej_resitele_orgem']
|
||||||
|
@admin.action(description="Udělej z řešitelů organizátory")
|
||||||
|
def udelej_resitele_orgem(self, req, qs):
|
||||||
|
osoby = m.Osoba.objects.filter(resitel__in=qs)
|
||||||
|
udelej_orgem(self, req, osoby)
|
||||||
|
|
||||||
admin.site.register(m.Skola)
|
admin.site.register(m.Skola)
|
||||||
admin.site.register(m.Prijemce)
|
admin.site.register(m.Prijemce)
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
"""
|
|
||||||
Soubor sloužící k pojmenování a jiným nastavením djangovské aplikace.
|
|
||||||
"""
|
|
||||||
from django.apps import AppConfig
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
class PersonalniConfig(AppConfig):
|
class PersonalniConfig(AppConfig):
|
||||||
name = 'personalni'
|
name = 'personalni'
|
||||||
|
verbose_name = 'Personální' # Má to nějaký použitelnější název?
|
||||||
|
|
|
@ -32,7 +32,7 @@ class UdajeForm(forms.Form):
|
||||||
jmeno = forms.CharField(label='Jméno', max_length=256, required=True)
|
jmeno = forms.CharField(label='Jméno', max_length=256, required=True)
|
||||||
prezdivka_resitele = forms.CharField(label='Přezdívka (veřejná)', max_length=256, required=False)
|
prezdivka_resitele = forms.CharField(label='Přezdívka (veřejná)', max_length=256, required=False)
|
||||||
prijmeni = forms.CharField(label='Příjmení', max_length=256, required=True)
|
prijmeni = forms.CharField(label='Příjmení', max_length=256, required=True)
|
||||||
pohlavi_muz = forms.ChoiceField(label='Pohlaví', choices=((True, 'muž'), (False, 'žena')), required=True)
|
osloveni = forms.ChoiceField(label='Oslovení', choices=Osoba.OSLOVENI_CHOICES, required=False)
|
||||||
email = forms.EmailField(label='E-mail', max_length=256, required=True)
|
email = forms.EmailField(label='E-mail', max_length=256, required=True)
|
||||||
telefon = forms.CharField(widget=TelInput(), label='Telefon', max_length=256, required=False)
|
telefon = forms.CharField(widget=TelInput(), label='Telefon', max_length=256, required=False)
|
||||||
datum_narozeni = forms.DateField(widget=DateInput(), label='Datum narození', required=False)
|
datum_narozeni = forms.DateField(widget=DateInput(), label='Datum narození', required=False)
|
||||||
|
|
14
personalni/migrations/0007_post_split_soustredeni.py
Normal file
14
personalni/migrations/0007_post_split_soustredeni.py
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
# Generated by Django 4.2.11 on 2024-04-30 21:53
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('personalni', '0006_pre_split_soustredeni'),
|
||||||
|
('soustredeni', '0003_post_split_soustredeni'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
]
|
40
personalni/migrations/0008_reforma_pohlavi.py
Normal file
40
personalni/migrations/0008_reforma_pohlavi.py
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
# Generated by Django 4.2.11 on 2024-04-12 14:03
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
# V migracích nemáme Osoba.OSLOVENI_*, tak si to sem nakopíruji.
|
||||||
|
OSLOVENI_MUZSKE = 'resitel'
|
||||||
|
OSLOVENI_ZENSKE = 'resitelka'
|
||||||
|
OSLOVENI_ZADNE = ''
|
||||||
|
|
||||||
|
def pohlavi_to_osloveni(apps, schema_editor):
|
||||||
|
Osoba = apps.get_model('personalni', 'Osoba')
|
||||||
|
Osoba.objects.filter(pohlavi_muz=True).update(osloveni=OSLOVENI_MUZSKE)
|
||||||
|
Osoba.objects.filter(pohlavi_muz=False).update(osloveni=OSLOVENI_ZENSKE)
|
||||||
|
|
||||||
|
def osloveni_to_pohlavi(apps, schema_editor):
|
||||||
|
Osoba = apps.get_model('personalni', 'Osoba')
|
||||||
|
nebinarni = Osoba.objects.filter(osloveni=OSLOVENI_ZADNE)
|
||||||
|
if nebinarni.count() > 0:
|
||||||
|
raise Exception("Nelze odmigrovat: v databázi jsou nebinární osoby, které starý model nereprezentuje správně.")
|
||||||
|
Osoba.objects.filter(osloveni=OSLOVENI_MUZSKE).update(pohlavi_muz=True)
|
||||||
|
Osoba.objects.filter(osloveni=OSLOVENI_MUZSKE).update(pohlavi_muz=False)
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('personalni', '0007_post_split_soustredeni'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='osoba',
|
||||||
|
name='osloveni',
|
||||||
|
field=models.CharField(blank=True, choices=[('resitel', 'Řešitel'), ('resitelka', 'Řešitelka')], max_length=32, verbose_name='Oslovení'),
|
||||||
|
),
|
||||||
|
migrations.RunPython(pohlavi_to_osloveni, osloveni_to_pohlavi),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='osoba',
|
||||||
|
name='pohlavi_muz',
|
||||||
|
),
|
||||||
|
]
|
13
personalni/migrations/0009_novinky_pre.py
Normal file
13
personalni/migrations/0009_novinky_pre.py
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
# Generated by Django 4.2.13 on 2024-05-13 20:35
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('personalni', '0008_reforma_pohlavi'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
]
|
14
personalni/migrations/0010_novinky_post.py
Normal file
14
personalni/migrations/0010_novinky_post.py
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
# Generated by Django 4.2.13 on 2024-05-13 20:59
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('personalni', '0009_novinky_pre'),
|
||||||
|
('novinky', '0003_novinky_post'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
]
|
18
personalni/migrations/0011_osloveni_vsechny_choices.py
Normal file
18
personalni/migrations/0011_osloveni_vsechny_choices.py
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 4.2.13 on 2024-06-03 14:31
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('personalni', '0010_novinky_post'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='osoba',
|
||||||
|
name='osloveni',
|
||||||
|
field=models.CharField(blank=True, choices=[('resitel', 'Řešitel'), ('resitelka', 'Řešitelka'), ('', 'Cokoliv jiného')], max_length=32, verbose_name='Oslovení'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
@ -38,8 +37,16 @@ class Osoba(SeminarModelBase):
|
||||||
user = models.OneToOneField(settings.AUTH_USER_MODEL, blank=True, null=True,
|
user = models.OneToOneField(settings.AUTH_USER_MODEL, blank=True, null=True,
|
||||||
verbose_name='uživatel', on_delete=models.DO_NOTHING)
|
verbose_name='uživatel', on_delete=models.DO_NOTHING)
|
||||||
|
|
||||||
# Pohlaví. Že ho neznáme se snad nestane (a ušetří to práci při programování)
|
# Pohlaví nás prakticky nezajímá, reálně.
|
||||||
pohlavi_muz = models.BooleanField('pohlaví (muž)', default=False)
|
OSLOVENI_MUZSKE = 'resitel'
|
||||||
|
OSLOVENI_ZENSKE = 'resitelka'
|
||||||
|
OSLOVENI_ZADNE = ''
|
||||||
|
OSLOVENI_CHOICES = [
|
||||||
|
(OSLOVENI_MUZSKE, 'Řešitel'),
|
||||||
|
(OSLOVENI_ZENSKE, 'Řešitelka'),
|
||||||
|
(OSLOVENI_ZADNE, 'Cokoliv jiného'), # Reálně nás u nikoho jiného oslovení nezajímá? (A pohlaví už vůbec)
|
||||||
|
]
|
||||||
|
osloveni = models.CharField('Oslovení', choices=OSLOVENI_CHOICES, max_length=32, blank=True)
|
||||||
|
|
||||||
email = models.EmailField('e-mail', max_length=256, blank=True, default='')
|
email = models.EmailField('e-mail', max_length=256, blank=True, default='')
|
||||||
|
|
||||||
|
@ -246,11 +253,19 @@ class Resitel(SeminarModelBase):
|
||||||
|
|
||||||
def export_row(self):
|
def export_row(self):
|
||||||
"Slovnik pro pouziti v AESOP exportu"
|
"Slovnik pro pouziti v AESOP exportu"
|
||||||
|
# Ref: https://opmk.mff.cuni.cz/wiki/aesop/import#telo
|
||||||
|
|
||||||
|
# FUJ: Oslovení nemusí souviset s genderem.
|
||||||
|
gender = {
|
||||||
|
Osoba.OSLOVENI_MUZSKE: 'M',
|
||||||
|
Osoba.OSLOVENI_ZENSKE: 'F',
|
||||||
|
Osoba.OSLOVENI_ZADNE: '',
|
||||||
|
}[self.osoba.osloveni]
|
||||||
return {
|
return {
|
||||||
'id': self.id,
|
'id': self.id,
|
||||||
'name': self.osoba.jmeno,
|
'name': self.osoba.jmeno,
|
||||||
'surname': self.osoba.prijmeni,
|
'surname': self.osoba.prijmeni,
|
||||||
'gender': 'M' if self.osoba.pohlavi_muz else 'F',
|
'gender': gender,
|
||||||
'born': self.osoba.datum_narozeni.isoformat() if self.osoba.datum_narozeni else '',
|
'born': self.osoba.datum_narozeni.isoformat() if self.osoba.datum_narozeni else '',
|
||||||
'email': self.osoba.email,
|
'email': self.osoba.email,
|
||||||
'end-year': self.rok_maturity or '',
|
'end-year': self.rok_maturity or '',
|
||||||
|
|
|
@ -13,18 +13,18 @@
|
||||||
<li>soustředění</li>
|
<li>soustředění</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/admin/seminar/novinky/add/"><strong>přidat novinku</strong></a> na web</li>
|
<li><a href="{% url 'admin:novinky_novinky_add' %}"><strong>přidat novinku</strong></a> na web</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
<h2><strong>Tvorba čísla</strong></h2>
|
<h2><strong>Tvorba čísla</strong></h2>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="/admin/seminar/problem/add/"><strong>přidat téma</strong></a></li>
|
<li><a href="{% url 'admin:seminar_problem_add' %}"><strong>přidat téma</strong></a></li>
|
||||||
<li><strong>korektury</strong>
|
<li><strong>korektury</strong>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="/korektury/">korekturování</a></li>
|
<li><a href="{% url 'korektury_list' %}">korekturování</a></li>
|
||||||
<li><a href="/admin/korektury/korekturovanepdf/add/">přidat pdf k opravám</a></li>
|
<li><a href="{% url 'admin:korektury_korekturovanepdf_add' %}">přidat pdf k opravám</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
|
@ -70,15 +70,15 @@
|
||||||
<h2><strong>Soustředění</strong></h2>
|
<h2><strong>Soustředění</strong></h2>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="/admin/seminar/soustredeni/add/">přidat soustředění</a></li>
|
<li><a href="{% url 'admin:soustredeni_soustredeni_add' %}">přidat soustředění</a></li>
|
||||||
<li><strong>přednášky</strong>
|
<li><strong>přednášky</strong>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="/admin/prednasky/prednaska/">vypisování přednášek</a></li>
|
<li><a href="{% url 'admin:prednasky_prednaska_add' %}">vypisování přednášek</a></li>
|
||||||
<li>hlasování o přednáškách</li>
|
<li>hlasování o přednáškách</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/soustredeni/probehlo/">proběhlá soustředění</a>
|
<li><a href="{% url 'seminar_seznam_soustredeni' %}">proběhlá soustředění</a>
|
||||||
<ul>
|
<ul>
|
||||||
<li>vytvoření galerie</li>
|
<li>vytvoření galerie</li>
|
||||||
<li>stažení seznamu účastníků</li>
|
<li>stažení seznamu účastníků</li>
|
||||||
|
@ -91,7 +91,7 @@
|
||||||
<h2><strong>Můj profil</strong></h2>
|
<h2><strong>Můj profil</strong></h2>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="/admin/seminar/organizator/{{ organizator.id }}/change/"><strong>upravit </strong></a></li>
|
<li><a href="{% url 'admin:personalni_organizator_change' organizator.id %}"><strong>upravit </strong></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<hr/>
|
<hr/>
|
||||||
|
@ -108,6 +108,6 @@
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
<p>Nemůžeš najít, co hledáš? Může to být v <a href="/admin/">administračním rozhraní webu</a>.</p>
|
<p>Nemůžeš najít, co hledáš? Může to být v <a href="{% url 'admin:index' %}">administračním rozhraní webu</a>.</p>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
{% include "personalni/udaje/prihlaska_field.html" with field=form.jmeno %}
|
{% include "personalni/udaje/prihlaska_field.html" with field=form.jmeno %}
|
||||||
{% include "personalni/udaje/prihlaska_field.html" with field=form.prezdivka_resitele %}
|
{% include "personalni/udaje/prihlaska_field.html" with field=form.prezdivka_resitele %}
|
||||||
{% include "personalni/udaje/prihlaska_field.html" with field=form.prijmeni %}
|
{% include "personalni/udaje/prihlaska_field.html" with field=form.prijmeni %}
|
||||||
{% include "personalni/udaje/prihlaska_field.html" with field=form.pohlavi_muz%}
|
{% include "personalni/udaje/prihlaska_field.html" with field=form.osloveni%}
|
||||||
{% include "personalni/udaje/prihlaska_field.html" with field=form.email %}
|
{% include "personalni/udaje/prihlaska_field.html" with field=form.email %}
|
||||||
{% include "personalni/udaje/prihlaska_field.html" with field=form.telefon %}
|
{% include "personalni/udaje/prihlaska_field.html" with field=form.telefon %}
|
||||||
{% include "personalni/udaje/prihlaska_field.html" with field=form.datum_narozeni %}
|
{% include "personalni/udaje/prihlaska_field.html" with field=form.datum_narozeni %}
|
||||||
|
|
|
@ -1,17 +1,3 @@
|
||||||
"""
|
|
||||||
Soubor sloužící jako „router“, tj. zde se definují url adresy a na co ukazují:
|
|
||||||
|
|
||||||
- ``org/add_solution`` (seminar_vloz_reseni) :class:`~odevzdavatko.views.PosliReseniView`
|
|
||||||
- ``resitel/nahraj_reseni`` (seminar_nahraj_reseni) :class:`~odevzdavatko.views.NahrajReseniView`
|
|
||||||
- ``resitel/odevzdana_reseni/`` (seminar_resitel_odevzdana_reseni) :class:`~odevzdavatko.views.PrehledOdevzdanychReseni`
|
|
||||||
- ``org/reseni/`` (odevzdavatko_tabulka) :class:`~odevzdavatko.views.TabulkaOdevzdanychReseniView`
|
|
||||||
- ``org/reseni/rocnik/<int:rocnik>/`` (odevzdavatko_tabulka) :class:`~odevzdavatko.views.TabulkaOdevzdanychReseniView`
|
|
||||||
- ``org/reseni/<int:problem>/<int:resitel>/`` (odevzdavatko_reseni_resitele_k_problemu) :class:`~odevzdavatko.views.ReseniProblemuView`
|
|
||||||
- ``org/reseni/<int:pk>/`` (odevzdavatko_detail_reseni) :func:`~seminar.utils.viewMethodSwitch` + :class:`~odevzdavatko.views.DetailReseniView` + :func:`~odevzdavatko.views.hodnoceniReseniView`
|
|
||||||
- ``org/reseni/all`` :class:`~odevzdavatko.views.SeznamReseniView`
|
|
||||||
- ``org/reseni/akt`` :class:`~odevzdavatko.views.TabulkaOdevzdanychReseniView`
|
|
||||||
- ``resitel/reseni/<int:pk>`` (odevzdavatko_resitel_reseni) :class:`~odevzdavatko.views.ResitelReseniView`
|
|
||||||
"""
|
|
||||||
from django.urls import path
|
from django.urls import path
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from . import views
|
from . import views
|
||||||
|
|
|
@ -4,7 +4,7 @@ from django.views import generic
|
||||||
from django.db.models import Q, Count, Min
|
from django.db.models import Q, Count, Min
|
||||||
from django.views.decorators.debug import sensitive_post_parameters
|
from django.views.decorators.debug import sensitive_post_parameters
|
||||||
from django.views.generic.base import TemplateView
|
from django.views.generic.base import TemplateView
|
||||||
from django.contrib.auth.models import User, Permission, Group
|
from django.contrib.auth.models import User, Permission, Group, AnonymousUser
|
||||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
|
@ -139,7 +139,7 @@ def resitelEditView(request):
|
||||||
form_logger.info("EDIT:" + str(fcd) + str(form_hash)) # TODO možná logovat jinak
|
form_logger.info("EDIT:" + str(fcd) + str(form_hash)) # TODO možná logovat jinak
|
||||||
osoba_edit.jmeno = fcd['jmeno']
|
osoba_edit.jmeno = fcd['jmeno']
|
||||||
osoba_edit.prijmeni = fcd['prijmeni']
|
osoba_edit.prijmeni = fcd['prijmeni']
|
||||||
osoba_edit.pohlavi_muz = fcd['pohlavi_muz']
|
osoba_edit.osloveni = fcd['osloveni']
|
||||||
osoba_edit.email = fcd['email']
|
osoba_edit.email = fcd['email']
|
||||||
osoba_edit.telefon = fcd['telefon']
|
osoba_edit.telefon = fcd['telefon']
|
||||||
osoba_edit.ulice = fcd['ulice']
|
osoba_edit.ulice = fcd['ulice']
|
||||||
|
@ -209,7 +209,7 @@ def prihlaskaView(request):
|
||||||
o = s.Osoba(
|
o = s.Osoba(
|
||||||
jmeno = fcd['jmeno'],
|
jmeno = fcd['jmeno'],
|
||||||
prijmeni = fcd['prijmeni'],
|
prijmeni = fcd['prijmeni'],
|
||||||
pohlavi_muz = fcd['pohlavi_muz'],
|
osloveni = fcd['osloveni'],
|
||||||
email = fcd['email'],
|
email = fcd['email'],
|
||||||
telefon = fcd.get('telefon',''),
|
telefon = fcd.get('telefon',''),
|
||||||
datum_narozeni = fcd.get('datum_narozeni',None),
|
datum_narozeni = fcd.get('datum_narozeni',None),
|
||||||
|
@ -242,7 +242,7 @@ def prihlaskaView(request):
|
||||||
|
|
||||||
# Porovnání údajů
|
# Porovnání údajů
|
||||||
assert orig_osoba.user is None, "Právě-registrující-se osoba už má Uživatele!"
|
assert orig_osoba.user is None, "Právě-registrující-se osoba už má Uživatele!"
|
||||||
osoba_attrs = ['jmeno', 'prijmeni', 'pohlavi_muz', 'email', 'telefon', 'datum_narozeni', 'ulice', 'mesto', 'psc', 'stat', 'datum_souhlasu_udaje', 'datum_souhlasu_zasilani', 'datum_registrace']
|
osoba_attrs = ['jmeno', 'prijmeni', 'osloveni', 'email', 'telefon', 'datum_narozeni', 'ulice', 'mesto', 'psc', 'stat', 'datum_souhlasu_udaje', 'datum_souhlasu_zasilani', 'datum_registrace']
|
||||||
diffattrs = []
|
diffattrs = []
|
||||||
for attr in osoba_attrs:
|
for attr in osoba_attrs:
|
||||||
new = getattr(o, attr)
|
new = getattr(o, attr)
|
||||||
|
@ -318,6 +318,12 @@ def prihlaskaView(request):
|
||||||
# Jen hloupé rozhazovátko
|
# Jen hloupé rozhazovátko
|
||||||
def profilView(request):
|
def profilView(request):
|
||||||
user = request.user
|
user = request.user
|
||||||
|
if not isinstance(user, AnonymousUser) and m.Osoba.objects.filter(user=user).count() != 1:
|
||||||
|
# m.Osoba.objects.get() v ostatních views selže
|
||||||
|
return render(request, "universal.html", {
|
||||||
|
'title': 'Krize identity.',
|
||||||
|
'raw_html': r'<blockquote>Zvláštní pocit, že jo?<br>[…]<br>Co to znamená?<br>— Že ti MaMweb neumí říct, kdo jsi.<br>A <a href="/admin">Admin</a> ano?<br>— V tom je rozdíl.</blockquote> — Matrix (1999), parafrázováno',
|
||||||
|
})
|
||||||
if user.has_perm('auth.org'):
|
if user.has_perm('auth.org'):
|
||||||
return OrgoRozcestnikView.as_view()(request)
|
return OrgoRozcestnikView.as_view()(request)
|
||||||
if user.has_perm('auth.resitel'):
|
if user.has_perm('auth.resitel'):
|
||||||
|
@ -339,7 +345,7 @@ def dataResiteluCsvResponse(queryset, columns=None, with_header=True):
|
||||||
'osoba__telefon',
|
'osoba__telefon',
|
||||||
'osoba__user__username',
|
'osoba__user__username',
|
||||||
'osoba__datum_narozeni',
|
'osoba__datum_narozeni',
|
||||||
'osoba__pohlavi_muz',
|
'osoba__osloveni',
|
||||||
'osoba__ulice',
|
'osoba__ulice',
|
||||||
'osoba__mesto',
|
'osoba__mesto',
|
||||||
'osoba__psc',
|
'osoba__psc',
|
||||||
|
@ -367,7 +373,7 @@ def dataResiteluCsvResponse(queryset, columns=None, with_header=True):
|
||||||
'osoba__telefon': 'telefon',
|
'osoba__telefon': 'telefon',
|
||||||
'osoba__user__username': 'user',
|
'osoba__user__username': 'user',
|
||||||
'osoba__datum_narozeni': 'datum_narozeni',
|
'osoba__datum_narozeni': 'datum_narozeni',
|
||||||
'osoba__pohlavi_muz': 'pohlavi_muz',
|
'osoba__osloveni': 'osloveni',
|
||||||
'osoba__ulice': 'ulice',
|
'osoba__ulice': 'ulice',
|
||||||
'osoba__mesto': 'mesto',
|
'osoba__mesto': 'mesto',
|
||||||
'osoba__psc': 'psc',
|
'osoba__psc': 'psc',
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from reversion.admin import VersionAdmin
|
from reversion.admin import VersionAdmin
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# coding: utf-8
|
|
||||||
from django import forms
|
from django import forms
|
||||||
|
|
||||||
class NewPrednaskyForm(forms.Form):
|
class NewPrednaskyForm(forms.Form):
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue