Compare commits
61 Commits
288 changed files with 5159 additions and 4911 deletions
@ -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,3 +0,0 @@ |
|||
""" |
|||
Obsahuje vše, co se týká aesopu (exportu, který po nás vyžaduje OPMK). |
|||
""" |
@ -1,8 +0,0 @@ |
|||
""" |
|||
Soubor sloužící k pojmenování a jiným nastavením djangovské aplikace. |
|||
""" |
|||
from django.apps import AppConfig |
|||
|
|||
|
|||
class AesopConfig(AppConfig): |
|||
name = 'aesop' |
@ -1,30 +0,0 @@ |
|||
from django.http import HttpResponse |
|||
from django.utils.encoding import force_text |
|||
|
|||
|
|||
class OvvpFile: |
|||
def __init__(self): |
|||
# { header: value, ... } |
|||
self.headers = {} |
|||
# [ 'column-name', ... ] |
|||
self.columns = [] |
|||
# [ { column: value, ...}, ...] |
|||
self.rows = [] |
|||
|
|||
def to_lines(self): |
|||
# header |
|||
for hk in sorted(self.headers.keys()): |
|||
yield f'{hk}\t{self.headers[hk]}\n' |
|||
yield '\n' |
|||
# columns |
|||
yield '\t'.join(self.columns) + '\n' |
|||
# rows |
|||
for r in self.rows: |
|||
yield '\t'.join([force_text(r[c]) for c in self.columns]) + '\n' |
|||
|
|||
def to_string(self): |
|||
return ''.join(self.to_lines()) |
|||
|
|||
# Pozn: tohle je ta jediná funkce, která se reálně používá… |
|||
def to_HttpResponse(self): |
|||
return HttpResponse(self.to_string(), content_type='text/plain; charset=utf-8') |
@ -1,27 +0,0 @@ |
|||
""" |
|||
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 aesop import views |
|||
|
|||
urlpatterns = [ |
|||
path( |
|||
'aesop-export/mam-rocnik-<int:prvni_rok>.csv', |
|||
views.ExportRocnikView.as_view(), |
|||
name='seminar_export_rocnik' |
|||
), |
|||
path( |
|||
'aesop-export/mam-sous-<str:datum_zacatku>.csv', |
|||
views.ExportSousView.as_view(), |
|||
name='seminar_export_sous' |
|||
), |
|||
path( |
|||
'aesop-export/index.csv', |
|||
views.ExportIndexView.as_view(), |
|||
name='seminar_export_index' |
|||
), |
|||
] |
@ -1,16 +0,0 @@ |
|||
import datetime |
|||
|
|||
from django.utils.encoding import force_text |
|||
|
|||
from aesop.ovvpfile import OvvpFile |
|||
|
|||
|
|||
def default_ovvpfile(event, rocnik): |
|||
of = OvvpFile() |
|||
of.headers['version'] = '1' |
|||
of.headers['event'] = event |
|||
of.headers['year'] = force_text(rocnik.prvni_rok) |
|||
of.headers['date'] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") |
|||
of.headers['id-scope'] = 'mam' |
|||
of.headers['id-generation'] = '1' |
|||
return of |
@ -1,101 +0,0 @@ |
|||
""" |
|||
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 |
|||
from django.shortcuts import get_object_or_404 |
|||
from django.http import HttpResponse |
|||
from django.urls import reverse |
|||
from django.views import generic |
|||
from django.utils.encoding import force_text |
|||
|
|||
from .utils import default_ovvpfile |
|||
from seminar.models import Rocnik, Soustredeni |
|||
from vysledkovky import utils |
|||
from seminar.utils import aktivniResitele |
|||
|
|||
class ExportIndexView(generic.View): |
|||
def get(self, request): |
|||
ls = [] |
|||
for r in Rocnik.objects.filter(exportovat = True): |
|||
url = reverse('seminar_export_rocnik', kwargs={'prvni_rok': r.prvni_rok}) |
|||
ls.append(url.split('/')[-1]) |
|||
for s in Soustredeni.objects.filter(exportovat = True): |
|||
url = reverse('seminar_export_sous', kwargs={'datum_zacatku': s.datum_zacatku.isoformat()}) |
|||
ls.append(url.split('/')[-1]) |
|||
|
|||
return HttpResponse('\n'.join(ls) + '\n', content_type='text/plain; charset=utf-8') |
|||
|
|||
|
|||
class ExportSousView(generic.View): |
|||
|
|||
def get(self, request, datum_zacatku=None): |
|||
try: |
|||
dz = django.utils.dateparse.parse_date(datum_zacatku) |
|||
except: |
|||
dz = None |
|||
if dz is None: |
|||
raise django.http.Http404() |
|||
|
|||
s = get_object_or_404(Soustredeni, datum_zacatku=dz, exportovat=True) |
|||
|
|||
akce = {Soustredeni.TYP_JARNI: 'MaM.sous.jaro', |
|||
Soustredeni.TYP_PODZIMNI: 'MaM.sous.podzim', |
|||
Soustredeni.TYP_VIKEND: 'MaM.vikend', |
|||
}[s.typ] |
|||
|
|||
of = default_ovvpfile(akce, s.rocnik) |
|||
of.headers['x-event-begin'] = s.datum_zacatku.isoformat() |
|||
of.headers['x-event-end'] = s.datum_konce.isoformat() |
|||
of.headers['x-event-location'] = s.misto |
|||
of.headers['comment'] = u'MaM-Web export ucastniku soustredeni v {x-event-location} od {x-event-begin} do {x-event-end}'.format(**of.headers) |
|||
of.columns = ['id', 'name', 'surname', 'gender', 'email', 'end-year', 'school', 'school-name'] |
|||
|
|||
for u in s.ucastnici.all(): |
|||
of.rows.append(u.export_row()) |
|||
|
|||
return of.to_HttpResponse() |
|||
|
|||
# POZOR! Předělání na nový model neotestováno v reálu (ale zase jen drobné změny) |
|||
class ExportRocnikView(generic.View): |
|||
|
|||
def get(self, request, prvni_rok=None): |
|||
try: |
|||
pr = int(prvni_rok) |
|||
except: |
|||
pr = None |
|||
if pr is None: |
|||
raise django.http.Http404() |
|||
|
|||
rocnik = get_object_or_404(Rocnik, prvni_rok=pr, exportovat=True) |
|||
cislo = rocnik.posledni_zverejnena_vysledkovka_cislo() |
|||
resitele = aktivniResitele(cislo, True) |
|||
slovnik_body = utils.secti_body_za_rocnik(cislo, resitele, False) |
|||
setrizeni_resitele, body = utils.setrid_resitele_a_body(slovnik_body) |
|||
|
|||
of = default_ovvpfile('MaM.rocnik', rocnik) |
|||
of.headers['comment'] = u'MaM-Web export aktivnich resitelu rocniku {rocnik} do cisla {cislo}'.format(rocnik=rocnik, cislo=cislo) |
|||
of.columns = ['id', 'name', 'surname', 'gender', 'born', 'email', 'end-year', |
|||
'street', 'town', 'postcode', 'country', 'spam-flag', 'spam-date', |
|||
'school', 'school-name', 'points', 'rank',] |
|||
|
|||
resitele_slovnik = {} |
|||
for r in resitele: |
|||
resitele_slovnik[r.id] = r |
|||
|
|||
# počítání pořadí řešitelů |
|||
posledni_body = 100000 |
|||
posledni_poradi = 0 |
|||
for i in range(len(setrizeni_resitele)): |
|||
rd = resitele_slovnik[setrizeni_resitele[i]].export_row() |
|||
|
|||
if posledni_body > body[i]: |
|||
posledni_body = body[i] |
|||
posledni_poradi = i + 1 |
|||
rd['rank'] = posledni_poradi |
|||
rd['points'] = body[i] |
|||
|
|||
of.rows.append(rd) |
|||
|
|||
return of.to_HttpResponse() |
@ -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 .exports import * |
|||
|
@ -1,17 +0,0 @@ |
|||
#!/bin/sh |
|||
|
|||
if test "$#" -lt 1 |
|||
then |
|||
echo "Usage: $0 file ..." |
|||
exit 2 |
|||
fi |
|||
|
|||
for file in "$@" |
|||
do |
|||
# Do the sed magic: keep replacing 4 spaces at the begining of line |
|||
sed -i -re ' |
|||
: loop |
|||
s/^( *) /\1 / |
|||
t loop |
|||
' "$file" |
|||
done |
@ -0,0 +1,600 @@ |
|||
[ |
|||
{ |
|||
"fields": { |
|||
"name": "org", |
|||
"permissions": [ |
|||
[ |
|||
"org", |
|||
"auth", |
|||
"user" |
|||
], |
|||
[ |
|||
"add_flatpage", |
|||
"flatpages", |
|||
"flatpage" |
|||
], |
|||
[ |
|||
"change_flatpage", |
|||
"flatpages", |
|||
"flatpage" |
|||
], |
|||
[ |
|||
"delete_flatpage", |
|||
"flatpages", |
|||
"flatpage" |
|||
], |
|||
[ |
|||
"view_flatpage", |
|||
"flatpages", |
|||
"flatpage" |
|||
], |
|||
[ |
|||
"add_galerie", |
|||
"galerie", |
|||
"galerie" |
|||
], |
|||
[ |
|||
"change_galerie", |
|||
"galerie", |
|||
"galerie" |
|||
], |
|||
[ |
|||
"delete_galerie", |
|||
"galerie", |
|||
"galerie" |
|||
], |
|||
[ |
|||
"view_galerie", |
|||
"galerie", |
|||
"galerie" |
|||
], |
|||
[ |
|||
"add_obrazek", |
|||
"galerie", |
|||
"obrazek" |
|||
], |
|||
[ |
|||
"change_obrazek", |
|||
"galerie", |
|||
"obrazek" |
|||
], |
|||
[ |
|||
"delete_obrazek", |
|||
"galerie", |
|||
"obrazek" |
|||
], |
|||
[ |
|||
"view_obrazek", |
|||
"galerie", |
|||
"obrazek" |
|||
], |
|||
[ |
|||
"add_fotkaheader", |
|||
"header_fotky", |
|||
"fotkaheader" |
|||
], |
|||
[ |
|||
"change_fotkaheader", |
|||
"header_fotky", |
|||
"fotkaheader" |
|||
], |
|||
[ |
|||
"delete_fotkaheader", |
|||
"header_fotky", |
|||
"fotkaheader" |
|||
], |
|||
[ |
|||
"view_fotkaheader", |
|||
"header_fotky", |
|||
"fotkaheader" |
|||
], |
|||
[ |
|||
"add_fotkaurlvazba", |
|||
"header_fotky", |
|||
"fotkaurlvazba" |
|||
], |
|||
[ |
|||
"change_fotkaurlvazba", |
|||
"header_fotky", |
|||
"fotkaurlvazba" |
|||
], |
|||
[ |
|||
"delete_fotkaurlvazba", |
|||
"header_fotky", |
|||
"fotkaurlvazba" |
|||
], |
|||
[ |
|||
"view_fotkaurlvazba", |
|||
"header_fotky", |
|||
"fotkaurlvazba" |
|||
], |
|||
[ |
|||
"add_komentar", |
|||
"korektury", |
|||
"komentar" |
|||
], |
|||
[ |
|||
"change_komentar", |
|||
"korektury", |
|||
"komentar" |
|||
], |
|||
[ |
|||
"delete_komentar", |
|||
"korektury", |
|||
"komentar" |
|||
], |
|||
[ |
|||
"view_komentar", |
|||
"korektury", |
|||
"komentar" |
|||
], |
|||
[ |
|||
"add_korekturovanepdf", |
|||
"korektury", |
|||
"korekturovanepdf" |
|||
], |
|||
[ |
|||
"change_korekturovanepdf", |
|||
"korektury", |
|||
"korekturovanepdf" |
|||
], |
|||
[ |
|||
"delete_korekturovanepdf", |
|||
"korektury", |
|||
"korekturovanepdf" |
|||
], |
|||
[ |
|||
"view_korekturovanepdf", |
|||
"korektury", |
|||
"korekturovanepdf" |
|||
], |
|||
[ |
|||
"add_oprava", |
|||
"korektury", |
|||
"oprava" |
|||
], |
|||
[ |
|||
"change_oprava", |
|||
"korektury", |
|||
"oprava" |
|||
], |
|||
[ |
|||
"delete_oprava", |
|||
"korektury", |
|||
"oprava" |
|||
], |
|||
[ |
|||
"view_oprava", |
|||
"korektury", |
|||
"oprava" |
|||
], |
|||
[ |
|||
"change_organizator", |
|||
"personalni", |
|||
"organizator" |
|||
], |
|||
[ |
|||
"view_organizator", |
|||
"personalni", |
|||
"organizator" |
|||
], |
|||
[ |
|||
"change_osoba", |
|||
"personalni", |
|||
"osoba" |
|||
], |
|||
[ |
|||
"view_osoba", |
|||
"personalni", |
|||
"osoba" |
|||
], |
|||
[ |
|||
"add_prijemce", |
|||
"personalni", |
|||
"prijemce" |
|||
], |
|||
[ |
|||
"change_prijemce", |
|||
"personalni", |
|||
"prijemce" |
|||
], |
|||
[ |
|||
"delete_prijemce", |
|||
"personalni", |
|||
"prijemce" |
|||
], |
|||
[ |
|||
"view_prijemce", |
|||
"personalni", |
|||
"prijemce" |
|||
], |
|||
[ |
|||
"change_resitel", |
|||
"personalni", |
|||
"resitel" |
|||
], |
|||
[ |
|||
"view_resitel", |
|||
"personalni", |
|||
"resitel" |
|||
], |
|||
[ |
|||
"change_skola", |
|||
"personalni", |
|||
"skola" |
|||
], |
|||
[ |
|||
"view_skola", |
|||
"personalni", |
|||
"skola" |
|||
], |
|||
[ |
|||
"add_hlasovani", |
|||
"prednasky", |
|||
"hlasovani" |
|||
], |
|||
[ |
|||
"change_hlasovani", |
|||
"prednasky", |
|||
"hlasovani" |
|||
], |
|||
[ |
|||
"delete_hlasovani", |
|||
"prednasky", |
|||
"hlasovani" |
|||
], |
|||
[ |
|||
"view_hlasovani", |
|||
"prednasky", |
|||
"hlasovani" |
|||
], |
|||
[ |
|||
"add_prednaska", |
|||
"prednasky", |
|||
"prednaska" |
|||
], |
|||
[ |
|||
"change_prednaska", |
|||
"prednasky", |
|||
"prednaska" |
|||
], |
|||
[ |
|||
"delete_prednaska", |
|||
"prednasky", |
|||
"prednaska" |
|||
], |
|||
[ |
|||
"view_prednaska", |
|||
"prednasky", |
|||
"prednaska" |
|||
], |
|||
[ |
|||
"add_seznam", |
|||
"prednasky", |
|||
"seznam" |
|||
], |
|||
[ |
|||
"change_seznam", |
|||
"prednasky", |
|||
"seznam" |
|||
], |
|||
[ |
|||
"delete_seznam", |
|||
"prednasky", |
|||
"seznam" |
|||
], |
|||
[ |
|||
"view_seznam", |
|||
"prednasky", |
|||
"seznam" |
|||
], |
|||
[ |
|||
"change_nastaveni", |
|||
"seminar", |
|||
"nastaveni" |
|||
], |
|||
[ |
|||
"view_nastaveni", |
|||
"seminar", |
|||
"nastaveni" |
|||
], |
|||
[ |
|||
"add_novinky", |
|||
"seminar", |
|||
"novinky" |
|||
], |
|||
[ |
|||
"change_novinky", |
|||
"seminar", |
|||
"novinky" |
|||
], |
|||
[ |
|||
"delete_novinky", |
|||
"seminar", |
|||
"novinky" |
|||
], |
|||
[ |
|||
"view_novinky", |
|||
"seminar", |
|||
"novinky" |
|||
], |
|||
[ |
|||
"add_konfera", |
|||
"soustredeni", |
|||
"konfera" |
|||
], |
|||
[ |
|||
"change_konfera", |
|||
"soustredeni", |
|||
"konfera" |
|||
], |
|||
[ |
|||
"delete_konfera", |
|||
"soustredeni", |
|||
"konfera" |
|||
], |
|||
[ |
|||
"view_konfera", |
|||
"soustredeni", |
|||
"konfera" |
|||
], |
|||
[ |
|||
"add_konfery_ucastnici", |
|||
"soustredeni", |
|||
"konfery_ucastnici" |
|||
], |
|||
[ |
|||
"change_konfery_ucastnici", |
|||
"soustredeni", |
|||
"konfery_ucastnici" |
|||
], |
|||
[ |
|||
"delete_konfery_ucastnici", |
|||
"soustredeni", |
|||
"konfery_ucastnici" |
|||
], |
|||
[ |
|||
"view_konfery_ucastnici", |
|||
"soustredeni", |
|||
"konfery_ucastnici" |
|||
], |
|||
[ |
|||
"add_soustredeni", |
|||
"soustredeni", |
|||
"soustredeni" |
|||
], |
|||
[ |
|||
"change_soustredeni", |
|||
"soustredeni", |
|||
"soustredeni" |
|||
], |
|||
[ |
|||
"delete_soustredeni", |
|||
"soustredeni", |
|||
"soustredeni" |
|||
], |
|||
[ |
|||
"view_soustredeni", |
|||
"soustredeni", |
|||
"soustredeni" |
|||
], |
|||
[ |
|||
"add_soustredeni_organizatori", |
|||
"soustredeni", |
|||
"soustredeni_organizatori" |
|||
], |
|||
[ |
|||
"change_soustredeni_organizatori", |
|||
"soustredeni", |
|||
"soustredeni_organizatori" |
|||
], |
|||
[ |
|||
"delete_soustredeni_organizatori", |
|||
"soustredeni", |
|||
"soustredeni_organizatori" |
|||
], |
|||
[ |
|||
"view_soustredeni_organizatori", |
|||
"soustredeni", |
|||
"soustredeni_organizatori" |
|||
], |
|||
[ |
|||
"add_soustredeni_ucastnici", |
|||
"soustredeni", |
|||
"soustredeni_ucastnici" |
|||
], |
|||
[ |
|||
"change_soustredeni_ucastnici", |
|||
"soustredeni", |
|||
"soustredeni_ucastnici" |
|||
], |
|||
[ |
|||
"delete_soustredeni_ucastnici", |
|||
"soustredeni", |
|||
"soustredeni_ucastnici" |
|||
], |
|||
[ |
|||
"view_soustredeni_ucastnici", |
|||
"soustredeni", |
|||
"soustredeni_ucastnici" |
|||
], |
|||
[ |
|||
"add_cislo", |
|||
"tvorba", |
|||
"cislo" |
|||
], |
|||
[ |
|||
"change_cislo", |
|||
"tvorba", |
|||
"cislo" |
|||
], |
|||
[ |
|||
"delete_cislo", |
|||
"tvorba", |
|||
"cislo" |
|||
], |
|||
[ |
|||
"view_cislo", |
|||
"tvorba", |
|||
"cislo" |
|||
], |
|||
[ |
|||
"add_clanek", |
|||
"tvorba", |
|||
"clanek" |
|||
], |
|||
[ |
|||
"change_clanek", |
|||
"tvorba", |
|||
"clanek" |
|||
], |
|||
[ |
|||
"delete_clanek", |
|||
"tvorba", |
|||
"clanek" |
|||
], |
|||
[ |
|||
"view_clanek", |
|||
"tvorba", |
|||
"clanek" |
|||
], |
|||
[ |
|||
"add_deadline", |
|||
"tvorba", |
|||
"deadline" |
|||
], |
|||
[ |
|||
"change_deadline", |
|||
"tvorba", |
|||
"deadline" |
|||
], |
|||
[ |
|||
"delete_deadline", |
|||
"tvorba", |
|||
"deadline" |
|||
], |
|||
[ |
|||
"view_deadline", |
|||
"tvorba", |
|||
"deadline" |
|||
], |
|||
[ |
|||
"add_pohadka", |
|||
"tvorba", |
|||
"pohadka" |
|||
], |
|||
[ |
|||
"change_pohadka", |
|||
"tvorba", |
|||
"pohadka" |
|||
], |
|||
[ |
|||
"delete_pohadka", |
|||
"tvorba", |
|||
"pohadka" |
|||
], |
|||
[ |
|||
"view_pohadka", |
|||
"tvorba", |
|||
"pohadka" |
|||
], |
|||
[ |
|||
"add_problem", |
|||
"tvorba", |
|||
"problem" |
|||
], |
|||
[ |
|||
"change_problem", |
|||
"tvorba", |
|||
"problem" |
|||
], |
|||
[ |
|||
"delete_problem", |
|||
"tvorba", |
|||
"problem" |
|||
], |
|||
[ |
|||
"view_problem", |
|||
"tvorba", |
|||
"problem" |
|||
], |
|||
[ |
|||
"add_rocnik", |
|||
"tvorba", |
|||
"rocnik" |
|||
], |
|||
[ |
|||
"change_rocnik", |
|||
"tvorba", |
|||
"rocnik" |
|||
], |
|||
[ |
|||
"delete_rocnik", |
|||
"tvorba", |
|||
"rocnik" |
|||
], |
|||
[ |
|||
"view_rocnik", |
|||
"tvorba", |
|||
"rocnik" |
|||
], |
|||
[ |
|||
"add_tema", |
|||
"tvorba", |
|||
"tema" |
|||
], |
|||
[ |
|||
"change_tema", |
|||
"tvorba", |
|||
"tema" |
|||
], |
|||
[ |
|||
"delete_tema", |
|||
"tvorba", |
|||
"tema" |
|||
], |
|||
[ |
|||
"view_tema", |
|||
"tvorba", |
|||
"tema" |
|||
], |
|||
[ |
|||
"add_uloha", |
|||
"tvorba", |
|||
"uloha" |
|||
], |
|||
[ |
|||
"change_uloha", |
|||
"tvorba", |
|||
"uloha" |
|||
], |
|||
[ |
|||
"delete_uloha", |
|||
"tvorba", |
|||
"uloha" |
|||
], |
|||
[ |
|||
"view_uloha", |
|||
"tvorba", |
|||
"uloha" |
|||
] |
|||
] |
|||
}, |
|||
"model": "auth.group", |
|||
"pk": 1 |
|||
}, |
|||
{ |
|||
"fields": { |
|||
"name": "resitel", |
|||
"permissions": [ |
|||
[ |
|||
"resitel", |
|||
"auth", |
|||
"user" |
|||
] |
|||
] |
|||
}, |
|||
"model": "auth.group", |
|||
"pk": 2 |
|||
} |
|||
] |
@ -1,3 +0,0 @@ |
|||
Tahle slozka obsahuje vsechny detaily a popisy, jak nasadit "druhou verzi" M&M webu. |
|||
|
|||
TODO: chybi tu popis na zprovozneni flatpages, na loaddata &c. |
Binary file not shown.
@ -1,652 +0,0 @@ |
|||
[ |
|||
{ |
|||
"codename": "org", |
|||
"ct_app_label": "auth", |
|||
"ct_model": "user" |
|||
}, |
|||
{ |
|||
"codename": "add_flatpage", |
|||
"ct_app_label": "flatpages", |
|||
"ct_model": "flatpage" |
|||
}, |
|||
{ |
|||
"codename": "change_flatpage", |
|||
"ct_app_label": "flatpages", |
|||
"ct_model": "flatpage" |
|||
}, |
|||
{ |
|||
"codename": "delete_flatpage", |
|||
"ct_app_label": "flatpages", |
|||
"ct_model": "flatpage" |
|||
}, |
|||
{ |
|||
"codename": "view_flatpage", |
|||
"ct_app_label": "flatpages", |
|||
"ct_model": "flatpage" |
|||
}, |
|||
{ |
|||
"codename": "add_galerie", |
|||
"ct_app_label": "galerie", |
|||
"ct_model": "galerie" |
|||
}, |
|||
{ |
|||
"codename": "change_galerie", |
|||
"ct_app_label": "galerie", |
|||
"ct_model": "galerie" |
|||
}, |
|||
{ |
|||
"codename": "delete_galerie", |
|||
"ct_app_label": "galerie", |
|||
"ct_model": "galerie" |
|||
}, |
|||
{ |
|||
"codename": "view_galerie", |
|||
"ct_app_label": "galerie", |
|||
"ct_model": "galerie" |
|||
}, |
|||
{ |
|||
"codename": "add_obrazek", |
|||
"ct_app_label": "galerie", |
|||
"ct_model": "obrazek" |
|||
}, |
|||
{ |
|||
"codename": "change_obrazek", |
|||
"ct_app_label": "galerie", |
|||
"ct_model": "obrazek" |
|||
}, |
|||
{ |
|||
"codename": "delete_obrazek", |
|||
"ct_app_label": "galerie", |
|||
"ct_model": "obrazek" |
|||
}, |
|||
{ |
|||
"codename": "view_obrazek", |
|||
"ct_app_label": "galerie", |
|||
"ct_model": "obrazek" |
|||
}, |
|||
{ |
|||
"codename": "add_komentar", |
|||
"ct_app_label": "korektury", |
|||
"ct_model": "komentar" |
|||
}, |
|||
{ |
|||
"codename": "change_komentar", |
|||
"ct_app_label": "korektury", |
|||
"ct_model": "komentar" |
|||
}, |
|||
{ |
|||
"codename": "delete_komentar", |
|||
"ct_app_label": "korektury", |
|||
"ct_model": "komentar" |
|||
}, |
|||
{ |
|||
"codename": "view_komentar", |
|||
"ct_app_label": "korektury", |
|||
"ct_model": "komentar" |
|||
}, |
|||
{ |
|||
"codename": "add_korekturovanepdf", |
|||
"ct_app_label": "korektury", |
|||
"ct_model": "korekturovanepdf" |
|||
}, |
|||
{ |
|||
"codename": "change_korekturovanepdf", |
|||
"ct_app_label": "korektury", |
|||
"ct_model": "korekturovanepdf" |
|||
}, |
|||
{ |
|||
"codename": "delete_korekturovanepdf", |
|||
"ct_app_label": "korektury", |
|||
"ct_model": "korekturovanepdf" |
|||
}, |
|||
{ |
|||
"codename": "view_korekturovanepdf", |
|||
"ct_app_label": "korektury", |
|||
"ct_model": "korekturovanepdf" |
|||
}, |
|||
{ |
|||
"codename": "add_oprava", |
|||
"ct_app_label": "korektury", |
|||
"ct_model": "oprava" |
|||
}, |
|||
{ |
|||
"codename": "change_oprava", |
|||
"ct_app_label": "korektury", |
|||
"ct_model": "oprava" |
|||
}, |
|||
{ |
|||
"codename": "delete_oprava", |
|||
"ct_app_label": "korektury", |
|||
"ct_model": "oprava" |
|||
}, |
|||
{ |
|||
"codename": "view_oprava", |
|||
"ct_app_label": "korektury", |
|||
"ct_model": "oprava" |
|||
}, |
|||
{ |
|||
"codename": "add_hlasovani", |
|||
"ct_app_label": "prednasky", |
|||
"ct_model": "hlasovani" |
|||
}, |
|||
{ |
|||
"codename": "change_hlasovani", |
|||
"ct_app_label": "prednasky", |
|||
"ct_model": "hlasovani" |
|||
}, |
|||
{ |
|||
"codename": "delete_hlasovani", |
|||
"ct_app_label": "prednasky", |
|||
"ct_model": "hlasovani" |
|||
}, |
|||
{ |
|||
"codename": "view_hlasovani", |
|||
"ct_app_label": "prednasky", |
|||
"ct_model": "hlasovani" |
|||
}, |
|||
{ |
|||
"codename": "add_prednaska", |
|||
"ct_app_label": "prednasky", |
|||
"ct_model": "prednaska" |
|||
}, |
|||
{ |
|||
"codename": "change_prednaska", |
|||
"ct_app_label": "prednasky", |
|||
"ct_model": "prednaska" |
|||
}, |
|||
{ |
|||
"codename": "delete_prednaska", |
|||
"ct_app_label": "prednasky", |
|||
"ct_model": "prednaska" |
|||
}, |
|||
{ |
|||
"codename": "view_prednaska", |
|||
"ct_app_label": "prednasky", |
|||
"ct_model": "prednaska" |
|||
}, |
|||
{ |
|||
"codename": "add_seznam", |
|||
"ct_app_label": "prednasky", |
|||
"ct_model": "seznam" |
|||
}, |
|||
{ |
|||
"codename": "change_seznam", |
|||
"ct_app_label": "prednasky", |
|||
"ct_model": "seznam" |
|||
}, |
|||
{ |
|||
"codename": "delete_seznam", |
|||
"ct_app_label": "prednasky", |
|||
"ct_model": "seznam" |
|||
}, |
|||
{ |
|||
"codename": "view_seznam", |
|||
"ct_app_label": "prednasky", |
|||
"ct_model": "seznam" |
|||
}, |
|||
{ |
|||
"codename": "add_cislo", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "cislo" |
|||
}, |
|||
{ |
|||
"codename": "change_cislo", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "cislo" |
|||
}, |
|||
{ |
|||
"codename": "delete_cislo", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "cislo" |
|||
}, |
|||
{ |
|||
"codename": "view_cislo", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "cislo" |
|||
}, |
|||
{ |
|||
"codename": "add_clanek", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "clanek" |
|||
}, |
|||
{ |
|||
"codename": "change_clanek", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "clanek" |
|||
}, |
|||
{ |
|||
"codename": "delete_clanek", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "clanek" |
|||
}, |
|||
{ |
|||
"codename": "view_clanek", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "clanek" |
|||
}, |
|||
{ |
|||
"codename": "add_konfera", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "konfera" |
|||
}, |
|||
{ |
|||
"codename": "change_konfera", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "konfera" |
|||
}, |
|||
{ |
|||
"codename": "delete_konfera", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "konfera" |
|||
}, |
|||
{ |
|||
"codename": "view_konfera", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "konfera" |
|||
}, |
|||
{ |
|||
"codename": "add_konfery_ucastnici", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "konfery_ucastnici" |
|||
}, |
|||
{ |
|||
"codename": "change_konfery_ucastnici", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "konfery_ucastnici" |
|||
}, |
|||
{ |
|||
"codename": "delete_konfery_ucastnici", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "konfery_ucastnici" |
|||
}, |
|||
{ |
|||
"codename": "view_konfery_ucastnici", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "konfery_ucastnici" |
|||
}, |
|||
{ |
|||
"codename": "add_nastaveni", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "nastaveni" |
|||
}, |
|||
{ |
|||
"codename": "change_nastaveni", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "nastaveni" |
|||
}, |
|||
{ |
|||
"codename": "delete_nastaveni", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "nastaveni" |
|||
}, |
|||
{ |
|||
"codename": "view_nastaveni", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "nastaveni" |
|||
}, |
|||
{ |
|||
"codename": "add_novinky", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "novinky" |
|||
}, |
|||
{ |
|||
"codename": "change_novinky", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "novinky" |
|||
}, |
|||
{ |
|||
"codename": "delete_novinky", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "novinky" |
|||
}, |
|||
{ |
|||
"codename": "view_novinky", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "novinky" |
|||
}, |
|||
{ |
|||
"codename": "add_organizator", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "organizator" |
|||
}, |
|||
{ |
|||
"codename": "change_organizator", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "organizator" |
|||
}, |
|||
{ |
|||
"codename": "delete_organizator", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "organizator" |
|||
}, |
|||
{ |
|||
"codename": "view_organizator", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "organizator" |
|||
}, |
|||
{ |
|||
"codename": "add_osoba", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "osoba" |
|||
}, |
|||
{ |
|||
"codename": "change_osoba", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "osoba" |
|||
}, |
|||
{ |
|||
"codename": "delete_osoba", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "osoba" |
|||
}, |
|||
{ |
|||
"codename": "view_osoba", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "osoba" |
|||
}, |
|||
{ |
|||
"codename": "add_pohadka", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "pohadka" |
|||
}, |
|||
{ |
|||
"codename": "change_pohadka", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "pohadka" |
|||
}, |
|||
{ |
|||
"codename": "delete_pohadka", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "pohadka" |
|||
}, |
|||
{ |
|||
"codename": "view_pohadka", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "pohadka" |
|||
}, |
|||
{ |
|||
"codename": "add_prijemce", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "prijemce" |
|||
}, |
|||
{ |
|||
"codename": "change_prijemce", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "prijemce" |
|||
}, |
|||
{ |
|||
"codename": "delete_prijemce", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "prijemce" |
|||
}, |
|||
{ |
|||
"codename": "view_prijemce", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "prijemce" |
|||
}, |
|||
{ |
|||
"codename": "add_problem", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "problem" |
|||
}, |
|||
{ |
|||
"codename": "change_problem", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "problem" |
|||
}, |
|||
{ |
|||
"codename": "delete_problem", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "problem" |
|||
}, |
|||
{ |
|||
"codename": "view_problem", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "problem" |
|||
}, |
|||
{ |
|||
"codename": "add_resitel", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "resitel" |
|||
}, |
|||
{ |
|||
"codename": "change_resitel", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "resitel" |
|||
}, |
|||
{ |
|||
"codename": "delete_resitel", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "resitel" |
|||
}, |
|||
{ |
|||
"codename": "view_resitel", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "resitel" |
|||
}, |
|||
{ |
|||
"codename": "add_rocnik", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "rocnik" |
|||
}, |
|||
{ |
|||
"codename": "change_rocnik", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "rocnik" |
|||
}, |
|||
{ |
|||
"codename": "delete_rocnik", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "rocnik" |
|||
}, |
|||
{ |
|||
"codename": "view_rocnik", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "rocnik" |
|||
}, |
|||
{ |
|||
"codename": "add_skola", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "skola" |
|||
}, |
|||
{ |
|||
"codename": "change_skola", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "skola" |
|||
}, |
|||
{ |
|||
"codename": "delete_skola", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "skola" |
|||
}, |
|||
{ |
|||
"codename": "view_skola", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "skola" |
|||
}, |
|||
{ |
|||
"codename": "add_soustredeni", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "soustredeni" |
|||
}, |
|||
{ |
|||
"codename": "change_soustredeni", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "soustredeni" |
|||
}, |
|||
{ |
|||
"codename": "delete_soustredeni", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "soustredeni" |
|||
}, |
|||
{ |
|||
"codename": "view_soustredeni", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "soustredeni" |
|||
}, |
|||
{ |
|||
"codename": "add_soustredeni_organizatori", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "soustredeni_organizatori" |
|||
}, |
|||
{ |
|||
"codename": "change_soustredeni_organizatori", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "soustredeni_organizatori" |
|||
}, |
|||
{ |
|||
"codename": "delete_soustredeni_organizatori", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "soustredeni_organizatori" |
|||
}, |
|||
{ |
|||
"codename": "view_soustredeni_organizatori", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "soustredeni_organizatori" |
|||
}, |
|||
{ |
|||
"codename": "add_soustredeni_ucastnici", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "soustredeni_ucastnici" |
|||
}, |
|||
{ |
|||
"codename": "change_soustredeni_ucastnici", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "soustredeni_ucastnici" |
|||
}, |
|||
{ |
|||
"codename": "delete_soustredeni_ucastnici", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "soustredeni_ucastnici" |
|||
}, |
|||
{ |
|||
"codename": "view_soustredeni_ucastnici", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "soustredeni_ucastnici" |
|||
}, |
|||
{ |
|||
"codename": "add_tema", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "tema" |
|||
}, |
|||
{ |
|||
"codename": "change_tema", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "tema" |
|||
}, |
|||
{ |
|||
"codename": "delete_tema", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "tema" |
|||
}, |
|||
{ |
|||
"codename": "view_tema", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "tema" |
|||
}, |
|||
{ |
|||
"codename": "add_uloha", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "uloha" |
|||
}, |
|||
{ |
|||
"codename": "change_uloha", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "uloha" |
|||
}, |
|||
{ |
|||
"codename": "delete_uloha", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "uloha" |
|||
}, |
|||
{ |
|||
"codename": "view_uloha", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "uloha" |
|||
}, |
|||
{ |
|||
"codename": "add_tag", |
|||
"ct_app_label": "taggit", |
|||
"ct_model": "tag" |
|||
}, |
|||
{ |
|||
"codename": "change_tag", |
|||
"ct_app_label": "taggit", |
|||
"ct_model": "tag" |
|||
}, |
|||
{ |
|||
"codename": "delete_tag", |
|||
"ct_app_label": "taggit", |
|||
"ct_model": "tag" |
|||
}, |
|||
{ |
|||
"codename": "view_tag", |
|||
"ct_app_label": "taggit", |
|||
"ct_model": "tag" |
|||
}, |
|||
{ |
|||
"codename": "add_taggeditem", |
|||
"ct_app_label": "taggit", |
|||
"ct_model": "taggeditem" |
|||
}, |
|||
{ |
|||
"codename": "change_taggeditem", |
|||
"ct_app_label": "taggit", |
|||
"ct_model": "taggeditem" |
|||
}, |
|||
{ |
|||
"codename": "delete_taggeditem", |
|||
"ct_app_label": "taggit", |
|||
"ct_model": "taggeditem" |
|||
}, |
|||
{ |
|||
"codename": "view_taggeditem", |
|||
"ct_app_label": "taggit", |
|||
"ct_model": "taggeditem" |
|||
}, |
|||
{ |
|||
"codename": "add_fotkaheader", |
|||
"ct_app_label": "header_fotky", |
|||
"ct_model": "fotkaheader" |
|||
}, |
|||
{ |
|||
"codename": "change_fotkaheader", |
|||
"ct_app_label": "header_fotky", |
|||
"ct_model": "fotkaheader" |
|||
}, |
|||
{ |
|||
"codename": "view_fotkaheader", |
|||
"ct_app_label": "header_fotky", |
|||
"ct_model": "fotkaheader" |
|||
}, |
|||
{ |
|||
"codename": "add_fotkaurlvazba", |
|||
"ct_app_label": "header_fotky", |
|||
"ct_model": "fotkaurlvazba" |
|||
}, |
|||
{ |
|||
"codename": "change_fotkaurlvazba", |
|||
"ct_app_label": "header_fotky", |
|||
"ct_model": "fotkaurlvazba" |
|||
}, |
|||
{ |
|||
"codename": "view_fotkaurlvazba", |
|||
"ct_app_label": "header_fotky", |
|||
"ct_model": "fotkaurlvazba" |
|||
}, |
|||
{ |
|||
"codename": "add_deadline", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "deadline" |
|||
}, |
|||
{ |
|||
"codename": "change_deadline", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "deadline" |
|||
}, |
|||
{ |
|||
"codename": "view_deadline", |
|||
"ct_app_label": "seminar", |
|||
"ct_model": "deadline" |
|||
} |
|||
] |
@ -1,513 +0,0 @@ |
|||
#!/usr/bin/env python3 |
|||
|
|||
import psycopg2 |
|||
import psycopg2.extras |
|||
|
|||
OLD_DB = "mam_old" |
|||
NEW_DB = "mamweb" |
|||
|
|||
oldconn = psycopg2.connect(f"dbname={OLD_DB}") |
|||
newconn = psycopg2.connect(f"dbname={NEW_DB}") |
|||
|
|||
oldcur = oldconn.cursor(cursor_factory=psycopg2.extras.DictCursor) |
|||
newcur = newconn.cursor(cursor_factory=psycopg2.extras.DictCursor) |
|||
|
|||
|
|||
# Uses global variables oldcur, newcur! |
|||
def execute_simple(old_query, new_query=None): |
|||
if new_query is None: |
|||
new_query = old_query |
|||
|
|||
oldcur.execute(old_query) |
|||
newcur.execute(new_query) |
|||
|
|||
if oldcur.rowcount != newcur.rowcount: |
|||
raise ValueError(f"Queries '{old_query}' and '{new_query}' returned different number of rows ({oldcur.rowcount} and {newcur.rowcount})") |
|||
|
|||
return(oldcur.fetchall(), newcur.fetchall()) |
|||
|
|||
def check_same(old_row, new_row, old_fields, new_fields=None): |
|||
if type(old_fields) != list: |
|||
old_fields = [old_fields] |
|||
|
|||
if new_fields is None: |
|||
new_fields = old_fields |
|||
|
|||
fields = zip(old_fields, new_fields) |
|||
|
|||
for old_field, new_field in fields: |
|||
if old_row[old_field] == new_row[new_field]: |
|||
continue |
|||
raise ValueError(f"Fields '{old_field}'({old_row[old_field]}) and '{new_field}'({new_row[new_field]}) differs for rows \n'{old_row}' and \n'{new_row}'") |
|||
return True |
|||
|
|||
def get_user_id_for_org_id(org_id): |
|||
query = """SELECT auth_user.id FROM auth_user |
|||
INNER JOIN seminar_osoby ON seminar_osoby.user_id = auth_user.id |
|||
INNER JOIN seminar_organizator ON seminar_organizator.osoba_id = seminar_osoby.id |
|||
WHERE seminar_organizator.id = %s """ |
|||
|
|||
newcur.execute(query,(org_id,)) |
|||
return newcur.fetchone()['id'] |
|||
|
|||
|
|||
|
|||
|
|||
def check_skola(): |
|||
old_query = "SELECT * FROM seminar_skoly ORDER BY id" |
|||
|
|||
old_res, new_res = execute_simple(old_query) |
|||
res = zip(old_res,new_res) |
|||
|
|||
for o,n in res: |
|||
check_same(o,n,['id','aesop_id','izo','nazev','kratky_nazev','ulice','mesto','psc','stat','je_zs','je_ss','poznamka']) |
|||
|
|||
def check_resitel(): |
|||
old_query = 'SELECT * FROM seminar_resitele ORDER BY id' |
|||
new_query = '''SELECT seminar_resitele.id, skola_id, rok_maturity, zasilat, seminar_resitele.poznamka, |
|||
o.jmeno AS jmeno, o.prijmeni AS prijmeni, o.user_id AS user_id, o.pohlavi_muz AS pohlavi_muz, o.email AS email, o.telefon AS telefon, o.datum_narozeni AS datum_narozeni, |
|||
o.datum_souhlasu_udaje AS datum_souhlasu_udaje, o.datum_souhlasu_zasilani AS datum_souhlasu_zasilani, o.datum_registrace AS datum_prihlaseni, o.ulice AS ulice, o.mesto AS mesto, o.psc AS psc, o.stat AS stat |
|||
FROM seminar_resitele JOIN seminar_osoby AS o ON seminar_resitele.osoba_id = o.id ORDER BY seminar_resitele.id''' |
|||
|
|||
old_res, new_res = execute_simple(old_query,new_query) |
|||
|
|||
res = zip(old_res,new_res) |
|||
|
|||
fields_osoba = [ |
|||
'jmeno', |
|||
'prijmeni', |
|||
'user_id', |
|||
'pohlavi_muz', |
|||
#'email', #vyreseno separatne |
|||
'telefon', |
|||
'datum_narozeni', |
|||
'datum_souhlasu_udaje', |
|||
'datum_souhlasu_zasilani', |
|||
'datum_prihlaseni', |
|||
'ulice', |
|||
'mesto', |
|||
'psc', |
|||
'stat', |
|||
] |
|||
fields_keep = [ |
|||
'id', |
|||
'skola_id', |
|||
'rok_maturity', |
|||
'zasilat', |
|||
'poznamka', |
|||
] |
|||
fields = fields_keep+fields_osoba |
|||
for o,n in res: |
|||
check_same(o,n,fields) |
|||
if o['email'] != n['email'] and o['email'] != '': |
|||
print(f"WARNING: Emails differ: old: {o['email']}, new: {n['email']}") |
|||
|
|||
def check_reseni(): |
|||
# Migrace 0058 zamerne meni (zmensuje) pocet reseni, aby kazdy clanek mel |
|||
# jen jedno reseni (s vice resiteli, coz postaru neslo) |
|||
# Kvuli tomu je potreba kontrolovat dve veci: |
|||
# 1) Ze kazdy resitel dostal za kazdy problem spravne bodu |
|||
# 2) Ze detaily reseni zustaly zachovany |
|||
|
|||
# Cast 1) |
|||
old_query = 'SELECT * FROM seminar_reseni ORDER BY problem_id, resitel_id, body, timestamp' |
|||
new_query = '''SELECT seminar_reseni.id, forma, seminar_reseni.poznamka, cas_doruceni, hodnoceni.problem_id AS problem_id, hodnoceni.body AS body, hodnoceni.cislo_body_id AS cislo_body_id, res.id AS resitel_id |
|||
FROM seminar_reseni |
|||
JOIN seminar_hodnoceni AS hodnoceni ON seminar_reseni.id = hodnoceni.reseni_id |
|||
JOIN seminar_reseni_resitele AS rr ON seminar_reseni.id = rr.reseni_id |
|||
JOIN seminar_resitele AS res ON res.id = rr.resitele_id |
|||
ORDER BY problem_id, resitel_id, body, cas_doruceni''' |
|||
|
|||
# Po spojeni nekterych problemu se lisi casy doruceni a poznamky, proto je nebudeme kontrolovat (jde v podstate o triviality, tak je to snad jedno) |
|||
same_fields = ['forma', 'problem_id', 'body', 'cislo_body_id', 'resitel_id'] |
|||
renamed_fields = [ |
|||
#('timestamp', 'cas_doruceni'), |
|||
] |
|||
old_fields = same_fields + [f[0] for f in renamed_fields] |
|||
new_fields = same_fields + [f[1] for f in renamed_fields] |
|||
|
|||
old_res, new_res = execute_simple(old_query, new_query) |
|||
|
|||
res = zip(old_res,new_res) |
|||
|
|||
for o,n in res: |
|||
check_same(o,n,old_fields, new_fields) |
|||
|
|||
# Cast 2) |
|||
# Query se lisi tim, ze uz nejoinujeme resitele. |
|||
old_query = 'SELECT * FROM seminar_reseni ORDER BY id' |
|||
new_query = '''SELECT seminar_reseni.id, forma, poznamka, cas_doruceni AS timestamp, h.problem_id AS problem_id, h.body AS body, h.cislo_body_id AS cislo_body_id |
|||
FROM seminar_reseni |
|||
JOIN seminar_hodnoceni AS h ON h.reseni_id = seminar_reseni.id |
|||
ORDER BY id''' |
|||
|
|||
# execute_simple kontroluje stejnost poctu radku, to nechceme. |
|||
oldcur.execute(old_query) |
|||
newcur.execute(new_query) |
|||
old_res, new_res = oldcur.fetchall(), newcur.fetchall() |
|||
# Zkontrolujeme, ze pro kazde nove reseni ma stare reseni spravna data. |
|||
new_ids = [n['id'] for n in new_res] |
|||
spravna_old = list(filter(lambda o: o['id'] in new_ids, old_res)) |
|||
res = zip(spravna_old,new_res) |
|||
for o,n in res: |
|||
# Tady by se poznamky i timestampy mely zachovat |
|||
# Z nejakeho duvodu se ale poznamky lisi ve whitespace, tak je zkontrolujeme separatne |
|||
check_same(o,n,['id', 'forma', 'timestamp', 'problem_id', 'body', 'cislo_body_id']) |
|||
old_pozn = o['poznamka'].strip() |
|||
new_pozn = n['poznamka'].strip() |
|||
if old_pozn != new_pozn: |
|||
raise ValueError('Poznamky se lisi pro radky {dict(o)} a {dict(n)}') |
|||
|
|||
|
|||
|
|||
def check_organizator(): |
|||
old_query = 'SELECT * FROM seminar_organizator ORDER BY id' |
|||
new_query = '''SELECT seminar_organizator.id AS id, studuje, strucny_popis_organizatora, users.id AS uid, osoba.prezdivka AS o_prezdivka, osoba.foto AS o_foto, organizuje_od, organizuje_do |
|||
FROM seminar_organizator |
|||
JOIN seminar_osoby AS osoba ON osoba_id = osoba.id |
|||
JOIN auth_user AS users ON osoba.user_id = users.id |
|||
ORDER BY seminar_organizator.id''' |
|||
|
|||
same_fields = ['studuje', 'strucny_popis_organizatora'] |
|||
renamed_fields = [ |
|||
('user_id', 'uid'), |
|||
#('prezdivka', 'o_prezdivka'), |
|||
('foto', 'o_foto'), |
|||
] |
|||
old_fields = same_fields + [f[0] for f in renamed_fields] |
|||
new_fields = same_fields + [f[1] for f in renamed_fields] |
|||
|
|||
old_res, new_res = execute_simple(old_query,new_query) |
|||
res = zip(old_res, new_res) |
|||
for o,n in res: |
|||
check_same(o,n,old_fields, new_fields) |
|||
# organizuje od, do: |
|||
# Migrace prirazuje aktualni casovou zonu, takze chceme tady rucne vynutit CET. |
|||
from datetime import timedelta, timezone |
|||
cet = timezone(timedelta(hours=1)) |
|||
if o['organizuje_od_roku'] is None and n['organizuje_od'] is None: |
|||
pass |
|||
elif o['organizuje_od_roku'] != n['organizuje_od'].astimezone(cet).year: |
|||
raise ValueError(f'Not matching organizuje_od for org id={o["id"]}: old {o["organizuje_od_roku"]}, new {n["organizuje_od"]}') |
|||
if o['organizuje_do_roku'] is None and n['organizuje_do'] is None: |
|||
pass |
|||
elif o['organizuje_do_roku'] != n['organizuje_do'].astimezone(cet).year: |
|||
raise ValueError(f'Not matching organizuje_do for org id={o["id"]}: old {o["organizuje_do_roku"]}, new {n["organizuje_do"]}') |
|||
if o['prezdivka'] == n['o_prezdivka']: |
|||
continue |
|||
if o['prezdivka'] is None and n['o_prezdivka'] == '': |
|||
continue |
|||
raise ValueError(f'Not matching prezdivka for org id={o["id"]}: old {o["prezdivka"]}, new {n["o_prezdivka"]}') |
|||
|
|||
|
|||
def check_rocnik(): |
|||
old_query = "SELECT * FROM seminar_rocniky ORDER BY id" |
|||
|
|||
old_res, new_res = execute_simple(old_query) |
|||
res = zip(old_res,new_res) |
|||
|
|||
for o,n in res: |
|||
check_same(o,n,['id','prvni_rok', 'rocnik', 'exportovat']) |
|||
|
|||
def check_cislo(): |
|||
old_query = "SELECT * FROM seminar_cisla ORDER BY id" |
|||
|
|||
old_res, new_res = execute_simple(old_query) |
|||
res = zip(old_res,new_res) |
|||
|
|||
for o,n in res: |
|||
check_same(o,n, ['id','rocnik_id','cislo', 'datum_vydani','datum_deadline','verejne','poznamka','pdf'], |
|||
['id','rocnik_id','poradi','datum_vydani','datum_deadline','verejne','poznamka','pdf']) |
|||
|
|||
def check_priloha_reseni(): |
|||
old_query = "SELECT * FROM seminar_priloha_reseni" |
|||
|
|||
old_res, new_res = execute_simple(old_query) |
|||
res = zip(old_res,new_res) |
|||
|
|||
for o,n in res: |
|||
check_same(o,n, ['id','reseni_id', 'timestamp', 'soubor', 'poznamka'], |
|||
['id','reseni_id', 'vytvoreno', 'soubor', 'poznamka']) |
|||
|
|||
def check_soustredeni(): |
|||
old_query = "SELECT * FROM seminar_soustredeni ORDER BY id" |
|||
|
|||
old_res, new_res = execute_simple(old_query) |
|||
res = zip(old_res,new_res) |
|||
|
|||
for o,n in res: |
|||
check_same(o,n,['id','rocnik_id','datum_zacatku','datum_konce','verejne','misto','text','typ','exportovat']) |
|||
#Kontrola ucasnici, organizatori v samostatnych funkcich |
|||
|
|||
def check_soustredeni_ucastnici(): |
|||
old_query = "SELECT * FROM seminar_soustredeni_ucastnici ORDER BY id" |
|||
|
|||
old_res, new_res = execute_simple(old_query) |
|||
res = zip(old_res,new_res) |
|||
|
|||
for o,n in res: |
|||
check_same(o,n,['id','resitel_id','soustredeni_id','poznamka']) |
|||
|
|||
def check_soustredeni_organizatori(): |
|||
old_query = "SELECT * FROM seminar_soustredeni_organizatori ORDER BY id" |
|||
|
|||
old_res, new_res = execute_simple(old_query) |
|||
res = zip(old_res,new_res) |
|||
|
|||
for o,n in res: |
|||
check_same(o,n,['id','organizator_id','soustredeni_id','poznamka']) |
|||
|
|||
def check_nastaveni(): |
|||
old_query = "SELECT * FROM seminar_nastaveni ORDER BY id" |
|||
|
|||
old_res, new_res = execute_simple(old_query) |
|||
res = zip(old_res,new_res) |
|||
|
|||
for o,n in res: |
|||
check_same(o,n,['id','aktualni_cislo_id']) |
|||
|
|||
def check_novinky(): |
|||
old_query = "SELECT * FROM seminar_novinky ORDER BY id" |
|||
|
|||
old_res, new_res = execute_simple(old_query) |
|||
res = zip(old_res,new_res) |
|||
|
|||
for o,n in res: |
|||
check_same(o,n,['id','datum','text','obrazek','zverejneno']) |
|||
if get_user_id_for_org_id(n['autor_id']) != o['autor_id']: |
|||
raise ValueError("Nesedi autori u novinek") |
|||
|
|||
def check_pohadka(): |
|||
old_query = "SELECT * FROM seminar_pohadky ORDER BY id" |
|||
new_query = """SELECT sp.id AS id, sp.autor_id AS autor_id, sp.vytvoreno AS vytvoreno, snp.treenode_ptr_id AS treenode_ptr_id, st.na_web AS text, |
|||
zn_pred.uloha_id AS uloha_pred, zn_po.uloha_id AS uloha_po |
|||
FROM seminar_pohadky AS sp |
|||
-- Text pohádky |
|||
INNER JOIN seminar_nodes_pohadka AS snp ON sp.id = snp.pohadka_id |
|||
INNER JOIN seminar_nodes_treenode AS snt ON snt.id = snp.treenode_ptr_id |
|||
INNER JOIN seminar_nodes_obsah AS sno ON sno.treenode_ptr_id = snt.first_child_id |
|||
INNER JOIN seminar_texty AS st ON sno.text_id = st.id |
|||
-- Predchozí úloha |
|||
LEFT OUTER JOIN seminar_nodes_treenode AS ztn_pred ON ztn_pred.succ_id = snt.id |
|||
LEFT OUTER JOIN seminar_nodes_uloha_zadani AS zn_pred ON zn_pred.treenode_ptr_id = ztn_pred.id |
|||
-- Následující úloha |
|||
LEFT OUTER JOIN seminar_nodes_uloha_zadani AS zn_po ON zn_po.treenode_ptr_id = snt.succ_id |
|||
|
|||
ORDER BY sp.id""" |
|||
|
|||
old_res, new_res = execute_simple(old_query,new_query) |
|||
res = zip(old_res,new_res) |
|||
|
|||
for o,n in res: |
|||
check_same(o,n,['id','timestamp','text'],['id','vytvoreno','text']) |
|||
if o['autor_id'] is not None: |
|||
if get_user_id_for_org_id(n['autor_id']) != o['autor_id']: |
|||
raise ValueError("Nesedi autori u pohadky") |
|||
# Správné úlohy |
|||
# NOTE: o['pred'] rika, zda je pohadka pred ulohou, nikoliv zda je relevantni uloha pred pohadkou! |
|||
spravny_klic = 'uloha_po' if o['pred'] else 'uloha_pred' |
|||
if o['uloha_id'] != n[spravny_klic]: |
|||
raise ValueError(f"Pohádka přidružená ke špatné úloze! old: {o['uloha_id']}, new: {n[spravny_klic]}, pozice: {spravny_klic}") |
|||
|
|||
|
|||
# Problémy jsou rozdělené podle typů: |
|||
def check_problem_common(): |
|||
old_query = "SELECT id, nazev, stav, kod, autor_id, text_org, timestamp, typ FROM seminar_problemy ORDER BY id" |
|||
new_query = """SELECT sp.id AS id, sp.nazev AS nazev, sp.stav AS stav, sp.kod AS kod, au.id AS autor_id, sp.poznamka AS poznamka, sp.vytvoreno AS vytvoreno |
|||
FROM seminar_problemy AS sp |
|||
LEFT OUTER JOIN seminar_organizator AS so ON sp.autor_id = so.id |
|||
LEFT OUTER JOIN seminar_osoby AS sos ON so.osoba_id = sos.id |
|||
LEFT OUTER JOIN auth_user AS au ON sos.user_id = au.id |
|||
ORDER BY sp.id""" |
|||
|
|||
same_fields = ['id', 'nazev', 'stav', 'autor_id', 'kod'] |
|||
renamed_fields = [ |
|||
('text_org', 'poznamka'), |
|||
('timestamp', 'vytvoreno'), |
|||
] |
|||
old_fields = same_fields + [f[0] for f in renamed_fields] |
|||
new_fields = same_fields + [f[1] for f in renamed_fields] |
|||
|
|||
old_res, new_res = execute_simple(old_query,new_query) |
|||
res = zip(old_res,new_res) |
|||
|
|||
for o,n in res: |
|||
check_same(o,n, old_fields, new_fields) |
|||
|
|||
# Opravovatelé |
|||
# Po staru byli opravovatele organizatori, takze je potreba je dohledat. |
|||
old_query = """SELECT seminar_problemy.id, org.id AS opravovatel_id FROM seminar_problemy |
|||
JOIN seminar_organizator AS org ON seminar_problemy.opravovatel_id = org.user_id;""" |
|||
new_query = "SELECT problem_id, organizator_id FROM seminar_problemy_opravovatele" |
|||
|
|||
# Simple cursors |
|||
#oldcur = oldconn.cursor() |
|||
oldcur.execute(old_query) |
|||
old_results = oldcur.fetchall() |
|||
#newcur = newconn.cursor() |
|||
newcur.execute(new_query) |
|||
new_results = newcur.fetchall() |
|||
|
|||
for oldr in old_results: |
|||
if oldr not in new_results: |
|||
raise ValueError(f'Opravovatel pair {oldr} not found in new db.') |
|||
|
|||
# Zaměření se vyřeší okometricky (#1186) |
|||
|
|||
|
|||
def check_uloha(): |
|||
old_query = "SELECT * FROM seminar_problemy WHERE typ = 'uloha' ORDER BY id" |
|||
new_query = """SELECT cislo_zadani_id, cislo_reseni_id, problem_ptr_id, max_body, COALESCE(uzt.na_web, '') AS text_zadani, COALESCE(uvt.na_web, '') AS text_reseni, cislo_deadline_id |
|||
FROM seminar_ulohy |
|||
-- Problém: |
|||
JOIN seminar_problemy AS problem ON problem_ptr_id = problem.id |
|||
-- Text zadání: |
|||
-- ZadaniNode a VzorakNode maji existovat vzdy, ale obsah nemusi (pokud ho nemaji) |
|||
INNER JOIN seminar_nodes_uloha_zadani AS uzn ON problem.id = uzn.uloha_id |
|||
INNER JOIN seminar_nodes_treenode AS uztn ON uztn.id = uzn.treenode_ptr_id |
|||
LEFT OUTER JOIN seminar_nodes_obsah AS uzo ON uzo.treenode_ptr_id = uztn.first_child_id |
|||
LEFT OUTER JOIN seminar_texty AS uzt ON uzo.text_id = uzt.id |
|||
-- Text vzoráku: |
|||
INNER JOIN seminar_nodes_uloha_vzorak AS uvn ON problem.id = uvn.uloha_id |
|||
INNER JOIN seminar_nodes_treenode AS uvtn ON uvtn.id = uvn.treenode_ptr_id |
|||
LEFT OUTER JOIN seminar_nodes_obsah AS uvo ON uvo.treenode_ptr_id = uvtn.first_child_id |
|||
LEFT OUTER JOIN seminar_texty AS uvt ON uvo.text_id = uvt.id |
|||
|
|||
ORDER BY problem_ptr_id""" |
|||
|
|||
same_fields = ['cislo_zadani_id', 'cislo_reseni_id', 'text_zadani', 'text_reseni'] |
|||
renamed_fields = [ |
|||
('id', 'problem_ptr_id'), |
|||
('body', 'max_body'), |
|||
] |
|||
old_fields = same_fields + [f[0] for f in renamed_fields] |
|||
new_fields = same_fields + [f[1] for f in renamed_fields] |
|||
|
|||
old_res, new_res = execute_simple(old_query, new_query) |
|||
res = zip(old_res,new_res) |
|||
|
|||
for o,n in res: |
|||
check_same(o,n, old_fields, new_fields) |
|||
# Datum deadline vypadá prázdně, tak to budeme předpokládat. |
|||
if n['cislo_deadline_id'] is not None: |
|||
raise ValueError("Úloha má deadline.") |
|||
|
|||
def check_tema(): |
|||
old_query = """SELECT text_zadani, text_reseni, typ, c.rocnik_id AS rocnik_id |
|||
FROM seminar_problemy |
|||
LEFT OUTER JOIN seminar_cisla AS c ON c.id = cislo_zadani_id |
|||
WHERE typ IN ('tema', 'serial') |
|||
ORDER BY seminar_problemy.id""" |
|||
new_query = """SELECT tema_typ, COALESCE(zad_text.na_web, '') AS text_zadani, COALESCE(res_text.na_web, '') AS text_reseni, rn.rocnik_id AS rocnik_id |
|||
FROM seminar_temata |
|||
-- Problém: |
|||
JOIN seminar_problemy AS problem ON problem_ptr_id = problem.id |
|||
-- Text: |
|||
-- TvCNode má dva potomky, oba TextNode. První drží původní text zadání, druhý řešení. |
|||
INNER JOIN seminar_nodes_temavcisle AS tvcn ON tvcn.tema_id = id |
|||
INNER JOIN seminar_nodes_treenode AS ttn ON tvcn.treenode_ptr_id = ttn.id |
|||
LEFT OUTER JOIN seminar_nodes_treenode AS zad_tn ON ttn.first_child_id = zad_tn.id -- jen 33 z nich ma zadani |
|||
LEFT OUTER JOIN seminar_nodes_treenode AS res_tn ON zad_tn.succ_id = res_tn.id -- jen 4 z nich ma reseni |
|||
LEFT OUTER JOIN seminar_nodes_obsah AS zad_on ON zad_on.treenode_ptr_id = zad_tn.id |
|||
LEFT OUTER JOIN seminar_nodes_obsah AS res_on ON res_on.treenode_ptr_id = res_tn.id |
|||
LEFT OUTER JOIN seminar_texty AS zad_text ON zad_on.text_id = zad_text.id |
|||
LEFT OUTER JOIN seminar_texty AS res_text ON res_on.text_id = res_text.id -- vsechny 4 |
|||
-- Ročník tématu: |
|||
-- Podle rootu TvCN |
|||
LEFT OUTER JOIN seminar_nodes_rocnik AS rn ON ttn.root_id = rn.treenode_ptr_id |
|||
|
|||
ORDER BY problem_ptr_id""" |
|||
same_fields = ['text_zadani', 'text_reseni', 'rocnik_id'] |
|||
renamed_fields = [ |
|||
('typ', 'tema_typ'), |
|||
] |
|||
old_fields = same_fields + [f[0] for f in renamed_fields] |
|||
new_fields = same_fields + [f[1] for f in renamed_fields] |
|||
|
|||
old_res, new_res = execute_simple(old_query, new_query) |
|||
res = zip(old_res,new_res) |
|||
|
|||
for o,n in res: |
|||
check_same(o,n, old_fields, new_fields) |
|||
|
|||
def check_konfera(): |
|||
old_query = "SELECT * FROM seminar_problemy WHERE typ = 'konfera'" |
|||
new_query = "SELECT * FROM seminar_konfera" |
|||
|
|||
oldcur.execute(old_query) |
|||
newcur.execute(new_query) |
|||
|
|||
if oldcur.rowcount != 0 or newcur.rowcount != 0: |
|||
raise ValueError('There exists a Konfera!') |
|||
|
|||
def check_org_clanek(): |
|||
old_query = "SELECT * FROM seminar_problemy WHERE typ = 'org-clanek'" |
|||
|
|||
oldcur.execute(old_query) |
|||
|
|||
if oldcur.rowcount != 0: |
|||
raise ValueError('There exists a Org-clanek!') |
|||
|
|||
def check_res_clanek(): |
|||
# Dva(!) články mají text (zadání), který se má zachovat. |
|||
old_query = "SELECT * FROM seminar_problemy WHERE typ = 'res-clanek' ORDER BY id" |
|||
new_query = """SELECT cislo_id, text.na_web AS text_zadani |
|||
FROM seminar_clanky |
|||
JOIN seminar_problemy AS problem ON problem_ptr_id = problem.id |
|||
INNER JOIN seminar_hodnoceni AS hodn ON problem.id = hodn.problem_id |
|||
INNER JOIN seminar_reseni AS rese ON rese.id = hodn.reseni_id |
|||
INNER JOIN seminar_nodes_otistene_reseni AS rn ON rese.text_cely_id = rn.treenode_ptr_id -- Tenhle radek neni potreba, ale ujistuje se mj. o spravnem typu TreeNode. |
|||
INNER JOIN seminar_nodes_treenode AS tn ON rn.treenode_ptr_id = tn.id |
|||
-- Nektere clanky vubec nemely text, tak jim migr 0058 nevyrobila dalsi treenody |
|||
LEFT OUTER JOIN seminar_nodes_obsah AS son ON son.treenode_ptr_id = tn.first_child_id |
|||
LEFT OUTER JOIN seminar_texty AS text ON text.id = son.text_id |
|||
|
|||
ORDER BY problem_ptr_id""" |
|||
same_fields = ['text_zadani'] |
|||
renamed_fields = [ |
|||
('cislo_zadani_id', 'cislo_id'), |
|||
] |
|||
old_fields = same_fields + [f[0] for f in renamed_fields] |
|||
new_fields = same_fields + [f[1] for f in renamed_fields] |
|||
|
|||
old_res, new_res = execute_simple(old_query, new_query) |
|||
res = zip(old_res,new_res) |
|||
|
|||
for o,n in res: |
|||
# text_zadani po novu mohl byt None |
|||
if n['text_zadani'] is None: |
|||
n['text_zadani'] = '' |
|||
check_same(o,n, old_fields, new_fields) |
|||
assert(o['text_reseni'] == '') |
|||
|
|||
def check_untyped_problem(): |
|||
old_query = "SELECT * FROM seminar_problemy WHERE typ NOT IN ('uloha', 'tema', 'serial', 'konfera', 'org-clanek', 'res-clanek')" |
|||
|
|||
oldcur.execute(old_query) |
|||
|
|||
if oldcur.rowcount != 0: |
|||
raise ValueError('There exists a Problem without type!') |
|||
|
|||
|
|||
|
|||
check_skola() |
|||
check_resitel() |
|||
check_reseni() |
|||
check_organizator() |
|||
check_rocnik() |
|||
check_cislo() |
|||
check_priloha_reseni() |
|||
check_soustredeni() |
|||
check_soustredeni_ucastnici() |
|||
check_soustredeni_organizatori() |
|||
check_nastaveni() |
|||
check_novinky() |
|||
check_pohadka() |
|||
|
|||
check_problem_common() |
|||
check_uloha() |
|||
check_tema() |
|||
check_konfera() |
|||
check_org_clanek() |
|||
check_res_clanek() |
|||
check_untyped_problem() |
@ -1,22 +0,0 @@ |
|||
#!/bin/bash |
|||
|
|||
set -u |
|||
|
|||
deactivate || true |
|||
|
|||
cd /akce/mam/www/mamweb-test/ |
|||
make sync_test |
|||
systemctl --user stop mamweb-test.service |
|||
rm -rvf env |
|||
make install_venv |
|||
. env/bin/activate |
|||
make install |
|||
deploy_v2/pre_migration.py |
|||
make deploy_test |
|||
./manage.py load_org_permissions admin_org_prava.json |
|||
./manage.py loaddata data/* |
|||
systemctl --user start mamweb-test.service |
|||
./manage.py generate_thumbnails |
|||
|
|||
echo 'Et voilá!' |
|||
echo 'Nezapomeň opravit práva pro sitetree!' |
@ -1,14 +0,0 @@ |
|||
Milí řešitelé M&M, |
|||
|
|||
web M&Mka dostal nový kabátek a zároveň se v něm objevilo odevzdávátko. Navíc, |
|||
pokud se zaregistrujete pod e-mailem, na který jsme vám poslali tuhle zprávu, |
|||
uvidíte rovnou i body za svá dosud odevzdaná řešení. |
|||
|
|||
Web budeme i nadále vylepšovat, a zajímá nás i jak to vidíte vy. Pokud byste |
|||
na webu našli nějaký nedostatek, nebo nám prostě jen chtěli napsat, nebojte se |
|||
k tomu použít adresu mam@matfyz.cz. |
|||
|
|||
Těšíme se na vaše řešení! (Připomínáme termín pro účast na soustředění 21. září.) |
|||
|
|||
Za časopis M&M, |
|||
Pavel Turinský |
@ -1,3 +0,0 @@ |
|||
Jsou špatně práva k sitetree (protože se používají primární klíče, které jsou jiné :-() |
|||
Špatné položky se dají najít pomocí následujícího příkazu: |
|||
grep -E 'access_permissions": \[$' data/sitetree.json -A17 | grep -E 'acc|tit' -A2 |
@ -1,42 +0,0 @@ |
|||
#!/usr/bin/env python3 |
|||
|
|||
import os |
|||
import sys |
|||
|
|||
import django |
|||
|
|||
#### Inicializace Djanga |
|||
sys.path.append(os.path.dirname(os.path.realpath(__file__))+'/..') |
|||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mamweb.settings') |
|||
django.setup() |
|||
|
|||
## Pozor, nejde pouzit ORM, protoze kod je na jine verzi nez databaze a nejde namigrovat. |
|||
from django.db import connection |
|||
|
|||
|
|||
def smaz_zle_clanky(): |
|||
# Tyhle clanky vubec nejsou clanky, bude potreba je udelat cele jinak a spravne. |
|||
#m.Problem.objects.filter(id__in=[1981, 1970, 2222]).delete() |
|||
## with connection.cursor() as cursor: |
|||
## # Nejdriv musime smazat reseni: |
|||
## cursor.execute('DELETE FROM seminar_reseni WHERE problem_id IN (1981, 1970, 2222);') |
|||
## # Nakonec i ty clanky samotne |
|||
## cursor.execute('DELETE FROM seminar_problemy WHERE id IN (1981, 1970, 2222);') |
|||
|
|||
# Update: stejně je v DB bordel, tak z nich prostě jen udělám témata a všechno zhruba přežije… |
|||
with connection.cursor() as cursor: |
|||
cursor.execute("UPDATE seminar_problemy SET typ = 'tema' WHERE id IN (1981, 1970, 2222);") |
|||
|
|||
def smaz_divne_uzivatele(): |
|||
# U techto uzivatelu neexistuje Organizator s nimi spojeny |
|||
# Takze pak delaji akorat neporadek |
|||
with connection.cursor() as cursor: |
|||
# Jeste je potreba zrusit vazby |
|||
cursor.execute('UPDATE django_comments SET user_id = NULL WHERE user_id = 34;') |
|||
cursor.execute('UPDATE seminar_problemy SET autor_id = NULL WHERE autor_id = 34;') |
|||
cursor.execute('DELETE FROM django_admin_log WHERE user_id = 34;') |
|||
cursor.execute('DELETE FROM auth_user_groups WHERE user_id = 34;') |
|||
cursor.execute('DELETE FROM auth_user WHERE id IN (34, 40, 30, 50, 54, 58, 43);') |
|||
|
|||
smaz_zle_clanky() |
|||
smaz_divne_uzivatele() |
@ -1,3 +1,4 @@ |
|||
TODO přepsat do rst případně přesunout na wiki |
|||
Přidání obrázků do odměn: |
|||
admin -> flatpage odměn -> ikona přidat obrázek |
|||
záložka odeslat, vybrat obrázek, odeslat |
@ -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,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) |
@ -0,0 +1,29 @@ |
|||
# Generated by Django 2.2.28 on 2023-08-09 19:30 |
|||
|
|||
from django.db import migrations, models |
|||
import django.db.models.deletion |
|||
|
|||
|
|||
class Migration(migrations.Migration): |
|||
|
|||
dependencies = [ |
|||
('galerie', '0010_auto_20200819_0947'), |
|||
('soustredeni', '0001_initial'), |
|||
] |
|||
|
|||
run_before = [ |
|||
('seminar', '0121_smazani_soustredeni'), |
|||
] |
|||
|
|||
operations = [ |
|||
migrations.SeparateDatabaseAndState( |
|||
state_operations=[ |
|||
migrations.AlterField( |
|||
model_name='galerie', |
|||
name='soustredeni', |
|||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='soustredeni.Soustredeni'), |
|||
), |
|||
], |
|||
database_operations=[], |
|||
), |
|||
] |
@ -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? |
|||
|
|||
|
@ -0,0 +1,39 @@ |
|||
# Generated by Django 2.2.28 on 2023-07-31 17:54 |
|||
|
|||
from django.db import migrations, models |
|||
import django.db.models.deletion |
|||
|
|||
|
|||
class Migration(migrations.Migration): |
|||
|
|||
dependencies = [ |
|||
('korektury', '0020_lepsi_popis_nazvu_PDF_v_adminu'), |
|||
('personalni', '0002_initial'), |
|||
] |
|||
|
|||
run_before = [ |
|||
('seminar', '0116_smazani_personalniho'), |
|||
] |
|||
|
|||
operations = [ |
|||
migrations.SeparateDatabaseAndState( |
|||
state_operations=[ |
|||
migrations.AlterField( |
|||
model_name='komentar', |
|||
name='autor', |
|||
field=models.ForeignKey(blank=True, help_text='Autor komentáře', null=True, on_delete=django.db.models.deletion.SET_NULL, to='personalni.Organizator'), |
|||
), |
|||
migrations.AlterField( |
|||
model_name='korekturovanepdf', |
|||
name='org', |
|||
field=models.ForeignKey(blank=True, default=None, help_text='Zodpovědný organizátor za obsah', null=True, on_delete=django.db.models.deletion.SET_NULL, to='personalni.Organizator'), |
|||
), |
|||
migrations.AlterField( |
|||
model_name='oprava', |
|||
name='autor', |
|||
field=models.ForeignKey(blank=True, help_text='Autor opravy', null=True, on_delete=django.db.models.deletion.SET_NULL, to='personalni.Organizator'), |
|||
), |
|||
], |
|||
database_operations=[], |
|||
), |
|||
] |
@ -1,3 +0,0 @@ |
|||
from django.test import TestCase |
|||
|
|||
# Create your tests here. |
@ -1,18 +1,10 @@ |
|||
""" |
|||
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 seminar.utils import org_required |
|||
from personalni.utils import org_required |
|||
from . import views |
|||
|
|||
urlpatterns = [ |
|||
path('korektury/', org_required(views.KorekturySeskupeneListView.as_view()), name='korektury_list'), |
|||
path('korektury/neseskupene/', org_required(views.KorekturyAktualniListView.as_view()), name='korektury_neseskupene_list'), |
|||
path('korektury/zastarale/', org_required(views.KorekturyZastaraleListView.as_view()), name='korektury_stare_list'), |
|||
path('korektury/<int:pdf>/', org_required(views.KorekturyView.as_view()), name='korektury'), |
|||
path('', org_required(views.KorekturySeskupeneListView.as_view()), name='korektury_list'), |
|||
path('neseskupene/', org_required(views.KorekturyAktualniListView.as_view()), name='korektury_neseskupene_list'), |
|||
path('zastarale/', org_required(views.KorekturyZastaraleListView.as_view()), name='korektury_stare_list'), |
|||
path('<int:pdf>/', org_required(views.KorekturyView.as_view()), name='korektury'), |
|||
] |
|||
|
@ -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 |
@ -0,0 +1,22 @@ |
|||
from .settings_common import * |
|||
|
|||
DEBUG = True |
|||
TEMPLATES[0]['OPTIONS']['debug'] = True |
|||
|
|||
MIDDLEWARE += ( |
|||
'debug_toolbar.middleware.DebugToolbarMiddleware', |
|||
) |
|||
|
|||
INSTALLED_APPS += ( |
|||
'debug_toolbar', # Takovéto užitečné (pro debug) na html stránce vpravo |
|||
'django_extensions', # Kolekce zajímavých ./manage.py commandů |
|||
) |
|||
|
|||
DEBUG_TOOLBAR_CONFIG = { |
|||
'SHOW_COLLAPSED': True, |
|||
} |
|||
|
|||
# Nechceme nikomu omylem poslat e-mail |
|||
# Když někdo spustí omylem tohle nastavení, prostě to při poslání mailu spadne |
|||
# V settings_local a settings_test přepíšeme... |
|||
EMAIL_BACKEND = None |
@ -0,0 +1,108 @@ |
|||
# Generated by Django 2.2.28 on 2023-08-09 17:37 |
|||
|
|||
from django.db import migrations, models |
|||
import django.db.models.deletion |
|||
import django.utils.timezone |
|||
import odevzdavatko.models |
|||
|
|||
|
|||
class Migration(migrations.Migration): |
|||
|
|||
initial = True |
|||
|
|||
dependencies = [ |
|||
('tvorba', '0001_initial'), |
|||
('personalni', '0002_initial'), |
|||
('seminar', '0117_separace_tvorby'), |
|||
] |
|||
|
|||
run_before = [ |
|||
('seminar', '0120_smazani_odevzdavatka'), |
|||
] |
|||
|
|||
operations = [ |
|||
migrations.SeparateDatabaseAndState( |
|||
state_operations=[ |
|||
migrations.CreateModel( |
|||
name='Hodnoceni', |
|||
fields=[ |
|||
('id', models.AutoField(primary_key=True, serialize=False)), |
|||
('body', models.DecimalField(blank=True, decimal_places=1, max_digits=8, null=True, verbose_name='body')), |
|||
('feedback', models.TextField(blank=True, default='', help_text='Zpětná vazba řešiteli (plain text)', verbose_name='zpětná vazba')), |
|||
('cislo_body', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='hodnoceni', to='tvorba.Cislo', verbose_name='číslo pro body')), |
|||
('deadline_body', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='hodnoceni', to='tvorba.Deadline', verbose_name='deadline pro body')), |
|||
('problem', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='hodnoceni', to='tvorba.Problem', verbose_name='problém')), |
|||
], |
|||
options={ |
|||
'verbose_name': 'Hodnocení', |
|||
'verbose_name_plural': 'Hodnocení', |
|||
'db_table': 'mam_hodnoceni', |
|||
}, |
|||
), |
|||
migrations.CreateModel( |
|||
name='Reseni', |
|||
fields=[ |
|||
('id', models.AutoField(primary_key=True, serialize=False)), |
|||
('cas_doruceni', models.DateTimeField(blank=True, default=django.utils.timezone.now, verbose_name='čas_doručení')), |
|||
('forma', models.CharField(choices=[('papir', 'Papírové řešení'), ('email', 'Emailem'), ('upload', 'Upload přes web')], default='email', max_length=16, verbose_name='forma řešení')), |
|||
('poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka k řešení (plain text)', verbose_name='neveřejná poznámka')), |
|||
('zverejneno', models.BooleanField(default=False, help_text='Udává, zda je řešení zveřejněno', verbose_name='řešení zveřejněno')), |
|||
('problem', models.ManyToManyField(help_text='Problém', through='odevzdavatko.Hodnoceni', to='tvorba.Problem', verbose_name='problém')), |
|||
], |
|||
options={ |
|||
'verbose_name': 'Řešení', |
|||
'verbose_name_plural': 'Řešení', |
|||
'db_table': 'mam_reseni', |
|||
'ordering': ['-cas_doruceni'], |
|||
}, |
|||
), |
|||
migrations.CreateModel( |
|||
name='Reseni_Resitele', |
|||
fields=[ |
|||
('id', models.AutoField(primary_key=True, serialize=False)), |
|||
('reseni', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='odevzdavatko.Reseni', verbose_name='řešení')), |
|||
('resitele', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='personalni.Resitel', verbose_name='řešitel')), |
|||
], |
|||
options={ |
|||
'verbose_name': 'Řešení řešitelů', |
|||
'verbose_name_plural': 'Řešení řešitelů', |
|||
'db_table': 'mam_reseni_resitele', |
|||
'ordering': ['reseni', 'resitele'], |
|||
}, |
|||
), |
|||
migrations.AddField( |
|||
model_name='reseni', |
|||
name='resitele', |
|||
field=models.ManyToManyField(help_text='Seznam autorů řešení', through='odevzdavatko.Reseni_Resitele', to='personalni.Resitel', verbose_name='autoři řešení'), |
|||
), |
|||
migrations.AddField( |
|||
model_name='reseni', |
|||
name='text_cely', |
|||
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='reseni_cely_set', to='seminar.ReseniNode', verbose_name='Plná verze textu řešení'), |
|||
), |
|||
migrations.CreateModel( |
|||
name='PrilohaReseni', |
|||
fields=[ |
|||
('id', models.AutoField(primary_key=True, serialize=False)), |
|||
('vytvoreno', models.DateTimeField(blank=True, default=django.utils.timezone.now, editable=False, verbose_name='vytvořeno')), |
|||
('soubor', models.FileField(upload_to=odevzdavatko.models.generate_filename, verbose_name='soubor')), |
|||
('poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka k příloze řešení (plain text), např. o původu', verbose_name='neveřejná poznámka')), |
|||
('res_poznamka', models.TextField(blank=True, help_text='Poznámka k příloze řešení, např. co daný soubor obsahuje', verbose_name='poznámka řešitele')), |
|||
('reseni', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='prilohy', to='odevzdavatko.Reseni', verbose_name='řešení')), |
|||
], |
|||
options={ |
|||
'verbose_name': 'Příloha řešení', |
|||
'verbose_name_plural': 'Přílohy řešení', |
|||
'db_table': 'mam_priloha_reseni', |
|||
'ordering': ['reseni', 'vytvoreno'], |
|||
}, |
|||
), |
|||
migrations.AddField( |
|||
model_name='hodnoceni', |
|||
name='reseni', |
|||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='odevzdavatko.Reseni', verbose_name='řešení'), |
|||
), |
|||
], |
|||
database_operations=[], |
|||
), |
|||
] |
@ -0,0 +1,25 @@ |
|||
# Generated by Django 2.2.28 on 2023-08-10 07:14 |
|||
|
|||
from django.db import migrations, models |
|||
import django.db.models.deletion |
|||
|
|||
|
|||
class Migration(migrations.Migration): |
|||
|
|||
dependencies = [ |
|||
('odevzdavatko', '0001_initial'), |
|||
('treenode', '0001_initial'), |
|||
] |
|||
|
|||
operations = [ |
|||
migrations.SeparateDatabaseAndState( |
|||
state_operations=[ |
|||
migrations.AlterField( |
|||
model_name='reseni', |
|||
name='text_cely', |
|||
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='reseni_cely_set', to='treenode.ReseniNode', verbose_name='Plná verze textu řešení'), |
|||
), |
|||
], |
|||
database_operations=[], |
|||
), |
|||
] |
@ -0,0 +1,49 @@ |
|||
import datetime |
|||
import random |
|||
|
|||
from .models import * |
|||
|
|||
|
|||
def gen_reseni_ulohy(rnd, cisla, uloha, pocet_resitelu, poradi_cisla, resitele_cisla, resitele): |
|||
pocet_reseni = rnd.randint(pocet_resitelu//4, pocet_resitelu * 4) |
|||
# generujeme náhodný počet řešení vzhledem k počtu řešitelů čísla |
|||
for _ in range(pocet_reseni): |
|||
# print("Generuji {}-té řešení".format(reseni)) |
|||
if rnd.randint(1, 10) == 1: |
|||
# cca desetina řešení od více řešitelů |
|||
res_vyber = rnd.sample(resitele_cisla, rnd.randint(2, 5)) |
|||
else: |
|||
res_vyber = rnd.sample(resitele_cisla, 1) |
|||
if resitele[0] in res_vyber: # speciální řešitel, který nemá žádné body |
|||
res_vyber.remove(resitele[0]) |
|||
|
|||
# Vytvoření řešení. |
|||
if uloha.cislo_zadani.zlomovy_deadline_pro_papirove_cislo() is not None: |
|||
# combine, abychom dostali plný čas a ne jen datum |
|||
cas_doruceni = ( |
|||
uloha.cislo_zadani.deadline_v_cisle.first().deadline - |
|||
datetime.timedelta(days=random.randint(0, 40)) - |
|||
datetime.timedelta(minutes=random.randint(0, 60*24)) |
|||
) |
|||
# astimezone, protože jinak vyhazuje warning o nenastavené TZ |
|||
res = Reseni.objects.create( |
|||
forma=rnd.choice(Reseni.FORMA_CHOICES)[0], |
|||
cas_doruceni=cas_doruceni.astimezone(datetime.timezone.utc), |
|||
) |
|||
else: |
|||
res = Reseni.objects.create( |
|||
forma=rnd.choice(Reseni.FORMA_CHOICES)[0], |
|||
) |
|||
# Problém a řešitele přiřadíme později, ManyToManyField |
|||
# se nedá vyplnit v create(). |
|||
res.resitele.set(res_vyber) |
|||
res.save() |
|||
|
|||
# Vytvoření hodnocení. |
|||
hod = Hodnoceni.objects.create( |
|||
body=rnd.randint(0, uloha.max_body), |
|||
cislo_body=cisla[poradi_cisla - 1], |
|||
reseni=res, |
|||
problem=uloha |
|||
) |
|||
return |
@ -0,0 +1,11 @@ |
|||
import decimal |
|||
|
|||
|
|||
def vzorecek_na_prepocet(body, resitelu): |
|||
""" Vzoreček na přepočet plných bodů na parciálni, když má řešení více řešitelů. """ |
|||
return body * 3 / (resitelu + 2) |
|||
|
|||
|
|||
def inverze_vzorecku_na_prepocet(body: decimal.Decimal, resitelu) -> decimal.Decimal: |
|||
""" Vzoreček na přepočet parciálních bodů na plné, když má řešení více řešitelů. """ |
|||
return round(body * (resitelu + 2) / 3, 1) |
@ -0,0 +1,134 @@ |
|||
# Generated by Django 2.2.28 on 2023-07-31 17:54 |
|||
|
|||
from django.conf import settings |
|||
from django.db import migrations, models |
|||
import django.utils.timezone |
|||
import django_countries.fields |
|||
import imagekit.models.fields |
|||
|
|||
|
|||
class Migration(migrations.Migration): |
|||
|
|||
initial = True |
|||
|
|||
dependencies = [ |
|||
migrations.swappable_dependency(settings.AUTH_USER_MODEL), |
|||
('personalni', '0001_skupiny'), |
|||
('seminar', '0114_prejmenovani_tabulek'), |
|||
] |
|||
|
|||
operations = [ |
|||
migrations.SeparateDatabaseAndState( |
|||
state_operations=[ |
|||
migrations.CreateModel( |
|||
name='Osoba', |
|||
fields=[ |
|||
('id', models.AutoField(primary_key=True, serialize=False)), |
|||
('jmeno', models.CharField(max_length=256, verbose_name='jméno')), |
|||
('prijmeni', models.CharField(max_length=256, verbose_name='příjmení')), |
|||
('prezdivka', models.CharField(blank=True, max_length=256, null=True, verbose_name='přezdívka')), |
|||
('pohlavi_muz', models.BooleanField(default=False, verbose_name='pohlaví (muž)')), |
|||
('email', models.EmailField(blank=True, default='', max_length=256, verbose_name='e-mail')), |
|||
('telefon', models.CharField(blank=True, default='', max_length=256, verbose_name='telefon')), |
|||
('datum_narozeni', models.DateField(blank=True, null=True, verbose_name='datum narození')), |
|||
('datum_souhlasu_udaje', models.DateField(blank=True, help_text='Datum souhlasu se zpracováním osobních údajů', null=True, verbose_name='datum souhlasu (údaje)')), |
|||
('datum_souhlasu_zasilani', models.DateField(blank=True, help_text='Datum souhlasu se zasíláním MFF materiálů', null=True, verbose_name='datum souhlasu (spam)')), |
|||
('datum_registrace', models.DateField(default=django.utils.timezone.now, verbose_name='datum registrace do semináře')), |
|||
('ulice', models.CharField(blank=True, default='', max_length=256, verbose_name='ulice')), |
|||
('mesto', models.CharField(blank=True, default='', max_length=256, verbose_name='město')), |
|||
('psc', models.CharField(blank=True, default='', max_length=32, verbose_name='PSČ')), |
|||
('stat', django_countries.fields.CountryField(default='CZ', help_text='ISO 3166-1 kód země velkými písmeny (CZ, SK, ...)', max_length=2, verbose_name='stát')), |
|||
('jak_se_dozvedeli', models.TextField(blank=True, verbose_name='Jak se dozvěděli')), |
|||
('poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka k osobě (plain text)', verbose_name='neveřejná poznámka')), |
|||
('foto', imagekit.models.fields.ProcessedImageField(blank=True, help_text='Vlož fotografii osoby o libovolné velikosti', null=True, upload_to='image_osoby/velke/%Y/', verbose_name='Fotografie osoby')), |
|||
('user', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, to=settings.AUTH_USER_MODEL, verbose_name='uživatel')), |
|||
], |
|||
options={ |
|||
'verbose_name': 'Osoba', |
|||
'verbose_name_plural': 'Osoby', |
|||
'db_table': 'mam_osoby', |
|||
'ordering': ['prijmeni', 'jmeno'], |
|||
}, |
|||
), |
|||
migrations.CreateModel( |
|||
name='Skola', |
|||
fields=[ |
|||
('id', models.AutoField(primary_key=True, serialize=False)), |
|||
('aesop_id', models.CharField(blank=True, default='', help_text='Aesopi ID typu "izo:..." nebo "aesop:..."', max_length=32, verbose_name='Aesop ID')), |
|||
('izo', models.CharField(blank=True, help_text='IZO školy (jen české školy)', max_length=32, verbose_name='IZO')), |
|||
('nazev', models.CharField(help_text='Celý název školy', max_length=256, verbose_name='název')), |
|||
('kratky_nazev', models.CharField(blank=True, help_text='Zkrácený název pro zobrazení ve výsledkovce', max_length=256, verbose_name='zkrácený název')), |
|||
('ulice', models.CharField(max_length=256, verbose_name='ulice')), |
|||
('mesto', models.CharField(max_length=256, verbose_name='město')), |
|||
('psc', models.CharField(max_length=32, verbose_name='PSČ')), |
|||
('stat', django_countries.fields.CountryField(default='CZ', help_text='ISO 3166-1 kód země velkými písmeny (CZ, SK, ...)', max_length=2, verbose_name='stát')), |
|||
('je_zs', models.BooleanField(default=True, verbose_name='základní stupeň')), |
|||
('je_ss', models.BooleanField(default=True, verbose_name='střední stupeň')), |
|||
('poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka ke škole (plain text)', verbose_name='neveřejná poznámka')), |
|||
('kontaktni_osoba', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='personalni.Osoba', verbose_name='Kontaktní osoba')), |
|||
], |
|||
options={ |
|||
'verbose_name': 'Škola', |
|||
'verbose_name_plural': 'Školy', |
|||
'db_table': 'mam_skoly', |
|||
'ordering': ['mesto', 'nazev'], |
|||
}, |
|||
), |
|||
migrations.CreateModel( |
|||
name='Resitel', |
|||
fields=[ |
|||
('id', models.AutoField(primary_key=True, serialize=False)), |
|||
('prezdivka_resitele', models.CharField(blank=True, max_length=256, null=True, unique=True, verbose_name='přezdívka řešitele')), |
|||
('rok_maturity', models.IntegerField(blank=True, null=True, verbose_name='rok maturity')), |
|||
('zasilat', models.CharField(choices=[('domu', 'Domů'), ('do_skoly', 'Do školy'), ('nikam', 'Nezasílat papírově')], default='domu', max_length=32, verbose_name='kam zasílat')), |
|||
('zasilat_cislo_emailem', models.BooleanField(default=False, help_text='True pokud chce řešitel dostávat číslo emailem', verbose_name='zasílat číslo emailem')), |
|||
('zasilat_cislo_papirove', models.BooleanField(default=True, help_text='True pokud chce řešitel dostávat číslo papírově', verbose_name='zasílat číslo papírově')), |
|||
('poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka k řešiteli (plain text)', verbose_name='neveřejná poznámka')), |
|||
('osoba', models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, to='personalni.Osoba', verbose_name='osoba')), |
|||
('skola', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='personalni.Skola', verbose_name='škola')), |
|||
], |
|||
options={ |
|||
'verbose_name': 'Řešitel', |
|||
'verbose_name_plural': 'Řešitelé', |
|||
'db_table': 'mam_resitele', |
|||
'ordering': ['osoba'], |
|||
}, |
|||
), |
|||
migrations.CreateModel( |
|||
name='Prijemce', |
|||
fields=[ |
|||
('id', models.AutoField(primary_key=True, serialize=False)), |
|||
('poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka k příemci čísel (plain text)', verbose_name='neveřejná poznámka')), |
|||
('zasilat_cislo_emailem', models.BooleanField(default=False, help_text='True pokud chce příjemce dostávat číslo emailem', verbose_name='zasílat číslo emailem')), |
|||
('osoba', models.OneToOneField(help_text='Které osobě či na jakou adresu se mají zasílat čísla', on_delete=django.db.models.deletion.CASCADE, to='personalni.Osoba', verbose_name='komu')), |
|||
], |
|||
options={ |
|||
'verbose_name': 'příjemce', |
|||
'verbose_name_plural': 'příjemce', |
|||
'db_table': 'mam_prijemce', |
|||
}, |
|||
), |
|||
migrations.CreateModel( |
|||
name='Organizator', |
|||
fields=[ |
|||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
|||
('vytvoreno', models.DateTimeField(blank=True, default=django.utils.timezone.now, editable=False, verbose_name='Vytvořeno')), |
|||
('organizuje_od', models.DateTimeField(blank=True, null=True, verbose_name='Organizuje od')), |
|||
('organizuje_do', models.DateTimeField(blank=True, null=True, verbose_name='Organizuje do')), |
|||
('studuje', models.CharField(blank=True, help_text="Např. 'Studuje Obecnou fyziku (Bc.), 3. ročník', 'Vystudovala Diskrétní modely a algoritmy (Mgr.)' nebo 'Přednáší na MFF'", max_length=256, null=True, verbose_name='Studium aj.')), |
|||
('strucny_popis_organizatora', models.TextField(blank=True, null=True, verbose_name='Stručný popis organizátora')), |
|||
('skola', models.CharField(blank=True, help_text='Škola, např. MFF, VŠCHT, VUT, ... prostě aby se nemuselo psát do studuješkolu, ale jen obor, možnost zobrazit zvlášť', max_length=256, null=True, verbose_name='Škola, kterou studuje')), |
|||
('osoba', models.OneToOneField(help_text='osobní údaje organizátora', on_delete=django.db.models.deletion.PROTECT, related_name='org', to='personalni.Osoba', verbose_name='osoba')), |
|||
], |
|||
options={ |
|||
'verbose_name': 'Organizátor', |
|||
'verbose_name_plural': 'Organizátoři', |
|||
'db_table': 'mam_organizatori', |
|||
'ordering': ['-organizuje_do', 'osoba__jmeno', 'osoba__prijmeni'], |
|||
}, |
|||
), |
|||
], |
|||
database_operations=[], |
|||
), |
|||
] |
|||
|
@ -0,0 +1,223 @@ |
|||
import unidecode |
|||
import logging |
|||
import datetime |
|||
from pytz import timezone |
|||
|
|||
from django.contrib.auth.models import Permission, Group |
|||
import django.contrib.auth |
|||
|
|||
from .models import * |
|||
|
|||
User = django.contrib.auth.get_user_model() |
|||
|
|||
logger = logging.getLogger(__name__) |
|||
|
|||
|
|||
# testuje unikátnost vygenerovaného jména |
|||
def __unikatni_jmeno(osoby, jmeno, prijmeni): |
|||
for os in osoby: |
|||
if os.jmeno == jmeno and os.prijmeni == prijmeni: |
|||
return 0 |
|||
return 1 |
|||
|
|||
|
|||
def gen_osoby(rnd, size): |
|||
logger.info('Generuji osoby (size={})...'.format(size)) |
|||
|
|||
jmena_m = ['Aleš', 'Tomáš', 'Martin', 'Jakub', 'Petr', 'Lukáš', 'Cyril', 'Pavel Karel'] |
|||
jmena_f = ['Eva', 'Karolína', 'Zuzana', 'Sylvie', 'Iva', 'Jana', 'Marie', 'Marta Iva', 'Shu Shan'] |
|||
prijmeni_m = ['Novotný', 'Svoboda', 'Pecha', 'Kořen', 'Holan', 'Uhlíř', 'Chytráček', 'Pokora', 'Koch', 'Szegedy', 'Rudý', "von Neumann", "d'Este"] |
|||
prijmeni_f = ['Novotná', 'Svobodová', 'Machová', 'Zelená', 'Yu-Xin', 'Mlsná', 'Dubná', 'Mrkvová', 'Suchá', 'Lovelace', 'Holcová', 'Rui', "Nováčková Tydlitátová"] |
|||
prezdivky = ['Kaki', 'Hurdur', 'Maracuja', 'Bobbo', "", "", "", "", "", "", "", 'Riki', 'Sapa', "", '', '---', 'Koko'] |
|||
domain = ['example.com', 'dolujeme.eu', 'mff.cuni.cz', 'strcprstskrzkrk.cz', 'british.co.uk', 'splachni.to', 'haha.org'] |
|||
seznam_ulic = ['Krátká', 'Vlhká', 'Jungmanova', '17. listopadu', '4. října', 'Roztocká', 'Forstova', 'Generála Františka Janouška', 'Náměstí Války', 'Svratecké náměstí', 'Zelená lhota', 'Z Plynu', 'K Jezeru', 'U Kocourkova', 'Uštěpačná', 'Ostrorepská', 'Zubří'] |
|||
seznam_mest = ['Praha', 'Brno', 'Ostrava', 'Horní Jelení', 'Dolní Zábrdovice', 'Prdelkov', 'Stará myslivna', 'Kocourkov', 'Šalingrad', 'Medvědí hora', 'Basilej', 'Unterschiedlich', 'Old York', 'Lancastershire', 'Vóloďháza'] |
|||
|
|||
osoby = [] |
|||
# 30 je náhodná konstanta, size je použité na víc místech a |
|||
# říká, jak velká asi chceme testovací data |
|||
for i in range(30 * size): |
|||
pohlavi = rnd.randint(0, 1) |
|||
jmeno = rnd.choice([jmena_m, jmena_f][pohlavi]) |
|||
prijmeni = rnd.choice([prijmeni_m, prijmeni_f][pohlavi]) |
|||
pokusy = 0 |
|||
max_pokusy = 120*size |
|||
while not __unikatni_jmeno and pokusy < max_pokusy: |
|||
# pokud jméno a příjmení není unikátní, zkoušíme generovat nová |
|||
# do daného limitu (abychom se nezacyklili do nekonečna při málo jménech a příjmeních |
|||
# ze kterých se generuje) |
|||
jmeno = rnd.choice([jmena_m, jmena_f][pohlavi]) |
|||
prijmeni = rnd.choice([prijmeni_m, prijmeni_f][pohlavi]) |
|||
pokusy += 1 |
|||
if pokusy >= max_pokusy: |
|||
print("Chyba, na danou velikost testovacích dat příliš málo možných jmen a příjmení") |
|||
exit() |
|||
prezdivka = rnd.choice(prezdivky) |
|||
email = "@".join([unidecode.unidecode(jmeno), rnd.choice(domain)]) |
|||
telefon = "".join([str(rnd.choice([k for k in range(10)])) for _ in range(9)]) |
|||
narozeni = datetime.date( |
|||
rnd.randint(1980, datetime.datetime.now().year), |
|||
rnd.randint(1, 12), rnd.randint(1, 28), |
|||
) |
|||
ulic = rnd.choice(seznam_ulic) |
|||
cp = rnd.randint(1, 99) |
|||
ulice = " ".join([ulic, str(cp)]) |
|||
mesto = rnd.choice(seznam_mest) |
|||
psc = "".join([str(rnd.choice([k for k in range(10)])) for _ in range(5)]) |
|||
|
|||
osoby.append(Osoba.objects.create( |
|||
jmeno=jmeno, prijmeni=prijmeni, |
|||
prezdivka=prezdivka, pohlavi_muz=pohlavi, email=email, |
|||
telefon=telefon, datum_narozeni=narozeni, ulice=ulice, |
|||
mesto=mesto, psc=psc, |
|||
datum_registrace=datetime.date( |
|||
rnd.randint(2019, 2029), |
|||
rnd.randint(1, 12), rnd.randint(1, 28) |
|||
), |
|||
)) |
|||
# TODO pridat foto male a velke. Jak? |
|||
# Pavel tvrdí, že to necháme a přidáme až do adminu |
|||
|
|||
return osoby |
|||
|
|||
|
|||
def gen_skoly(): # TODO někdy to přepsat, aby jich bylo více |
|||
logger.info('Generuji školy...') |
|||
|
|||
skoly = [] |
|||
prvnizs = Skola.objects.create( |
|||
mesto='Praha', stat='CZ', psc='101 00', |
|||
ulice='Krátká 5', nazev='První ZŠ', je_zs=True, je_ss=False, |
|||
) |
|||
skoly.append(prvnizs) |
|||
skoly.append(Skola.objects.create( |
|||
mesto='Praha', stat='CZ', psc='101 00', |
|||
ulice='Krátká 5', nazev='První SŠ', je_zs=False, je_ss=True, |
|||
)) |
|||
skoly.append(Skola.objects.create( |
|||
mesto='Praha', stat='CZ', psc='102 00', |
|||
ulice='Dlouhá 5', nazev='Druhá SŠ', je_zs=False, je_ss=True, |
|||
)) |
|||
skoly.append(Skola.objects.create( |
|||
mesto='Praha', stat='CZ', psc='103 00', |
|||
ulice='Široká 3', nazev='Třetí SŠ a ZŠ', je_zs=True, je_ss=True, |
|||
)) |
|||
skoly.append(Skola.objects.create( |
|||
mesto='Ostrava', stat='CZ', psc='700 00', |
|||
ulice='Hluboká 42', nazev='Hutní gympl', je_zs=False, je_ss=True, |
|||
)) |
|||
skoly.append(Skola.objects.create( |
|||
mesto='Humenné', stat='SK', psc='012 34', |
|||
ulice='Pltká 1', nazev='Sredná škuola', je_zs=False, je_ss=True, |
|||
)) |
|||
|
|||
# tohle bude speciální škola, které později dodáme kontaktní osobu |
|||
zlinska = None |
|||
zlinska = Skola.objects.create( |
|||
mesto='Zlín', stat='CZ', psc='76001', |
|||
ulice='náměstí T.G. Masaryka 2734-9', |
|||
nazev='Gymnázium a Střední jazyková škola s právem SJZ', |
|||
kratky_nazev="GaSJŠspSJZ", je_zs=True, je_ss=True, |
|||
) |
|||
skoly.append(zlinska) |
|||
return skoly, zlinska |
|||
|
|||
|
|||
def gen_resitele(rnd, osoby, skoly): |
|||
logger.info('Generuji řešitele...') |
|||
|
|||
resitele = [] |
|||
x = 0 |
|||
resitel_perm = Permission.objects.filter(codename__exact='resitel').first() |
|||
resitel_group = Group.objects.filter(name__exact='resitel').first() |
|||
for os in osoby: |
|||
rand = rnd.randint(0, 8) |
|||
if not (rand % 8 == 0): |
|||
if not os.user: |
|||
if x: |
|||
user = User.objects.create_user( |
|||
username='r'+str(x), email=os.email, password='r', |
|||
) |
|||
else: |
|||
user = User.objects.create_user( |
|||
username='r', email=os.email, password='r', |
|||
) |
|||
x += 1 |
|||
os.user = user |
|||
os.save() |
|||
os.user.user_permissions.add(resitel_perm) |
|||
os.user.groups.add(resitel_group) |
|||
resitele.append(Resitel.objects.create( |
|||
osoba=os, skola=rnd.choice(skoly), |
|||
rok_maturity=os.datum_narozeni.year + rnd.randint(18, 21), |
|||
zasilat=rnd.choice(Resitel.ZASILAT_CHOICES)[0] |
|||
)) |
|||
return resitele |
|||
|
|||
|
|||
def gen_prijemci(rnd, osoby, kolik=10): |
|||
logger.info('Generuji příjemce (kolik={})...'.format(kolik)) |
|||
prijemci = [] |
|||
for i in rnd.sample(osoby, kolik): |
|||
prijemci.append(Prijemce.objects.create(osoba=i)) |
|||
return prijemci |
|||
|
|||
|
|||
def gen_organizatori(rnd, osoby, last_rocnik): |
|||
logger.info('Generuji organizátory...') |
|||
organizatori = [] |
|||
|
|||
seznam_konicku = ["vařím", "jezdím na kole", "řeším diferenciální rovnice", "koukám z okna", "tancuji", "programuji", "jezdím vlakem", "nedělám nic"] |
|||
seznam_oboru = ["matematiku", "matematiku", "matematiku", "fyziku", "literaturu", "informatiku", "informatiku", "běhání dokolečka"] |
|||
|
|||
x = 0 |
|||
org_perm = Permission.objects.filter(codename__exact='org').first() |
|||
org_group = Group.objects.filter(name__exact='org').first() |
|||
for os in osoby: |
|||
rand = rnd.randint(0, 8) |
|||
if rand % 8 == 0: |
|||
pusobnost = rnd.randint(1, last_rocnik) |
|||
od = datetime.datetime( |
|||
year=1993 + pusobnost, |
|||
month=rnd.randint(1, 12), |
|||
day=rnd.randint(1, 28), |
|||
tzinfo=timezone('CET'), |
|||
) |
|||
do = datetime.datetime( |
|||
year=od.year + rnd.randint(1, 6), |
|||
month=rnd.randint(1, 12), |
|||
day=rnd.randint(1, 28), |
|||
tzinfo=timezone('CET'), |
|||
) |
|||
# aktualni organizatori jeste nemaji vyplnene organizuje_do |
|||
|
|||
# popis orga |
|||
konicek1 = rnd.choice(seznam_konicku) |
|||
konicek2 = rnd.choice(seznam_konicku) |
|||
obor = rnd.choice(seznam_oboru) |
|||
popis_orga = "Ve volném čase " + konicek1 + " a také " + konicek2 + ". Studuji " + obor + " a moc mě to baví." |
|||
|
|||
if do.year > datetime.datetime.now().year: |
|||
do = None |
|||
if not os.user: |
|||
if x: |
|||
user = User.objects.create_user( |
|||
username='o'+str(x), email=os.email, password='o', |
|||
) |
|||
else: |
|||
user = User.objects.create_user( |
|||
username='o', email=os.email, password='o', |
|||
) |
|||
x += 1 |
|||
os.user = user |
|||
os.save() |
|||
os.user.user_permissions.add(org_perm) |
|||
os.user.groups.add(org_group) |
|||
os.user.is_staff = True |
|||
os.user.save() |
|||
organizatori.append(Organizator.objects.create( |
|||
osoba=os, |
|||
organizuje_od=od, organizuje_do=do, |
|||
strucny_popis_organizatora=popis_orga |
|||
)) |
|||
return organizatori |
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue