From 33969e26ee2cc68f69243f6a071ca9bf90968bf5 Mon Sep 17 00:00:00 2001 From: "Tomas \"Jethro\" Pokorny" Date: Tue, 13 Aug 2019 23:16:44 +0200 Subject: [PATCH 01/92] Prihlasovaci formular, zatim bez zpracovani. --- mamweb/static/css/mamweb.css | 24 ++++++++++++ seminar/forms.py | 23 ++++++++++- seminar/templates/seminar/gdpr.html | 49 ++++++++++++++++++++++++ seminar/templates/seminar/prihlaska.html | 29 +++++++++++++- seminar/urls.py | 2 +- seminar/views.py | 8 ++-- 6 files changed, 126 insertions(+), 9 deletions(-) create mode 100644 seminar/templates/seminar/gdpr.html diff --git a/mamweb/static/css/mamweb.css b/mamweb/static/css/mamweb.css index 6e5b9488..b48357e8 100644 --- a/mamweb/static/css/mamweb.css +++ b/mamweb/static/css/mamweb.css @@ -698,3 +698,27 @@ div.nahledy_cisel { div.nahledy_cisel div, div.nahledy_cisel img { position: absolute; } +ul.form { + list-style-type: none; + padding-left: 0px; +} +label.field-label { + font-weight: normal; +} +label.field-required { + font-weight: bold; +} +.field-error { + font-size: 14px; + color: red; +} +ul.form li{ + margin-bottom: 3px; +} +p.gdpr { + font-size: 6pt; + margin-bottom: .66em; +} +div.gdpr { + font-size: 6pt; +} diff --git a/seminar/forms.py b/seminar/forms.py index 693e36df..a9aa725c 100644 --- a/seminar/forms.py +++ b/seminar/forms.py @@ -1,6 +1,25 @@ from django import forms +from seminar.models import Resitel -class NameForm(forms.Form): - your_name = forms.CharField(label='Your name', max_length=100) +class PrihlaskaForm(forms.Form): + jmeno = forms.CharField(label='Jméno', max_length=256, required=True) + prijmeni = forms.CharField(label='Příjmení', max_length=256, required=True) + pohlavi = forms.ChoiceField(label='Pohlaví', + choices = ((True,'muž'),(False,'žena')), required=True) + email = forms.EmailField(label='E-mail',max_length=256, required=True) + telefon = forms.CharField(label='Telefon',max_length=256, required=False) + datum_narozeni = forms.DateField(label='Datum narození', required=False) + ulice = forms.CharField(label='Ulice', max_length=256, required=False) + mesto = forms.CharField(label='Město', max_length=256, required=False) + psc = forms.CharField(label='PSČ', max_length=32, required=False) + stat = forms.ChoiceField(label='Stát', + choices = (('CZ', 'Česká Republika'), + ('SK', 'Slovenská Republika'), + ('other', 'Jiné')), + required=False) + #TODO skola + rok_maturity = forms.IntegerField(label='Rok maturity', min_value=2019, required=True) + zasilat = forms.ChoiceField(label='Kam zasílat čísla a řešení',choices = Resitel.ZASILAT_CHOICES, required=True) + gdpr = forms.BooleanField(label='Souhlasím se zpracováním osobních údajů', required=True) diff --git a/seminar/templates/seminar/gdpr.html b/seminar/templates/seminar/gdpr.html new file mode 100644 index 00000000..74e253f5 --- /dev/null +++ b/seminar/templates/seminar/gdpr.html @@ -0,0 +1,49 @@ +

+TL;DR: +K tomu, abychom mohli zpracovávat Tvá data (uložit si tvou adresu, zobrazit Tvé jméno ve výsledkové listině, opravit Tvá řešení) od Tebe potřebujeme souhlas. +Pokud se zpracováváním souhlasíš dle níže uvedených podmínek, zaškrtni políčko níže. +

+
+

+Získáváme od Tebe údaje vyplněné v přihlášce do semináře (jméno, příjmení, poštovní a e-mailovou adresu, školu, kterou navštěvuješ a rok maturity), případně v přihlášce na soustředění (navíc datum narození, telefonní číslo). Také uchováváme všechna řešení, která nám pošleš, a jejich hodnocení. +

+

+Slibujeme Ti, že Tvá osobní data nezneužijeme k ničemu, co by nesouviselo s M&M nebo s dalšími aktivitami Matfyzu, a nikdy je nepředáme nikomu cizímu. Údaje využíváme k zajištění chodu semináře a také je sdílíme s ostatními propagačními akcemi Matfyzu, abychom mohli vyhodnocovat úspěšnost akcí. Pokud budeš mít zájem, budeme Ti také posílat zajímavé zprávy a novinky týkajíci se Matfyzu. +

+

+Veřejně vystavujeme pouze výsledkové listiny, které také uchováváme pro archivní účely. Pokud ale z nějakého důvodu nebudeš chtít mít své jméno či školu uvedené ve výsledkové listině, není problém to zařídit, napiš nám. Z tištěných materiálů samozřejmě údaje už odstranit nemůžeme. +

+

+Na soustředěních a dalších akcích semináře navíc pořizujeme fotografie a videozáznamy a používáme je ke zpravodajským a propagačním účelům. Pro propagační účely si od Tebe vyžádáme samostatný souhlas na začátku akce. +

+

+Souhlas se zpracováním osobních údajů pro potřeby chodu semináře +

+

+Tímto uděluji souhlas Univerzitě Karlově, se sídlem Ovocný trh 560/5, 116 36 Praha 1, IČO 00216208 (dále jen UK), která je správcem osobních údajů všech fakult a součástí UK, ke zpracování osobních údajů pro potřeby Korespondenčního semináře M&M a Matematicko-fyzikální fakulty UK (dále jen M&M a MFF UK). +

+

+Tento souhlas uděluji pro všechny výše uvedené osobní údaje, a to po dobu účasti v semináři a 10 let poté, a dále souhlasím s uchováváním potřebných dat pro archivní účely i po této lhůtě (vystavené výsledkové listiny aj.). +

+

+MFF UK tyto údaje zpracovává za účelem evidence řešitelů a účastníků M&M, k zajištění celoročního fungování semináře, analýze účinnosti jednotlivých propagačních akcí MFF UK a zpravodajským účelům. Osobám, které o to projeví zájem v nastavení svého účtu, bude MFF UK také zasílat propagační materiály. +

+

+Údaje nebudou předány třetí osobě ani využívány k jiným účelům, než ke kterým byly poskytnuty. +

+

+Tento souhlas uděluji ze své vlastní a svobodné vůle a beru na vědomí, že jej mohu kdykoliv odvolat zasláním e-mailu na adresu mam@matfyz.cz. Stejně tak může být požadováno vymazání i z archivních údajů M&M, pokud to bude technicky možné. Beru na vědomí, že údaje z tištěných publikací není možné zpětně odstranit. +

+

+Dále máte právo: +

diff --git a/seminar/templates/seminar/prihlaska.html b/seminar/templates/seminar/prihlaska.html index 891bdb6d..9e5fbbc8 100644 --- a/seminar/templates/seminar/prihlaska.html +++ b/seminar/templates/seminar/prihlaska.html @@ -1,5 +1,30 @@ +{% extends "seminar/zadani/base.html" %} +{% load staticfiles %} + +{% block content %} +

+ {% block nadpis1a %}{% block nadpis1b %} + Přihláška do semináře + {% endblock %}{% endblock %} +

{% csrf_token %} - {{ form }} - + {{form.non_field_errors}} + +
+ +{% endblock %} + diff --git a/seminar/urls.py b/seminar/urls.py index 67d0b526..d3b8c645 100644 --- a/seminar/urls.py +++ b/seminar/urls.py @@ -97,7 +97,7 @@ urlpatterns = [ staff_member_required(views.texUploadView), name='seminar_tex_upload' ), - path('prihlaska/',views.get_name), + path('prihlaska/',views.prihlaskaView), path('', views.TitulniStranaView.as_view(), name='titulni_strana'), # Ceka na autocomplete v3 diff --git a/seminar/views.py b/seminar/views.py index 57c85b65..7ddfcf62 100644 --- a/seminar/views.py +++ b/seminar/views.py @@ -15,7 +15,7 @@ from .models import Problem, Cislo, Reseni, Nastaveni, Rocnik, Soustredeni, Orga #from .models import VysledkyZaCislo, VysledkyKCisluZaRocnik, VysledkyKCisluOdjakziva from . import utils from .unicodecsv import UnicodeWriter -from .forms import NameForm +from .forms import PrihlaskaForm from datetime import timedelta, date, datetime from itertools import groupby @@ -949,11 +949,11 @@ def texDownloadView(request, rocnik, cislo): ## Formulare -def get_name(request): +def prihlaskaView(request): # if this is a POST request we need to process the form data if request.method == 'POST': # create a form instance and populate it with data from the request: - form = NameForm(request.POST) + form = PrihlaskaForm(request.POST) # check whether it's valid: if form.is_valid(): # process the data in form.cleaned_data as required @@ -963,7 +963,7 @@ def get_name(request): # if a GET (or any other method) we'll create a blank form else: - form = NameForm() + form = PrihlaskaForm() return render(request, 'seminar/prihlaska.html', {'form': form}) From d9daca0358c3376cd952b7ef96ea72a2552064b3 Mon Sep 17 00:00:00 2001 From: "Pavel \"LEdoian\" Turinsky" Date: Tue, 13 Aug 2019 20:57:33 +0200 Subject: [PATCH 02/92] =?UTF-8?q?P=C5=99id=C3=A1no=20django-polymorphic,?= =?UTF-8?q?=20polymorfizov=C3=A1ny=20TreeNody=20+=20p=C5=99id=C3=A1n=20=5F?= =?UTF-8?q?=5Fstr=5F=5F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Vyřeší to naše problémy s TreeNody, možná... --- mamweb/settings_common.py | 2 ++ requirements.txt | 1 + seminar/models.py | 25 ++++++++++++++++++++++++- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/mamweb/settings_common.py b/mamweb/settings_common.py index 6201d348..995bc4ad 100644 --- a/mamweb/settings_common.py +++ b/mamweb/settings_common.py @@ -115,6 +115,8 @@ INSTALLED_APPS = ( 'imagekit', + 'polymorphic', + # MaMweb 'mamweb', 'seminar', diff --git a/requirements.txt b/requirements.txt index 0b73a6d4..2bcec862 100644 --- a/requirements.txt +++ b/requirements.txt @@ -25,6 +25,7 @@ django-taggit django-autocomplete-light==2.3.6 django-crispy-forms django-imagekit +django-polymorphic # Comments akismet==1.0.1 diff --git a/seminar/models.py b/seminar/models.py index e87aa325..cab97533 100644 --- a/seminar/models.py +++ b/seminar/models.py @@ -25,6 +25,7 @@ from seminar.utils import roman from unidecode import unidecode +from polymorphic.models import PolymorphicModel class SeminarModelBase(models.Model): @@ -1139,7 +1140,7 @@ class Obrazek(SeminarModelBase): help_text = 'Černobílá verze obrázku do čísla', upload_to = 'obrazky/%Y/%m/%d/', blank=True, null=True) -class TreeNode(models.Model): +class TreeNode(PolymorphicModel): class Meta: db_table = "seminar_nodes_treenode" verbose_name = "TreeNode" @@ -1170,6 +1171,8 @@ class TreeNode(models.Model): if self.succ: self.succ.print_tree(indent=indent) + def __str__(self): + return "Generický TreeNode!" class RocnikNode(TreeNode): class Meta: @@ -1179,6 +1182,8 @@ class RocnikNode(TreeNode): rocnik = models.OneToOneField(Rocnik, on_delete = models.PROTECT, # Pokud chci mazat ročník, musím si Node pořešit ručně verbose_name = "ročník") + def __str__(self): + return 'RocnikNode: '+str(self.rocnik) class CisloNode(TreeNode): class Meta: @@ -1188,12 +1193,16 @@ class CisloNode(TreeNode): cislo = models.OneToOneField(Cislo, on_delete = models.PROTECT, # Pokud chci mazat číslo, musím si Node pořešit ručně verbose_name = "číslo") + def __str__(self): + return 'CisloNode: '+str(self.cislo) class MezicisloNode(TreeNode): class Meta: db_table = 'seminar_nodes_mezicislo' verbose_name = 'Mezičíslo (Node)' verbose_name_plural = 'Mezičísla (Node)' + def __str__(self): + return 'MezicisloNode' class TemaVCisleNode(TreeNode): """ Obsahuje příspěvky k tématu v daném čísle """ @@ -1204,6 +1213,8 @@ class TemaVCisleNode(TreeNode): tema = models.ForeignKey(Tema, on_delete=models.PROTECT, # Pokud chci mazat téma, musím si Node pořešit ručně verbose_name = "téma v čísle") + def __str__(self): + return 'TemaVCisleNode: tema: '+str(self.tema) class KonferaNode(TreeNode): class Meta: @@ -1215,6 +1226,8 @@ class KonferaNode(TreeNode): verbose_name = "konfera", null=True, blank=False) + def __str__(self): + return 'KonferaNode: '+str(self.konfera) class ClanekNode(TreeNode): class Meta: @@ -1226,6 +1239,8 @@ class ClanekNode(TreeNode): verbose_name = "článek", null=True, blank=False) + def __str__(self): + return 'ClanekNode: '+str(self.clanek) class UlohaZadaniNode(TreeNode): class Meta: @@ -1237,6 +1252,8 @@ class UlohaZadaniNode(TreeNode): verbose_name = "úloha", null=True, blank=False) + def __str__(self): + return 'UlohaZadaniNode: '+str(self.uloha) class PohadkaNode(TreeNode): class Meta: @@ -1247,6 +1264,8 @@ class PohadkaNode(TreeNode): on_delete=models.PROTECT, # Pokud chci mazat pohádku, musím si Node pořešit ručně verbose_name = "pohádka", ) + def __str__(self): + return 'PohadkaNode: '+str(self.pohadka) class UlohaVzorakNode(TreeNode): class Meta: @@ -1258,6 +1277,8 @@ class UlohaVzorakNode(TreeNode): verbose_name = "úloha", null=True, blank=False) + def __str__(self): + return 'UlohaVzorakNode: '+str(self.uloha) class TextNode(TreeNode): class Meta: @@ -1267,6 +1288,8 @@ class TextNode(TreeNode): text = models.ForeignKey(Text, on_delete=models.PROTECT, verbose_name = 'text') + def __str__(self): + return 'TextNode: '+str(self.text) ## FIXME: Logiku přesunout do views. #class VysledkyBase(SeminarModelBase): From d64214c75ddd6eafda432843e9fdfac69881b582 Mon Sep 17 00:00:00 2001 From: "Pavel \"LEdoian\" Turinsky" Date: Tue, 13 Aug 2019 22:03:31 +0200 Subject: [PATCH 03/92] =?UTF-8?q?Models:=20Polymorphizov=C3=A1n=20Problem?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../0002_treenode_polymorphic_ctype.py | 20 +++++++++++++++++++ .../0003_problem_polymorphic_ctype.py | 20 +++++++++++++++++++ seminar/models.py | 3 ++- 3 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 seminar/migrations/0002_treenode_polymorphic_ctype.py create mode 100644 seminar/migrations/0003_problem_polymorphic_ctype.py diff --git a/seminar/migrations/0002_treenode_polymorphic_ctype.py b/seminar/migrations/0002_treenode_polymorphic_ctype.py new file mode 100644 index 00000000..4398be6c --- /dev/null +++ b/seminar/migrations/0002_treenode_polymorphic_ctype.py @@ -0,0 +1,20 @@ +# Generated by Django 2.2.4 on 2019-08-13 19:36 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('contenttypes', '0002_remove_content_type_name'), + ('seminar', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='treenode', + name='polymorphic_ctype', + field=models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_seminar.treenode_set+', to='contenttypes.ContentType'), + ), + ] diff --git a/seminar/migrations/0003_problem_polymorphic_ctype.py b/seminar/migrations/0003_problem_polymorphic_ctype.py new file mode 100644 index 00000000..279efbf4 --- /dev/null +++ b/seminar/migrations/0003_problem_polymorphic_ctype.py @@ -0,0 +1,20 @@ +# Generated by Django 2.2.4 on 2019-08-13 19:45 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('contenttypes', '0002_remove_content_type_name'), + ('seminar', '0002_treenode_polymorphic_ctype'), + ] + + operations = [ + migrations.AddField( + model_name='problem', + name='polymorphic_ctype', + field=models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_seminar.problem_set+', to='contenttypes.ContentType'), + ), + ] diff --git a/seminar/models.py b/seminar/models.py index cab97533..6efd27dd 100644 --- a/seminar/models.py +++ b/seminar/models.py @@ -584,7 +584,8 @@ class Soustredeni(SeminarModelBase): @reversion.register(ignore_duplicates=True) -class Problem(SeminarModelBase): +# Pozor na následující řádek. *Nekrmit, asi kouše!* +class Problem(SeminarModelBase,PolymorphicModel): class Meta: # Není abstraktní, protože se na něj jinak nedají dělat ForeignKeys. From 4ee3d412374615878a5bed06c56324831e6ab00b Mon Sep 17 00:00:00 2001 From: "Pavel \"LEdoian\" Turinsky" Date: Tue, 13 Aug 2019 23:17:56 +0200 Subject: [PATCH 04/92] =?UTF-8?q?Polymorfi=C4=8Dt=C3=AD=20admini=20pro=20T?= =?UTF-8?q?reeNody?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/admin.py | 89 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 78 insertions(+), 11 deletions(-) diff --git a/seminar/admin.py b/seminar/admin.py index d02b4db7..0a66f30f 100644 --- a/seminar/admin.py +++ b/seminar/admin.py @@ -1,5 +1,7 @@ from django.contrib import admin +from polymorphic.admin import PolymorphicParentModelAdmin, PolymorphicChildModelAdmin, PolymorphicChildModelFilter + import seminar.models as m admin.site.register(m.Osoba) @@ -10,27 +12,92 @@ admin.site.register(m.Rocnik) admin.site.register(m.Cislo) admin.site.register(m.Organizator) admin.site.register(m.Soustredeni) + +# TODO: Polymorphic admin admin.site.register(m.Problem) admin.site.register(m.Tema) admin.site.register(m.Clanek) admin.site.register(m.Text) admin.site.register(m.Uloha) +# END TODO. + admin.site.register(m.Reseni) admin.site.register(m.Hodnoceni) admin.site.register(m.PrilohaReseni) admin.site.register(m.Pohadka) admin.site.register(m.Konfera) admin.site.register(m.Obrazek) -admin.site.register(m.TreeNode) -admin.site.register(m.RocnikNode) -admin.site.register(m.CisloNode) -admin.site.register(m.MezicisloNode) -admin.site.register(m.TemaVCisleNode) -admin.site.register(m.KonferaNode) -admin.site.register(m.ClanekNode) -admin.site.register(m.UlohaZadaniNode) -admin.site.register(m.PohadkaNode) -admin.site.register(m.UlohaVzorakNode) -admin.site.register(m.TextNode) + + +# Polymorfismus pro stromy +# TODO: Inlines podle https://django-polymorphic.readthedocs.io/en/stable/admin.html + +@admin.register(m.TreeNode) +class TreeNodeAdmin(PolymorphicParentModelAdmin): + base_model = m.TreeNode + child_models = [ + m.RocnikNode, + m.CisloNode, + m.MezicisloNode, + m.TemaVCisleNode, + m.KonferaNode, + m.ClanekNode, + m.UlohaZadaniNode, + m.PohadkaNode, + m.UlohaVzorakNode, + m.TextNode, + ] + +@admin.register(m.RocnikNode) +class RocnikNodeAdmin(PolymorphicChildModelAdmin): + base_model = m.RocnikNode + show_in_index = True + +@admin.register(m.CisloNode) +class CisloNodeAdmin(PolymorphicChildModelAdmin): + base_model = m.CisloNode + show_in_index = True + +@admin.register(m.MezicisloNode) +class MezicisloNodeAdmin(PolymorphicChildModelAdmin): + base_model = m.MezicisloNode + show_in_index = True + +@admin.register(m.TemaVCisleNode) +class TemaVCisleNodeAdmin(PolymorphicChildModelAdmin): + base_model = m.TemaVCisleNode + show_in_index = True + +@admin.register(m.KonferaNode) +class KonferaNodeAdmin(PolymorphicChildModelAdmin): + base_model = m.KonferaNode + show_in_index = True + +@admin.register(m.ClanekNode) +class ClanekNodeAdmin(PolymorphicChildModelAdmin): + base_model = m.ClanekNode + show_in_index = True + +@admin.register(m.UlohaZadaniNode) +class UlohaZadaniNodeAdmin(PolymorphicChildModelAdmin): + base_model = m.UlohaZadaniNode + show_in_index = True + +@admin.register(m.PohadkaNode) +class PohadkaNodeAdmin(PolymorphicChildModelAdmin): + base_model = m.PohadkaNode + show_in_index = True + +@admin.register(m.UlohaVzorakNode) +class UlohaVzorakNodeAdmin(PolymorphicChildModelAdmin): + base_model = m.UlohaVzorakNode + show_in_index = True + +@admin.register(m.TextNode) +class TextNodeAdmin(PolymorphicChildModelAdmin): + base_model = m.TextNode + show_in_index = True + + admin.site.register(m.Nastaveni) admin.site.register(m.Novinky) From 2d23a79ad62898139fc91a9b873107bb68e27832 Mon Sep 17 00:00:00 2001 From: "Pavel \"LEdoian\" Turinsky" Date: Wed, 14 Aug 2019 01:15:40 +0200 Subject: [PATCH 05/92] =?UTF-8?q?Migrace:=20P=C5=99idat=20content-types,?= =?UTF-8?q?=20!mo=C5=BEn=C3=A1=20blb=C4=9B!,=20tabs,=20oprava=20po=C5=99ad?= =?UTF-8?q?=C3=AD.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../0002_treenode_polymorphic_ctype.py | 20 ------------ .../0003_problem_polymorphic_ctype.py | 20 ------------ .../0065_treenode_polymorphic_ctype.py | 31 +++++++++++++++++++ .../0066_problem_polymorphic_ctype.py | 29 +++++++++++++++++ 4 files changed, 60 insertions(+), 40 deletions(-) delete mode 100644 seminar/migrations/0002_treenode_polymorphic_ctype.py delete mode 100644 seminar/migrations/0003_problem_polymorphic_ctype.py create mode 100644 seminar/migrations/0065_treenode_polymorphic_ctype.py create mode 100644 seminar/migrations/0066_problem_polymorphic_ctype.py diff --git a/seminar/migrations/0002_treenode_polymorphic_ctype.py b/seminar/migrations/0002_treenode_polymorphic_ctype.py deleted file mode 100644 index 4398be6c..00000000 --- a/seminar/migrations/0002_treenode_polymorphic_ctype.py +++ /dev/null @@ -1,20 +0,0 @@ -# Generated by Django 2.2.4 on 2019-08-13 19:36 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('contenttypes', '0002_remove_content_type_name'), - ('seminar', '0001_initial'), - ] - - operations = [ - migrations.AddField( - model_name='treenode', - name='polymorphic_ctype', - field=models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_seminar.treenode_set+', to='contenttypes.ContentType'), - ), - ] diff --git a/seminar/migrations/0003_problem_polymorphic_ctype.py b/seminar/migrations/0003_problem_polymorphic_ctype.py deleted file mode 100644 index 279efbf4..00000000 --- a/seminar/migrations/0003_problem_polymorphic_ctype.py +++ /dev/null @@ -1,20 +0,0 @@ -# Generated by Django 2.2.4 on 2019-08-13 19:45 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('contenttypes', '0002_remove_content_type_name'), - ('seminar', '0002_treenode_polymorphic_ctype'), - ] - - operations = [ - migrations.AddField( - model_name='problem', - name='polymorphic_ctype', - field=models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_seminar.problem_set+', to='contenttypes.ContentType'), - ), - ] diff --git a/seminar/migrations/0065_treenode_polymorphic_ctype.py b/seminar/migrations/0065_treenode_polymorphic_ctype.py new file mode 100644 index 00000000..71eef262 --- /dev/null +++ b/seminar/migrations/0065_treenode_polymorphic_ctype.py @@ -0,0 +1,31 @@ +# Generated by Django 2.2.4 on 2019-08-13 19:36 + +from django.db import migrations, models +import django.db.models.deletion + +def vyrob_treenodum_ctypes(apps, schema_editor): + # Kód zkopírovaný z dokumentace: https://django-polymorphic.readthedocs.io/en/stable/migrating.html + # XXX: Nevím, jestli se tohle náhodou nemělo spustit na všech childech (jen/i) + TreeNode = apps.get_model('seminar', 'TreeNode') + ContentType = apps.get_model('contenttypes', 'ContentType') + + new_ct = ContentType.objects.get_for_model(TreeNode) + TreeNode.objects.filter(polymorphic_ctype__isnull=True).update(polymorphic_ctype=new_ct) + + + +class Migration(migrations.Migration): + + dependencies = [ + ('contenttypes', '0002_remove_content_type_name'), + ('seminar', '0064_auto_20190610_2358'), + ] + + operations = [ + migrations.AddField( + model_name='treenode', + name='polymorphic_ctype', + field=models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_seminar.treenode_set+', to='contenttypes.ContentType'), + ), + migrations.RunPython(vyrob_treenodum_ctypes, migrations.RunPython.noop), + ] diff --git a/seminar/migrations/0066_problem_polymorphic_ctype.py b/seminar/migrations/0066_problem_polymorphic_ctype.py new file mode 100644 index 00000000..f956217e --- /dev/null +++ b/seminar/migrations/0066_problem_polymorphic_ctype.py @@ -0,0 +1,29 @@ +# Generated by Django 2.2.4 on 2019-08-13 19:45 + +from django.db import migrations, models +import django.db.models.deletion + +def vyrob_problemum_ctypes(apps, schema_editor): + # Kód zkopírovaný z dokumentace: https://django-polymorphic.readthedocs.io/en/stable/migrating.html + # XXX: Nevím, jestli se tohle náhodou nemělo spustit na všech childech (jen/i) + Problem = apps.get_model('seminar', 'Problem') + ContentType = apps.get_model('contenttypes', 'ContentType') + + new_ct = ContentType.objects.get_for_model(Problem) + Problem.objects.filter(polymorphic_ctype__isnull=True).update(polymorphic_ctype=new_ct) + +class Migration(migrations.Migration): + + dependencies = [ + ('contenttypes', '0002_remove_content_type_name'), + ('seminar', '0065_treenode_polymorphic_ctype'), + ] + + operations = [ + migrations.AddField( + model_name='problem', + name='polymorphic_ctype', + field=models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_seminar.problem_set+', to='contenttypes.ContentType'), + ), + migrations.RunPython(vyrob_problemum_ctypes, migrations.RunPython.noop), + ] From 7462c5ffc61a3d21e936449006f7a2bb59f86476 Mon Sep 17 00:00:00 2001 From: "Pavel \"LEdoian\" Turinsky" Date: Wed, 14 Aug 2019 01:17:05 +0200 Subject: [PATCH 06/92] Drop reversion --- mamweb/settings_common.py | 4 ++-- seminar/admin.py | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/mamweb/settings_common.py b/mamweb/settings_common.py index 995bc4ad..ce471e70 100644 --- a/mamweb/settings_common.py +++ b/mamweb/settings_common.py @@ -53,7 +53,7 @@ AUTHENTICATION_BACKENDS = ( MIDDLEWARE = ( - 'reversion.middleware.RevisionMiddleware', +# 'reversion.middleware.RevisionMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', @@ -97,7 +97,7 @@ INSTALLED_APPS = ( # Utilities 'sekizai', - 'reversion', +# 'reversion', 'django_countries', 'solo', 'ckeditor', diff --git a/seminar/admin.py b/seminar/admin.py index 0a66f30f..310df7fe 100644 --- a/seminar/admin.py +++ b/seminar/admin.py @@ -2,6 +2,8 @@ from django.contrib import admin from polymorphic.admin import PolymorphicParentModelAdmin, PolymorphicChildModelAdmin, PolymorphicChildModelFilter +# Todo: reversion + import seminar.models as m admin.site.register(m.Osoba) From 81c561a1a86927d97c3caf461225852df098a023 Mon Sep 17 00:00:00 2001 From: "Pavel \"LEdoian\" Turinsky" Date: Wed, 14 Aug 2019 01:34:50 +0200 Subject: [PATCH 07/92] =?UTF-8?q?Admin=20pro=20polymorfick=C3=A9=20probl?= =?UTF-8?q?=C3=A9my?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/admin.py | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/seminar/admin.py b/seminar/admin.py index 310df7fe..e524a19d 100644 --- a/seminar/admin.py +++ b/seminar/admin.py @@ -15,14 +15,32 @@ admin.site.register(m.Cislo) admin.site.register(m.Organizator) admin.site.register(m.Soustredeni) -# TODO: Polymorphic admin -admin.site.register(m.Problem) -admin.site.register(m.Tema) -admin.site.register(m.Clanek) -admin.site.register(m.Text) -admin.site.register(m.Uloha) -# END TODO. +@admin.register(m.Problem) +class ProblemAdmin(PolymorphicParentModelAdmin): + base_model = m.Problem + child_models = [ + m.Tema, + m.Clanek, + m.Uloha, + ] +@admin.register(m.Tema) +class TemaAdmin(PolymorphicChildModelAdmin): + base_model = m.Tema + show_in_index = True + +@admin.register(m.Clanek) +class ClanekAdmin(PolymorphicChildModelAdmin): + base_model = m.Clanek + show_in_index = True + +@admin.register(m.Uloha) +class UlohaAdmin(PolymorphicChildModelAdmin): + base_model = m.Uloha + show_in_index = True + + +admin.site.register(m.Text) admin.site.register(m.Reseni) admin.site.register(m.Hodnoceni) admin.site.register(m.PrilohaReseni) From fbf288039cc9ba2a41ce43a1fd1cb7cf2f3efbb2 Mon Sep 17 00:00:00 2001 From: "Pavel \"LEdoian\" Turinsky" Date: Wed, 14 Aug 2019 01:45:06 +0200 Subject: [PATCH 08/92] Testdata command: tabs --- seminar/management/commands/testdata.py | 30 ++++++++++++------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/seminar/management/commands/testdata.py b/seminar/management/commands/testdata.py index 6a7fb30c..d770f77b 100644 --- a/seminar/management/commands/testdata.py +++ b/seminar/management/commands/testdata.py @@ -15,21 +15,21 @@ User = django.contrib.auth.get_user_model() class Command(BaseCommand): - help = "Clear database and load testing data." - - def handle(self, *args, **options): - assert settings.DEBUG == True - dbfile = settings.DATABASES['default']['NAME'] - if os.path.exists(dbfile): - os.rename(dbfile, dbfile + '.old') - self.stderr.write('Stara databaze prejmenovana na "%s"' % (dbfile + '.old')) - call_command('migrate', no_input=True) - self.stdout.write('Vytvarim uzivatele "admin" (heslo "admin") a pseudo-nahodna data ...') - create_test_data(size=8) - self.stdout.write('Vytvoreno {} uzivatelu, {} skol, {} resitelu, {} rocniku, {} cisel,' - ' {} problemu, {} reseni.'.format(User.objects.count(), Skola.objects.count(), - Resitel.objects.count(), Rocnik.objects.count(), Cislo.objects.count(), - Problem.objects.count(), Reseni.objects.count())) + help = "Clear database and load testing data." + + def handle(self, *args, **options): + assert settings.DEBUG == True + dbfile = settings.DATABASES['default']['NAME'] + if os.path.exists(dbfile): + os.rename(dbfile, dbfile + '.old') + self.stderr.write('Stara databaze prejmenovana na "%s"' % (dbfile + '.old')) + call_command('migrate', no_input=True) + self.stdout.write('Vytvarim uzivatele "admin" (heslo "admin") a pseudo-nahodna data ...') + create_test_data(size=8) + self.stdout.write('Vytvoreno {} uzivatelu, {} skol, {} resitelu, {} rocniku, {} cisel,' + ' {} problemu, {} reseni.'.format(User.objects.count(), Skola.objects.count(), + Resitel.objects.count(), Rocnik.objects.count(), Cislo.objects.count(), + Problem.objects.count(), Reseni.objects.count())) From 723cccc9d907be6fff22ba56c40750540fe2cfc2 Mon Sep 17 00:00:00 2001 From: "Pavel \"LEdoian\" Turinsky" Date: Wed, 14 Aug 2019 02:06:31 +0200 Subject: [PATCH 09/92] =?UTF-8?q?Testdata:=20mo=C5=BEnost=20nemigrovat=20a?= =?UTF-8?q?=20pracovat=20na=20st=C3=A1vaj=C3=ADc=C3=AD=20DB.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Vhodné asi jen pro debugování migrací --- seminar/management/commands/testdata.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/seminar/management/commands/testdata.py b/seminar/management/commands/testdata.py index d770f77b..d7c65367 100644 --- a/seminar/management/commands/testdata.py +++ b/seminar/management/commands/testdata.py @@ -17,13 +17,26 @@ User = django.contrib.auth.get_user_model() class Command(BaseCommand): help = "Clear database and load testing data." + def add_arguments(self, parser): + parser.add_argument( + '--no-clean', + action='store_true', + help='Změny se provedou v aktuální DB, ne v čisté. Aktuální DB se nezachová. (jen k debugování)', + ) + parser.add_argument( + '--no-migrate', + action='store_true', + help='Neprovádět migrace před generováním testovacích dat (jen k debugování)', + ) + def handle(self, *args, **options): assert settings.DEBUG == True dbfile = settings.DATABASES['default']['NAME'] - if os.path.exists(dbfile): + if os.path.exists(dbfile) and not options['no_clean']: os.rename(dbfile, dbfile + '.old') self.stderr.write('Stara databaze prejmenovana na "%s"' % (dbfile + '.old')) - call_command('migrate', no_input=True) + if not options['no_migrate']: + call_command('migrate', no_input=True) self.stdout.write('Vytvarim uzivatele "admin" (heslo "admin") a pseudo-nahodna data ...') create_test_data(size=8) self.stdout.write('Vytvoreno {} uzivatelu, {} skol, {} resitelu, {} rocniku, {} cisel,' From 1ed4d121aeeba8d93da0641fc19d7f326031c774 Mon Sep 17 00:00:00 2001 From: "Pavel \"LEdoian\" Turinsky" Date: Wed, 14 Aug 2019 03:02:23 +0200 Subject: [PATCH 10/92] =?UTF-8?q?Settings:=20Vy=C4=8Dlen=C4=9Bno=20zobrazo?= =?UTF-8?q?v=C3=A1n=C3=AD=20DB=20dotaz=C5=AF=20do=20separ=C3=A1tn=C3=ADho?= =?UTF-8?q?=20configu?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Použijte proměnnou prostředí nebo --settings. --- mamweb/settings_debug.py | 13 +++++++++++++ mamweb/settings_local.py | 6 ------ 2 files changed, 13 insertions(+), 6 deletions(-) create mode 100644 mamweb/settings_debug.py diff --git a/mamweb/settings_debug.py b/mamweb/settings_debug.py new file mode 100644 index 00000000..7dd34fae --- /dev/null +++ b/mamweb/settings_debug.py @@ -0,0 +1,13 @@ +# Debugovaci nastaveni settings.py +# Pro vyber tohoto nastaveni muzete pouzit tez: +# DJANGO_SETTINGS_MODULE=mamweb.settings_debug ./manage.py ... + +# Import local settings +from .settings_local import * + +# Vypisovani databazovych dotazu do konzole +LOGGING['loggers']['django.db.backends'] = { + 'level': 'DEBUG', + 'handlers': ['console'], + 'propagate': False, +} diff --git a/mamweb/settings_local.py b/mamweb/settings_local.py index a11617d0..e5011926 100644 --- a/mamweb/settings_local.py +++ b/mamweb/settings_local.py @@ -72,12 +72,6 @@ LOGGING = { }, }, 'loggers': { - # Vypisovani databazovych dotazu do konzole - 'django.db.backends': { - 'level': 'DEBUG', - 'handlers': ['console'], - 'propagate': False, - }, '': { 'handlers': ['console'], 'level': 'DEBUG', From d14366d38ef7061a4c1f3438f1d873dd8b417bb4 Mon Sep 17 00:00:00 2001 From: "Pavel \"LEdoian\" Turinsky" Date: Wed, 14 Aug 2019 03:36:42 +0200 Subject: [PATCH 11/92] =?UTF-8?q?Testdata:=20oprava=20odsazen=C3=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/testutils.py | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/seminar/testutils.py b/seminar/testutils.py index c0c70222..c2c5ba1c 100644 --- a/seminar/testutils.py +++ b/seminar/testutils.py @@ -219,27 +219,27 @@ def gen_ulohy_do_cisla(rnd, organizatori, resitele, rocnik_cisla, rocniky, size) return def gen_soustredeni(rnd, resitele, organizatori): - soustredeni = [] - for _ in range(1, 10): #FIXME Tu range si změňte jak chcete, nevím, co přesně znamená size (asi Anet?) - datum_zacatku=datetime.date(rnd.randint(2000, 2020), rnd.randint(1, 12), rnd.randint(1, 28)) - working_sous = Soustredeni.objects.create( - rocnik=Rocnik.objects.order_by('?').first(), - verejne_db=rnd.choice([True, False]), - misto=rnd.choice(['Kremrolovice', 'Indiánov', 'U zmzliny', 'Vafláreň', 'Větrník', 'Horní Rakvička', 'Dolní cheesecake']), - typ=rnd.choice(['jarni', 'podzimni', 'vikend']), - datum_zacatku=datum_zacatku, - datum_konce=datum_zacatku + datetime.timedelta(days=7)) - ucastnici = rnd.sample(resitele, min(len(resitele), 20)) - working_sous.ucastnici.set(ucastnici) - #for res in rnd.sample(resitele, min(len(resitele), 20)): - # Soustredeni_Ucastnici.objects.create(resitel=res, soutredeni=working_sous) - orgove_vyber = rnd.sample(organizatori, min(len(organizatori), 20)) - working_sous.organizatori.set(orgove_vyber) - #for org in rnd.sample(organizatori, min(len(organizatori), 20)): - # Soustredeni_Organizatori.objects.create(organizator=org, soutredeni=working_sous) - working_sous.save() - soustredeni.append(working_sous) - return soustredeni + soustredeni = [] + for _ in range(1, 10): #FIXME Tu range si změňte jak chcete, nevím, co přesně znamená size (asi Anet?) + datum_zacatku=datetime.date(rnd.randint(2000, 2020), rnd.randint(1, 12), rnd.randint(1, 28)) + working_sous = Soustredeni.objects.create( + rocnik=Rocnik.objects.order_by('?').first(), + verejne_db=rnd.choice([True, False]), + misto=rnd.choice(['Kremrolovice', 'Indiánov', 'U zmzliny', 'Vafláreň', 'Větrník', 'Horní Rakvička', 'Dolní cheesecake']), + typ=rnd.choice(['jarni', 'podzimni', 'vikend']), + datum_zacatku=datum_zacatku, + datum_konce=datum_zacatku + datetime.timedelta(days=7)) + ucastnici = rnd.sample(resitele, min(len(resitele), 20)) + working_sous.ucastnici.set(ucastnici) + #for res in rnd.sample(resitele, min(len(resitele), 20)): + # Soustredeni_Ucastnici.objects.create(resitel=res, soutredeni=working_sous) + orgove_vyber = rnd.sample(organizatori, min(len(organizatori), 20)) + working_sous.organizatori.set(orgove_vyber) + #for org in rnd.sample(organizatori, min(len(organizatori), 20)): + # Soustredeni_Organizatori.objects.create(organizator=org, soutredeni=working_sous) + working_sous.save() + soustredeni.append(working_sous) + return soustredeni def gen_rocniky(last_rocnik, size): rocniky = [] From e8e97355c78244c21a3ee6119e0f3c5018790247 Mon Sep 17 00:00:00 2001 From: "Pavel \"LEdoian\" Turinsky" Date: Wed, 14 Aug 2019 14:08:56 +0200 Subject: [PATCH 12/92] =?UTF-8?q?Testdata:=20zlikvidov=C3=A1ny=20RuntimeWa?= =?UTF-8?q?rningy=20o=20chyb=C4=9Bj=C3=ADc=C3=AD=20=C4=8Dasov=C3=A9=20z?= =?UTF-8?q?=C3=B3n=C4=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/testutils.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/seminar/testutils.py b/seminar/testutils.py index 1068d9f1..5977128c 100644 --- a/seminar/testutils.py +++ b/seminar/testutils.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- import datetime +from pytz import timezone import random import lorem import django.contrib.auth @@ -121,9 +122,18 @@ def gen_organizatori(rnd, osoby, last_rocnik, users): rand = rnd.randint(0, 8) if (rand % 8 == 0): pusobnost = rnd.randint(1, last_rocnik) - od = datetime.date(1993 + pusobnost, rnd.randint(1, 12), rnd.randint(1, 28)) - do = datetime.date(od.year + rnd.randint(1, 6), rnd.randint(1, 12), - rnd.randint(1, 28)) + 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 if do.year > datetime.datetime.now().year: do = None From cd5e17b5720ddb2c13f604b6897b8412f466fdfd Mon Sep 17 00:00:00 2001 From: "Pavel \"LEdoian\" Turinsky" Date: Wed, 14 Aug 2019 03:34:49 +0200 Subject: [PATCH 13/92] =?UTF-8?q?Testdata:=20logov=C3=A1n=C3=AD=20pr=C5=AF?= =?UTF-8?q?b=C4=9Bhu?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Použil jsem Djangové/Pythonové logovadlo, ať se to dá kdyžtak vypnout/skrýt --- seminar/testutils.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/seminar/testutils.py b/seminar/testutils.py index c2c5ba1c..f9208280 100644 --- a/seminar/testutils.py +++ b/seminar/testutils.py @@ -6,6 +6,7 @@ import lorem import django.contrib.auth from django.db import transaction import unidecode +import logging from seminar.models import Skola, Resitel, Rocnik, Cislo, Problem, Reseni, PrilohaReseni, Nastaveni, Soustredeni, Soustredeni_Ucastnici, Soustredeni_Organizatori, Osoba, Organizator, Prijemce, Tema, Uloha, Konfera, KonferaNode, TextNode, UlohaVzorakNode, RocnikNode, CisloNode, TemaVCisleNode, Text, Hodnoceni, UlohaZadaniNode, Novinky @@ -15,7 +16,11 @@ from django.contrib.sites.models import Site User = django.contrib.auth.get_user_model() zlinska = None # tohle bude speciální škola, které později dodáme kontaktní osobu +logger = logging.getLogger(__name__) + 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'] @@ -66,6 +71,8 @@ def gen_osoby(rnd, size): 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) @@ -89,6 +96,8 @@ def gen_skoly(): #TODO někdy to přepsat, aby jich bylo více return skoly def gen_resitele(rnd, osoby, skoly): + logger.info('Generuji řešitele...') + resitele = [] for os in osoby: rand = rnd.randint(0, 8) @@ -99,12 +108,14 @@ def gen_resitele(rnd, osoby, skoly): 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, users): + logger.info('Generuji organizátory...') organizatori = [] for os in osoby: rand = rnd.randint(0, 8) @@ -121,6 +132,8 @@ def gen_organizatori(rnd, osoby, last_rocnik, users): return organizatori def gen_ulohy_do_cisla(rnd, organizatori, resitele, rocnik_cisla, rocniky, size): + logger.info('Generuji úlohy do čísla (size={})...'.format(size)) + # ulohy resene v cisle jaka = ["Šachová", "Černá", "Větrná", "Dlouhá", "Křehká", "Rychlá", "Zákeřná", "Fyzikální"] @@ -219,6 +232,8 @@ def gen_ulohy_do_cisla(rnd, organizatori, resitele, rocnik_cisla, rocniky, size) return def gen_soustredeni(rnd, resitele, organizatori): + logger.info('Generuji soustředění...') + soustredeni = [] for _ in range(1, 10): #FIXME Tu range si změňte jak chcete, nevím, co přesně znamená size (asi Anet?) datum_zacatku=datetime.date(rnd.randint(2000, 2020), rnd.randint(1, 12), rnd.randint(1, 28)) @@ -242,6 +257,8 @@ def gen_soustredeni(rnd, resitele, organizatori): return soustredeni def gen_rocniky(last_rocnik, size): + logger.info('Generuji ročníky (size={})...'.format(size)) + rocniky = [] node = None for ri in range(min(last_rocnik - size, 1), last_rocnik + 1): @@ -253,6 +270,8 @@ def gen_rocniky(last_rocnik, size): return rocniky def gen_konfery(size, rnd, organizatori, resitele, soustredeni): + logger.info('Generuji konfery (size={})...'.format(size)) + konfery = [] for _ in range(1, size): #FIXME Tu range si změňte jak chcete, nevím, co přesně znamená size (asi Anet?) konfera = Konfera.objects.create( @@ -275,6 +294,8 @@ def gen_konfery(size, rnd, organizatori, resitele, soustredeni): return konfery def gen_cisla(rnd, rocniky): + logger.info('Generuji čísla...') + rocnik_cisla = [] for rocnik in rocniky: otec = True @@ -318,6 +339,8 @@ def gen_cisla(rnd, rocniky): return rocnik_cisla def gen_temata(rnd, rocniky, rocnik_cisla, organizatori): + logger.info('Generuji témata...') + jake = ["Hravé", "Fyzikální", "Nejlepší", "Totálně masakrální", "Šokující", "Magnetické", "Modré", "Překvapivé", "Plasmatické", "Novoroční"] @@ -361,6 +384,8 @@ def gen_temata(rnd, rocniky, rocnik_cisla, organizatori): def gen_ulohy_k_tematum(rnd, rocniky, rocnik_cisla, rocnik_temata, organizatori): + logger.info('Generuji úlohy k tématům...') + # ulohy resene v cisle jaka = ["Šachová", "Černá", "Větrná", "Dlouhá", "Křehká", "Rychlá", "Zákeřná", "Fyzikální"] @@ -457,6 +482,8 @@ def gen_ulohy_k_tematum(rnd, rocniky, rocnik_cisla, rocnik_temata, organizatori) return def gen_novinky(rnd, organizatori): + logger.info('Generuji novinky...') + jake = ["zábavné", "veselé", "dobrodružné", "skvělé"] co = ["soustředění", "Fyziklání", "víkendové setkání"] @@ -478,6 +505,8 @@ def otec_syn(otec, syn): @transaction.atomic def create_test_data(size = 6, rnd = None): + logger.info('Vyrábím testovací data (size={})...'.format(size)) + assert size >= 1 # pevna pseudo-nahodnost rnd = rnd or random.Random(x=42) From 402f5bdeb4cec6509861964851f5649fdf0791b9 Mon Sep 17 00:00:00 2001 From: "Pavel \"LEdoian\" Turinsky" Date: Wed, 14 Aug 2019 14:29:24 +0200 Subject: [PATCH 14/92] =?UTF-8?q?Odstran=C4=9Bn=20dal=C5=A1=C3=AD=20Runtim?= =?UTF-8?q?eWarning?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/views.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/seminar/views.py b/seminar/views.py index 57c85b65..02a27909 100644 --- a/seminar/views.py +++ b/seminar/views.py @@ -18,6 +18,7 @@ from .unicodecsv import UnicodeWriter from .forms import NameForm from datetime import timedelta, date, datetime +from django.utils import timezone from itertools import groupby import tempfile import subprocess @@ -143,7 +144,7 @@ class StareNovinkyView(generic.ListView): # Organizatori -def aktivniOrganizatori(datum=date.today()): +def aktivniOrganizatori(datum=timezone.now()): return Organizator.objects.exclude( organizuje_do__isnull=False, organizuje_do__lt=datum From d57214446d153083174e51518e68f5b5cf09f3a1 Mon Sep 17 00:00:00 2001 From: "Pavel \"LEdoian\" Turinsky" Date: Wed, 14 Aug 2019 04:41:12 +0200 Subject: [PATCH 15/92] Testdata: Fix CHOICES MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit v DB byl bordel (celé tuply), nevešly se do postgresového limitu. --- seminar/testutils.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/seminar/testutils.py b/seminar/testutils.py index f9208280..1068d9f1 100644 --- a/seminar/testutils.py +++ b/seminar/testutils.py @@ -104,7 +104,7 @@ def gen_resitele(rnd, osoby, skoly): if not (rand % 8 == 0): resitele.append(Resitel.objects.create(osoba=os, skola=rnd.choice(skoly), rok_maturity=rnd.randint(2019, 2029), - zasilat=rnd.choice(Resitel.ZASILAT_CHOICES))) + zasilat=rnd.choice(Resitel.ZASILAT_CHOICES)[0])) return resitele def gen_prijemci(rnd, osoby, kolik=10): @@ -218,7 +218,7 @@ def gen_ulohy_do_cisla(rnd, organizatori, resitele, rocnik_cisla, rocniky, size) res_vyber = rnd.sample(resitele, rnd.randint(1, 5)) # problem a resitele přiřadíme později, ManyToManyField # se nedá vyplnit v create() - res = Reseni.objects.create(forma=rnd.choice(Reseni.FORMA_CHOICES)) + res = Reseni.objects.create(forma=rnd.choice(Reseni.FORMA_CHOICES)[0]) #res.save() <- asi smazat res.resitele.set(res_vyber) res.save() @@ -367,7 +367,7 @@ def gen_temata(rnd, rocniky, rocnik_cisla, organizatori): garant=rnd.choice(organizatori), kod=str(n), # atributy třídy Téma - tema_typ=rnd.choice(Tema.TEMA_CHOICES), + tema_typ=rnd.choice(Tema.TEMA_CHOICES)[0], rocnik=rocnik ) konec_tematu = min(rnd.randint(ci, 7), len(cisla)) From 7a911b3a3d6d3cdd6384e0064f8c268cb15f19eb Mon Sep 17 00:00:00 2001 From: "Pavel \"LEdoian\" Turinsky" Date: Wed, 14 Aug 2019 14:49:23 +0200 Subject: [PATCH 16/92] =?UTF-8?q?Nukedb:=20p=C5=99=C3=ADkaz,=20kter=C3=BD?= =?UTF-8?q?=20v=C5=A1echny=20aplikace=20odmigruje?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Uvede tedy databázi do naprosto čistého stavu, bez tabulek ap. Není závislá na databázi (narozdíl od 'rm db-local.sqlite3') a nepotřebuje práva vytvářet nové databáze (narozdíl od 'DROP DATABASE' nebo './manage.py reset_db' nad Postgresem) Jinak je to prostě for-cyklus přes INSTALLED_APPS. --- seminar/management/commands/nukedb.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 seminar/management/commands/nukedb.py diff --git a/seminar/management/commands/nukedb.py b/seminar/management/commands/nukedb.py new file mode 100644 index 00000000..f253841a --- /dev/null +++ b/seminar/management/commands/nukedb.py @@ -0,0 +1,20 @@ +from mamweb.settings import INSTALLED_APPS +from django.core.management.base import BaseCommand, CommandError +from django.core.management import call_command + +class Command(BaseCommand): + help = "Odmigruje všechny moduly (i.e. smaže všechny tabulky, ale databázi nechá)" + + def add_arguments(self, parser): + # TODO: --force (makat a neblábolit) + pass + def handle(self, *args, **options): + # TODO: zeptat se + for app in INSTALLED_APPS: + app = app.split('.')[-1] + try: + call_command('migrate', app, 'zero') + except CommandError: + # app nemá migrace (aspoň typicky) + pass + call_command('showmigrations') From dbbaf4f1f7399e83655354eccc3218052a924774 Mon Sep 17 00:00:00 2001 From: "Pavel \"LEdoian\" Turinsky" Date: Wed, 14 Aug 2019 08:05:44 +0200 Subject: [PATCH 17/92] =?UTF-8?q?Models:=20v=C4=9Bt=C5=A1=C3=AD=20mo=C5=BE?= =?UTF-8?q?n=C3=A1=20d=C3=A9lka=20n=C3=A1zvu=20konfery=20kv=C5=AFli=20test?= =?UTF-8?q?dat=C5=AFm?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/migrations/0067_auto_20190814_0805.py | 18 ++++++++++++++++++ seminar/models.py | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 seminar/migrations/0067_auto_20190814_0805.py diff --git a/seminar/migrations/0067_auto_20190814_0805.py b/seminar/migrations/0067_auto_20190814_0805.py new file mode 100644 index 00000000..8a72a659 --- /dev/null +++ b/seminar/migrations/0067_auto_20190814_0805.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2.4 on 2019-08-14 06:05 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0066_problem_polymorphic_ctype'), + ] + + operations = [ + migrations.AlterField( + model_name='konfera', + name='nazev', + field=models.CharField(help_text='Název konfery', max_length=100, verbose_name='název konfery'), + ), + ] diff --git a/seminar/models.py b/seminar/models.py index 6efd27dd..42460c9a 100644 --- a/seminar/models.py +++ b/seminar/models.py @@ -1022,7 +1022,7 @@ class Konfera(models.Model): # Interní ID id = models.AutoField(primary_key = True) - nazev = models.CharField('název konfery', max_length=40, help_text = 'Název konfery') + nazev = models.CharField('název konfery', max_length=100, help_text = 'Název konfery') anotace = models.TextField('anotace', blank=True, help_text='Popis, o čem bude konfera.') From d5860e532e9c024c558cc88f87d5a6fb7b31d7cc Mon Sep 17 00:00:00 2001 From: "Pavel \"LEdoian\" Turinsky" Date: Mon, 19 Aug 2019 20:58:11 +0200 Subject: [PATCH 18/92] =?UTF-8?q?Migrace:=20Semin=C3=A1=C5=99ov=C3=A9=20mi?= =?UTF-8?q?grace=20t=C3=ADmto=20resetov=C3=A1ny?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Takže už se nebude při každém ./manage.py migrate provádět spousta obskurních změn. --- galerie/migrations/0001_initial.py | 2 +- .../0010_Pridani_odkazu_na_organizatora.py | 2 +- korektury/migrations/0014_add_org_to_pdf.py | 2 +- prednasky/migrations/0001_initial.py | 2 +- .../migrations/0005_auto_20160929_0153.py | 2 +- seminar/migrations/0001_initial.py | 251 ------- seminar/migrations/0001_reset.py | 670 ++++++++++++++++++ seminar/migrations/0002_add_body_views.py | 48 -- seminar/migrations/0003_add_skola_zs_ss.py | 32 - seminar/migrations/0004_add_old_dakos_id.py | 44 -- .../migrations/0005_alter_problem_autor.py | 21 - .../migrations/0006_problem_add_timestamp.py | 28 - seminar/migrations/0007_problem_zamereni.py | 22 - seminar/migrations/0008_reseni_forma.py | 20 - .../migrations/0009_rename_imported_IDs.py | 47 -- seminar/migrations/0010_alter_rok_maturity.py | 20 - .../migrations/0011_alter_timestamp_def.py | 39 - .../0012_remove_soustredeni_ucastnici.py | 18 - ...013_soustredeni_ucastnici_through_model.py | 36 - seminar/migrations/0014_uprava_poznamek.py | 50 -- seminar/migrations/0015_soustredeni_text.py | 20 - seminar/migrations/0016_texty_problemu.py | 42 -- .../migrations/0017_texty_problemu_minor.py | 20 - .../0018_problemnavrh_problemzadany.py | 36 - seminar/migrations/0019_rocnik_ciselne.py | 32 - seminar/migrations/0020_indexy_a_razeni.py | 44 -- .../0021_cislo_verejna_vysledkovka.py | 20 - seminar/migrations/0022_decimal_body.py | 29 - seminar/migrations/0023_add_novinky.py | 32 - seminar/migrations/0024_add_organizator.py | 35 - .../0025_zmena_cesty_nahravani_obrazku.py | 20 - seminar/migrations/0026_soustredeni_typ.py | 20 - .../migrations/0027_export_flag_a_typ_akce.py | 32 - .../migrations/0028_add_body_celkem_views.py | 75 -- .../migrations/0029_fix_body_celkem_views.py | 51 -- seminar/migrations/0030_add_vysledky.py | 60 -- seminar/migrations/0031_cislo_pdf.py | 21 - .../migrations/0032_cislo_pdf_blank_typos.py | 44 -- .../0033_organizator_studuje_popisek.py | 20 - .../0034_reseni_forma_default_email.py | 20 - seminar/migrations/0035_django_imagekit.py | 25 - .../migrations/0036_add_org_to_soustredeni.py | 36 - seminar/migrations/0037_prispevek.py | 29 - .../migrations/0038_change_meta_prispevek.py | 18 - seminar/migrations/0039_pohadka.py | 34 - .../0040_pohadka_nepovinny_autor.py | 20 - seminar/migrations/0041_konfery.py | 71 -- seminar/migrations/0042_auto_20161005_0847.py | 31 - seminar/migrations/0042_cislo_faze.py | 19 - seminar/migrations/0043_uprava_faze.py | 19 - seminar/migrations/0044_uprava_faze.py | 19 - .../0045_cislo_pridani_faze_nahrano.py | 19 - seminar/migrations/0046_merge.py | 15 - seminar/migrations/0047_auto_20170120_2118.py | 19 - ...48_add_cislo_datum_deadline_soustredeni.py | 19 - seminar/migrations/0049_auto_20190430_2354.py | 508 ------------- seminar/migrations/0050_auto_20190510_2228.py | 191 ----- seminar/migrations/0051_resitel_to_osoba.py | 89 --- .../migrations/0052_user_to_organizator.py | 82 --- .../0053_organizator_organizuje_od_do.py | 36 - .../0055_smazat_nemigrovane_zastarale_veci.py | 56 -- .../0056_vrcholy_pro_rocniky_a_cisla.py | 47 -- .../0057_reseni_to_reseni_hodnoceni.py | 34 - .../0058_problem_to_uloha_tema_clanek.py | 161 ----- .../migrations/0059_vytvorit_pohadkanode.py | 29 - seminar/migrations/0060_spoj_stromy.py | 112 --- seminar/migrations/0061_kill_frankenstein.py | 153 ---- .../migrations/0062_redukce_modelu_pohadky.py | 33 - seminar/migrations/0063_procisteni_migraci.py | 35 - seminar/migrations/0064_auto_20190610_2358.py | 162 ----- .../0065_treenode_polymorphic_ctype.py | 31 - .../0066_problem_polymorphic_ctype.py | 29 - seminar/migrations/0067_auto_20190814_0805.py | 18 - 73 files changed, 675 insertions(+), 3553 deletions(-) delete mode 100644 seminar/migrations/0001_initial.py create mode 100644 seminar/migrations/0001_reset.py delete mode 100644 seminar/migrations/0002_add_body_views.py delete mode 100644 seminar/migrations/0003_add_skola_zs_ss.py delete mode 100644 seminar/migrations/0004_add_old_dakos_id.py delete mode 100644 seminar/migrations/0005_alter_problem_autor.py delete mode 100644 seminar/migrations/0006_problem_add_timestamp.py delete mode 100644 seminar/migrations/0007_problem_zamereni.py delete mode 100644 seminar/migrations/0008_reseni_forma.py delete mode 100644 seminar/migrations/0009_rename_imported_IDs.py delete mode 100644 seminar/migrations/0010_alter_rok_maturity.py delete mode 100644 seminar/migrations/0011_alter_timestamp_def.py delete mode 100644 seminar/migrations/0012_remove_soustredeni_ucastnici.py delete mode 100644 seminar/migrations/0013_soustredeni_ucastnici_through_model.py delete mode 100644 seminar/migrations/0014_uprava_poznamek.py delete mode 100644 seminar/migrations/0015_soustredeni_text.py delete mode 100644 seminar/migrations/0016_texty_problemu.py delete mode 100644 seminar/migrations/0017_texty_problemu_minor.py delete mode 100644 seminar/migrations/0018_problemnavrh_problemzadany.py delete mode 100644 seminar/migrations/0019_rocnik_ciselne.py delete mode 100644 seminar/migrations/0020_indexy_a_razeni.py delete mode 100644 seminar/migrations/0021_cislo_verejna_vysledkovka.py delete mode 100644 seminar/migrations/0022_decimal_body.py delete mode 100644 seminar/migrations/0023_add_novinky.py delete mode 100644 seminar/migrations/0024_add_organizator.py delete mode 100644 seminar/migrations/0025_zmena_cesty_nahravani_obrazku.py delete mode 100644 seminar/migrations/0026_soustredeni_typ.py delete mode 100644 seminar/migrations/0027_export_flag_a_typ_akce.py delete mode 100644 seminar/migrations/0028_add_body_celkem_views.py delete mode 100644 seminar/migrations/0029_fix_body_celkem_views.py delete mode 100644 seminar/migrations/0030_add_vysledky.py delete mode 100644 seminar/migrations/0031_cislo_pdf.py delete mode 100644 seminar/migrations/0032_cislo_pdf_blank_typos.py delete mode 100644 seminar/migrations/0033_organizator_studuje_popisek.py delete mode 100644 seminar/migrations/0034_reseni_forma_default_email.py delete mode 100644 seminar/migrations/0035_django_imagekit.py delete mode 100644 seminar/migrations/0036_add_org_to_soustredeni.py delete mode 100644 seminar/migrations/0037_prispevek.py delete mode 100644 seminar/migrations/0038_change_meta_prispevek.py delete mode 100644 seminar/migrations/0039_pohadka.py delete mode 100644 seminar/migrations/0040_pohadka_nepovinny_autor.py delete mode 100644 seminar/migrations/0041_konfery.py delete mode 100644 seminar/migrations/0042_auto_20161005_0847.py delete mode 100644 seminar/migrations/0042_cislo_faze.py delete mode 100644 seminar/migrations/0043_uprava_faze.py delete mode 100644 seminar/migrations/0044_uprava_faze.py delete mode 100644 seminar/migrations/0045_cislo_pridani_faze_nahrano.py delete mode 100644 seminar/migrations/0046_merge.py delete mode 100644 seminar/migrations/0047_auto_20170120_2118.py delete mode 100644 seminar/migrations/0048_add_cislo_datum_deadline_soustredeni.py delete mode 100644 seminar/migrations/0049_auto_20190430_2354.py delete mode 100644 seminar/migrations/0050_auto_20190510_2228.py delete mode 100644 seminar/migrations/0051_resitel_to_osoba.py delete mode 100644 seminar/migrations/0052_user_to_organizator.py delete mode 100644 seminar/migrations/0053_organizator_organizuje_od_do.py delete mode 100644 seminar/migrations/0055_smazat_nemigrovane_zastarale_veci.py delete mode 100644 seminar/migrations/0056_vrcholy_pro_rocniky_a_cisla.py delete mode 100644 seminar/migrations/0057_reseni_to_reseni_hodnoceni.py delete mode 100644 seminar/migrations/0058_problem_to_uloha_tema_clanek.py delete mode 100644 seminar/migrations/0059_vytvorit_pohadkanode.py delete mode 100644 seminar/migrations/0060_spoj_stromy.py delete mode 100644 seminar/migrations/0061_kill_frankenstein.py delete mode 100644 seminar/migrations/0062_redukce_modelu_pohadky.py delete mode 100644 seminar/migrations/0063_procisteni_migraci.py delete mode 100644 seminar/migrations/0064_auto_20190610_2358.py delete mode 100644 seminar/migrations/0065_treenode_polymorphic_ctype.py delete mode 100644 seminar/migrations/0066_problem_polymorphic_ctype.py delete mode 100644 seminar/migrations/0067_auto_20190814_0805.py diff --git a/galerie/migrations/0001_initial.py b/galerie/migrations/0001_initial.py index 21701185..23de992b 100644 --- a/galerie/migrations/0001_initial.py +++ b/galerie/migrations/0001_initial.py @@ -8,7 +8,7 @@ import django.db.models.deletion class Migration(migrations.Migration): dependencies = [ - ('seminar', '0033_organizator_studuje_popisek'), + ('seminar', '0001_reset'), ] operations = [ diff --git a/korektury/migrations/0010_Pridani_odkazu_na_organizatora.py b/korektury/migrations/0010_Pridani_odkazu_na_organizatora.py index 6b318cab..a0579b4a 100644 --- a/korektury/migrations/0010_Pridani_odkazu_na_organizatora.py +++ b/korektury/migrations/0010_Pridani_odkazu_na_organizatora.py @@ -7,7 +7,7 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('seminar', '0041_konfery'), + ('seminar', '0001_reset'), ('korektury', '0009_trizeni_korektur_v_seznamu'), ] diff --git a/korektury/migrations/0014_add_org_to_pdf.py b/korektury/migrations/0014_add_org_to_pdf.py index afd939ba..33cedd0d 100644 --- a/korektury/migrations/0014_add_org_to_pdf.py +++ b/korektury/migrations/0014_add_org_to_pdf.py @@ -7,7 +7,7 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('seminar', '0041_konfery'), + ('seminar', '0001_reset'), ('korektury', '0013_rename_autor_org'), ] diff --git a/prednasky/migrations/0001_initial.py b/prednasky/migrations/0001_initial.py index 07da4a4e..80f33bc9 100644 --- a/prednasky/migrations/0001_initial.py +++ b/prednasky/migrations/0001_initial.py @@ -7,7 +7,7 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('seminar', '0036_add_org_to_soustredeni'), + ('seminar', '0001_reset'), ] operations = [ diff --git a/prednasky/migrations/0005_auto_20160929_0153.py b/prednasky/migrations/0005_auto_20160929_0153.py index 7ecff0a0..b67625d0 100644 --- a/prednasky/migrations/0005_auto_20160929_0153.py +++ b/prednasky/migrations/0005_auto_20160929_0153.py @@ -7,7 +7,7 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('seminar', '0041_konfery'), + ('seminar', '0001_reset'), ('prednasky', '0004_remove_prednaska_seznam'), ] diff --git a/seminar/migrations/0001_initial.py b/seminar/migrations/0001_initial.py deleted file mode 100644 index 088193b3..00000000 --- a/seminar/migrations/0001_initial.py +++ /dev/null @@ -1,251 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations -import django_countries.fields -import seminar.models -import django.utils.timezone -from django.conf import settings - - -class Migration(migrations.Migration): - - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ] - - operations = [ - migrations.CreateModel( - name='VysledkyKCislu', - fields=[ - ('dummy_id', models.CharField(max_length=32, serialize=False, verbose_name='dummy ID pro view', primary_key=True, db_column='id')), - ('body', models.IntegerField(verbose_name='body za \u010d\xedslo', db_column='body')), - ('body_celkem', models.IntegerField(verbose_name='body celkem do \u010d\xedsla', db_column='body_celkem')), - ], - options={ - 'abstract': False, - 'db_table': 'seminar_body_k_cislu', - 'managed': False, - }, - bases=(models.Model,), - ), - migrations.CreateModel( - name='VysledkyZaCislo', - fields=[ - ('dummy_id', models.CharField(max_length=32, serialize=False, verbose_name='dummy ID pro view', primary_key=True, db_column='id')), - ('body', models.IntegerField(verbose_name='body za \u010d\xedslo', db_column='body')), - ], - options={ - 'abstract': False, - 'db_table': 'seminar_body_za_cislo', - 'managed': False, - }, - bases=(models.Model,), - ), - migrations.CreateModel( - name='Cislo', - fields=[ - ('id', models.AutoField(serialize=False, primary_key=True)), - ('cislo', models.CharField(help_text='V\u011bt\u0161inou jen "1", vyj\xedme\u010dn\u011b "7-8", lexikograficky ur\u010dije po\u0159ad\xed v ro\u010dn\xedku!', max_length=32, verbose_name='n\xe1zev \u010d\xedsla')), - ('datum_vydani', models.DateField(help_text='Datum vyd\xe1n\xed fin\xe1ln\xed verze', null=True, verbose_name='datum vyd\xe1n\xed', blank=True)), - ('datum_deadline', models.DateField(help_text='Datum pro p\u0159\xedjem \u0159e\u0161en\xed \xfaloh zadan\xfdch v tomto \u010d\xedsle', null=True, verbose_name='datum deadline', blank=True)), - ('verejne_db', models.BooleanField(default=False, verbose_name='\u010d\xedslo zve\u0159ejn\u011bno', db_column='verejne')), - ], - options={ - 'ordering': ['rocnik__rocnik', 'cislo'], - 'db_table': 'seminar_cisla', - 'verbose_name': '\u010c\xedslo', - 'verbose_name_plural': '\u010c\xedsla', - }, - bases=(models.Model,), - ), - migrations.CreateModel( - name='Nastaveni', - fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('aktualni_cislo', models.ForeignKey(verbose_name='posledn\xed vydan\xe9 \u010d\xedslo', to='seminar.Cislo', on_delete=models.CASCADE)), - ], - options={ - 'db_table': 'seminar_nastaveni', - 'verbose_name': 'Nastaven\xed semin\xe1\u0159e', - }, - bases=(models.Model,), - ), - migrations.CreateModel( - name='PrilohaReseni', - fields=[ - ('id', models.AutoField(serialize=False, primary_key=True)), - ('timestamp', models.DateTimeField(auto_now=True, verbose_name='vytvo\u0159eno')), - ('soubor', models.FileField(upload_to=seminar.models.generate_filename, verbose_name='soubor')), - ('poznamka', models.TextField(help_text='Neve\u0159ejn\xe1 pozn\xe1mka k p\u0159\xedloze \u0159e\u0161en\xed (plain text), nap\u0159. o p\u016fvodu', verbose_name='neve\u0159ejn\xe1 pozn\xe1mka', blank=True)), - ], - options={ - 'ordering': ['reseni', 'timestamp'], - 'db_table': 'seminar_priloha_reseni', - 'verbose_name': 'P\u0159\xedloha \u0159e\u0161en\xed', - 'verbose_name_plural': 'P\u0159\xedlohy \u0159e\u0161en\xed', - }, - bases=(models.Model,), - ), - migrations.CreateModel( - name='Problem', - fields=[ - ('id', models.AutoField(serialize=False, primary_key=True)), - ('nazev', models.CharField(max_length=256, verbose_name='n\xe1zev')), - ('typ', models.CharField(default=b'uloha', max_length=32, verbose_name='typ probl\xe9mu', choices=[(b'uloha', '\xdaloha'), (b'tema', 'T\xe9ma'), (b'serial', 'Seri\xe1l'), (b'org-clanek', 'Organiz\xe1torsk\xfd \u010dl\xe1nek'), (b'res-clanek', '\u0158esitelsk\xfd \u010dl\xe1nek')])), - ('stav', models.CharField(default=b'navrh', max_length=32, verbose_name='stav probl\xe9mu', choices=[(b'navrh', 'N\xe1vrh'), (b'zadany', 'Zadan\xfd'), (b'smazany', 'Smazan\xfd')])), - ('text_problemu_org', models.TextField(verbose_name='organiz\xe1torsk\xfd (neve\u0159ejn\xfd) text', blank=True)), - ('text_problemu', models.TextField(verbose_name='ve\u0159ejn\xfd text zad\xe1n\xed a \u0159e\u0161en\xed', blank=True)), - ('kod', models.CharField(default=b'', help_text='\u010c\xedslo/k\xf3d \xfalohy v \u010d\xedsle nebo k\xf3d t\xe9matu/\u010dl\xe1nku/seri\xe1lu v ro\u010dn\xedku', max_length=32, verbose_name='lok\xe1ln\xed k\xf3d', blank=True)), - ('body', models.IntegerField(null=True, verbose_name='maximum bod\u016f', blank=True)), - ('autor', models.ForeignKey(related_name='autor_uloh', verbose_name='autor probl\xe9mu', to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), - ('cislo_reseni', models.ForeignKey(related_name='resene_problemy', blank=True, to='seminar.Cislo', help_text='\u010c\xedslo s \u0159e\u0161en\xedm \xfalohy, jen pro \xfalohy', null=True, verbose_name='\u010d\xedslo \u0159e\u0161en\xed', on_delete=models.CASCADE)), - ('cislo_zadani', models.ForeignKey(related_name='zadane_problemy', verbose_name='\u010d\xedslo zad\xe1n\xed', blank=True, to='seminar.Cislo', null=True, on_delete=models.CASCADE)), - ('opravovatel', models.ForeignKey(related_name='opravovatel_uloh', verbose_name='opravovatel', blank=True, to=settings.AUTH_USER_MODEL, null=True, on_delete=models.CASCADE)), - ], - options={ - 'db_table': 'seminar_problemy', - 'verbose_name': 'Probl\xe9m', - 'verbose_name_plural': 'Probl\xe9my', - }, - bases=(models.Model,), - ), - migrations.CreateModel( - name='Reseni', - fields=[ - ('id', models.AutoField(serialize=False, primary_key=True)), - ('body', models.IntegerField(null=True, verbose_name='body', blank=True)), - ('timestamp', models.DateTimeField(auto_now=True, verbose_name='vytvo\u0159eno')), - ('poznamka', models.TextField(help_text='Neve\u0159ejn\xe1 pozn\xe1mka k \u0159e\u0161en\xed (plain text)', verbose_name='neve\u0159ejn\xe1 pozn\xe1mka', blank=True)), - ('cislo_body', models.ForeignKey(related_name='bodovana_reseni', verbose_name='\u010d\xedslo pro body', blank=True, to='seminar.Cislo', null=True, on_delete=models.CASCADE)), - ('problem', models.ForeignKey(related_name='reseni', verbose_name='probl\xe9m', to='seminar.Problem', on_delete=models.CASCADE)), - ], - options={ - 'ordering': ['problem', 'resitel'], - 'db_table': 'seminar_reseni', - 'verbose_name': '\u0158e\u0161en\xed', - 'verbose_name_plural': '\u0158e\u0161en\xed', - }, - bases=(models.Model,), - ), - migrations.CreateModel( - name='Resitel', - fields=[ - ('id', models.AutoField(serialize=False, primary_key=True)), - ('jmeno', models.CharField(max_length=256, verbose_name='jm\xe9no')), - ('prijmeni', models.CharField(max_length=256, verbose_name='p\u0159\xedjmen\xed')), - ('pohlavi_muz', models.BooleanField(default=False, verbose_name='pohlav\xed (mu\u017e)')), - ('rok_maturity', models.IntegerField(verbose_name='rok maturity')), - ('email', models.EmailField(default=b'', max_length=256, verbose_name='e-mail', blank=True)), - ('telefon', models.CharField(default=b'', max_length=256, verbose_name='telefon', blank=True)), - ('datum_narozeni', models.DateField(null=True, verbose_name='datum narozen\xed', blank=True)), - ('datum_souhlasu_udaje', models.DateField(help_text='Datum souhlasu se zpracov\xe1n\xedm osobn\xedch \xfadaj\u016f', null=True, verbose_name='datum souhlasu (\xfadaje)', blank=True)), - ('datum_souhlasu_zasilani', models.DateField(help_text='Datum souhlasu se zas\xedl\xe1n\xedm MFF materi\xe1l\u016f', null=True, verbose_name='datum souhlasu (spam)', blank=True)), - ('datum_prihlaseni', models.DateField(default=django.utils.timezone.now, verbose_name='datum p\u0159ihl\xe1\u0161en\xed')), - ('zasilat', models.CharField(default=b'domu', max_length=32, verbose_name='kam zas\xedlat', choices=[(b'domu', 'Dom\u016f'), (b'do_skoly', 'Do \u0161koly'), (b'nikam', 'Nikam')])), - ('ulice', models.CharField(default=b'', max_length=256, verbose_name='ulice', blank=True)), - ('mesto', models.CharField(default=b'', max_length=256, verbose_name='m\u011bsto', blank=True)), - ('psc', models.CharField(default=b'', max_length=32, verbose_name='PS\u010c', blank=True)), - ('stat', django_countries.fields.CountryField(default=b'CZ', help_text='ISO 3166-1 k\xf3d zem\u011b velk\xfdmi p\xedsmeny (CZ, SK, ...)', max_length=2, verbose_name='st\xe1t')), - ('poznamka', models.TextField(help_text='Neve\u0159ejn\xe1 pozn\xe1mka k \u0159e\u0161iteli (plain text)', verbose_name='neve\u0159ejn\xe1 pozn\xe1mka', blank=True)), - ], - options={ - 'ordering': ['prijmeni', 'jmeno'], - 'db_table': 'seminar_resitele', - 'verbose_name': '\u0158e\u0161itel', - 'verbose_name_plural': '\u0158e\u0161itel\xe9', - }, - bases=(models.Model,), - ), - migrations.CreateModel( - name='Rocnik', - fields=[ - ('id', models.AutoField(serialize=False, primary_key=True)), - ('prvni_rok', models.IntegerField(verbose_name='prvn\xed rok')), - ('rocnik', models.CharField(max_length=16, verbose_name='\u010d\xedslo ro\u010dn\xedku')), - ], - options={ - 'ordering': ['rocnik'], - 'db_table': 'seminar_rocniky', - 'verbose_name': 'Ro\u010dn\xedk', - 'verbose_name_plural': 'Ro\u010dn\xedky', - }, - bases=(models.Model,), - ), - migrations.CreateModel( - name='Skola', - fields=[ - ('id', models.AutoField(serialize=False, primary_key=True)), - ('aesop_id', models.CharField(default=b'', help_text='Aesopi ID typu "izo:..." nebo "aesop:..."', max_length=32, verbose_name='Aesop ID', blank=True)), - ('izo', models.CharField(help_text='IZO \u0161koly (jen \u010desk\xe9 \u0161koly)', max_length=32, verbose_name='IZO', blank=True)), - ('nazev', models.CharField(help_text='Cel\xfd n\xe1zev \u0161koly', max_length=256, verbose_name='n\xe1zev')), - ('kratky_nazev', models.CharField(help_text=b'Zkr\xc3\xa1cen\xc3\xbd n\xc3\xa1zev pro zobrazen\xc3\xad ve v\xc3\xbdsledkovce', max_length=256, verbose_name='zkr\xe1cen\xfd n\xe1zev', blank=True)), - ('ulice', models.CharField(max_length=256, verbose_name='ulice')), - ('mesto', models.CharField(max_length=256, verbose_name='m\u011bsto')), - ('psc', models.CharField(max_length=32, verbose_name='PS\u010c')), - ('stat', django_countries.fields.CountryField(default=b'CZ', help_text='ISO 3166-1 k\xf3d zeme velk\xfdmi p\xedsmeny (CZ, SK, ...)', max_length=2, verbose_name='st\xe1t')), - ('poznamka', models.TextField(help_text='Neve\u0159ejn\xe1 pozn\xe1mka ke \u0161kole (plain text)', verbose_name='neve\u0159ejn\xe1 pozn\xe1mka', blank=True)), - ], - options={ - 'db_table': 'seminar_skoly', - 'verbose_name': '\u0160kola', - 'verbose_name_plural': '\u0160koly', - }, - bases=(models.Model,), - ), - migrations.CreateModel( - name='Soustredeni', - fields=[ - ('id', models.AutoField(serialize=False, primary_key=True)), - ('datum_zacatku', models.DateField(help_text='Prvn\xed den soust\u0159ed\u011bn\xed', null=True, verbose_name='datum za\u010d\xe1tku', blank=True)), - ('datum_konce', models.DateField(help_text='Posledn\xed den soust\u0159ed\u011bn\xed', null=True, verbose_name='datum konce', blank=True)), - ('verejne_db', models.BooleanField(default=False, verbose_name='soust\u0159ed\u011bn\xed zve\u0159ejn\u011bno', db_column='verejne')), - ('misto', models.CharField(default=b'', help_text='M\xedsto (n\xe1zev obce, voliteln\u011b t\xe9\u017e objektu', max_length=256, verbose_name='m\xedsto soust\u0159ed\u011bn\xed', blank=True)), - ('rocnik', models.ForeignKey(related_name='soustredeni', verbose_name='ro\u010dn\xedk', to='seminar.Rocnik', on_delete=models.CASCADE)), - ('ucastnici', models.ManyToManyField(help_text='Seznam \xfa\u010dastn\xedk\u016f soust\u0159ed\u011bn\xed', to='seminar.Resitel', db_table='seminar_soustredeni_ucastnici', verbose_name='\xfa\u010dastn\xedci soust\u0159ed\u011bn\xed')), - ], - options={ - 'ordering': ['rocnik__rocnik', 'datum_zacatku'], - 'db_table': 'seminar_soustredeni', - 'verbose_name': 'Soust\u0159ed\u011bn\xed', - 'verbose_name_plural': 'Soust\u0159ed\u011bn\xed', - }, - bases=(models.Model,), - ), - migrations.AddField( - model_name='resitel', - name='skola', - field=models.ForeignKey(verbose_name='\u0161kola', blank=True, to='seminar.Skola', null=True, on_delete=models.CASCADE), - preserve_default=True, - ), - migrations.AddField( - model_name='resitel', - name='user', - field=models.OneToOneField(null=True, blank=True, to=settings.AUTH_USER_MODEL, verbose_name='u\u017eivatel', on_delete=models.CASCADE), - preserve_default=True, - ), - migrations.AddField( - model_name='reseni', - name='resitel', - field=models.ForeignKey(related_name='reseni', verbose_name='\u0159e\u0161itel', to='seminar.Resitel', on_delete=models.CASCADE), - preserve_default=True, - ), - migrations.AddField( - model_name='prilohareseni', - name='reseni', - field=models.ForeignKey(related_name='prilohy', verbose_name='\u0159e\u0161en\xed', to='seminar.Reseni', on_delete=models.CASCADE), - preserve_default=True, - ), - migrations.AddField( - model_name='nastaveni', - name='aktualni_rocnik', - field=models.ForeignKey(verbose_name='aktu\xe1ln\xed ro\u010dn\xedk', to='seminar.Rocnik', on_delete=models.CASCADE), - preserve_default=True, - ), - migrations.AddField( - model_name='cislo', - name='rocnik', - field=models.ForeignKey(related_name='cisla', verbose_name='ro\u010dn\xedk', to='seminar.Rocnik', on_delete=models.CASCADE), - preserve_default=True, - ), - ] diff --git a/seminar/migrations/0001_reset.py b/seminar/migrations/0001_reset.py new file mode 100644 index 00000000..07ae6c65 --- /dev/null +++ b/seminar/migrations/0001_reset.py @@ -0,0 +1,670 @@ +# Generated by Django 2.2.4 on 2019-08-19 18:52 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone +import django_countries.fields +import imagekit.models.fields +import seminar.models +import taggit.managers + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('taggit', '0003_taggeditem_add_unique_index'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('contenttypes', '0002_remove_content_type_name'), + ] + + operations = [ + migrations.CreateModel( + name='Cislo', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('cislo', models.CharField(db_index=True, help_text='Většinou jen "1", vyjímečně "7-8", lexikograficky určuje pořadí v ročníku!', max_length=32, verbose_name='název čísla')), + ('datum_vydani', models.DateField(blank=True, help_text='Datum vydání finální verze', null=True, verbose_name='datum vydání')), + ('datum_deadline', models.DateField(blank=True, help_text='Datum pro příjem řešení úloh zadaných v tomto čísle', null=True, verbose_name='datum deadline')), + ('datum_deadline_soustredeni', models.DateField(blank=True, help_text='Datum pro příjem řešení pro účast na soustředění', null=True, verbose_name='datum deadline soustředění')), + ('verejne_db', models.BooleanField(db_column='verejne', default=False, verbose_name='číslo zveřejněno')), + ('verejna_vysledkovka', models.BooleanField(default=False, help_text='Je-li false u veřejného čísla, není výsledkovka zatím veřejná.', verbose_name='zveřejněna výsledkovka')), + ('poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka k číslu (plain text)', verbose_name='neveřejná poznámka')), + ('pdf', models.FileField(blank=True, help_text='Pdf čísla, které si mohou řešitelé stáhnout', null=True, upload_to=seminar.models.cislo_pdf_filename, verbose_name='pdf')), + ], + options={ + 'verbose_name': 'Číslo', + 'verbose_name_plural': 'Čísla', + 'db_table': 'seminar_cisla', + 'ordering': ['-rocnik__rocnik', '-cislo'], + }, + ), + migrations.CreateModel( + name='Hodnoceni', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('body', models.DecimalField(decimal_places=1, max_digits=8, verbose_name='body')), + ('cislo_body', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='hodnoceni', to='seminar.Cislo', verbose_name='číslo pro body')), + ], + options={ + 'verbose_name': 'Hodnocení', + 'verbose_name_plural': 'Hodnocení', + 'db_table': 'seminar_hodnoceni', + }, + ), + migrations.CreateModel( + name='Konfera', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('nazev', models.CharField(help_text='Název konfery', max_length=100, verbose_name='název konfery')), + ('anotace', models.TextField(blank=True, help_text='Popis, o čem bude konfera.', verbose_name='anotace')), + ('abstrakt', models.TextField(blank=True, help_text='Abstrakt konfery tak, jak byl uveden ve sborníku', verbose_name='abstrakt')), + ('poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka ke konfeře(plain text)', verbose_name='neveřejná poznámka')), + ('typ_prezentace', models.CharField(choices=[('veletrh', 'Veletrh (postery)'), ('prezentace', 'Prezentace (přednáška)')], default='veletrh', max_length=16, verbose_name='typ prezentace')), + ('prezentace', models.FileField(blank=True, help_text='Prezentace nebo fotka posteru', upload_to=seminar.models.generate_filename_konfera, verbose_name='prezentace')), + ('materialy', models.FileField(blank=True, help_text='Další materiály ke konfeře zabalené do jednoho souboru', upload_to=seminar.models.generate_filename_konfera, verbose_name='materialy')), + ], + options={ + 'verbose_name': 'Konfera', + 'verbose_name_plural': 'Konfery', + 'db_table': 'seminar_konfera', + }, + ), + 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')), + ], + options={ + 'verbose_name': 'Organizátor', + 'verbose_name_plural': 'Organizátoři', + }, + ), + 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(max_length=256, 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')), + ('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': 'seminar_osoby', + 'ordering': ['prijmeni', 'jmeno'], + }, + ), + migrations.CreateModel( + name='Problem', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('nazev', models.CharField(max_length=256, verbose_name='název')), + ('stav', models.CharField(choices=[('navrh', 'Návrh'), ('zadany', 'Zadaný'), ('vyreseny', 'Vyřešený'), ('smazany', 'Smazaný')], default='navrh', max_length=32, verbose_name='stav problému')), + ('poznamka', models.TextField(blank=True, help_text='Neveřejný návrh úlohy, návrh řešení, text zadání, poznámky ...', verbose_name='org poznámky (HTML)')), + ('kod', models.CharField(blank=True, default='', help_text='Číslo/kód úlohy v čísle nebo kód tématu/článku/seriálu v ročníku', max_length=32, verbose_name='lokální kód')), + ('vytvoreno', models.DateTimeField(blank=True, default=django.utils.timezone.now, editable=False, verbose_name='vytvořeno')), + ('autor', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='autor_problemu_problem', to='seminar.Organizator', verbose_name='autor problému')), + ('garant', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='garant_problemu_problem', to='seminar.Organizator', verbose_name='garant zadaného problému')), + ('nadproblem', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='nadproblem_problem', to='seminar.Problem', verbose_name='nadřazený problém')), + ('opravovatele', models.ManyToManyField(blank=True, related_name='opravovatele_problem', to='seminar.Organizator', verbose_name='opravovatelé')), + ('polymorphic_ctype', models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_seminar.problem_set+', to='contenttypes.ContentType')), + ('zamereni', taggit.managers.TaggableManager(blank=True, help_text='Zaměření M/F/I/O problému, příp. další tagy', through='taggit.TaggedItem', to='taggit.Tag', verbose_name='zaměření')), + ], + options={ + 'verbose_name': 'Problém', + 'verbose_name_plural': 'Problémy', + 'db_table': 'seminar_problemy', + 'ordering': ['nazev'], + }, + ), + 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='seminar.Hodnoceni', to='seminar.Problem', verbose_name='problém')), + ], + options={ + 'verbose_name': 'Řešení', + 'verbose_name_plural': 'Řešení', + 'db_table': 'seminar_reseni', + 'ordering': ['-cas_doruceni'], + }, + ), + migrations.CreateModel( + name='Resitel', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('rok_maturity', models.IntegerField(blank=True, null=True, verbose_name='rok maturity')), + ('zasilat', models.CharField(choices=[('domu', 'Domů'), ('do_skoly', 'Do školy'), ('nikam', 'Nikam')], default='domu', max_length=32, verbose_name='kam zasílat')), + ('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(null=True, on_delete=django.db.models.deletion.SET_NULL, to='seminar.Osoba', verbose_name='osoba')), + ], + options={ + 'verbose_name': 'Řešitel', + 'verbose_name_plural': 'Řešitelé', + 'db_table': 'seminar_resitele', + 'ordering': ['osoba'], + }, + ), + migrations.CreateModel( + name='Rocnik', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('prvni_rok', models.IntegerField(db_index=True, unique=True, verbose_name='první rok')), + ('rocnik', models.IntegerField(db_index=True, unique=True, verbose_name='číslo ročníku')), + ('exportovat', models.BooleanField(db_column='exportovat', default=False, help_text='Exportuje se jen podle tohoto flagu (ne veřejnosti), a to jen čísla s veřejnou výsledkovkou', verbose_name='export do AESOPa')), + ], + options={ + 'verbose_name': 'Ročník', + 'verbose_name_plural': 'Ročníky', + 'db_table': 'seminar_rocniky', + 'ordering': ['-rocnik'], + }, + ), + migrations.CreateModel( + name='Soustredeni', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('datum_zacatku', models.DateField(blank=True, help_text='První den soustředění', null=True, verbose_name='datum začátku')), + ('datum_konce', models.DateField(blank=True, help_text='Poslední den soustředění', null=True, verbose_name='datum konce')), + ('verejne_db', models.BooleanField(db_column='verejne', default=False, verbose_name='soustředění zveřejněno')), + ('misto', models.CharField(blank=True, default='', help_text='Místo (název obce, volitelně též objektu', max_length=256, verbose_name='místo soustředění')), + ('text', models.TextField(blank=True, default='', verbose_name='text k soustředění (HTML)')), + ('typ', models.CharField(choices=[('jarni', 'Jarní soustředění'), ('podzimni', 'Podzimní soustředění'), ('vikend', 'Víkendový sraz')], default='podzimni', max_length=16, verbose_name='typ akce')), + ('exportovat', models.BooleanField(db_column='exportovat', default=False, help_text='Exportuje se jen podle tohoto flagu (ne veřejnosti)', verbose_name='export do AESOPa')), + ], + options={ + 'verbose_name': 'Soustředění', + 'verbose_name_plural': 'Soustředění', + 'db_table': 'seminar_soustredeni', + 'ordering': ['-rocnik__rocnik', '-datum_zacatku'], + }, + ), + migrations.CreateModel( + name='Text', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('na_web', models.TextField(blank=True, help_text='Text ke zveřejnění na webu', verbose_name='text na web')), + ('do_cisla', models.TextField(blank=True, help_text='Text ke zveřejnění v čísle', verbose_name='text do čísla')), + ], + options={ + 'verbose_name': 'text', + 'verbose_name_plural': 'texty', + 'db_table': 'seminar_texty', + }, + ), + migrations.CreateModel( + name='TreeNode', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('first_child', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='seminar.TreeNode', verbose_name='první potomek')), + ('polymorphic_ctype', models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_seminar.treenode_set+', to='contenttypes.ContentType')), + ('root', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='potomci_set', to='seminar.TreeNode', verbose_name='kořen stromu')), + ('succ', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='prev', to='seminar.TreeNode', verbose_name='další element na stejné úrovni')), + ], + options={ + 'verbose_name': 'TreeNode', + 'verbose_name_plural': 'TreeNody', + 'db_table': 'seminar_nodes_treenode', + }, + ), + migrations.CreateModel( + name='Clanek', + fields=[ + ('problem_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.Problem')), + ], + options={ + 'verbose_name': 'Článek', + 'verbose_name_plural': 'Články', + 'db_table': 'seminar_clanky', + }, + bases=('seminar.problem',), + ), + migrations.CreateModel( + name='MezicisloNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ], + options={ + 'verbose_name': 'Mezičíslo (Node)', + 'verbose_name_plural': 'Mezičísla (Node)', + 'db_table': 'seminar_nodes_mezicislo', + }, + bases=('seminar.treenode',), + ), + migrations.CreateModel( + name='Tema', + fields=[ + ('problem_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.Problem')), + ('tema_typ', models.CharField(choices=[('tema', 'Téma'), ('serial', 'Seriál')], default='tema', max_length=16, verbose_name='Typ tématu')), + ('rocnik', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='seminar.Rocnik', verbose_name='ročník')), + ], + options={ + 'verbose_name': 'Téma', + 'verbose_name_plural': 'Témata', + 'db_table': 'seminar_temata', + }, + bases=('seminar.problem',), + ), + migrations.CreateModel( + name='Uloha', + fields=[ + ('problem_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.Problem')), + ('max_body', models.DecimalField(blank=True, decimal_places=1, max_digits=8, null=True, verbose_name='maximum bodů')), + ], + options={ + 'verbose_name': 'Úloha', + 'verbose_name_plural': 'Úlohy', + 'db_table': 'seminar_ulohy', + }, + bases=('seminar.problem',), + ), + migrations.CreateModel( + name='Soustredeni_Ucastnici', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka k účasti (plain text)', verbose_name='neveřejná poznámka')), + ('resitel', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Resitel', verbose_name='řešitel')), + ('soustredeni', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Soustredeni', verbose_name='soustředění')), + ], + options={ + 'verbose_name': 'Účast na soustředění', + 'verbose_name_plural': 'Účasti na soustředění', + 'db_table': 'seminar_soustredeni_ucastnici', + 'ordering': ['soustredeni', 'resitel'], + }, + ), + migrations.CreateModel( + name='Soustredeni_Organizatori', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka k účasti organizátora (plain text)', verbose_name='neveřejná poznámka')), + ('organizator', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Organizator', verbose_name='organizátor')), + ('soustredeni', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Soustredeni', verbose_name='soustředění')), + ], + options={ + 'verbose_name': 'Účast organizátorů na soustředění', + 'verbose_name_plural': 'Účasti organizátorů na soustředění', + 'db_table': 'seminar_soustredeni_organizatori', + 'ordering': ['soustredeni', 'organizator'], + }, + ), + migrations.AddField( + model_name='soustredeni', + name='organizatori', + field=models.ManyToManyField(help_text='Seznam organizátorů soustředění', through='seminar.Soustredeni_Organizatori', to='seminar.Organizator', verbose_name='Organizátoři soustředění'), + ), + migrations.AddField( + model_name='soustredeni', + name='rocnik', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='soustredeni', to='seminar.Rocnik', verbose_name='ročník'), + ), + migrations.AddField( + model_name='soustredeni', + name='ucastnici', + field=models.ManyToManyField(help_text='Seznam účastníků soustředění', through='seminar.Soustredeni_Ucastnici', to='seminar.Resitel', verbose_name='účastníci soustředění'), + ), + 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='seminar.Osoba', verbose_name='Kontaktní osoba')), + ], + options={ + 'verbose_name': 'Škola', + 'verbose_name_plural': 'Školy', + 'db_table': 'seminar_skoly', + 'ordering': ['mesto', 'nazev'], + }, + ), + migrations.AddField( + model_name='resitel', + name='skola', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='seminar.Skola', verbose_name='škola'), + ), + 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='seminar.Reseni', verbose_name='řešení')), + ('resitele', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Resitel', verbose_name='řešitel')), + ], + options={ + 'verbose_name': 'Řešení řešitelů', + 'verbose_name_plural': 'Řešení řešitelů', + 'db_table': 'seminar_reseni_resitele', + 'ordering': ['reseni', 'resitele'], + }, + ), + migrations.AddField( + model_name='reseni', + name='resitele', + field=models.ManyToManyField(help_text='Seznam autorů řešení', through='seminar.Reseni_Resitele', to='seminar.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.SET_NULL, related_name='reseni_cely_set', to='seminar.Text', verbose_name='Plná verze textu řešení'), + ), + migrations.AddField( + model_name='reseni', + name='text_zkraceny', + field=models.ManyToManyField(help_text='Seznam úryvků z řešení', related_name='reseni_zkraceny_set', to='seminar.Text', verbose_name='zkrácené verze ř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=seminar.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')), + ('reseni', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='prilohy', to='seminar.Reseni', verbose_name='řešení')), + ], + options={ + 'verbose_name': 'Příloha řešení', + 'verbose_name_plural': 'Přílohy řešení', + 'db_table': 'seminar_priloha_reseni', + 'ordering': ['reseni', 'vytvoreno'], + }, + ), + 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')), + ('osoba', models.OneToOneField(help_text='Které osobě či na jakou adresu se mají zasílat čísla', on_delete=django.db.models.deletion.CASCADE, to='seminar.Osoba', verbose_name='komu')), + ], + options={ + 'verbose_name': 'příjemce', + 'verbose_name_plural': 'příjemce', + 'db_table': 'seminar_prijemce', + }, + ), + migrations.CreateModel( + name='Pohadka', + 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')), + ('autor', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='seminar.Organizator', verbose_name='Autor pohádky')), + ], + options={ + 'verbose_name': 'Pohádka', + 'verbose_name_plural': 'Pohádky', + 'db_table': 'seminar_pohadky', + 'ordering': ['vytvoreno'], + }, + ), + migrations.AddField( + model_name='organizator', + name='osoba', + field=models.OneToOneField(help_text='osobní údaje organizátora', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='org', to='seminar.Osoba', verbose_name='osoba'), + ), + migrations.CreateModel( + name='Obrazek', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('na_web', models.ImageField(blank=True, null=True, upload_to='obrazky/%Y/%m/%d/', verbose_name='obrázek na web')), + ('do_cisla_barevny', models.FileField(blank=True, help_text='Barevná verze obrázku do čísla', null=True, upload_to='obrazky/%Y/%m/%d/', verbose_name='barevný obrázek do čísla')), + ('do_cisla_cernobily', models.FileField(blank=True, help_text='Černobílá verze obrázku do čísla', null=True, upload_to='obrazky/%Y/%m/%d/', verbose_name='černobílý obrázek do čísla')), + ('text', models.ForeignKey(help_text='text, ve kterém se obrázek vyskytuje', on_delete=django.db.models.deletion.CASCADE, to='seminar.Text', verbose_name='text')), + ], + options={ + 'verbose_name': 'obrázek', + 'verbose_name_plural': 'obrázky', + 'db_table': 'seminar_obrazky', + }, + ), + migrations.CreateModel( + name='Novinky', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('datum', models.DateField(auto_now_add=True)), + ('text', models.TextField(blank=True, null=True, verbose_name='Text novinky')), + ('obrazek', models.ImageField(blank=True, null=True, upload_to='image_novinky/%Y/%m/%d/', verbose_name='Obrázek')), + ('zverejneno', models.BooleanField(default=False, verbose_name='Zveřejněno')), + ('autor', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='seminar.Organizator', verbose_name='Autor novinky')), + ], + options={ + 'verbose_name': 'Novinka', + 'verbose_name_plural': 'Novinky', + 'ordering': ['-datum'], + }, + ), + migrations.CreateModel( + name='Nastaveni', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('aktualni_cislo', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Cislo', verbose_name='poslední vydané číslo')), + ('aktualni_rocnik', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Rocnik', verbose_name='aktuální ročník')), + ], + options={ + 'verbose_name': 'Nastavení semináře', + 'db_table': 'seminar_nastaveni', + }, + ), + migrations.CreateModel( + name='Konfery_Ucastnici', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka k účasti (plain text)', verbose_name='neveřejná poznámka')), + ('konfera', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Konfera', verbose_name='konfera')), + ('resitel', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Resitel', verbose_name='řešitel')), + ], + options={ + 'verbose_name': 'Účast na konfeře', + 'verbose_name_plural': 'Účasti na konfeře', + 'db_table': 'seminar_konfery_ucastnici', + 'ordering': ['konfera', 'resitel'], + }, + ), + migrations.AddField( + model_name='konfera', + name='organizator', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='konfery', to='seminar.Organizator', verbose_name='organizátor'), + ), + migrations.AddField( + model_name='konfera', + name='reseni', + field=models.OneToOneField(blank=True, help_text='Účastnický přípěvek o konfeře', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='konfery', to='seminar.Reseni', verbose_name='článek ke konfeře'), + ), + migrations.AddField( + model_name='konfera', + name='soustredeni', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='konfery', to='seminar.Soustredeni', verbose_name='soustředění'), + ), + migrations.AddField( + model_name='konfera', + name='ucastnici', + field=models.ManyToManyField(help_text='Seznam účastníků konfery', through='seminar.Konfery_Ucastnici', to='seminar.Resitel', verbose_name='účastníci konfery'), + ), + migrations.AddField( + model_name='hodnoceni', + name='problem', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Problem', verbose_name='problém'), + ), + migrations.AddField( + model_name='hodnoceni', + name='reseni', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Reseni', verbose_name='řešení'), + ), + migrations.AddField( + model_name='cislo', + name='rocnik', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='cisla', to='seminar.Rocnik', verbose_name='ročník'), + ), + migrations.CreateModel( + name='UlohaZadaniNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('uloha', models.OneToOneField(null=True, on_delete=django.db.models.deletion.PROTECT, to='seminar.Uloha', verbose_name='úloha')), + ], + options={ + 'verbose_name': 'Zadání úlohy (Node)', + 'verbose_name_plural': 'Zadání úloh (Node)', + 'db_table': 'seminar_nodes_uloha_zadani', + }, + bases=('seminar.treenode',), + ), + migrations.CreateModel( + name='UlohaVzorakNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('uloha', models.OneToOneField(null=True, on_delete=django.db.models.deletion.PROTECT, to='seminar.Uloha', verbose_name='úloha')), + ], + options={ + 'verbose_name': 'Vzorák úlohy (Node)', + 'verbose_name_plural': 'Vzoráky úloh (Node)', + 'db_table': 'seminar_nodes_uloha_vzorak', + }, + bases=('seminar.treenode',), + ), + migrations.AddField( + model_name='uloha', + name='cislo_deadline', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='deadlinove_ulohy', to='seminar.Cislo', verbose_name='číslo deadlinu'), + ), + migrations.AddField( + model_name='uloha', + name='cislo_reseni', + field=models.ForeignKey(blank=True, help_text='Číslo s řešením úlohy, jen pro úlohy', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='resene_ulohy', to='seminar.Cislo', verbose_name='číslo řešení'), + ), + migrations.AddField( + model_name='uloha', + name='cislo_zadani', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='zadane_ulohy', to='seminar.Cislo', verbose_name='číslo zadání'), + ), + migrations.CreateModel( + name='TextNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('text', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Text', verbose_name='text')), + ], + options={ + 'verbose_name': 'Text (Node)', + 'verbose_name_plural': 'Text (Node)', + 'db_table': 'seminar_nodes_obsah', + }, + bases=('seminar.treenode',), + ), + migrations.CreateModel( + name='TemaVCisleNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('tema', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Tema', verbose_name='téma v čísle')), + ], + options={ + 'verbose_name': 'Téma v čísle (Node)', + 'verbose_name_plural': 'Témata v čísle (Node)', + 'db_table': 'seminar_nodes_temavcisle', + }, + bases=('seminar.treenode',), + ), + migrations.CreateModel( + name='RocnikNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('rocnik', models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, to='seminar.Rocnik', verbose_name='ročník')), + ], + options={ + 'verbose_name': 'Ročník (Node)', + 'verbose_name_plural': 'Ročníky (Node)', + 'db_table': 'seminar_nodes_rocnik', + }, + bases=('seminar.treenode',), + ), + migrations.CreateModel( + name='PohadkaNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('pohadka', models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, to='seminar.Pohadka', verbose_name='pohádka')), + ], + options={ + 'verbose_name': 'Pohádka (Node)', + 'verbose_name_plural': 'Pohádky (Node)', + 'db_table': 'seminar_nodes_pohadka', + }, + bases=('seminar.treenode',), + ), + migrations.CreateModel( + name='KonferaNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('konfera', models.OneToOneField(null=True, on_delete=django.db.models.deletion.PROTECT, to='seminar.Konfera', verbose_name='konfera')), + ], + options={ + 'verbose_name': 'Konfera (Node)', + 'verbose_name_plural': 'Konfery (Node)', + 'db_table': 'seminar_nodes_konfera', + }, + bases=('seminar.treenode',), + ), + migrations.CreateModel( + name='ClanekNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('clanek', models.OneToOneField(null=True, on_delete=django.db.models.deletion.PROTECT, to='seminar.Clanek', verbose_name='článek')), + ], + options={ + 'verbose_name': 'Článek (Node)', + 'verbose_name_plural': 'Články (Node)', + 'db_table': 'seminar_nodes_clanek', + }, + bases=('seminar.treenode',), + ), + migrations.AddField( + model_name='clanek', + name='cislo', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='seminar.Cislo', verbose_name='číslo'), + ), + migrations.CreateModel( + name='CisloNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('cislo', models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, to='seminar.Cislo', verbose_name='číslo')), + ], + options={ + 'verbose_name': 'Číslo (Node)', + 'verbose_name_plural': 'Čísla (Node)', + 'db_table': 'seminar_nodes_cislo', + }, + bases=('seminar.treenode',), + ), + ] diff --git a/seminar/migrations/0002_add_body_views.py b/seminar/migrations/0002_add_body_views.py deleted file mode 100644 index 3d128ab9..00000000 --- a/seminar/migrations/0002_add_body_views.py +++ /dev/null @@ -1,48 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations -import django_countries.fields -import seminar.models -import django.utils.timezone -from django.conf import settings - -CREATE_VIEWS=""" -create view seminar_body_za_cislo as - select - sr.cislo_body_id || '-' || sr.resitel_id as id, - sr.cislo_body_id as cislo_id, - sr.resitel_id as resitel_id, - sum(sr.body) as body - from seminar_reseni as sr - group by sr.cislo_body_id, sr.resitel_id - order by body desc; - -create view seminar_body_k_cislu as - select - akt_c.id || '-' || min_bzc.resitel_id as id, - akt_c.id as cislo_id, - min_bzc.resitel_id as resitel_id, - max(akt_bzc.body) as body, - sum(min_bzc.body) as body_celkem - from ((seminar_cisla as akt_c - inner join seminar_cisla as min_c on min_c.rocnik_id = akt_c.rocnik_id and akt_c.cislo >= min_c.cislo) - inner join seminar_body_za_cislo as min_bzc on min_c.id = min_bzc.cislo_id) - left outer join seminar_body_za_cislo as akt_bzc on akt_bzc.cislo_id = akt_c.id and akt_bzc.resitel_id = min_bzc.resitel_id - group by akt_c.id, min_bzc.resitel_id, akt_bzc.resitel_id - order by body_celkem desc; -""" - -DROP_VIEWS=""" -drop view seminar_body_k_cislu; -drop view seminar_body_za_cislo; -""" - -class Migration(migrations.Migration): - - dependencies = [("seminar", "0001_initial")] - - operations = [ - migrations.RunSQL(sql=CREATE_VIEWS, reverse_sql=DROP_VIEWS) - ] - diff --git a/seminar/migrations/0003_add_skola_zs_ss.py b/seminar/migrations/0003_add_skola_zs_ss.py deleted file mode 100644 index 1b1fbb80..00000000 --- a/seminar/migrations/0003_add_skola_zs_ss.py +++ /dev/null @@ -1,32 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0002_add_body_views'), - ] - - operations = [ - migrations.AddField( - model_name='skola', - name='je_ss', - field=models.BooleanField(default=True, verbose_name='st\u0159edn\xed stupe\u0148'), - preserve_default=False, - ), - migrations.AddField( - model_name='skola', - name='je_zs', - field=models.BooleanField(default=True, verbose_name='z\xe1kladn\xed stupe\u0148'), - preserve_default=False, - ), - migrations.AlterField( - model_name='reseni', - name='poznamka', - field=models.TextField(help_text='Neve\u0159ejn\xe1 pozn\xe1mka k \u0159e\u0161en\xed (plain text, editace v detailu \u0159e\u0161en\xed)', verbose_name='neve\u0159ejn\xe1 pozn\xe1mka', blank=True), - preserve_default=True, - ), - ] diff --git a/seminar/migrations/0004_add_old_dakos_id.py b/seminar/migrations/0004_add_old_dakos_id.py deleted file mode 100644 index 1ec28943..00000000 --- a/seminar/migrations/0004_add_old_dakos_id.py +++ /dev/null @@ -1,44 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0003_add_skola_zs_ss'), - ] - - operations = [ - migrations.AddField( - model_name='problem', - name='dakos_id', - field=models.CharField(default=b'', help_text='DaKoS ID z exportu, s prefixem podle p\u016fvodu: "AZAD:xxx" (z MM_AZAD), "DOZ:xxx" (z MM_DOZ), "ZAD:xxx" (z MM_ZADANIA)', max_length=32, verbose_name='Star\xe9 DaKoS ID', blank=True), - preserve_default=True, - ), - migrations.AddField( - model_name='resitel', - name='dakos_id', - field=models.CharField(default=b'', help_text='DaKoS ID z exportu, jen historick\xfd v\xfdznam, podle tabulky mamoper.MM_RIESITELIA', max_length=32, verbose_name='Stare DaKoS ID', blank=True), - preserve_default=True, - ), - migrations.AddField( - model_name='skola', - name='dakos_id', - field=models.CharField(default=b'', help_text='DaKoS ID z exportu, jen historick\xfd v\xfdznam, podle tabulky dksroot.V_skola', max_length=32, verbose_name='Stare DaKoS ID', blank=True), - preserve_default=True, - ), - migrations.AlterField( - model_name='skola', - name='je_ss', - field=models.BooleanField(default=True, verbose_name='st\u0159edn\xed stupe\u0148'), - preserve_default=True, - ), - migrations.AlterField( - model_name='skola', - name='je_zs', - field=models.BooleanField(default=True, verbose_name='z\xe1kladn\xed stupe\u0148'), - preserve_default=True, - ), - ] diff --git a/seminar/migrations/0005_alter_problem_autor.py b/seminar/migrations/0005_alter_problem_autor.py deleted file mode 100644 index d8a40585..00000000 --- a/seminar/migrations/0005_alter_problem_autor.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations -from django.conf import settings - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0004_add_old_dakos_id'), - ] - - operations = [ - migrations.AlterField( - model_name='problem', - name='autor', - field=models.ForeignKey(related_name='autor_uloh', verbose_name='autor probl\xe9mu', blank=True, to=settings.AUTH_USER_MODEL, null=True, on_delete=models.CASCADE), - preserve_default=True, - ), - ] diff --git a/seminar/migrations/0006_problem_add_timestamp.py b/seminar/migrations/0006_problem_add_timestamp.py deleted file mode 100644 index 3df8bfdb..00000000 --- a/seminar/migrations/0006_problem_add_timestamp.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations -import datetime -from django.utils.timezone import utc - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0005_alter_problem_autor'), - ] - - operations = [ - migrations.AddField( - model_name='problem', - name='timestamp', - field=models.DateTimeField(default=datetime.datetime(2015, 5, 15, 8, 54, 56, 319985, tzinfo=utc), verbose_name='vytvo\u0159eno', auto_now=True), - preserve_default=False, - ), - migrations.AlterField( - model_name='problem', - name='dakos_id', - field=models.CharField(default=b'', help_text='DaKoS ID z exportu, s prefixem podle p\u016fvodu: "AZAD:xxx (z MM_AZAD), ""DOZ:xxx" (z MM_DOZ), "ZAD:rocnik.cislo.uloha.typ" (z MM_ZADANIA)', max_length=32, verbose_name='Star\xe9 DaKoS ID', blank=True), - preserve_default=True, - ), - ] diff --git a/seminar/migrations/0007_problem_zamereni.py b/seminar/migrations/0007_problem_zamereni.py deleted file mode 100644 index 10718bd7..00000000 --- a/seminar/migrations/0007_problem_zamereni.py +++ /dev/null @@ -1,22 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations -import taggit.managers - - -class Migration(migrations.Migration): - - dependencies = [ - ('taggit', '0001_initial'), - ('seminar', '0006_problem_add_timestamp'), - ] - - operations = [ - migrations.AddField( - model_name='problem', - name='zamereni', - field=taggit.managers.TaggableManager(to='taggit.Tag', through='taggit.TaggedItem', blank=True, help_text=b'Zam\xc4\x9b\xc5\x99en\xc3\xad M/F/I/O probl\xc3\xa9mu, p\xc5\x99\xc3\xadp. dal\xc5\xa1\xc3\xad tagy', verbose_name='zam\u011b\u0159en\xed'), - preserve_default=True, - ), - ] diff --git a/seminar/migrations/0008_reseni_forma.py b/seminar/migrations/0008_reseni_forma.py deleted file mode 100644 index 399e81a9..00000000 --- a/seminar/migrations/0008_reseni_forma.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0007_problem_zamereni'), - ] - - operations = [ - migrations.AddField( - model_name='reseni', - name='forma', - field=models.CharField(default=b'papir', max_length=16, verbose_name='forma \u0159e\u0161en\xed', choices=[(b'papir', 'Pap\xedrov\xe9 \u0159e\u0161en\xed'), (b'email', 'Emailem'), (b'upload', 'Upload p\u0159es web')]), - preserve_default=True, - ), - ] diff --git a/seminar/migrations/0009_rename_imported_IDs.py b/seminar/migrations/0009_rename_imported_IDs.py deleted file mode 100644 index 997bc0ac..00000000 --- a/seminar/migrations/0009_rename_imported_IDs.py +++ /dev/null @@ -1,47 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0008_reseni_forma'), - ] - - operations = [ - migrations.RenameField( - model_name='problem', - old_name='dakos_id', - new_name='import_dakos_id', - ), - migrations.RenameField( - model_name='resitel', - old_name='dakos_id', - new_name='import_mamoper_id', - ), - migrations.RenameField( - model_name='skola', - old_name='dakos_id', - new_name='import_dakos_id', - ), - migrations.AlterField( - model_name='problem', - name='import_dakos_id', - field=models.CharField(default=b'', help_text='ID z importu z DAKOSU s prefixem podle p\u016fvodu: "AZAD:xxx (MAMOPER.MM_AZAD), ""DOZ:xxx" (MAMOPER.MM_DOZ), "ZAD:rocnik.cislo.uloha.typ" (MAMOPER.MM_ZADANIA)', max_length=32, verbose_name='importovan\xe9 ID s typem', blank=True), - preserve_default=True, - ), - migrations.AlterField( - model_name='resitel', - name='import_mamoper_id', - field=models.CharField(default=b'', help_text='MAMOPER.MM_RIESITELIA.ID z DAKOS importu, jen historick\xfd v\xfdznam', max_length=32, verbose_name='importovan\xe9 MM_RIESITELIA.ID', blank=True), - preserve_default=True, - ), - migrations.AlterField( - model_name='skola', - name='import_dakos_id', - field=models.CharField(default=b'', help_text='DKSROOT.V_SKOLA.ID z DAKOS importu, jen historick\xfd v\xfdznam', max_length=32, verbose_name='importovan\xe9 DKSROOT.V_SKOLA.ID', blank=True), - preserve_default=True, - ), - ] diff --git a/seminar/migrations/0010_alter_rok_maturity.py b/seminar/migrations/0010_alter_rok_maturity.py deleted file mode 100644 index 58c099fb..00000000 --- a/seminar/migrations/0010_alter_rok_maturity.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0009_rename_imported_IDs'), - ] - - operations = [ - migrations.AlterField( - model_name='resitel', - name='rok_maturity', - field=models.IntegerField(null=True, verbose_name='rok maturity', blank=True), - preserve_default=True, - ), - ] diff --git a/seminar/migrations/0011_alter_timestamp_def.py b/seminar/migrations/0011_alter_timestamp_def.py deleted file mode 100644 index 238386a6..00000000 --- a/seminar/migrations/0011_alter_timestamp_def.py +++ /dev/null @@ -1,39 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations -import django.utils.timezone - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0010_alter_rok_maturity'), - ] - - operations = [ - migrations.AlterField( - model_name='prilohareseni', - name='timestamp', - field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='vytvo\u0159eno', editable=False, blank=True), - preserve_default=True, - ), - migrations.AlterField( - model_name='problem', - name='import_dakos_id', - field=models.CharField(default=b'', help_text='ID z importu z DAKOSU s prefixem podle p\u016fvodu: "AZAD:xxx (MAMOPER.MM_AZAD), ""DOZ:xxx" (MAMOPER.MM_DOZ), "ZAD:rocnik.cislo.uloha.typ" (MAMOPER.MM_ZADANIA), "ULOHA:xxx" (MAMOPER.MM_ULOHY)', max_length=32, verbose_name='importovan\xe9 ID s typem', blank=True), - preserve_default=True, - ), - migrations.AlterField( - model_name='problem', - name='timestamp', - field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='vytvo\u0159eno', editable=False, blank=True), - preserve_default=True, - ), - migrations.AlterField( - model_name='reseni', - name='timestamp', - field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='vytvo\u0159eno', editable=False, blank=True), - preserve_default=True, - ), - ] diff --git a/seminar/migrations/0012_remove_soustredeni_ucastnici.py b/seminar/migrations/0012_remove_soustredeni_ucastnici.py deleted file mode 100644 index ddb61304..00000000 --- a/seminar/migrations/0012_remove_soustredeni_ucastnici.py +++ /dev/null @@ -1,18 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0011_alter_timestamp_def'), - ] - - operations = [ - migrations.RemoveField( - model_name='soustredeni', - name='ucastnici', - ), - ] diff --git a/seminar/migrations/0013_soustredeni_ucastnici_through_model.py b/seminar/migrations/0013_soustredeni_ucastnici_through_model.py deleted file mode 100644 index c725691d..00000000 --- a/seminar/migrations/0013_soustredeni_ucastnici_through_model.py +++ /dev/null @@ -1,36 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0012_remove_soustredeni_ucastnici'), - ] - - operations = [ - migrations.CreateModel( - name='Soustredeni_Ucastnici', - fields=[ - ('id', models.AutoField(serialize=False, primary_key=True)), - ('poznamka', models.CharField(default=b'', help_text='Neve\u0159ejn\xe1 pozn\xe1mka k \xfa\u010dasti (plain text)', max_length=64, verbose_name='neve\u0159ejn\xe1 pozn\xe1mka', blank=True)), - ('resitel', models.ForeignKey(verbose_name='\u0159e\u0161itel', to='seminar.Resitel', on_delete=models.CASCADE)), - ('soustredeni', models.ForeignKey(verbose_name='soust\u0159ed\u011bn\xed', to='seminar.Soustredeni',on_delete=models.CASCADE)), - ], - options={ - 'ordering': ['soustredeni', 'resitel'], - 'db_table': 'seminar_soustredeni_ucastnici', - 'verbose_name': '\xda\u010dast na soust\u0159ed\u011bn\xed', - 'verbose_name_plural': '\xda\u010dasti na soust\u0159ed\u011bn\xed', - }, - bases=(models.Model,), - ), - migrations.AddField( - model_name='soustredeni', - name='ucastnici', - field=models.ManyToManyField(help_text='Seznam \xfa\u010dastn\xedk\u016f soust\u0159ed\u011bn\xed', to='seminar.Resitel', verbose_name='\xfa\u010dastn\xedci soust\u0159ed\u011bn\xed', through='seminar.Soustredeni_Ucastnici'), - preserve_default=True, - ), - ] diff --git a/seminar/migrations/0014_uprava_poznamek.py b/seminar/migrations/0014_uprava_poznamek.py deleted file mode 100644 index 0eb34984..00000000 --- a/seminar/migrations/0014_uprava_poznamek.py +++ /dev/null @@ -1,50 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0013_soustredeni_ucastnici_through_model'), - ] - - operations = [ - migrations.AlterModelOptions( - name='problem', - options={'ordering': ['nazev'], 'verbose_name': 'Probl\xe9m', 'verbose_name_plural': 'Probl\xe9my'}, - ), - migrations.AlterModelOptions( - name='reseni', - options={'ordering': ['problem_id', 'resitel_id'], 'verbose_name': '\u0158e\u0161en\xed', 'verbose_name_plural': '\u0158e\u0161en\xed'}, - ), - migrations.AlterModelOptions( - name='skola', - options={'ordering': ['mesto', 'nazev'], 'verbose_name': '\u0160kola', 'verbose_name_plural': '\u0160koly'}, - ), - migrations.AddField( - model_name='cislo', - name='poznamka', - field=models.TextField(help_text='Neve\u0159ejn\xe1 pozn\xe1mka k \u010d\xedslu (plain text)', verbose_name='neve\u0159ejn\xe1 pozn\xe1mka', blank=True), - preserve_default=True, - ), - migrations.AlterField( - model_name='problem', - name='text_problemu_org', - field=models.TextField(verbose_name='neve\u0159ejn\xe9 zad\xe1n\xed a organiz\xe1torsk\xe9 a pozn\xe1mky', blank=True), - preserve_default=True, - ), - migrations.AlterField( - model_name='reseni', - name='poznamka', - field=models.TextField(help_text='Neve\u0159ejn\xe1 pozn\xe1mka k \u0159e\u0161en\xed (plain text)', verbose_name='neve\u0159ejn\xe1 pozn\xe1mka', blank=True), - preserve_default=True, - ), - migrations.AlterField( - model_name='soustredeni_ucastnici', - name='poznamka', - field=models.TextField(help_text='Neve\u0159ejn\xe1 pozn\xe1mka k \xfa\u010dasti (plain text)', verbose_name='neve\u0159ejn\xe1 pozn\xe1mka', blank=True), - preserve_default=True, - ), - ] diff --git a/seminar/migrations/0015_soustredeni_text.py b/seminar/migrations/0015_soustredeni_text.py deleted file mode 100644 index 87298eba..00000000 --- a/seminar/migrations/0015_soustredeni_text.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0014_uprava_poznamek'), - ] - - operations = [ - migrations.AddField( - model_name='soustredeni', - name='text', - field=models.TextField(default=b'', verbose_name='text k soust\u0159ed\u011bn\xed (HTML)', blank=True), - preserve_default=True, - ), - ] diff --git a/seminar/migrations/0016_texty_problemu.py b/seminar/migrations/0016_texty_problemu.py deleted file mode 100644 index 451c888e..00000000 --- a/seminar/migrations/0016_texty_problemu.py +++ /dev/null @@ -1,42 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0015_soustredeni_text'), - ] - - operations = [ - migrations.RenameField( - model_name='problem', - old_name='text_problemu_org', - new_name='text_org', - ), - migrations.RenameField( - model_name='problem', - old_name='text_problemu', - new_name='text_zadani', - ), - migrations.AddField( - model_name='problem', - name='text_reseni', - field=models.TextField(help_text='Ve\u0159ejn\xfd text \u0159e\u0161en\xed (HTML, u t\xe9mat i p\u0159\xedsp\u011bvky a koment\xe1\u0159e)', verbose_name='ve\u0159ejn\xe9 \u0159e\u0161en\xed (HTML)', blank=True), - preserve_default=True, - ), - migrations.AlterField( - model_name='problem', - name='text_org', - field=models.TextField(help_text='Neve\u0159ejn\xfd n\xe1vrh \xfalohy, n\xe1vrh \u0159e\u0161en\xed, text zad\xe1n\xed, pozn\xe1mky ...', verbose_name='org pozn\xe1mky (HTML)', blank=True), - preserve_default=True, - ), - migrations.AlterField( - model_name='problem', - name='text_zadani', - field=models.TextField(help_text='Ve\u0159ejn\xfd text zad\xe1n\xed (HTML)', verbose_name='ve\u0159ejn\xe9 zad\xe1n\xed (HTML)', blank=True), - preserve_default=True, - ), - ] diff --git a/seminar/migrations/0017_texty_problemu_minor.py b/seminar/migrations/0017_texty_problemu_minor.py deleted file mode 100644 index f732c111..00000000 --- a/seminar/migrations/0017_texty_problemu_minor.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0016_texty_problemu'), - ] - - operations = [ - migrations.AlterField( - model_name='problem', - name='text_reseni', - field=models.TextField(help_text='Ve\u0159ejn\xfd text \u0159e\u0161en\xed (HTML, u t\xe9mat i p\u0159\xedsp\u011bvky a koment\xe1\u0159e)', verbose_name='ve\u0159ejn\xe9 \u0159e\u0161en\xed (HTML)', blank=True), - preserve_default=True, - ), - ] diff --git a/seminar/migrations/0018_problemnavrh_problemzadany.py b/seminar/migrations/0018_problemnavrh_problemzadany.py deleted file mode 100644 index afdcfa8c..00000000 --- a/seminar/migrations/0018_problemnavrh_problemzadany.py +++ /dev/null @@ -1,36 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0017_texty_problemu_minor'), - ] - - operations = [ - migrations.CreateModel( - name='ProblemNavrh', - fields=[ - ], - options={ - 'verbose_name': 'Probl\xe9m (n\xe1vrh)', - 'proxy': True, - 'verbose_name_plural': 'Probl\xe9my (n\xe1vrhy)', - }, - bases=('seminar.problem',), - ), - migrations.CreateModel( - name='ProblemZadany', - fields=[ - ], - options={ - 'verbose_name': 'Probl\xe9m (zadan\xfd)', - 'proxy': True, - 'verbose_name_plural': 'Probl\xe9my (zadan\xe9)', - }, - bases=('seminar.problem',), - ), - ] diff --git a/seminar/migrations/0019_rocnik_ciselne.py b/seminar/migrations/0019_rocnik_ciselne.py deleted file mode 100644 index 42308b2f..00000000 --- a/seminar/migrations/0019_rocnik_ciselne.py +++ /dev/null @@ -1,32 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0018_problemnavrh_problemzadany'), - ] - - operations = [ - migrations.AddField( - model_name='rocnik', - name='rocnik_n', - field=models.IntegerField(default=0, verbose_name='\u010d\xedslo ro\u010dn\xedku'), - preserve_default=False, - ), - migrations.RunSQL( - sql="update seminar_rocniky set rocnik_n = cast (rocnik as integer)" - ), - migrations.RemoveField( - model_name='rocnik', - name='rocnik', - ), - migrations.RenameField( - model_name='rocnik', - old_name='rocnik_n', - new_name='rocnik', - ), - ] diff --git a/seminar/migrations/0020_indexy_a_razeni.py b/seminar/migrations/0020_indexy_a_razeni.py deleted file mode 100644 index 1e199f0e..00000000 --- a/seminar/migrations/0020_indexy_a_razeni.py +++ /dev/null @@ -1,44 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0019_rocnik_ciselne'), - ] - - operations = [ - migrations.AlterModelOptions( - name='cislo', - options={'ordering': ['-rocnik__rocnik', '-cislo'], 'verbose_name': '\u010c\xedslo', 'verbose_name_plural': '\u010c\xedsla'}, - ), - migrations.AlterModelOptions( - name='reseni', - options={'ordering': ['problem_id', 'resitel__prijmeni', 'resitel__jmeno'], 'verbose_name': '\u0158e\u0161en\xed', 'verbose_name_plural': '\u0158e\u0161en\xed'}, - ), - migrations.AlterModelOptions( - name='rocnik', - options={'ordering': ['-rocnik'], 'verbose_name': 'Ro\u010dn\xedk', 'verbose_name_plural': 'Ro\u010dn\xedky'}, - ), - migrations.AlterField( - model_name='cislo', - name='cislo', - field=models.CharField(help_text='V\u011bt\u0161inou jen "1", vyj\xedme\u010dn\u011b "7-8", lexikograficky ur\u010dije po\u0159ad\xed v ro\u010dn\xedku!', max_length=32, verbose_name='n\xe1zev \u010d\xedsla', db_index=True), - preserve_default=True, - ), - migrations.AlterField( - model_name='rocnik', - name='prvni_rok', - field=models.IntegerField(unique=True, verbose_name='prvn\xed rok', db_index=True), - preserve_default=True, - ), - migrations.AlterField( - model_name='rocnik', - name='rocnik', - field=models.IntegerField(unique=True, verbose_name='\u010d\xedslo ro\u010dn\xedku', db_index=True), - preserve_default=True, - ), - ] diff --git a/seminar/migrations/0021_cislo_verejna_vysledkovka.py b/seminar/migrations/0021_cislo_verejna_vysledkovka.py deleted file mode 100644 index d4d34c7f..00000000 --- a/seminar/migrations/0021_cislo_verejna_vysledkovka.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0020_indexy_a_razeni'), - ] - - operations = [ - migrations.AddField( - model_name='cislo', - name='verejna_vysledkovka', - field=models.BooleanField(default=False, help_text='Je-li false u ve\u0159ejn\xe9ho \u010d\xedsla, nen\xed v\xfdsledkovka zat\xedm ve\u0159ejn\xe1.', verbose_name='zve\u0159ejn\u011bna v\xfdsledkovka'), - preserve_default=True, - ), - ] diff --git a/seminar/migrations/0022_decimal_body.py b/seminar/migrations/0022_decimal_body.py deleted file mode 100644 index ff92fcde..00000000 --- a/seminar/migrations/0022_decimal_body.py +++ /dev/null @@ -1,29 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals -import importlib - -from django.db import models, migrations - -migration_0022 = importlib.import_module('seminar.migrations.0002_add_body_views') - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0021_cislo_verejna_vysledkovka'), - ] - operations = [ - migrations.RunSQL(migration_0022.DROP_VIEWS), - migrations.AlterField( - model_name='problem', - name='body', - field=models.DecimalField(null=True, verbose_name='maximum bod\u016f', max_digits=8, decimal_places=1, blank=True), - preserve_default=True, - ), - migrations.AlterField( - model_name='reseni', - name='body', - field=models.DecimalField(null=True, verbose_name='body', max_digits=8, decimal_places=1, blank=True), - preserve_default=True, - ), - migrations.RunSQL(migration_0022.CREATE_VIEWS), - ] diff --git a/seminar/migrations/0023_add_novinky.py b/seminar/migrations/0023_add_novinky.py deleted file mode 100644 index 7db2a005..00000000 --- a/seminar/migrations/0023_add_novinky.py +++ /dev/null @@ -1,32 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations -from django.conf import settings - - -class Migration(migrations.Migration): - - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('seminar', '0022_decimal_body'), - ] - - operations = [ - migrations.CreateModel( - name='Novinky', - fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('datum', models.DateField(auto_now_add=True)), - ('text', models.TextField(null=True, verbose_name=b'Text novinky', blank=True)), - ('obrazek', models.ImageField(upload_to=b'image_novinky/%Y/%m/%d/', null=True, verbose_name=b'Obr\xc3\xa1zek', blank=True)), - ('zverejneno', models.BooleanField(default=False, verbose_name=b'Zve\xc5\x99ejn\xc4\x9bno')), - ('autor', models.ForeignKey(verbose_name=b'Autor novinky', to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)) - ], - options={ - 'verbose_name': 'Novinka', - 'verbose_name_plural': 'Novinky', - }, - bases=(models.Model,), - ), - ] diff --git a/seminar/migrations/0024_add_organizator.py b/seminar/migrations/0024_add_organizator.py deleted file mode 100644 index 16faee72..00000000 --- a/seminar/migrations/0024_add_organizator.py +++ /dev/null @@ -1,35 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations -from django.conf import settings - - -class Migration(migrations.Migration): - - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('seminar', '0023_add_novinky'), - ] - - operations = [ - migrations.CreateModel( - name='Organizator', - fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('prezdivka', models.CharField(max_length=32, null=True, verbose_name=b'P\xc5\x99ezd\xc3\xadvka', blank=True)), - ('organizuje_od_roku', models.IntegerField(null=True, verbose_name=b'Organizuje od roku', blank=True)), - ('organizuje_do_roku', models.IntegerField(null=True, verbose_name=b'Organizuje do roku', blank=True)), - ('studuje', models.CharField(max_length=256, null=True, verbose_name=b'Studuje', blank=True)), - ('strucny_popis_organizatora', models.TextField(null=True, verbose_name=b'Stru\xc4\x8dn\xc3\xbd popis organiz\xc3\xa1tora', blank=True)), - ('foto', models.ImageField(help_text=b'Vlo\xc5\xbe fotografii organiz\xc3\xa1tora o libovon\xc3\xa9 velikosti', upload_to=b'image_organizatori/%Y/', null=True, verbose_name=b'Fotografie organiz\xc3\xa1tora', blank=True)), - ('foto_male', models.ImageField(upload_to=b'image_organizatori/male/%Y/', null=True, editable=False, blank=True)), - ('user', models.OneToOneField(verbose_name=b'Osoba', to=settings.AUTH_USER_MODEL, help_text=b'Vyber \xc3\xba\xc4\x8det sp\xc5\x99a\xc5\xbeen\xc3\xbd s organiz\xc3\xa1torem.',on_delete=models.CASCADE)), - ], - options={ - 'verbose_name': 'Organiz\xe1tor', - 'verbose_name_plural': 'Organiz\xe1to\u0159i', - }, - bases=(models.Model,), - ), - ] diff --git a/seminar/migrations/0025_zmena_cesty_nahravani_obrazku.py b/seminar/migrations/0025_zmena_cesty_nahravani_obrazku.py deleted file mode 100644 index 23e02c95..00000000 --- a/seminar/migrations/0025_zmena_cesty_nahravani_obrazku.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0024_add_organizator'), - ] - - operations = [ - migrations.AlterField( - model_name='organizator', - name='foto', - field=models.ImageField(help_text=b'Vlo\xc5\xbe fotografii organiz\xc3\xa1tora o libovon\xc3\xa9 velikosti', upload_to=b'image_organizatori/velke/%Y/', null=True, verbose_name=b'Fotografie organiz\xc3\xa1tora', blank=True), - preserve_default=True, - ), - ] diff --git a/seminar/migrations/0026_soustredeni_typ.py b/seminar/migrations/0026_soustredeni_typ.py deleted file mode 100644 index 46d3416f..00000000 --- a/seminar/migrations/0026_soustredeni_typ.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0025_zmena_cesty_nahravani_obrazku'), - ] - - operations = [ - migrations.AddField( - model_name='soustredeni', - name='typ', - field=models.CharField(default=b'podzimni', max_length=16, verbose_name='typ akce', choices=[(b'jarni', 'Jarn\xed soust\u0159ed\u011bn\xed'), (b'podzimni', 'Podzimn\xed soust\u0159ed\u011bn\xed'), (b'sraz', 'Nepravideln\xfd sraz')]), - preserve_default=True, - ), - ] diff --git a/seminar/migrations/0027_export_flag_a_typ_akce.py b/seminar/migrations/0027_export_flag_a_typ_akce.py deleted file mode 100644 index e7172dcc..00000000 --- a/seminar/migrations/0027_export_flag_a_typ_akce.py +++ /dev/null @@ -1,32 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0026_soustredeni_typ'), - ] - - operations = [ - migrations.AddField( - model_name='rocnik', - name='exportovat', - field=models.BooleanField(default=False, help_text='Exportuje se jen podle tohoto flagu (ne ve\u0159ejnosti), a to jen \u010d\xedsla s ve\u0159ejnou v\xfdsledkovkou', verbose_name='export do AESOPa', db_column='exportovat'), - preserve_default=True, - ), - migrations.AddField( - model_name='soustredeni', - name='exportovat', - field=models.BooleanField(default=False, help_text='Exportuje se jen podle tohoto flagu (ne ve\u0159ejnosti)', verbose_name='export do AESOPa', db_column='exportovat'), - preserve_default=True, - ), - migrations.AlterField( - model_name='soustredeni', - name='typ', - field=models.CharField(default=b'podzimni', max_length=16, verbose_name='typ akce', choices=[(b'jarni', 'Jarn\xed soust\u0159ed\u011bn\xed'), (b'podzimni', 'Podzimn\xed soust\u0159ed\u011bn\xed'), (b'vikend', 'V\xedkendov\xfd sraz')]), - preserve_default=True, - ), - ] diff --git a/seminar/migrations/0028_add_body_celkem_views.py b/seminar/migrations/0028_add_body_celkem_views.py deleted file mode 100644 index 0f6799f0..00000000 --- a/seminar/migrations/0028_add_body_celkem_views.py +++ /dev/null @@ -1,75 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations -import django_countries.fields -import seminar.models -import django.utils.timezone -from django.conf import settings - -CREATE_VIEWS=""" -drop view seminar_body_k_cislu; -drop view seminar_body_za_cislo; - -create view seminar_body_za_cislo as - select - seminar_reseni.cislo_body_id || '-' || seminar_reseni.resitel_id as id, - seminar_reseni.cislo_body_id as cislo_id, - seminar_reseni.resitel_id as resitel_id, - seminar_cisla.cislo as cislo, - seminar_cisla.rocnik_id as rocnik_id, - seminar_rocniky.rocnik as rocnik, - seminar_cisla.verejna_vysledkovka as verejna_vysledkovka, - sum(seminar_reseni.body) as body - from - seminar_reseni - inner join seminar_cisla on seminar_reseni.cislo_body_id = seminar_cisla.id - inner join seminar_rocniky on seminar_cisla.rocnik_id = seminar_rocniky.id - group by seminar_reseni.cislo_body_id, seminar_reseni.resitel_id, seminar_cisla.cislo, - seminar_cisla.rocnik_id, seminar_rocniky.rocnik, seminar_cisla.verejna_vysledkovka - order by body desc; - -create view seminar_body_k_cislu_rocnik as - select - akt_body.id as id, - akt_body.cislo_id as cislo_id, - akt_body.resitel_id as resitel_id, - akt_body.body as body, - sum(min_body.body) as body_celkem - from - seminar_body_za_cislo as akt_body - inner join seminar_body_za_cislo as min_body on - (akt_body.resitel_id = min_body.resitel_id and - (akt_body.rocnik = min_body.rocnik and akt_body.cislo >= min_body.cislo) - ) - group by akt_body.id, akt_body.cislo_id, akt_body.resitel_id, akt_body.body - order by body_celkem desc; - -create view seminar_body_k_cislu_odjakziva as - select - akt_body.id as id, - akt_body.cislo_id as cislo_id, - akt_body.resitel_id as resitel_id, - akt_body.body as body, - sum(min_body.body) as body_celkem - from - seminar_body_za_cislo as akt_body - inner join seminar_body_za_cislo as min_body on - (akt_body.resitel_id = min_body.resitel_id and - ((akt_body.rocnik = min_body.rocnik and akt_body.cislo >= min_body.cislo) or - (akt_body.rocnik < min_body.rocnik) - ) - ) - group by akt_body.id, akt_body.cislo_id, akt_body.resitel_id, akt_body.body - order by body_celkem desc; - -""" - -class Migration(migrations.Migration): - - dependencies = [("seminar", "0027_export_flag_a_typ_akce")] - - operations = [ - migrations.RunSQL(sql=CREATE_VIEWS) - ] - diff --git a/seminar/migrations/0029_fix_body_celkem_views.py b/seminar/migrations/0029_fix_body_celkem_views.py deleted file mode 100644 index 5e287747..00000000 --- a/seminar/migrations/0029_fix_body_celkem_views.py +++ /dev/null @@ -1,51 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations -import django_countries.fields -import seminar.models -import django.utils.timezone -from django.conf import settings - -CREATE_VIEWS=""" - -drop view seminar_body_k_cislu_rocnik; -create view seminar_body_k_cislu_rocnik as - select - seminar_cisla.id || '-' || min_body.resitel_id as id, - seminar_cisla.id as cislo_id, - min_body.resitel_id as resitel_id, - sum(min_body.body) as body - from - seminar_cisla - inner join seminar_body_za_cislo as min_body on - (min_body.rocnik_id = seminar_cisla.rocnik_id and seminar_cisla.cislo >= min_body.cislo) - group by seminar_cisla.id, min_body.resitel_id - order by body desc; - -drop view seminar_body_k_cislu_odjakziva; -create view seminar_body_k_cislu_odjakziva as - select - seminar_cisla.id || '-' || min_body.resitel_id as id, - seminar_cisla.id as cislo_id, - min_body.resitel_id as resitel_id, - sum(min_body.body) as body - from - seminar_cisla - inner join seminar_rocniky on - (seminar_cisla.rocnik_id = seminar_rocniky.id) - inner join seminar_body_za_cislo as min_body on - (min_body.rocnik_id = seminar_cisla.rocnik_id and seminar_cisla.cislo >= min_body.cislo) or - (min_body.rocnik < seminar_rocniky.rocnik) - group by seminar_cisla.id, min_body.resitel_id - order by body desc; -""" - -class Migration(migrations.Migration): - - dependencies = [("seminar", "0028_add_body_celkem_views")] - - operations = [ - migrations.RunSQL(sql=CREATE_VIEWS) - ] - diff --git a/seminar/migrations/0030_add_vysledky.py b/seminar/migrations/0030_add_vysledky.py deleted file mode 100644 index 06842c6b..00000000 --- a/seminar/migrations/0030_add_vysledky.py +++ /dev/null @@ -1,60 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0029_fix_body_celkem_views'), - ] - - operations = [ - migrations.CreateModel( - name='VysledkyCelkemKCislu', - fields=[ - ('dummy_id', models.CharField(max_length=32, serialize=False, verbose_name='dummy ID pro view', primary_key=True, db_column=b'id')), - ('body', models.DecimalField(decimal_places=1, verbose_name='body za \u010d\xedslo', max_digits=8, db_column=b'body')), - ('body_celkem', models.DecimalField(decimal_places=1, verbose_name='body celkem do \u010d\xedsla v\u010detn\u011b minul\xfdch ro\u010dn\xedk\u016f', max_digits=8, db_column=b'body_celkem')), - ], - options={ - 'abstract': False, - 'db_table': 'seminar_body_celkem_k_cislu', - 'managed': False, - }, - bases=(models.Model,), - ), - migrations.CreateModel( - name='VysledkyKCisluOdjakziva', - fields=[ - ('dummy_id', models.CharField(max_length=32, serialize=False, verbose_name='dummy ID pro view', primary_key=True, db_column=b'id')), - ('body', models.DecimalField(decimal_places=1, verbose_name='body za \u010d\xedslo', max_digits=8, db_column=b'body')), - ], - options={ - 'abstract': False, - 'db_table': 'seminar_body_k_cislu_odjakziva', - 'managed': False, - }, - bases=(models.Model,), - ), - migrations.CreateModel( - name='VysledkyKCisluZaRocnik', - fields=[ - ('dummy_id', models.CharField(max_length=32, serialize=False, verbose_name='dummy ID pro view', primary_key=True, db_column=b'id')), - ('body', models.DecimalField(decimal_places=1, verbose_name='body za \u010d\xedslo', max_digits=8, db_column=b'body')), - ], - options={ - 'abstract': False, - 'db_table': 'seminar_body_k_cislu_rocnik', - 'managed': False, - }, - bases=(models.Model,), - ), - migrations.AlterField( - model_name='organizator', - name='foto', - field=models.ImageField(help_text=b'Vlo\xc5\xbe fotografii organiz\xc3\xa1tora o libovoln\xc3\xa9 velikosti', upload_to=b'image_organizatori/velke/%Y/', null=True, verbose_name=b'Fotografie organiz\xc3\xa1tora', blank=True), - preserve_default=True, - ), - ] diff --git a/seminar/migrations/0031_cislo_pdf.py b/seminar/migrations/0031_cislo_pdf.py deleted file mode 100644 index c51570bf..00000000 --- a/seminar/migrations/0031_cislo_pdf.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations -import seminar.models - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0030_add_vysledky'), - ] - - operations = [ - migrations.AddField( - model_name='cislo', - name='pdf', - field=models.FileField(help_text='Pdf \u010d\xedsla, kter\xe9 si mohou \u0159e\u0161itel\xe9 st\xe1hnout', upload_to=seminar.models.cislo_pdf_filename, null=True, verbose_name='pdf'), - preserve_default=True, - ), - ] diff --git a/seminar/migrations/0032_cislo_pdf_blank_typos.py b/seminar/migrations/0032_cislo_pdf_blank_typos.py deleted file mode 100644 index b16c4501..00000000 --- a/seminar/migrations/0032_cislo_pdf_blank_typos.py +++ /dev/null @@ -1,44 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations -import django_countries.fields -import seminar.models - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0031_cislo_pdf'), - ] - - operations = [ - migrations.AlterModelOptions( - name='soustredeni', - options={'ordering': ['-rocnik__rocnik', '-datum_zacatku'], 'verbose_name': 'Soust\u0159ed\u011bn\xed', 'verbose_name_plural': 'Soust\u0159ed\u011bn\xed'}, - ), - migrations.AlterField( - model_name='cislo', - name='cislo', - field=models.CharField(help_text='V\u011bt\u0161inou jen "1", vyj\xedme\u010dn\u011b "7-8", lexikograficky ur\u010duje po\u0159ad\xed v ro\u010dn\xedku!', max_length=32, verbose_name='n\xe1zev \u010d\xedsla', db_index=True), - preserve_default=True, - ), - migrations.AlterField( - model_name='cislo', - name='pdf', - field=models.FileField(help_text='Pdf \u010d\xedsla, kter\xe9 si mohou \u0159e\u0161itel\xe9 st\xe1hnout', upload_to=seminar.models.cislo_pdf_filename, null=True, verbose_name='pdf', blank=True), - preserve_default=True, - ), - migrations.AlterField( - model_name='problem', - name='typ', - field=models.CharField(default=b'uloha', max_length=32, verbose_name='typ probl\xe9mu', choices=[(b'uloha', '\xdaloha'), (b'tema', 'T\xe9ma'), (b'serial', 'Seri\xe1l'), (b'org-clanek', 'Organiz\xe1torsk\xfd \u010dl\xe1nek'), (b'res-clanek', '\u0158e\u0161itelsk\xfd \u010dl\xe1nek')]), - preserve_default=True, - ), - migrations.AlterField( - model_name='skola', - name='stat', - field=django_countries.fields.CountryField(default=b'CZ', help_text='ISO 3166-1 k\xf3d zem\u011b velk\xfdmi p\xedsmeny (CZ, SK, ...)', max_length=2, verbose_name='st\xe1t'), - preserve_default=True, - ), - ] diff --git a/seminar/migrations/0033_organizator_studuje_popisek.py b/seminar/migrations/0033_organizator_studuje_popisek.py deleted file mode 100644 index 07f15712..00000000 --- a/seminar/migrations/0033_organizator_studuje_popisek.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0032_cislo_pdf_blank_typos'), - ] - - operations = [ - migrations.AlterField( - model_name='organizator', - name='studuje', - field=models.CharField(help_text=b"Nap\xc5\x99. 'Studuje Obecnou fyziku (Bc.), 3. ro\xc4\x8dn\xc3\xadk', 'Vystudovala Diskr\xc3\xa9tn\xc3\xad modely a algoritmy (Mgr.)' nebo 'P\xc5\x99edn\xc3\xa1\xc5\xa1\xc3\xad na MFF'", max_length=256, null=True, verbose_name=b'Studium aj.', blank=True), - preserve_default=True, - ), - ] diff --git a/seminar/migrations/0034_reseni_forma_default_email.py b/seminar/migrations/0034_reseni_forma_default_email.py deleted file mode 100644 index 2d691b30..00000000 --- a/seminar/migrations/0034_reseni_forma_default_email.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0033_organizator_studuje_popisek'), - ] - - operations = [ - migrations.AlterField( - model_name='reseni', - name='forma', - field=models.CharField(default=b'email', max_length=16, verbose_name='forma \u0159e\u0161en\xed', choices=[(b'papir', 'Pap\xedrov\xe9 \u0159e\u0161en\xed'), (b'email', 'Emailem'), (b'upload', 'Upload p\u0159es web')]), - preserve_default=True, - ), - ] diff --git a/seminar/migrations/0035_django_imagekit.py b/seminar/migrations/0035_django_imagekit.py deleted file mode 100644 index dd443018..00000000 --- a/seminar/migrations/0035_django_imagekit.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations -import imagekit.models.fields - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0034_reseni_forma_default_email'), - ] - - operations = [ - migrations.RemoveField( - model_name='organizator', - name='foto_male', - ), - migrations.AlterField( - model_name='organizator', - name='foto', - field=imagekit.models.fields.ProcessedImageField(help_text=b'Vlo\xc5\xbe fotografii organiz\xc3\xa1tora o libovoln\xc3\xa9 velikosti', upload_to=b'image_organizatori/velke/%Y/', null=True, verbose_name=b'Fotografie organiz\xc3\xa1tora', blank=True), - preserve_default=True, - ), - ] diff --git a/seminar/migrations/0036_add_org_to_soustredeni.py b/seminar/migrations/0036_add_org_to_soustredeni.py deleted file mode 100644 index 4db43239..00000000 --- a/seminar/migrations/0036_add_org_to_soustredeni.py +++ /dev/null @@ -1,36 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0035_django_imagekit'), - ] - - operations = [ - migrations.CreateModel( - name='Soustredeni_Organizatori', - fields=[ - ('id', models.AutoField(serialize=False, primary_key=True)), - ('poznamka', models.TextField(help_text='Neve\u0159ejn\xe1 pozn\xe1mka k \xfa\u010dasti organiz\xe1tora (plain text)', verbose_name='neve\u0159ejn\xe1 pozn\xe1mka', blank=True)), - ('organizator', models.ForeignKey(verbose_name='organiz\xe1tor', to='seminar.Organizator', on_delete=models.CASCADE)), - ('soustredeni', models.ForeignKey(verbose_name='soust\u0159ed\u011bn\xed', to='seminar.Soustredeni', on_delete=models.CASCADE)), - ], - options={ - 'ordering': ['soustredeni', 'organizator'], - 'db_table': 'seminar_soustredeni_organizatori', - 'verbose_name': '\xda\u010dast organiz\xe1tor\u016f na soust\u0159ed\u011bn\xed', - 'verbose_name_plural': '\xda\u010dasti organiz\xe1tor\u016f na soust\u0159ed\u011bn\xed', - }, - bases=(models.Model,), - ), - migrations.AddField( - model_name='soustredeni', - name='organizatori', - field=models.ManyToManyField(help_text='Seznam organiz\xe1tor\u016f soust\u0159ed\u011bn\xed', to='seminar.Organizator', verbose_name='Organiz\xe1to\u0159i soust\u0159ed\u011bn\xed', through='seminar.Soustredeni_Organizatori'), - preserve_default=True, - ), - ] diff --git a/seminar/migrations/0037_prispevek.py b/seminar/migrations/0037_prispevek.py deleted file mode 100644 index c4c3b867..00000000 --- a/seminar/migrations/0037_prispevek.py +++ /dev/null @@ -1,29 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0036_add_org_to_soustredeni'), - ] - - operations = [ - migrations.CreateModel( - name='Prispevek', - fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('nazev', models.CharField(max_length=200, verbose_name=b'N\xc3\xa1zev')), - ('text_org', models.TextField(null=True, verbose_name=b'Orgovsk\xc3\xbd text', blank=True)), - ('text_resitel', models.TextField(null=True, verbose_name=b'\xc5\x98e\xc5\xa1itelsk\xc3\xbd text', blank=True)), - ('zverejnit', models.BooleanField(verbose_name=b'Zve\xc5\x99ejnit?')), - ('problem', models.ForeignKey(verbose_name=b'Probl\xc3\xa9m', to='seminar.Problem', on_delete=models.CASCADE)), - ('reseni', models.OneToOneField(null=True, blank=True, to='seminar.Reseni', verbose_name=b'\xc5\x98e\xc5\xa1en\xc3\xad', on_delete=models.CASCADE)), - ], - options={ - 'abstract': False, - }, - ), - ] diff --git a/seminar/migrations/0038_change_meta_prispevek.py b/seminar/migrations/0038_change_meta_prispevek.py deleted file mode 100644 index 5378e57e..00000000 --- a/seminar/migrations/0038_change_meta_prispevek.py +++ /dev/null @@ -1,18 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0037_prispevek'), - ] - - operations = [ - migrations.AlterModelOptions( - name='prispevek', - options={'verbose_name': 'P\u0159\xedsp\u011bvek k probl\xe9mu', 'verbose_name_plural': 'P\u0159\xedsp\u011bvky k probl\xe9m\u016fm'}, - ), - ] diff --git a/seminar/migrations/0039_pohadka.py b/seminar/migrations/0039_pohadka.py deleted file mode 100644 index f798bd75..00000000 --- a/seminar/migrations/0039_pohadka.py +++ /dev/null @@ -1,34 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import migrations, models -import django.utils.timezone -from django.conf import settings - - -class Migration(migrations.Migration): - - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('seminar', '0038_change_meta_prispevek'), - ] - - operations = [ - migrations.CreateModel( - name='Pohadka', - fields=[ - ('id', models.AutoField(serialize=False, primary_key=True)), - ('text', models.TextField(verbose_name='Text poh\xe1dky')), - ('pred', models.BooleanField(default=True, verbose_name='P\u0159ed \xfalohou')), - ('timestamp', models.DateTimeField(default=django.utils.timezone.now, verbose_name='Vytvo\u0159eno', editable=False, blank=True)), - ('autor', models.ForeignKey(verbose_name=b'Autor poh\xc3\xa1dky', to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), - ('uloha', models.ForeignKey(related_name='pohadky', verbose_name='\xdaloha', to='seminar.Problem',on_delete=models.CASCADE)), - ], - options={ - 'ordering': ['uloha__cislo_zadani', 'uloha__kod', '-pred'], - 'db_table': 'seminar_pohadky', - 'verbose_name': 'Poh\xe1dka', - 'verbose_name_plural': 'Poh\xe1dky', - }, - ), - ] diff --git a/seminar/migrations/0040_pohadka_nepovinny_autor.py b/seminar/migrations/0040_pohadka_nepovinny_autor.py deleted file mode 100644 index babf9b24..00000000 --- a/seminar/migrations/0040_pohadka_nepovinny_autor.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import migrations, models -from django.conf import settings - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0039_pohadka'), - ] - - operations = [ - migrations.AlterField( - model_name='pohadka', - name='autor', - field=models.ForeignKey(verbose_name=b'Autor poh\xc3\xa1dky', to=settings.AUTH_USER_MODEL, null=True, on_delete=models.CASCADE), - ), - ] diff --git a/seminar/migrations/0041_konfery.py b/seminar/migrations/0041_konfery.py deleted file mode 100644 index 9fddbe17..00000000 --- a/seminar/migrations/0041_konfery.py +++ /dev/null @@ -1,71 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import migrations, models -import django.db.models.deletion -import seminar.models - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0040_pohadka_nepovinny_autor'), - ] - - operations = [ - migrations.CreateModel( - name='Konfera', - fields=[ - ('id', models.AutoField(serialize=False, primary_key=True)), - ('nazev', models.CharField(help_text='N\xe1zev konfery', max_length=40, verbose_name='n\xe1zev konfery')), - ('popis', models.TextField(help_text='Popis konfery k zobrazen\xed na webu', verbose_name='popis konfery', blank=True)), - ('abstrakt', models.TextField(help_text='Abstrakt konfery tak, jak byl uveden ve sborn\xedku', verbose_name='abstrakt', blank=True)), - ('org_poznamka', models.TextField(help_text='Neve\u0159ejn\xe1 pozn\xe1mka ke konfe\u0159e(plain text)', verbose_name='neve\u0159ejn\xe1 pozn\xe1mka', blank=True)), - ('typ_prezentace', models.CharField(default=b'veletrh', max_length=16, verbose_name='typ prezentace', choices=[(b'veletrh', 'Veletrh (postery)'), (b'prezentace', 'Prezentace (p\u0159edn\xe1\u0161ka)')])), - ('prezentace', models.FileField(help_text='Prezentace nebo fotka posteru', upload_to=seminar.models.generate_filename_konfera, verbose_name='prezentace')), - ('materialy', models.FileField(help_text='Dal\u0161\xed materi\xe1ly ke konfe\u0159e zabalen\xe9 do jednoho souboru', upload_to=seminar.models.generate_filename_konfera, verbose_name='materialy')), - ('organizator', models.ForeignKey(related_name='konfery', on_delete=django.db.models.deletion.SET_NULL, verbose_name='organiz\xe1tor', to='seminar.Organizator', null=True)), - ], - options={ - 'db_table': 'seminar_konfera', - 'verbose_name': 'Konfera', - 'verbose_name_plural': 'Konfery', - }, - ), - migrations.CreateModel( - name='Konfery_Ucastnici', - fields=[ - ('id', models.AutoField(serialize=False, primary_key=True)), - ('poznamka', models.TextField(help_text='Neve\u0159ejn\xe1 pozn\xe1mka k \xfa\u010dasti (plain text)', verbose_name='neve\u0159ejn\xe1 pozn\xe1mka', blank=True)), - ('konfera', models.ForeignKey(verbose_name='konfera', to='seminar.Konfera', - on_delete=models.PROTECT)), - ('resitel', models.ForeignKey(verbose_name='\u0159e\u0161itel', to='seminar.Resitel',on_delete=models.CASCADE)), - ], - options={ - 'ordering': ['konfera', 'resitel'], - 'db_table': 'seminar_konfery_ucastnici', - 'verbose_name': '\xda\u010dast na konfe\u0159e', - 'verbose_name_plural': '\xda\u010dasti na konfe\u0159e', - }, - ), - migrations.AlterField( - model_name='problem', - name='typ', - field=models.CharField(default=b'uloha', max_length=32, verbose_name='typ probl\xe9mu', choices=[(b'uloha', '\xdaloha'), (b'tema', 'T\xe9ma'), (b'serial', 'Seri\xe1l'), (b'konfera', 'Konfera'), (b'org-clanek', 'Organiz\xe1torsk\xfd \u010dl\xe1nek'), (b'res-clanek', '\u0158e\u0161itelsk\xfd \u010dl\xe1nek')]), - ), - migrations.AddField( - model_name='konfera', - name='prispevek', - field=models.ForeignKey(related_name='konfery', on_delete=django.db.models.deletion.SET_NULL, verbose_name='p\u0159\xedsp\u011bvek do \u010d\xedsla', to='seminar.Problem', help_text='\xda\u010dastnick\xfd p\u0159\xedp\u011bvek o konfe\u0159e', null=True), - ), - migrations.AddField( - model_name='konfera', - name='soustredeni', - field=models.ForeignKey(related_name='konfery', on_delete=django.db.models.deletion.SET_NULL, verbose_name='soust\u0159ed\u011bn\xed', to='seminar.Soustredeni', null=True), - ), - migrations.AddField( - model_name='konfera', - name='ucastnici', - field=models.ManyToManyField(help_text='Seznam \xfa\u010dastn\xedk\u016f konfery', to='seminar.Resitel', verbose_name='\xfa\u010dastn\xedci konfery', through='seminar.Konfery_Ucastnici'), - ), - ] diff --git a/seminar/migrations/0042_auto_20161005_0847.py b/seminar/migrations/0042_auto_20161005_0847.py deleted file mode 100644 index 27930952..00000000 --- a/seminar/migrations/0042_auto_20161005_0847.py +++ /dev/null @@ -1,31 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import migrations, models -import django.db.models.deletion -import seminar.models - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0041_konfery'), - ] - - operations = [ - migrations.AlterField( - model_name='konfera', - name='materialy', - field=models.FileField(help_text='Dal\u0161\xed materi\xe1ly ke konfe\u0159e zabalen\xe9 do jednoho souboru', upload_to=seminar.models.generate_filename_konfera, verbose_name='materialy', blank=True), - ), - migrations.AlterField( - model_name='konfera', - name='prezentace', - field=models.FileField(help_text='Prezentace nebo fotka posteru', upload_to=seminar.models.generate_filename_konfera, verbose_name='prezentace', blank=True), - ), - migrations.AlterField( - model_name='konfera', - name='prispevek', - field=models.ForeignKey(related_name='konfery', on_delete=django.db.models.deletion.SET_NULL, blank=True, to='seminar.Problem', help_text='\xda\u010dastnick\xfd p\u0159\xedp\u011bvek o konfe\u0159e', null=True, verbose_name='p\u0159\xedsp\u011bvek do \u010d\xedsla'), - ), - ] diff --git a/seminar/migrations/0042_cislo_faze.py b/seminar/migrations/0042_cislo_faze.py deleted file mode 100644 index 7d35ace5..00000000 --- a/seminar/migrations/0042_cislo_faze.py +++ /dev/null @@ -1,19 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0041_konfery'), - ] - - operations = [ - migrations.AddField( - model_name='cislo', - name='faze', - field=models.CharField(default='admin', help_text='B\u011bhem f\xe1ze "admin" se obsah \u010d\xedsla vytv\xe1\u0159\xed (a p\u0159\xedpadn\u011b komentuje) ve webov\xe9m rozhran\xed. B\u011bhem f\xe1ze "tex" u\u017e obsah ve webov\xe9m rozhran\xed editovat nelze. N\xe1vrhy na \xfapravy se pak p\xed\u0161\xed do korekturov\xe1tka a zan\xe1\u0161ej\xed do gitu. Z n\u011bj se pak generuje verze pro web.', max_length=32, verbose_name='F\xe1ze vytv\xe1\u0159en\xed obsahu'), - ), - ] diff --git a/seminar/migrations/0043_uprava_faze.py b/seminar/migrations/0043_uprava_faze.py deleted file mode 100644 index 29e06e01..00000000 --- a/seminar/migrations/0043_uprava_faze.py +++ /dev/null @@ -1,19 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0042_cislo_faze'), - ] - - operations = [ - migrations.AlterField( - model_name='cislo', - name='faze', - field=models.CharField(default='admin', help_text='B\u011bhem f\xe1ze "admin" se obsah \u010d\xedsla vytv\xe1\u0159\xed (a p\u0159\xedpadn\u011b komentuje) ve webov\xe9m rozhran\xed. B\u011bhem f\xe1ze "tex" u\u017e obsah ve webov\xe9m rozhran\xed editovat nelze. N\xe1vrhy na \xfapravy se pak p\xed\u0161\xed do korekturov\xe1tka a zan\xe1\u0161ej\xed do gitu. Z n\u011bj se pak generuje verze pro web.', max_length=32, verbose_name='F\xe1ze vytv\xe1\u0159en\xed obsahu', choices=[('admin', 'Zad\xe1v\xe1n\xed \xfaloh do webu'), ('tex', '\xdapravy \xfaloh v TeXov\xe9m repozit\xe1\u0159i')]), - ), - ] diff --git a/seminar/migrations/0044_uprava_faze.py b/seminar/migrations/0044_uprava_faze.py deleted file mode 100644 index 0d683d6c..00000000 --- a/seminar/migrations/0044_uprava_faze.py +++ /dev/null @@ -1,19 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0043_uprava_faze'), - ] - - operations = [ - migrations.AlterField( - model_name='cislo', - name='faze', - field=models.CharField(default='admin', help_text='B\u011bhem f\xe1ze "\xdapravy na webu" se obsah \u010d\xedsla vytv\xe1\u0159\xed (a p\u0159\xedpadn\u011b komentuje) ve webov\xe9m rozhran\xed. B\u011bhem f\xe1ze "\xdapravy na webu" u\u017e obsah ve webov\xe9m rozhran\xed editovat nelze a n\xe1vrhy na \xfapravy se p\xed\u0161\xed do korekturov\xe1tka a zan\xe1\u0161ej\xed do gitu. Z n\u011bj se pak generuje verze pro web.', max_length=32, verbose_name='F\xe1ze vytv\xe1\u0159en\xed obsahu', choices=[('admin', '\xdapravy na webu'), ('tex', '\xdapravy v TeXu')]), - ), - ] diff --git a/seminar/migrations/0045_cislo_pridani_faze_nahrano.py b/seminar/migrations/0045_cislo_pridani_faze_nahrano.py deleted file mode 100644 index 06ca8201..00000000 --- a/seminar/migrations/0045_cislo_pridani_faze_nahrano.py +++ /dev/null @@ -1,19 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0044_uprava_faze'), - ] - - operations = [ - migrations.AlterField( - model_name='cislo', - name='faze', - field=models.CharField(default='admin', help_text='B\u011bhem f\xe1ze "\xdapravy na webu" se obsah \u010d\xedsla vytv\xe1\u0159\xed (a p\u0159\xedpadn\u011b komentuje) ve webov\xe9m rozhran\xed. B\u011bhem f\xe1ze "\xdapravy v TeXu" u\u017e obsah ve webov\xe9m rozhran\xed editovat nelze a n\xe1vrhy na \xfapravy se p\xed\u0161\xed do korekturov\xe1tka a zan\xe1\u0161ej\xed do gitu. Z n\u011bj se pak vygeneruje verze pro web a \u010d\xedslo se p\u0159epne do f\xe1ze "Nahr\xe1no na web", co\u017e jen znamen\xe1, \u017ee u\u017e nejde automaticky st\xe1hnout obsah pro zalo\u017een\xed \u010d\xedsla v TeXu.', max_length=32, verbose_name='F\xe1ze vytv\xe1\u0159en\xed obsahu', choices=[('admin', '\xdapravy na webu'), ('tex', '\xdapravy v TeXu'), ('tex', 'Nahr\xe1no na web')]), - ), - ] diff --git a/seminar/migrations/0046_merge.py b/seminar/migrations/0046_merge.py deleted file mode 100644 index 19352440..00000000 --- a/seminar/migrations/0046_merge.py +++ /dev/null @@ -1,15 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0042_auto_20161005_0847'), - ('seminar', '0045_cislo_pridani_faze_nahrano'), - ] - - operations = [ - ] diff --git a/seminar/migrations/0047_auto_20170120_2118.py b/seminar/migrations/0047_auto_20170120_2118.py deleted file mode 100644 index 1876fe25..00000000 --- a/seminar/migrations/0047_auto_20170120_2118.py +++ /dev/null @@ -1,19 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0046_merge'), - ] - - operations = [ - migrations.AlterField( - model_name='cislo', - name='faze', - field=models.CharField(default='admin', help_text='B\u011bhem f\xe1ze "\xdapravy na webu" se obsah \u010d\xedsla vytv\xe1\u0159\xed (a p\u0159\xedpadn\u011b komentuje) ve webov\xe9m rozhran\xed. B\u011bhem f\xe1ze "\xdapravy v TeXu" u\u017e obsah ve webov\xe9m rozhran\xed editovat nelze a n\xe1vrhy na \xfapravy se p\xed\u0161\xed do korekturov\xe1tka a zan\xe1\u0161ej\xed do gitu. Z n\u011bj se pak vygeneruje verze pro web a \u010d\xedslo se p\u0159epne do f\xe1ze "Nahr\xe1no na web", co\u017e jen znamen\xe1, \u017ee u\u017e nejde automaticky st\xe1hnout obsah pro zalo\u017een\xed \u010d\xedsla v TeXu.', max_length=32, verbose_name='F\xe1ze vytv\xe1\u0159en\xed obsahu', choices=[('admin', '\xdapravy na webu'), ('tex', '\xdapravy v TeXu'), ('nahrano', 'Nahr\xe1no na web')]), - ), - ] diff --git a/seminar/migrations/0048_add_cislo_datum_deadline_soustredeni.py b/seminar/migrations/0048_add_cislo_datum_deadline_soustredeni.py deleted file mode 100644 index 134a00a8..00000000 --- a/seminar/migrations/0048_add_cislo_datum_deadline_soustredeni.py +++ /dev/null @@ -1,19 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0047_auto_20170120_2118'), - ] - - operations = [ - migrations.AddField( - model_name='cislo', - name='datum_deadline_soustredeni', - field=models.DateField(help_text='Datum pro p\u0159\xedjem \u0159e\u0161en\xed pro \xfa\u010dast na soust\u0159ed\u011bn\xed', null=True, verbose_name='datum deadline soust\u0159ed\u011bn\xed', blank=True), - ), - ] diff --git a/seminar/migrations/0049_auto_20190430_2354.py b/seminar/migrations/0049_auto_20190430_2354.py deleted file mode 100644 index de2b1b0d..00000000 --- a/seminar/migrations/0049_auto_20190430_2354.py +++ /dev/null @@ -1,508 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.20 on 2019-04-30 21:54 -from __future__ import unicode_literals - -from django.conf import settings -from django.db import migrations, models -import django.db.models.deletion -import django.utils.timezone -import django_countries.fields -import imagekit.models.fields -import taggit.managers - - -class Migration(migrations.Migration): - atomic = False - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('seminar', '0048_add_cislo_datum_deadline_soustredeni'), - ] - - operations = [ - migrations.CreateModel( - name='Clanek', - fields=[ - ('problem_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.Problem')), - ], - options={ - 'verbose_name': 'Článek', - 'verbose_name_plural': 'Články', - 'db_table': 'seminar_clanky', - }, - bases=('seminar.problem',), - ), - migrations.CreateModel( - name='Hodnoceni', - fields=[ - ('id', models.AutoField(primary_key=True, serialize=False)), - ('body', models.DecimalField(decimal_places=1, max_digits=8, verbose_name='body')), - ], - options={ - 'verbose_name': 'Hodnocení', - 'verbose_name_plural': 'Hodnocení', - 'db_table': 'seminar_hodnoceni', - }, - ), - migrations.CreateModel( - name='Obrazek', - fields=[ - ('id', models.AutoField(primary_key=True, serialize=False)), - ('na_web', models.ImageField(blank=True, null=True, upload_to='obrazky/%Y/%m/%d/', verbose_name='obrázek na web')), - ('do_cisla_barevny', models.FileField(blank=True, help_text='Barevná verze obrázku do čísla', null=True, upload_to='obrazky/%Y/%m/%d/', verbose_name='barevný obrázek do čísla')), - ('do_cisla_cernobily', models.FileField(blank=True, help_text='Černobílá verze obrázku do čísla', null=True, upload_to='obrazky/%Y/%m/%d/', verbose_name='černobílý obrázek do čísla')), - ], - options={ - 'verbose_name': 'obrázek', - 'verbose_name_plural': 'obrázky', - 'db_table': 'seminar_obrazky', - }, - ), - 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(max_length=256, 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')), - ('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.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='uživatel')), - ], - options={ - 'verbose_name': 'Osoba', - 'verbose_name_plural': 'Osoby', - 'db_table': 'seminar_osoby', - 'ordering': ['prijmeni', 'jmeno'], - }, - ), - 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')), - ('osoba', models.ForeignKey(help_text='Které osobě či na jakou adresu se mají zasílat čísla', on_delete=django.db.models.deletion.CASCADE, to='seminar.Osoba', verbose_name='komu')), - ], - options={ - 'verbose_name': 'příjemce', - 'verbose_name_plural': 'příjemce', - 'db_table': 'seminar_prijemce', - }, - ), - migrations.CreateModel( - name='Reseni_Resitele', - fields=[ - ('id', models.AutoField(primary_key=True, serialize=False)), - ], - options={ - 'verbose_name': 'Řešení řešitelů', - 'verbose_name_plural': 'Řešení řešitelů', - 'db_table': 'seminar_reseni_resitele', - 'ordering': ['reseni', 'resitele'], - }, - ), - migrations.CreateModel( - name='Tema', - fields=[ - ('problem_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.Problem')), - ('tema_typ', models.CharField(choices=[('tema', 'Téma'), ('serial', 'Seriál')], default='tema', max_length=16, verbose_name='Typ tématu')), - ], - options={ - 'verbose_name': 'Téma', - 'verbose_name_plural': 'Témata', - 'db_table': 'seminar_temata', - }, - bases=('seminar.problem',), - ), - migrations.CreateModel( - name='Text', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('na_web', models.TextField(blank=True, help_text='Text ke zveřejnění na webu', verbose_name='text na web')), - ('do_cisla', models.TextField(blank=True, help_text='Text ke zveřejnění v čísle', verbose_name='text do čísla')), - ], - options={ - 'verbose_name': 'text', - 'verbose_name_plural': 'texty', - 'db_table': 'seminar_texty', - }, - ), - migrations.CreateModel( - name='Uloha', - fields=[ - ('problem_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.Problem')), - ('max_body', models.DecimalField(blank=True, decimal_places=1, max_digits=8, null=True, verbose_name='maximum bodů')), - ], - options={ - 'verbose_name': 'Úloha', - 'verbose_name_plural': 'Úlohy', - 'db_table': 'seminar_ulohy', - }, - bases=('seminar.problem',), - ), - migrations.AlterModelOptions( - name='novinky', - options={'ordering': ['-datum'], 'verbose_name': 'Novinka', 'verbose_name_plural': 'Novinky'}, - ), - migrations.AlterModelOptions( - name='prilohareseni', - options={'ordering': ['reseni', 'vytvoreno'], 'verbose_name': 'Příloha řešení', 'verbose_name_plural': 'Přílohy řešení'}, - ), - migrations.AlterModelOptions( - name='reseni', - options={'ordering': ['-cas_doruceni'], 'verbose_name': 'Řešení', 'verbose_name_plural': 'Řešení'}, - ), - migrations.AlterModelOptions( - name='resitel', - options={'ordering': ['osoba'], 'verbose_name': 'Řešitel', 'verbose_name_plural': 'Řešitelé'}, - ), - migrations.RenameField( - model_name='konfera', - old_name='org_poznamka', - new_name='poznamka', - ), - migrations.RenameField( - model_name='pohadka', - old_name='timestamp', - new_name='vytvoreno', - ), - migrations.RenameField( - model_name='reseni', - old_name='timestamp', - new_name='cas_doruceni', - ), - migrations.RenameField( - model_name='prilohareseni', - old_name='timestamp', - new_name='vytvoreno', - ), - migrations.RenameField( - model_name='problem', - old_name='text_org', - new_name='poznamka', - ), - migrations.RenameField( - model_name='problem', - old_name='timestamp', - new_name='vytvoreno', - ), - migrations.RenameField( - model_name='problem', - old_name='cislo_zadani', - new_name='cislo_zadani_old', - ), - migrations.RenameField( - model_name='problem', - old_name='cislo_reseni', - new_name='cislo_reseni_old', - ), - migrations.AddField( - model_name='konfera', - name='anotace', - field=models.TextField(blank=True, help_text='Popis, o čem bude konfera.', verbose_name='anotace'), - ), - migrations.AddField( - model_name='konfera', - name='reseni', - field=models.ForeignKey(blank=True, help_text='Účastnický přípěvek o konfeře', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='konfery', to='seminar.Reseni', verbose_name='článek ke konfeře'), - ), - migrations.AddField( - model_name='organizator', - name='organizuje_do', - field=models.DateTimeField(blank=True, null=True, verbose_name='Organizuje do'), - ), - migrations.AddField( - model_name='organizator', - name='organizuje_od', - field=models.DateTimeField(null=True,blank=True, verbose_name='Organizuje od'), - ), - migrations.AddField( - model_name='organizator', - name='skola', - field=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'), - ), - migrations.AddField( - model_name='organizator', - name='vytvoreno', - field=models.DateTimeField(blank=True, default=django.utils.timezone.now, editable=False, verbose_name='Vytvořeno'), - ), - migrations.AddField( - model_name='problem', - name='garant', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='garant_problemu_problem', to='seminar.Organizator', verbose_name='garant zadaného problému'), - ), - migrations.AddField( - model_name='problem', - name='nadproblem', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='nadproblem_problem', to='seminar.Problem', verbose_name='nadřazený problém'), - ), - migrations.AddField( - model_name='problem', - name='opravovatele', - field=models.ManyToManyField(blank=True, related_name='opravovatele_problem', to='seminar.Organizator', verbose_name='opravovatelé'), - ), - migrations.AddField( - model_name='reseni', - name='zverejneno', - field=models.BooleanField(default=False, help_text='Udává, zda je řešení zveřejněno', verbose_name='řešení zveřejněno'), - ), - migrations.AlterField( - model_name='cislo', - name='verejna_vysledkovka', - field=models.BooleanField(default=False, help_text='Je-li false u veřejného čísla,\t\t\t\t není výsledkovka zatím veřejná.', verbose_name='zveřejněna výsledkovka'), - ), - migrations.AlterField( - model_name='cislo', - name='verejne_db', - field=models.BooleanField(db_column='verejne', default=False, verbose_name='číslo zveřejněno'), - ), - migrations.AlterField( - model_name='konfera', - name='typ_prezentace', - field=models.CharField(choices=[('veletrh', 'Veletrh (postery)'), ('prezentace', 'Prezentace (přednáška)')], default='veletrh', max_length=16, verbose_name='typ prezentace'), - ), - migrations.RenameField( - model_name='novinky', - old_name='autor', - new_name='autor_old' - ), - migrations.AddField( - model_name='novinky', - name='autor', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Organizator', verbose_name='Autor novinky', null=True), - ), - migrations.AlterField( - model_name='novinky', - name='obrazek', - field=models.ImageField(blank=True, null=True, upload_to='image_novinky/%Y/%m/%d/', verbose_name='Obrázek'), - ), - migrations.AlterField( - model_name='novinky', - name='text', - field=models.TextField(blank=True, null=True, verbose_name='Text novinky'), - ), - migrations.AlterField( - model_name='novinky', - name='zverejneno', - field=models.BooleanField(default=False, verbose_name='Zveřejněno'), - ), - migrations.AlterField( - model_name='organizator', - name='strucny_popis_organizatora', - field=models.TextField(blank=True, null=True, verbose_name='Stručný popis organizátora'), - ), - migrations.AlterField( - model_name='organizator', - name='studuje', - field=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.'), - ), - migrations.RenameField( - model_name='pohadka', - old_name='autor', - new_name='autor_old' - ), - migrations.AddField( - model_name='pohadka', - name='autor', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='seminar.Organizator', verbose_name='Autor pohádky'), - ), - migrations.RenameField( - model_name='pohadka', - old_name='uloha', - new_name='uloha_old' - ), - migrations.AddField( - model_name='pohadka', - name='uloha', - field=models.ForeignKey(null=True,on_delete=django.db.models.deletion.CASCADE, related_name='pohadky', to='seminar.Uloha', verbose_name='Úloha'), - ), - migrations.RenameField( - model_name='problem', - old_name='autor', - new_name='autor_old', - ), - migrations.AddField( - model_name='problem', - name='autor', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='autor_problemu_problem', to='seminar.Organizator', verbose_name='autor problému'), - ), - migrations.AlterField( - model_name='problem', - name='kod', - field=models.CharField(blank=True, default='', help_text='Číslo/kód úlohy v čísle nebo kód tématu/článku/seriálu v ročníku', max_length=32, verbose_name='lokální kód'), - ), - migrations.AlterField( - model_name='problem', - name='stav', - field=models.CharField(choices=[('navrh', 'Návrh'), ('zadany', 'Zadaný'), ('vyreseny', 'Vyřešený'), ('smazany', 'Smazaný')], default='navrh', max_length=32, verbose_name='stav problému'), - ), - migrations.AlterField( - model_name='problem', - name='zamereni', - field=taggit.managers.TaggableManager(blank=True, help_text='Zaměření M/F/I/O problému, příp. další tagy', through='taggit.TaggedItem', to='taggit.Tag', verbose_name='zaměření'), - ), - migrations.AlterField( - model_name='reseni', - name='forma', - field=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í'), - ), - migrations.RenameField( - model_name='reseni', - old_name='problem', - new_name='problem_old', - ), - migrations.AlterField( - model_name='resitel', - name='zasilat', - field=models.CharField(choices=[('domu', 'Domů'), ('do_skoly', 'Do školy'), ('nikam', 'Nikam')], default='domu', max_length=32, verbose_name='kam zasílat'), - ), - migrations.AlterField( - model_name='rocnik', - name='exportovat', - field=models.BooleanField(db_column='exportovat', default=False, help_text='Exportuje se jen podle tohoto flagu (ne veřejnosti), a to jen čísla s veřejnou výsledkovkou', verbose_name='export do AESOPa'), - ), - migrations.AlterField( - model_name='skola', - name='aesop_id', - field=models.CharField(blank=True, default='', help_text='Aesopi ID typu "izo:..." nebo "aesop:..."', max_length=32, verbose_name='Aesop ID'), - ), - migrations.AlterField( - model_name='skola', - name='kratky_nazev', - field=models.CharField(blank=True, help_text='Zkrácený název pro zobrazení ve výsledkovce', max_length=256, verbose_name='zkrácený název'), - ), - migrations.AlterField( - model_name='skola', - name='stat', - field=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'), - ), - migrations.AlterField( - model_name='soustredeni', - name='exportovat', - field=models.BooleanField(db_column='exportovat', default=False, help_text='Exportuje se jen podle tohoto flagu (ne veřejnosti)', verbose_name='export do AESOPa'), - ), - migrations.AlterField( - model_name='soustredeni', - name='misto', - field=models.CharField(blank=True, default='', help_text='Místo (název obce, volitelně též objektu', max_length=256, verbose_name='místo soustředění'), - ), - migrations.AlterField( - model_name='soustredeni', - name='text', - field=models.TextField(blank=True, default='', verbose_name='text k soustředění (HTML)'), - ), - migrations.AlterField( - model_name='soustredeni', - name='typ', - field=models.CharField(choices=[('jarni', 'Jarní soustředění'), ('podzimni', 'Podzimní soustředění'), ('vikend', 'Víkendový sraz')], default='podzimni', max_length=16, verbose_name='typ akce'), - ), - migrations.AlterField( - model_name='soustredeni', - name='verejne_db', - field=models.BooleanField(db_column='verejne', default=False, verbose_name='soustředění zveřejněno'), - ), - migrations.AlterModelTable( - name='problem', - table='seminar_problemy', - ), - migrations.AddField( - model_name='uloha', - name='cislo_deadline', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='deadlinove_ulohy', to='seminar.Cislo', verbose_name='číslo deadlinu'), - ), - migrations.AddField( - model_name='uloha', - name='cislo_reseni', - field=models.ForeignKey(blank=True, help_text='Číslo s řešením úlohy, jen pro úlohy', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='resene_ulohy', to='seminar.Cislo', verbose_name='číslo řešení'), - ), - migrations.AddField( - model_name='uloha', - name='cislo_zadani', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='zadane_ulohy', to='seminar.Cislo', verbose_name='číslo zadání'), - ), - migrations.AddField( - model_name='tema', - name='rocnik', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='seminar.Rocnik', verbose_name='ročník'), - ), - migrations.AddField( - model_name='reseni_resitele', - name='reseni', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Reseni', verbose_name='řešení'), - ), - migrations.AddField( - model_name='reseni_resitele', - name='resitele', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Resitel', verbose_name='řešitel'), - ), - migrations.AddField( - model_name='obrazek', - name='text', - field=models.ForeignKey(help_text='text, ve kterém se obrázek vyskytuje', on_delete=django.db.models.deletion.CASCADE, to='seminar.Text', verbose_name='text'), - ), - migrations.AddField( - model_name='hodnoceni', - name='cislo_body', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='hodnoceni', to='seminar.Cislo', verbose_name='číslo pro body'), - ), - migrations.AddField( - model_name='hodnoceni', - name='problem', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Problem', verbose_name='problém'), - ), - migrations.AddField( - model_name='hodnoceni', - name='reseni', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Reseni', verbose_name='řešení'), - ), - migrations.AddField( - model_name='clanek', - name='cislo', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='seminar.Cislo', verbose_name='číslo'), - ), - migrations.AddField( - model_name='organizator', - name='osoba', - field=models.ForeignKey(help_text='osobní údaje organizátora', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='org', to='seminar.Osoba', verbose_name='osoba'), - ), - migrations.AddField( - model_name='reseni', - name='resitele', - field=models.ManyToManyField(help_text='Seznam autorů řešení', through='seminar.Reseni_Resitele', to='seminar.Resitel', verbose_name='autoři řešení'), - ), - migrations.AddField( - model_name='reseni', - name='text_cely', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='reseni_cely_set', to='seminar.Text', verbose_name='Plná verze textu řešení'), - ), - migrations.AddField( - model_name='reseni', - name='text_zkraceny', - field=models.ManyToManyField(help_text='Seznam úryvků z řešení', related_name='reseni_zkraceny_set', to='seminar.Text', verbose_name='zkrácené verze řešení'), - ), - migrations.AddField( - model_name='resitel', - name='osoba', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='seminar.Osoba', verbose_name='osoba'), - ), - migrations.AddField( - model_name='skola', - name='kontaktni_osoba', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='seminar.Osoba', verbose_name='Kontaktní osoba'), - ), - migrations.AddField( - model_name='reseni', - name='problem', - field=models.ManyToManyField(help_text='Problém', through='seminar.Hodnoceni', to='seminar.Problem', verbose_name='problém'), - ), - ] diff --git a/seminar/migrations/0050_auto_20190510_2228.py b/seminar/migrations/0050_auto_20190510_2228.py deleted file mode 100644 index c6ed9f66..00000000 --- a/seminar/migrations/0050_auto_20190510_2228.py +++ /dev/null @@ -1,191 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.20 on 2019-05-10 20:28 -from __future__ import unicode_literals - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0049_auto_20190430_2354'), - ] - - operations = [ - migrations.AlterField( - model_name='konfera', - name='reseni', - field=models.OneToOneField(blank=True, help_text='Účastnický přípěvek o konfeře', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='konfery', to='seminar.Reseni', verbose_name='článek ke konfeře'), - ), - migrations.AlterField( - model_name='organizator', - name='osoba', - field=models.OneToOneField(help_text='osobní údaje organizátora', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='org', to='seminar.Osoba', verbose_name='osoba'), - ), - migrations.AlterField( - model_name='reseni', - name='text_cely', - field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='reseni_cely_set', to='seminar.Text', verbose_name='Plná verze textu řešení'), - ), - migrations.AlterField( - model_name='resitel', - name='osoba', - field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.CASCADE, to='seminar.Osoba', verbose_name='osoba'), - ), - migrations.CreateModel( - name='TreeNode', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ], - options={ - 'verbose_name': 'TreeNode', - 'verbose_name_plural': 'TreeNody', - 'db_table': 'seminar_nodes_treenode', - }, - ), - migrations.CreateModel( - name='CisloNode', - fields=[ - ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), - ('cislo', models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, to='seminar.Cislo', verbose_name='číslo')), - ], - options={ - 'verbose_name': 'Číslo (Node)', - 'verbose_name_plural': 'Čísla (Node)', - 'db_table': 'seminar_nodes_cislo', - }, - bases=('seminar.treenode',), - ), - migrations.CreateModel( - name='ClanekNode', - fields=[ - ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), - ('clanek', models.OneToOneField(null=True, on_delete=django.db.models.deletion.PROTECT, to='seminar.Clanek', verbose_name='článek')), - ], - options={ - 'verbose_name': 'Článek (Node)', - 'verbose_name_plural': 'Články (Node)', - 'db_table': 'seminar_nodes_clanek', - }, - bases=('seminar.treenode',), - ), - migrations.CreateModel( - name='KonferaNode', - fields=[ - ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), - ('konfera', models.OneToOneField(null=True, on_delete=django.db.models.deletion.PROTECT, to='seminar.Konfera', verbose_name='konfera')), - ], - options={ - 'verbose_name': 'Konfera (Node)', - 'verbose_name_plural': 'Konfery (Node)', - 'db_table': 'seminar_nodes_konfera', - }, - bases=('seminar.treenode',), - ), - migrations.CreateModel( - name='MezicisloNode', - fields=[ - ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), - ], - options={ - 'verbose_name': 'Mezičíslo (Node)', - 'verbose_name_plural': 'Mezičísla (Node)', - 'db_table': 'seminar_nodes_mezicislo', - }, - bases=('seminar.treenode',), - ), - migrations.CreateModel( - name='RocnikNode', - fields=[ - ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), - ('rocnik', models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, to='seminar.Rocnik', verbose_name='ročník')), - ], - options={ - 'verbose_name': 'Ročník (Node)', - 'verbose_name_plural': 'Ročníky (Node)', - 'db_table': 'seminar_nodes_rocnik', - }, - bases=('seminar.treenode',), - ), - migrations.CreateModel( - name='TemaVCisleNode', - fields=[ - ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), - ('tema', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Tema', verbose_name='téma v čísle')), - ], - options={ - 'verbose_name': 'Téma v čísle (Node)', - 'verbose_name_plural': 'Témata v čísle (Node)', - 'db_table': 'seminar_nodes_temavcisle', - }, - bases=('seminar.treenode',), - ), - migrations.CreateModel( - name='TextNode', - fields=[ - ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), - ('text', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Text', verbose_name='text')), - ], - options={ - 'verbose_name': 'Text (Node)', - 'verbose_name_plural': 'Text (Node)', - 'db_table': 'seminar_nodes_obsah', - }, - bases=('seminar.treenode',), - ), - migrations.CreateModel( - name='UlohaVzorakNode', - fields=[ - ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), - ('uloha', models.OneToOneField(null=True, on_delete=django.db.models.deletion.PROTECT, to='seminar.Uloha', verbose_name='úloha')), - ], - options={ - 'verbose_name': 'Vzorák úlohy (Node)', - 'verbose_name_plural': 'Vzoráky úloh (Node)', - 'db_table': 'seminar_nodes_uloha_vzorak', - }, - bases=('seminar.treenode',), - ), - migrations.CreateModel( - name='UlohaZadaniNode', - fields=[ - ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), - ('uloha', models.OneToOneField(null=True, on_delete=django.db.models.deletion.PROTECT, to='seminar.Uloha', verbose_name='úloha')), - ], - options={ - 'verbose_name': 'Zadání úlohy (Node)', - 'verbose_name_plural': 'Zadání úloh (Node)', - 'db_table': 'seminar_nodes_uloha_zadani', - }, - bases=('seminar.treenode',), - ), - migrations.CreateModel( - name='PohadkaNode', - fields=[ - ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), - ('pohadka', models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, to='seminar.Pohadka', verbose_name='pohádka')), - ], - options={ - 'verbose_name': 'Pohádka (Node)', - 'verbose_name_plural': 'Pohádky (Node)', - 'db_table': 'seminar_nodes_pohadka', - }, - bases=('seminar.treenode',), - ), - migrations.AddField( - model_name='treenode', - name='first_child', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='seminar.TreeNode', verbose_name='první potomek'), - ), - migrations.AddField( - model_name='treenode', - name='root', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='potomci_set', to='seminar.TreeNode', verbose_name='kořen stromu'), - ), - migrations.AddField( - model_name='treenode', - name='succ', - field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='prev', to='seminar.TreeNode', verbose_name='další element na stejné úrovni'), - ), - ] diff --git a/seminar/migrations/0051_resitel_to_osoba.py b/seminar/migrations/0051_resitel_to_osoba.py deleted file mode 100644 index 17237bd0..00000000 --- a/seminar/migrations/0051_resitel_to_osoba.py +++ /dev/null @@ -1,89 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.20 on 2019-05-10 20:44 -from __future__ import unicode_literals - -from django.db import migrations - -def resitel_to_osoba(apps,schema_editor): - Resitel = apps.get_model('seminar','Resitel') - Osoba = apps.get_model('seminar','Osoba') - for r in Resitel.objects.all(): - o = Osoba() - o.datum_narozeni = r.datum_narozeni - o.datum_registrace = r.datum_prihlaseni - o.datum_souhlasu_udaje = r.datum_souhlasu_udaje - o.datum_souhlasu_zasilani = r.datum_souhlasu_zasilani - o.email = r.email - o.jmeno = r.jmeno - o.mesto = r.mesto - o.pohlavi_muz = r.pohlavi_muz - o.prijmeni = r.prijmeni - o.psc = r.psc - o.stat = r.stat - o.telefon = r.telefon - o.ulice = r.ulice - o.user = r.user - if o.user: - u = o.user - if u.first_name: - if not o.jmeno: - o.jmeno = u.first_name - u.first_name = 'Použij osobu!' - elif o.jmeno == u.first_name: - u.first_name = 'Použij osobu!' - else: - raise ValueError('jmeno a first_name rozdílné: "{}" vs. "{}"'.format(o.jmeno, u.first_name)) - if u.last_name: - if not o.prijmeni: - o.prijmeni = u.last_name - u.last_name = 'Použij osobu!' - elif o.prijmeni == u.last_name: - u.last_name = 'Použij osobu!' - else: - raise ValueError('prijmeni a last_name rozdílné: "{}" vs. "{}"'.format(o.prijmeni, u.last_name)) - if u.email: - if not o.email: - o.email = u.email - u.email = 'Použij osobu!' - elif o.email == u.email: - u.email = 'Použij osobu!' - else: - raise ValueError('o.email a u.email rozdílné: "{}" vs. "{}"'.format(o.email, u.email)) - u.save() - - - o.save() - r.osoba = o - r.save() - -def osoba_to_resitel(apps, schema_editor): - Resitel = apps.get_model('seminar','Resitel') - Osoba = apps.get_model('seminar','Osoba') - for r in Resitel.objects.all(): - o = r.osoba - r.datum_narozeni = o.datum_narozeni - r.datum_prihlaseni = o.datum_registrace - r.datum_souhlasu_udaje = o.datum_souhlasu_udaje - r.datum_souhlasu_zasilani = o.datum_souhlasu_zasilani - r.email = o.email - r.jmeno = o.jmeno - r.mesto = o.mesto - r.pohlavi_muz = o.pohlavi_muz - r.prijmeni = o.prijmeni - r.psc = o.psc - r.stat = o.stat - r.telefon = o.telefon - r.ulice = o.ulice - r.user = o.user - r.save() - o.delete() - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0050_auto_20190510_2228'), - ] - - operations = [ - migrations.RunPython(resitel_to_osoba, osoba_to_resitel), - ] diff --git a/seminar/migrations/0052_user_to_organizator.py b/seminar/migrations/0052_user_to_organizator.py deleted file mode 100644 index d52e29ca..00000000 --- a/seminar/migrations/0052_user_to_organizator.py +++ /dev/null @@ -1,82 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.15 on 2019-05-16 20:59 -from __future__ import unicode_literals - -from django.db import migrations - -def spoj_k_organizatorum_osoby(apps, scema_editor): - Organizator = apps.get_model('seminar', 'Organizator') - Resitel = apps.get_model('seminar', 'Resitel') - Osoba = apps.get_model('seminar', 'Osoba') - for org in Organizator.objects.all(): - - # Spárování organizátora s osobou - user = org.user - resitele = Resitel.objects.filter(user=user) - if resitele.count() != 0: - osoba = resitele.first().osoba - else: - osoba = Osoba(user=user) - - # Přesun informací z usera do osoby - # pro řešitele již v minule migraci - osoba.jmeno = user.first_name - osoba.prijmeni = user.last_name - osoba.email = user.email - user.jmeno = "Použij osobu!" - user.prijmeni = "Použij osobu!" - user.email = "Použij osobu!" - user.save() - - # Přesun informací z organizátora do jeho osoby - osoba.prezdivka = org.prezdivka if org.prezdivka is not None else '' - osoba.foto = org.foto - - # Všechno uložit - osoba.save() - org.osoba = osoba - org.save() - -def fix_problem(apps, schema_editor): - Problem = apps.get_model('seminar', 'Problem') - Organizator = apps.get_model('seminar', 'Organizator') - for pr in Problem.objects.all(): - if pr.autor_old is not None: - pr.autor = Organizator.objects.filter(osoba__user=pr.autor_old).first() - else: - pr.autor = None - if pr.opravovatel is not None: - pr.opravovatele.add(Organizator.objects.filter(osoba__user=pr.opravovatel).first()) - pr.save() - -def fix_pohadka(apps, schema_editor): - Pohadka = apps.get_model('seminar', 'Pohadka') - Organizator = apps.get_model('seminar', 'Organizator') - for poh in Pohadka.objects.all(): - if poh.autor_old is not None: - poh.autor = Organizator.objects.filter(osoba__user=poh.autor_old).first() - else: - poh.autor = None - poh.save() - -def fix_novinka(apps, schema_editor): - Novinky = apps.get_model('seminar', 'Novinky') - Organizator = apps.get_model('seminar', 'Organizator') - for nov in Novinky.objects.all(): - nov.autor = Organizator.objects.filter(osoba__user=nov.autor_old).first() - nov.save() - - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0051_resitel_to_osoba'), - ] - - operations = [ - migrations.RunPython(spoj_k_organizatorum_osoby), - migrations.RunPython(fix_problem), - migrations.RunPython(fix_pohadka), - migrations.RunPython(fix_novinka), - ] diff --git a/seminar/migrations/0053_organizator_organizuje_od_do.py b/seminar/migrations/0053_organizator_organizuje_od_do.py deleted file mode 100644 index b94e8032..00000000 --- a/seminar/migrations/0053_organizator_organizuje_od_do.py +++ /dev/null @@ -1,36 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.20 on 2019-05-16 21:26 -from __future__ import unicode_literals - -import datetime as dt -from django.db import migrations - -def rok_to_datetime(apps,schema_editor): - Organizator = apps.get_model('seminar','Organizator') - for o in Organizator.objects.all(): - rok = o.organizuje_od_roku - if rok: - o.organizuje_od = dt.datetime(rok,1,1) - rok = o.organizuje_do_roku - if rok: - o.organizuje_do = dt.datetime(rok,12,31) - o.save() - -def datetime_to_rok(apps,schema_editor): - Organizator = apps.get_model('seminar','Organizator') - for o in Organizator.objects.all(): - o.organizuje_od_roku = o.organizuje_od.year - o.organizuje_do_roku = o.organizuje_do.year - o.save() - - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0052_user_to_organizator'), - ] - - operations = [ - migrations.RunPython(rok_to_datetime, datetime_to_rok), - ] diff --git a/seminar/migrations/0055_smazat_nemigrovane_zastarale_veci.py b/seminar/migrations/0055_smazat_nemigrovane_zastarale_veci.py deleted file mode 100644 index 1b6f95f4..00000000 --- a/seminar/migrations/0055_smazat_nemigrovane_zastarale_veci.py +++ /dev/null @@ -1,56 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.20 on 2019-05-23 20:16 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0053_organizator_organizuje_od_do'), - ] - - operations = [ - migrations.RemoveField( - model_name='prispevek', - name='problem', - ), - migrations.RemoveField( - model_name='prispevek', - name='reseni', - ), - migrations.DeleteModel( - name='ProblemNavrh', - ), - migrations.DeleteModel( - name='ProblemZadany', - ), - migrations.RemoveField( - model_name='cislo', - name='faze', - ), - migrations.RemoveField( - model_name='konfera', - name='popis', - ), - migrations.RemoveField( - model_name='konfera', - name='prispevek', - ), - migrations.RemoveField( - model_name='problem', - name='import_dakos_id', - ), - migrations.RemoveField( - model_name='resitel', - name='import_mamoper_id', - ), - migrations.RemoveField( - model_name='skola', - name='import_dakos_id', - ), - migrations.DeleteModel( - name='Prispevek', - ), - ] diff --git a/seminar/migrations/0056_vrcholy_pro_rocniky_a_cisla.py b/seminar/migrations/0056_vrcholy_pro_rocniky_a_cisla.py deleted file mode 100644 index 024400a4..00000000 --- a/seminar/migrations/0056_vrcholy_pro_rocniky_a_cisla.py +++ /dev/null @@ -1,47 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.20 on 2019-05-23 21:54 -from __future__ import unicode_literals - -from django.db import migrations - -def generuj_RocnikNody_a_CisloNody(apps,schema_editor): - Rocnik = apps.get_model('seminar', 'Rocnik') - RocnikNode = apps.get_model('seminar', 'RocnikNode') - Cislo = apps.get_model('seminar', 'Cislo') - CisloNode = apps.get_model('seminar', 'CisloNode') - - last_rn = None # last_* slouží k navázání následníků - for r in Rocnik.objects.all(): - rn = RocnikNode.objects.create(rocnik=r) - rn.save() - rn.root = rn - rn.save() - if last_rn: - last_rn.succ = rn - last_rn.save() - last_rn = rn - - last_cn = None - for c in Cislo.objects.filter(rocnik=r): - cn = CisloNode.objects.create(cislo=c, root=rn) - cn.save() - if last_cn: # Jsme něčí následník - last_cn.succ = cn - last_cn.save() - else: # Jsme první v řadě, takže se musíme přidat jako first_child RočníkNodu - rn.first_child = cn - rn.save() - last_cn = cn - - - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0055_smazat_nemigrovane_zastarale_veci'), - ] - - operations = [ - migrations.RunPython(generuj_RocnikNody_a_CisloNody), - ] diff --git a/seminar/migrations/0057_reseni_to_reseni_hodnoceni.py b/seminar/migrations/0057_reseni_to_reseni_hodnoceni.py deleted file mode 100644 index b3f0405b..00000000 --- a/seminar/migrations/0057_reseni_to_reseni_hodnoceni.py +++ /dev/null @@ -1,34 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.20 on 2019-05-28 21:46 -from __future__ import unicode_literals - -from django.db import migrations - -def reseni_to_Reseni(apps, schema_editor): - Reseni = apps.get_model('seminar','Reseni') - Reseni_Resitele = apps.get_model('seminar','Reseni_Resitele') - Hodnoceni = apps.get_model('seminar','Hodnoceni') - - for r in Reseni.objects.all(): - rr = Reseni_Resitele.objects.create(resitele = r.resitel, reseni=r) - if r.body == None: - print("!!!!!!!!!!!!!!!") - print(r.id,r) - print("!!!!!!!!!!!!!!!") - else: - h = Hodnoceni.objects.create( - body=r.body, - cislo_body = r.cislo_body, - problem = r.problem_old, - reseni = r) - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0056_vrcholy_pro_rocniky_a_cisla'), - ] - - operations = [ - migrations.RunPython(reseni_to_Reseni) - ] diff --git a/seminar/migrations/0058_problem_to_uloha_tema_clanek.py b/seminar/migrations/0058_problem_to_uloha_tema_clanek.py deleted file mode 100644 index 333f5453..00000000 --- a/seminar/migrations/0058_problem_to_uloha_tema_clanek.py +++ /dev/null @@ -1,161 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.20 on 2019-05-17 17:44 -from __future__ import unicode_literals - -from django.db import migrations - -from django.db.models import Q - -def poskladej_strom(apps, rodic, *texty): - Text = apps.get_model('seminar', 'Text') - TextNode = apps.get_model('seminar', 'TextNode') - if not rodic: - raise ValueError("Rodič musí být definovaný") - - uz_ma_deti = False - tn = None - for txt in texty: - if not txt: - continue - # Přidej do stromu: - textobj = Text.objects.create(na_web = txt) - textobj.save() - textnode = TextNode.objects.create(text = textobj) - textnode.save() - if not uz_ma_deti: - rodic.first_child = textnode - rodic.save() - tn = rodic.first_child - uz_ma_deti = True - else: - tn.succ = textnode - tn.save() - tn = tn.succ - -def uloha_to_Uloha(apps,schema_editor): - Problem = apps.get_model('seminar', 'Problem') - Uloha = apps.get_model('seminar', 'Uloha') - Text = apps.get_model('seminar', 'Text') - UlohaZadaniNode = apps.get_model('seminar', 'UlohaZadaniNode') - UlohaVzorakNode = apps.get_model('seminar', 'UlohaVzorakNode') - TextNode = apps.get_model('seminar', 'TextNode') - - ulohy = Problem.objects.filter(typ = 'uloha') - for uold in ulohy: - unew = Uloha.objects.create( - problem_ptr = uold, - # Zakomentované fieldy by se už měly nacházet v příslušném problému - #nazev = uold.nazev, - #stav = uold.stav, - #zamereni = uold.zamereni, - #poznamka = uold.poznamka, - #autor = uold.autor, - #kod = uold.kod, - cislo_zadani = uold.cislo_zadani_old, - cislo_reseni = uold.cislo_reseni_old, - max_body = uold.body, - #vytvoreno = uold.vytvoreno, - ) -# unew.opravovatele.add(*uold.opravovatele.all()) - unew.save() - - # Nody: - zadani_node = UlohaZadaniNode.objects.create(uloha = unew) - poskladej_strom(apps, zadani_node, uold.text_zadani) - zadani_node.save() - vzorak_node = UlohaVzorakNode.objects.create(uloha = unew) - poskladej_strom(apps, vzorak_node, uold.text_reseni) - vzorak_node.save() - -def konfery_rucne(apps, schema_editor): - # Tohle dělat nebudu, máme aktuálně celou jednu. Ale "Errors should never pass silently" - Problem = apps.get_model('seminar', 'Problem') - pocet_konfer = Problem.objects.filter(typ = 'konfera').count() - if pocet_konfer > 0: - raise NotImplementedError("Zkonvertuj {} konfer na objekt Konfera ručně, prosím".format(pocet_konfer)) - -def clanek_to_Clanek(apps,schema_editor): - Problem = apps.get_model('seminar', 'Problem') - Clanek = apps.get_model('seminar', 'Clanek') - ClanekNode = apps.get_model('seminar', 'ClanekNode') - Text = apps.get_model('seminar', 'Text') - TextNode = apps.get_model('seminar', 'TextNode') - - clanky = Problem.objects.filter(Q(typ='org-clanek') | Q(typ='res-clanek')) - for cl in clanky: - # Vybereme vhodné číslo pro článek z čísla zadání a čísla řešení: - if cl.cislo_zadani_old is None: - cislo = cl.cislo_reseni_old - elif cl.cislo_reseni_old is None: - cislo = cl.cislo_zadani_old - elif cl.cislo_reseni_old == cl.cislo_zadani_old: - cislo = cl.cislo_zadani_old - else: - raise ValueError("Různá čísla zadání a řešení u článku! (Článek: {})".format(cl.nazev)) - - clnew = Clanek.objects.create( - problem_ptr = cl, - # Problém by nemělo být potřeba upravovat - cislo = cislo, - # Body ignorujeme, protože už jsou v hodnocení - ) - clnew.save() - - # Aktuálně nemáme v modelu informaci o tom, jestli je to org-článek - # nebo řešitelský článek. Aby se neztratila informace, poznamenám to do - # poznámky. - cl.poznamka += "\nTyp:\t{}".format(cl.typ) - cl.save() - - # Vyrobíme nody: - clnode = ClanekNode(clanek = clnew) - poskladej_strom(apps, clnode, cl.text_zadani, cl.text_reseni) - clnode.save() - -def tema_to_Tema(apps, schema_editor): - Problem = apps.get_model('seminar', 'Problem') - Tema = apps.get_model('seminar', 'Tema') - TemaVCisleNode = apps.get_model('seminar', 'TemaVCisleNode') - Text = apps.get_model('seminar', 'Text') - TextNode = apps.get_model('seminar', 'TextNode') - - temata = Problem.objects.filter(Q(typ = 'tema') | Q(typ='serial')) - for t in temata: - # Vymyslíme správně ročník: - if t.cislo_zadani_old is None and t.cislo_reseni_old is None: - rocnik = None - elif t.cislo_zadani_old is None: - rocnik = t.cislo_reseni_old.rocnik - elif t.cislo_reseni_old is None: - rocnik = t.cislo_zadani_old.rocnik - elif t.cislo_reseni_old.rocnik == t.cislo_zadani_old.rocnik: - rocnik = t.cislo_zadani_old.rocnik - else: - raise ValueError("Nelze mít téma přes více ročníků! (Téma: {}".format(t.nazev)) - - tnew = Tema.objects.create( - problem_ptr = t, - tema_typ = t.typ, - rocnik = rocnik, - ) - tnew.save() - - # Nody: - tnode = TemaVCisleNode(tema = tnew) - poskladej_strom(apps, tnode, t.text_zadani, t.text_reseni) - tnode.save() - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0057_reseni_to_reseni_hodnoceni'), - ] - - operations = [ - # ashes to Ashes, dust to Dust.... - migrations.RunPython(uloha_to_Uloha), - migrations.RunPython(tema_to_Tema), - migrations.RunPython(clanek_to_Clanek), - migrations.RunPython(konfery_rucne), - ] diff --git a/seminar/migrations/0059_vytvorit_pohadkanode.py b/seminar/migrations/0059_vytvorit_pohadkanode.py deleted file mode 100644 index 7ff7c655..00000000 --- a/seminar/migrations/0059_vytvorit_pohadkanode.py +++ /dev/null @@ -1,29 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.20 on 2019-05-29 03:26 -from __future__ import unicode_literals - -from django.db import migrations - -def vytvor_pohadkanode(apps, schema_editor): - Pohadka = apps.get_model('seminar', 'Pohadka') - PohadkaNode = apps.get_model('seminar', 'PohadkaNode') - Text = apps.get_model('seminar', 'Text') - TextNode = apps.get_model('seminar', 'TextNode') - - for p in Pohadka.objects.all(): - t = Text.objects.create(na_web = p.text) - t.save() - tn = TextNode.objects.create(text = t) - tn.save() - pn = PohadkaNode.objects.create(pohadka = p, first_child = tn) - pn.save() - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0058_problem_to_uloha_tema_clanek'), - ] - - operations = [ - migrations.RunPython(vytvor_pohadkanode), - ] diff --git a/seminar/migrations/0060_spoj_stromy.py b/seminar/migrations/0060_spoj_stromy.py deleted file mode 100644 index a94caf48..00000000 --- a/seminar/migrations/0060_spoj_stromy.py +++ /dev/null @@ -1,112 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.20 on 2019-05-29 03:26 -from __future__ import unicode_literals - -from django.db import migrations - -from django.db.models import Q - -def pridej_potomka(rodic, potomek): - # Daný vrchol bude posledním potomkem rodiče - uz_ma_deti = False - posledni = None - - # Přidávaný potomek by neměl mít následovníka -- přidáváme potomka, ne podles. - if potomek.succ: - raise ValueError("Potomek má následovníka, to je velmi podezřelé!") - - # Najdeme aktuálně posledního potomka: - if rodic.first_child: - uz_ma_deti = True - posledni = rodic.first_child - while posledni.succ: - posledni = posledni.succ - - # Nastavíme kořen: - potomek.root = rodic.root - potomek.save() - - # Připojíme vrchol: - if uz_ma_deti: - posledni.succ = potomek - posledni.save() - else: - rodic.first_child = potomek - rodic.save() - -def pokacej_les(apps, schema_editor): - # Teď je potřeba všechny TreeNody příslušející k zadaným problémům připojit - # do hlavního stromu - # Tohle je jednoduchá verze: nejdřív témátka a seriály, pak úložky a pohádky, - # pak články a konfery, pak vzoráky, všechno setříděné podle kódu (FIXME?) - - # Kopírování je častým zdrojem chyb! - Cislo = apps.get_model('seminar', 'Cislo') - Tema = apps.get_model('seminar', 'Tema') - Konfera = apps.get_model('seminar', 'Konfera') - Clanek = apps.get_model('seminar', 'Clanek') - Uloha = apps.get_model('seminar', 'Uloha') - Problem = apps.get_model('seminar', 'Problem') - Pohadka = apps.get_model('seminar', 'Pohadka') - - for c in Cislo.objects.all().reverse(): - cnode = c.cislonode - - # Témata a seriály: - relevantni_temata = Tema.objects.filter(Q(cislo_zadani_old = c) | Q(cislo_reseni_old = c)).order_by('kod') - # Téma dáme do prvního čísla, kde se vyskytne - for t in relevantni_temata: - tnode = t.temavcislenode - if t.cislo_zadani_old and t.cislo_reseni_old: - assert(t.cislo_zadani_old <= t.cislo_reseni_old) - if t.cislo_reseni_old == c: - # Už by mělo být přidané do čísla zadání - continue - else: - # Patří sem (buď je to jediné číslo, nebo je to číslo zadání) - pridej_potomka(cnode, tnode) - - # Úložky (zadání) a pohádky - for u in Uloha.objects.filter(cislo_zadani = c).order_by('kod'): - unode = u.ulohazadaninode - pohadky_pred = Pohadka.objects.filter(uloha_old = u.problem_ptr, pred = True) - pohadky_po = Pohadka.objects.filter(uloha_old = u.problem_ptr, pred = False) - for p in pohadky_pred: - pnode = p.pohadkanode - pridej_potomka(cnode, pnode) - pridej_potomka(cnode, unode) - for p in pohadky_po: - pnode = p.pohadkanode - pridej_potomka(cnode, pnode) - - # Pohádky, které nejsou u úlohy jsou špatně: - if Pohadka.objects.exclude(uloha_old__typ='uloha').count(): - raise ValueError("Existuje pohádka, která není u úlohy") - - # Články - for cl in Clanek.objects.filter(cislo = c).order_by('kod'): - clnode = cl.claneknode - pridej_potomka(cnode, clnode) - - # Konfery - for k in Konfera.objects.all(): - knode = k.konferanode - if k.reseni and knode.root is None: - # Takováhle konfera nejspíš neexistuje - raise NotImplementedError("Konfery neumím zapojit do stromu") - - # Vzoráky - for u in Uloha.objects.filter(cislo_reseni = c).order_by('kod'): - unode = u.ulohavzoraknode - pridej_potomka(cnode, unode) - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0059_vytvorit_pohadkanode'), - ] - - operations = [ - migrations.RunPython(pokacej_les), - ] diff --git a/seminar/migrations/0061_kill_frankenstein.py b/seminar/migrations/0061_kill_frankenstein.py deleted file mode 100644 index 0a367edf..00000000 --- a/seminar/migrations/0061_kill_frankenstein.py +++ /dev/null @@ -1,153 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.20 on 2019-05-29 03:29 -from __future__ import unicode_literals - -from django.db import migrations, models -import django.db.models.deletion -import django.utils.timezone - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0060_spoj_stromy'), - ] - - operations = [ - migrations.RemoveField( - model_name='novinky', - name='autor_old', - ), - migrations.RemoveField( - model_name='organizator', - name='foto', - ), - migrations.RemoveField( - model_name='organizator', - name='organizuje_do_roku', - ), - migrations.RemoveField( - model_name='organizator', - name='organizuje_od_roku', - ), - migrations.RemoveField( - model_name='organizator', - name='prezdivka', - ), - migrations.RemoveField( - model_name='organizator', - name='user', - ), - migrations.RemoveField( - model_name='pohadka', - name='autor_old', - ), - migrations.RemoveField( - model_name='pohadka', - name='uloha_old', - ), - migrations.RemoveField( - model_name='problem', - name='autor_old', - ), - migrations.RemoveField( - model_name='problem', - name='body', - ), - migrations.RemoveField( - model_name='problem', - name='cislo_reseni_old', - ), - migrations.RemoveField( - model_name='problem', - name='cislo_zadani_old', - ), - migrations.RemoveField( - model_name='problem', - name='opravovatel', - ), - migrations.RemoveField( - model_name='problem', - name='text_reseni', - ), - migrations.RemoveField( - model_name='problem', - name='text_zadani', - ), - migrations.RemoveField( - model_name='problem', - name='typ', - ), - migrations.RemoveField( - model_name='reseni', - name='body', - ), - migrations.RemoveField( - model_name='reseni', - name='cislo_body', - ), - migrations.RemoveField( - model_name='reseni', - name='problem_old', - ), - migrations.RemoveField( - model_name='reseni', - name='resitel', - ), - migrations.RemoveField( - model_name='resitel', - name='datum_narozeni', - ), - migrations.RemoveField( - model_name='resitel', - name='datum_prihlaseni', - ), - migrations.RemoveField( - model_name='resitel', - name='datum_souhlasu_udaje', - ), - migrations.RemoveField( - model_name='resitel', - name='datum_souhlasu_zasilani', - ), - migrations.RemoveField( - model_name='resitel', - name='email', - ), - migrations.RemoveField( - model_name='resitel', - name='jmeno', - ), - migrations.RemoveField( - model_name='resitel', - name='mesto', - ), - migrations.RemoveField( - model_name='resitel', - name='pohlavi_muz', - ), - migrations.RemoveField( - model_name='resitel', - name='prijmeni', - ), - migrations.RemoveField( - model_name='resitel', - name='psc', - ), - migrations.RemoveField( - model_name='resitel', - name='stat', - ), - migrations.RemoveField( - model_name='resitel', - name='telefon', - ), - migrations.RemoveField( - model_name='resitel', - name='ulice', - ), - migrations.RemoveField( - model_name='resitel', - name='user', - ), - ] diff --git a/seminar/migrations/0062_redukce_modelu_pohadky.py b/seminar/migrations/0062_redukce_modelu_pohadky.py deleted file mode 100644 index b4e5f11e..00000000 --- a/seminar/migrations/0062_redukce_modelu_pohadky.py +++ /dev/null @@ -1,33 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.20 on 2019-05-30 01:16 -from __future__ import unicode_literals - -from django.db import migrations, models -import django.db.models.deletion -import django.utils.timezone - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0061_kill_frankenstein'), - ] - - operations = [ - migrations.AlterModelOptions( - name='pohadka', - options={'ordering': ['vytvoreno'], 'verbose_name': 'Pohádka', 'verbose_name_plural': 'Pohádky'}, - ), - migrations.RemoveField( - model_name='pohadka', - name='pred', - ), - migrations.RemoveField( - model_name='pohadka', - name='text', - ), - migrations.RemoveField( - model_name='pohadka', - name='uloha', - ), - ] diff --git a/seminar/migrations/0063_procisteni_migraci.py b/seminar/migrations/0063_procisteni_migraci.py deleted file mode 100644 index 3dce57ad..00000000 --- a/seminar/migrations/0063_procisteni_migraci.py +++ /dev/null @@ -1,35 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.20 on 2019-05-30 01:32 -from __future__ import unicode_literals - -from django.db import migrations, models -import django.db.models.deletion -import django.utils.timezone - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0062_redukce_modelu_pohadky'), - ] - - operations = [ - migrations.AlterField( - model_name='cislo', - name='verejna_vysledkovka', - # Změnil se help_text -- byly v něm tabulátory kvůli zlomu v modelech - field=models.BooleanField(default=False, help_text='Je-li false u veřejného čísla, není výsledkovka zatím veřejná.', verbose_name='zveřejněna výsledkovka'), - ), - migrations.AlterField( - model_name='prijemce', - name='osoba', - # Bylo: ForeignKey - field=models.OneToOneField(help_text='Které osobě či na jakou adresu se mají zasílat čísla', on_delete=django.db.models.deletion.CASCADE, to='seminar.Osoba', verbose_name='komu'), - ), - migrations.AlterField( - model_name='reseni', - name='cas_doruceni', - # Bylo: editable=False - field=models.DateTimeField(blank=True, default=django.utils.timezone.now, verbose_name='čas_doručení'), - ), - ] diff --git a/seminar/migrations/0064_auto_20190610_2358.py b/seminar/migrations/0064_auto_20190610_2358.py deleted file mode 100644 index 344b132c..00000000 --- a/seminar/migrations/0064_auto_20190610_2358.py +++ /dev/null @@ -1,162 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.21 on 2019-06-10 21:58 -from __future__ import unicode_literals - -from django.conf import settings -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0063_procisteni_migraci'), - ] - - operations = [ - migrations.AlterField( - model_name='cislo', - name='rocnik', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='cisla', to='seminar.Rocnik', verbose_name='ročník'), - ), - migrations.AlterField( - model_name='clanek', - name='cislo', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='seminar.Cislo', verbose_name='číslo'), - ), - migrations.AlterField( - model_name='hodnoceni', - name='cislo_body', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='hodnoceni', to='seminar.Cislo', verbose_name='číslo pro body'), - ), - migrations.AlterField( - model_name='hodnoceni', - name='problem', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Problem', verbose_name='problém'), - ), - migrations.AlterField( - model_name='konfery_ucastnici', - name='konfera', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Konfera', verbose_name='konfera'), - ), - migrations.AlterField( - model_name='konfery_ucastnici', - name='resitel', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Resitel', verbose_name='řešitel'), - ), - migrations.AlterField( - model_name='nastaveni', - name='aktualni_cislo', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Cislo', verbose_name='poslední vydané číslo'), - ), - migrations.AlterField( - model_name='nastaveni', - name='aktualni_rocnik', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Rocnik', verbose_name='aktuální ročník'), - ), - migrations.AlterField( - model_name='novinky', - name='autor', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='seminar.Organizator', verbose_name='Autor novinky'), - ), - migrations.AlterField( - model_name='organizator', - name='osoba', - field=models.OneToOneField(help_text='osobní údaje organizátora', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='org', to='seminar.Osoba', verbose_name='osoba'), - ), - migrations.AlterField( - model_name='osoba', - name='user', - field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, to=settings.AUTH_USER_MODEL, verbose_name='uživatel'), - ), - migrations.AlterField( - model_name='pohadka', - name='autor', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='seminar.Organizator', verbose_name='Autor pohádky'), - ), - migrations.AlterField( - model_name='problem', - name='autor', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='autor_problemu_problem', to='seminar.Organizator', verbose_name='autor problému'), - ), - migrations.AlterField( - model_name='problem', - name='garant', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='garant_problemu_problem', to='seminar.Organizator', verbose_name='garant zadaného problému'), - ), - migrations.AlterField( - model_name='problem', - name='nadproblem', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='nadproblem_problem', to='seminar.Problem', verbose_name='nadřazený problém'), - ), - migrations.AlterField( - model_name='reseni', - name='text_cely', - field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='reseni_cely_set', to='seminar.Text', verbose_name='Plná verze textu řešení'), - ), - migrations.AlterField( - model_name='reseni_resitele', - name='resitele', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Resitel', verbose_name='řešitel'), - ), - migrations.AlterField( - model_name='resitel', - name='osoba', - field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.SET_NULL, to='seminar.Osoba', verbose_name='osoba'), - ), - migrations.AlterField( - model_name='resitel', - name='skola', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='seminar.Skola', verbose_name='škola'), - ), - migrations.AlterField( - model_name='skola', - name='kontaktni_osoba', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='seminar.Osoba', verbose_name='Kontaktní osoba'), - ), - migrations.AlterField( - model_name='soustredeni', - name='rocnik', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='soustredeni', to='seminar.Rocnik', verbose_name='ročník'), - ), - migrations.AlterField( - model_name='soustredeni_organizatori', - name='organizator', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Organizator', verbose_name='organizátor'), - ), - migrations.AlterField( - model_name='soustredeni_organizatori', - name='soustredeni', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Soustredeni', verbose_name='soustředění'), - ), - migrations.AlterField( - model_name='soustredeni_ucastnici', - name='resitel', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Resitel', verbose_name='řešitel'), - ), - migrations.AlterField( - model_name='soustredeni_ucastnici', - name='soustredeni', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Soustredeni', verbose_name='soustředění'), - ), - migrations.AlterField( - model_name='tema', - name='rocnik', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='seminar.Rocnik', verbose_name='ročník'), - ), - migrations.AlterField( - model_name='uloha', - name='cislo_deadline', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='deadlinove_ulohy', to='seminar.Cislo', verbose_name='číslo deadlinu'), - ), - migrations.AlterField( - model_name='uloha', - name='cislo_reseni', - field=models.ForeignKey(blank=True, help_text='Číslo s řešením úlohy, jen pro úlohy', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='resene_ulohy', to='seminar.Cislo', verbose_name='číslo řešení'), - ), - migrations.AlterField( - model_name='uloha', - name='cislo_zadani', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='zadane_ulohy', to='seminar.Cislo', verbose_name='číslo zadání'), - ), - ] diff --git a/seminar/migrations/0065_treenode_polymorphic_ctype.py b/seminar/migrations/0065_treenode_polymorphic_ctype.py deleted file mode 100644 index 71eef262..00000000 --- a/seminar/migrations/0065_treenode_polymorphic_ctype.py +++ /dev/null @@ -1,31 +0,0 @@ -# Generated by Django 2.2.4 on 2019-08-13 19:36 - -from django.db import migrations, models -import django.db.models.deletion - -def vyrob_treenodum_ctypes(apps, schema_editor): - # Kód zkopírovaný z dokumentace: https://django-polymorphic.readthedocs.io/en/stable/migrating.html - # XXX: Nevím, jestli se tohle náhodou nemělo spustit na všech childech (jen/i) - TreeNode = apps.get_model('seminar', 'TreeNode') - ContentType = apps.get_model('contenttypes', 'ContentType') - - new_ct = ContentType.objects.get_for_model(TreeNode) - TreeNode.objects.filter(polymorphic_ctype__isnull=True).update(polymorphic_ctype=new_ct) - - - -class Migration(migrations.Migration): - - dependencies = [ - ('contenttypes', '0002_remove_content_type_name'), - ('seminar', '0064_auto_20190610_2358'), - ] - - operations = [ - migrations.AddField( - model_name='treenode', - name='polymorphic_ctype', - field=models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_seminar.treenode_set+', to='contenttypes.ContentType'), - ), - migrations.RunPython(vyrob_treenodum_ctypes, migrations.RunPython.noop), - ] diff --git a/seminar/migrations/0066_problem_polymorphic_ctype.py b/seminar/migrations/0066_problem_polymorphic_ctype.py deleted file mode 100644 index f956217e..00000000 --- a/seminar/migrations/0066_problem_polymorphic_ctype.py +++ /dev/null @@ -1,29 +0,0 @@ -# Generated by Django 2.2.4 on 2019-08-13 19:45 - -from django.db import migrations, models -import django.db.models.deletion - -def vyrob_problemum_ctypes(apps, schema_editor): - # Kód zkopírovaný z dokumentace: https://django-polymorphic.readthedocs.io/en/stable/migrating.html - # XXX: Nevím, jestli se tohle náhodou nemělo spustit na všech childech (jen/i) - Problem = apps.get_model('seminar', 'Problem') - ContentType = apps.get_model('contenttypes', 'ContentType') - - new_ct = ContentType.objects.get_for_model(Problem) - Problem.objects.filter(polymorphic_ctype__isnull=True).update(polymorphic_ctype=new_ct) - -class Migration(migrations.Migration): - - dependencies = [ - ('contenttypes', '0002_remove_content_type_name'), - ('seminar', '0065_treenode_polymorphic_ctype'), - ] - - operations = [ - migrations.AddField( - model_name='problem', - name='polymorphic_ctype', - field=models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_seminar.problem_set+', to='contenttypes.ContentType'), - ), - migrations.RunPython(vyrob_problemum_ctypes, migrations.RunPython.noop), - ] diff --git a/seminar/migrations/0067_auto_20190814_0805.py b/seminar/migrations/0067_auto_20190814_0805.py deleted file mode 100644 index 8a72a659..00000000 --- a/seminar/migrations/0067_auto_20190814_0805.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 2.2.4 on 2019-08-14 06:05 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('seminar', '0066_problem_polymorphic_ctype'), - ] - - operations = [ - migrations.AlterField( - model_name='konfera', - name='nazev', - field=models.CharField(help_text='Název konfery', max_length=100, verbose_name='název konfery'), - ), - ] From 2f3386e84fd385b9d238a8fbb553662ff2e96e7e Mon Sep 17 00:00:00 2001 From: "Tomas \"Jethro\" Pokorny" Date: Mon, 19 Aug 2019 23:06:33 +0200 Subject: [PATCH 19/92] Pridano vybirani skol ukradene od KSP. --- seminar/forms.py | 18 +- seminar/static/seminar/skoly.js | 939 +++++++++++++++++++++++ seminar/templates/seminar/prihlaska.html | 9 + 3 files changed, 965 insertions(+), 1 deletion(-) create mode 100644 seminar/static/seminar/skoly.js diff --git a/seminar/forms.py b/seminar/forms.py index a9aa725c..2bc3ecee 100644 --- a/seminar/forms.py +++ b/seminar/forms.py @@ -17,7 +17,23 @@ class PrihlaskaForm(forms.Form): ('SK', 'Slovenská Republika'), ('other', 'Jiné')), required=False) - #TODO skola + + + skola_stat_select = forms.ChoiceField(label='Stát', + choices = (('cz', 'Česká Republika'), + ('sk', 'Slovenská Republika'), + ('other', 'Jiné')), + required=True) + kraj_select = forms.ChoiceField(label='Kraj',required=True) + skola_select = forms.ChoiceField(label='Škola',required=True) + #kraj + #škola + trida = forms.CharField(label='Třída',max_length=10, required=True) + #název školy + #adresa školy + skola_nazev = forms.CharField(label='Název školy', max_length=256, required=False) + skola_adresa = forms.CharField(label='Adresa školy', max_length=256, required=False) + rok_maturity = forms.IntegerField(label='Rok maturity', min_value=2019, required=True) zasilat = forms.ChoiceField(label='Kam zasílat čísla a řešení',choices = Resitel.ZASILAT_CHOICES, required=True) gdpr = forms.BooleanField(label='Souhlasím se zpracováním osobních údajů', required=True) diff --git a/seminar/static/seminar/skoly.js b/seminar/static/seminar/skoly.js new file mode 100644 index 00000000..f617bc94 --- /dev/null +++ b/seminar/static/seminar/skoly.js @@ -0,0 +1,939 @@ +var regions = { + 'cz': [ + [0, '--- Vyber si kraj ---'], + [2, 'Jihomoravský kraj'], + [1, 'Jihočeský kraj'], + [3, 'Karlovarský kraj'], + [13, 'Kraj Vysočina'], + [4, 'Královéhradecký kraj'], + [5, 'Liberecký kraj'], + [6, 'Moravskoslezský kraj'], + [7, 'Olomoucký kraj'], + [8, 'Pardubický kraj'], + [10, 'Plzeňský kraj'], + [9, 'Praha'], + [11, 'Středočeský kraj'], + [14, 'Zlínský kraj'], + [12, 'Ústecký kraj'], + ], + 'sk': [ + [0, '--- Vyber si kraj ---'], + [16, 'Banskobystrický kraj'], + [15, 'Bratislavský kraj'], + [17, 'Košický kraj'], + [18, 'Nitriansky kraj'], + [19, 'Prešovský kraj'], + [20, 'Trenčiansky kraj'], + [21, 'Trnavský kraj'], + [22, 'Žilinský kraj'], + ], + 'xx': [ + [0, '--- Vyber si kraj ---'], + [23, 'Mimo ČR/SR'], + ], +}; + +var schools = { + 0: [ + [0,'--- Vyber si školu ---'], + ], + 1: [ + [0,'--- Vyber si školu ---'], + [-1,'Blatná'], + [172,"Střední odborná škola (V Jezárkách 745, 38817 Blatná)"], + [-1,'České Budějovice'], + [493,"Biskupské gymnázium J. N. Neumanna a Církevní základní škola (Jirsíkova 420/5, 370 01 České Budějovice)"], + [490,"EDUCAnet – SŠ a ZŠ České Budějovice, s.r.o. (Lannova tř. 1595/29a 37001 České Budějovice)"], + [204,"Gymnázium Česká (Česká 64, 37021 České Budějovice)"], + [227,"Gymnázium Jana Valeriána Jirsíka (Fráni Šrámka 23, 37001 České Budějovice)"], + [130,"Gymnázium Jírovcova (Jírovcova 8, 37161 České Budějovice)"], + [375,"Střední škola informatiky a právních studií, o. p. s. (Žižkova 4, 37001 České Budějovice)"], + [469,"Střední škola obchodu, služeb a podnikání a VOŠ (Kněžskodvorská 33/A, 37004 České Budějovice)"], + [459,"Základní škola Oskara Nedbala (Oskara Nedbala 30, České Budějovice)"], + [419,"ZŠ Dukelská (Dukelská 11, 37001 České Budějovice)"], + [-1,'Český Krumlov'], + [241,"Gymnázium Český Krumlov (Chvalšinská 112, 38101 Český Krumlov)"], + [-1,'Čkyně'], + [492,"ZŠ a MŠ Čkyně (č. p. 155, 38441 Čkyně)"], + [-1,'Dačice'], + [399,"Gymnázium Dačice (Boženy Němcové 213/V, 38001 Dačice)"], + [-1,'Hluboká nad Vltavou'], + [236,"Střední odborná škola elektrotechnická COP (Zvolenovská 537, 37341 Hluboká nad Vltavou)"], + [-1,'Jindřichův Hradec'], + [115,"Gymnázium Vítězslava Nováka (Husova 333, 37715 Jindřichův Hradec)"], + [528,"Střední zdravotnická škola (Klášterská 77/II, 377 01 Jindřichův Hradec)"], + [-1,'Kaplice'], + [174,"Gymnázium, SOŠE a SOU Kaplice (Pohorská 86, 38241 Kaplice)"], + [-1,'Milevsko'], + [400,"Gymnázium Milevsko (Masarykova 183, 39901 Milevsko)"], + [-1,'Písek'], + [156,"Gymnázium Písek (Komenského 89/20, 39701 Písek)"], + [6,"SPŠ a VOŠ Písek (Karla Čapka 402, 39711 Písek)"], + [-1,'Prachatice'], + [157,"Gymnázium Prachatice (Zlatá stezka 137, 38301 Prachatice)"], + [-1,'Soběslav'], + [271,"Gymnázium Soběslav (tř. Dr. Edvarda Beneše 449/20, 39201 Soběslav II)"], + [-1,'Strakonice'], + [17,"Gymnázium Strakonice (Máchova 174, 38648 Strakonice)"], + [322,"ZŠ Dukelská (Dukelská 166, 38601 Strakonice)"], + [-1,'Tábor'], + [88,"Gymnázium Pierra de Coubertina (Náměstí Františka Křižíka 860, 39030 Tábor)"], + [-1,'Třeboň'], + [477,"Gymnázium Třeboň, Na sadech 308 (Na Sadech 308, 37926 Třeboň)"], + [-1,'Týn nad Vltavou'], + [135,"Gymnázium Týn nad Vltavou (Havlíčkova 13, 37501 Týn nad Vltavou)"], + [-1,'Vimperk'], + [15,"Gymnázium a SOŠ ekonomická (Pivovarská 69, 38501 Vimperk)"], + ], + 2: [ + [0,'--- Vyber si školu ---'], + [-1,'Blansko'], + [281,"Gymnázium Blansko (Seifertova 13, 67801 Blansko)"], + [-1,'Boskovice'], + [120,"Gymnázium Boskovice (Palackého náměstí 1, 68001 Boskovice)"], + [-1,'Břeclav'], + [10,"Gymnázium a jazyková škola s právem SJZ (Sady 28. října 1, 69002 Břeclav)"], + [-1,'Brno'], + [257,"Biskupské gymnázium Brno (Barvičova 85, 60200 Brno)"], + [557,"Cyrilometodějské gymnázium a střední odborná škola pedagogická (Lerchova 63, 602 00 Brno)"], + [325,"EDUCAnet Brno, o. p. s. (Arménská 573/21, 62500 Brno)"], + [171,"EKO gymnázium Brno o. p. s. (Labská 27, 62500 Brno)"], + [39,"Gymnázium Brno (tř. Kapitána Jaroše 14, 65870 Brno)"], + [298,"Gymnázium Brno-Řečkovice (Terezy Novákové 2, 62100 Brno - Řečkovice)"], + [286,"Gymnázium Elgartova (Elgartova 3, 61400 Brno)"], + [213,"Gymnázium Křenová (Křenová 36, 60200 Brno)"], + [40,"Gymnázium Matyáše Lercha (Žižkova 55, 61600 Brno)"], + [379,"Gymnázium Slovanské náměstí (Slovanské náměstí 7, 61200 Brno)"], + [209,"Gymnázium Terezy Novákové (Terezy Novákové 2, 62100 Brno-Řečkovice)"], + [216,"Gymnázium Vídeňská (Vídeňská 47, 63900 Brno)"], + [485,"Klasické a španělské gymnázium Brno-Bystrc (Vejrostova 2, 63500 Brno)"], + [558,"Mateřská škola, základní škola a střední škola Gellnerka Brno, příspěvková organizace (Gellnerova 1, 637 00 Brno)"], + [207,"OA, SOŠ a VOŠ Kotlářská (Kotlářská 9, 61153 Brno)"], + [240,"SPŠ chemická (Vranovská 65, 61400 Brno)"], + [211,"SŠ inf. technologií a soc. péče (Purkyňova 97, 61200 Brno - Královo Pole)"], + [474,"Střední průmyslová škola a VOŠ Brno (Sokolská 1, 60200 Brno)"], + [543,"Střední škola grafická Brno (Kudelova 6, 602 00 Brno)"], + [377,"Střední škola informatiky, poštovnictví a finančnictví Brno (Čichnova 23, 62400 Brno)"], + [479,"Vzdělávací institut INTEGRA BRNO (Rašelinová 2433/11, 62800 Brno-Líšeň)"], + [416,"ZŠ a MŠ Křídlovická (Křídlovická 30b, 60300 Brno)"], + [-1,'Bučovice'], + [376,"Gymnázium a OA Bučovice (Součkova 500, 68501 Bučovice)"], + [-1,'Hodonín'], + [12,"Gymnázium Hodonín (P. O. BOX 38, 69511 Hodonín)"], + [-1,'Hustopeče'], + [251,"Gymnázium T.G.Masaryka (Dukelské náměstí 7, 69331 Hustopeče)"], + [-1,'Jedovnice'], + [275,"SPŠ Jedovnice (Na Větřáku 463, 67906 Jedovnice)"], + [-1,'Klobouky u Brna'], + [415,"Městské víceleté gymnázium Klobouky u Brna (Vinařská 29, 69172 Klobouky u Brna)"], + [-1,'Kyjov'], + [470,"Klvaňovo gymnázium a SZŠ Kyjov (Třída Komenského 549, 69701 Kyjov)"], + [-1,'Moravský Krumlov'], + [66,"Gymnázium Moravský Krumlov (Smetanova 168, 67201 Moravský Krumlov)"], + [-1,'Šlapanice'], + [231,"Gymnázium a ZUŠ (Riegrova 17, 66451 Šlapanice)"], + [-1,'Strážnice'], + [81,"Purkyňovo gymnázium Strážnice (Masarykova 379, 69662 Strážnice)"], + [-1,'Tišnov'], + [161,"Gymnázium Tišnov (Na Hrádku 20, 66601 Tišnov)"], + [-1,'Velké Bílovice'], + [463,"ZŠ Velké Bílovice (Fabián 1215, 69102 Velké Bílovice)"], + [-1,'Vyškov'], + [357,"Gymnázium Vyškov (Komenského 16, 68201 Vyškov)"], + [-1,'Zastávka'], + [232,"Gymnázium T. G. Masaryka (U Školy 39, 66484 Zastávka)"], + [-1,'Znojmo'], + [499,"Gymnázium Dr. Karla Polesného (Komenského náměstí 4, 66975 Znojmo)"], + [323,"SOŠ stavební (Jarošova 1335/14, 66902 Znojmo)"], + ], + 3: [ + [0,'--- Vyber si školu ---'], + [-1,'Cheb'], + [437,"Gymnázium Cheb (Nerudova 2283/7, 35002 Cheb)"], + [475,"Svobodná chebská škola (Jánské náměstí 15, 35002 Cheb)"], + [-1,'Chodov'], + [440,"Gymnázium a obchodní akademie Chodov (Smetanova 738, 35735 Chodov)"], + [-1,'Karlovy Vary'], + [90,"První české gymnázium v K. Varech (Národní 25, 36020 Karlovy Vary)"], + [-1,'Mariánské Lázně'], + [374,"Gymnázium a OA Mariánské Lázně (Ruská 355, 35369 Mariánské Lázně)"], + [259,"OA Mariánské Lázně (Lužická 412, 35324 Mariánské Lázně)"], + [-1,'Nové Sedlo'], + [293,"ZŠ Nové Sedlo (Masarykova 425, 35734 Nové Sedlo)"], + [-1,'Ostrov'], + [101,"Gymnázium Ostrov (Studentská 1205, 36301 Ostrov)"], + [31,"SPŠ Ostrov (Jáchymovská 1, 36311 Ostrov)"], + [-1,'Sokolov'], + [151,"Gymnázium Sokolov (Husitská 2053, 35611 Sokolov)"], + ], + 4: [ + [0,'--- Vyber si školu ---'], + [-1,'Broumov'], + [235,"Gymnázium Broumov (Hradební 218, 55001 Broumov)"], + [-1,'Dobruška'], + [336,"Gymnázium Dobruška (Pulická 779, 51801 Dobruška)"], + [278,"SPŠ elektrotechniky a informačních technologií (Čs. odboje 670, 58001 Dobruška)"], + [-1,'Dvůr Králové nad Labem'], + [92,"SPŠ Dvůr Králové nad Labem (nábřeží J. Wolkera 132, 54411 Dvůr Králové nad Labem)"], + [-1,'Hořice'], + [205,"Gymnázium a SOŠ Hořice (Husova 1414, 50822 Hořice)"], + [-1,'Hradec Králové'], + [318,"Biskupské gymnázium Bohuslava Balbína (Orlické nábřeží 356/1, 50003 Hradec Králové)"], + [225,"Gymnázium Boženy Němcové (Pospíšilova třída 324, 50002 Hradec Králové)"], + [131,"Gymnázium J. K. Tyla (Tylovo nábřeží 682, 50002 Hradec Králové)"], + [441,"První soukromé jazykové gymnázium spol. s r.o. (Brandlova 875, 50003 Hradec Králové)"], + [340,"SOŠ veterinární (Pražská 68, 50101 Hradec Králové - Kukleny)"], + [94,"SŠ aplikované kybernetiky (Hradecká 1151, 50002 Hradec Králové)"], + [531,"Střední škola Sion High School (Na Kotli 1201, 500 09 Hradec Králové)"], + [-1,'Jaroměř'], + [263,"Gymnázium a SOŠ Jaroměř (Lužická 423, 55123 Jaroměř)"], + [-1,'Jičín'], + [217,"Lepařovo gymnázium (Jiráskova 30, 50601 Jičín)"], + [84,"VOŠ a SPŠ Jičín (Pod Koželuhy 100, 50641 Jičín)"], + [-1,'Náchod'], + [301,"Jiráskovo Gymnázium (Řezníčkova 451, 54744 Náchod)"], + [-1,'Nová Paka'], + [118,"Gymnázium a SOŠPg (Kumburská 740, 50901 Nová Paka)"], + [-1,'Nový Bydžov'], + [155,"Gymnázium Nový Bydžov (Komenského 77, 50401 Nový Bydžov)"], + [-1,'Rychnov nad Kněžnou'], + [276,"Gymnázium F.M. Pelcla (Hrdinů odboje 36, 51601 Rychnov nad Kněžnou)"], + [-1,'Sobotka'], + [482,"ZŠ Sobotka (Jičínská 136, 50743 Sobotka)"], + [-1,'Trutnov'], + [107,"Gymnázium Trutnov (Jiráskovo náměstí 325, 54101 Trutnov)"], + [348,"SPŠ Trutnov (Školní 101, 54101 Trutnov)"], + [-1,'Úpice'], + [299,"Městské gymnázium a střední odborná škola Úpice (Havlíčkova 812, 54232 Úpice)"], + [-1,'Vrchlabí'], + [59,"Gymnázium Vrchlabí (Komenského 586, 54301 Vrchlabí)"], + [-1,'Žacléř'], + [465,"ZŠ Žacléř (Komenského 339, 54201 Žacléř)"], + ], + 5: [ + [0,'--- Vyber si školu ---'], + [-1,'Česká Lípa'], + [11,"Gymnázium Česká Lípa (Žitavská 2969, 47006 Česká Lípa)"], + [-1,'Jablonec nad Nisou'], + [128,"Gymnázium Jablonec (U Balvanu 16, 46601 Jablonec nad Nisou)"], + [319,"SPŠT (Belgická 4852, 46601 Jablonec nad Nisou)"], + [153,"Víceleté a sportovní gymnázium (Dr. Randy 13, 46601 Jablonec nad Nisou)"], + [-1,'Liberec'], + [75,"Gymnázium a SOŠPg (Jeronýmova 27, 46007 Liberec 7)"], + [109,"Gymnázium F. X. Šaldy (Partyzánská 530, 46011 Liberec 11)"], + [163,"SPŠ strojní a elektrotechnická a VOŠ (Masarykova 460/3, 46084 Liberec 1)"], + [421,"SŠ strojní, stavební a dopravní Liberec (Ještědská 358/106, 46008 Liberec 8)"], + [-1,'Semily'], + [279,"Gymnázium I. Olbrachta (Nad Špejcharem 574, 51301 Semily)"], + [-1,'Tanvald'], + [27,"Gymnázium Tanvald (Školní 305, 46841 Tanvald)"], + [-1,'Turnov'], + [111,"Gymnázium Turnov (Jana Palacha 804, 51101 Turnov)"], + ], + 6: [ + [0,'--- Vyber si školu ---'], + [-1,'Bílovec'], + [76,"Gymnázium M. Koperníka (17. listopadu 526, 74311 Bílovec)"], + [-1,'Bohumín'], + [260,"Gymnázium Františka Živného (Jana Palacha 794, 73581 Bohumín)"], + [-1,'Bruntál'], + [22,"SPŠ Bruntál (Kavalcova 1, 79201 Bruntál)"], + [1,"ZŠ a městské osmileté gymnázium Bruntál (Školní 2, 79201 Bruntál)"], + [-1,'Český Těšín'], + [546,"Gymnázium Josefa Božka, Český Těšín, příspěvková organizace (Frýdecká 30, 73701 Český Těšín)"], + [124,"Gymnázium s polským jazykem vyučovacím Český Těšín (Havlíčkova 213/13, 73701 Český Těšín)"], + [-1,'Frenštát pod Radhoštěm'], + [417,"Gymnázium a SPŠ Frenštát pod Radhoštěm (Křižíkova 1258, 74401 Frenštát pod Radhoštěm)"], + [33,"Gymnázium Frenštát pod Radhoštěm (Martinská čtvrť 1172, 74401 Frenštát pod Radhoštěm)"], + [-1,'Frýdek'], + [85,"Gymnázium a SOŠ (Cihelní 410, 73801 Frýdek-Místek)"], + [34,"Gymnázium Petra Bezruče (ČSA 517, 73802 Frýdek - Místek)"], + [198,"Střední škola informačních technologií, s. r. o. (třída Pionýrů 2069, 73802 Frýdek-Místek)"], + [-1,'Frýdlant nad Ostravicí'], + [237,"Gymnázium Frýdlant nad Ostravicí (nám. T. G. Masaryka 1260, 73911 Frýdlant nad Ostravicí)"], + [-1,'Havířov'], + [212,"Gymnázium Havířov (Komenského 2, 73601 Havířov-Město)"], + [454,"Gymnázium Havířov-Podlesí (Studentská 1198/11, 73601 Havířov)"], + [137,"SPŠE Havířov (Makarenkova 1, 73601 Havířov - Město)"], + [460,"ZŠ Generála Svobody (Generála Svobody 16, Havířov - Šumbark)"], + [195,"ZŠ Havířov (Školní 1/814, 73564 Havířov-Šumburk)"], + [-1,'Hlučín'], + [289,"Gymnázium Josefa Kainara (Dr. Edvarda Beneše 7/586, 74801 Hlučín)"], + [498,"Základní škola dr. Miroslava Tyrše (Tyršova 1062/2, 74801 Hlučín)"], + [-1,'Karviná'], + [245,"Gymnázium Karviná (Mírová 1442, 73506 Karviná - Nové Město)"], + [139,"SPŠ Karviná (Žižkova 1818, 73301 Karviná - Hranice)"], + [-1,'Kopřivnice'], + [331,"VOŠ, SOŠ a SOU Kopřivnice (Husova 1302, 74221 Kopřivnice)"], + [-1,'Krnov'], + [404,"Gymnázium Krnov (Smetanův okruh 19/2, 79401 Krnov)"], + [-1,'Nový Jičín'], + [342,"Gymnázium a SOŠ Nový Jičín (Palackého 50/52, 74111 Nový Jičín)"], + [-1,'Opava'], + [65,"Mendelovo gymnázium (Komenského 5, 74601 Opava)"], + [-1,'Orlová'], + [221,"Gymnázium Orlová (Masarykova třída 1313, 73514 Orlová - Lutyně)"], + [-1,'Ostrava'], + [210,"Biskupské gymnázium (Karla Pokorného 1284, 70800 Ostrava - Poruba)"], + [491,"Gymnázium Hladnov a Jazyková škola s právem státní jazykové zkoušky Ostrava (Hladnovská 35, 710 00 Slezská Ostrava)"], + [396,"Gymnázium Olgy Havlové (Marie Majerové 1691, 708 00 Ostrava-Poruba)"], + [553,"Gymnázium Ostrava-Hrabůvka p.o. (Františka Hajdy 1429/34 700 30 Ostrava-Hrabůvka)"], + [57,"Gymnázium Ostrava-Zábřeh (Volgogradská 6a, 70400 Ostrava - Zábřeh)"], + [242,"Matiční gymnázium (Dr. Šmerala 25, 72804 Ostrava)"], + [312,"SPŠ elektrotechniky a informatiky (Kratochvílova 7, 70200 Ostrava - Moravská Ostrava)"], + [530,"Střední umělecká škola (Poděbradova 33, 702 00 Moravská Ostrava a Přívoz)"], + [244,"Wichterlovo gymnázium (Čs. exilu 669, 70800 Ostrava-Poruba)"], + [-1,'Příbor'], + [87,"Masarykovo gymnázium (Jičínská 528, 74258 Příbor)"], + [-1,'Rýmařov'], + [502,"Gymnázium a SOŠ Rýmařov (Sokolovská 466/34, 79501 Rýmařov)"], + [-1,'Slezská Ostrava'], + [19,"Gymnázium Hladnov a Jazyková škola s právem SJZ (Hladnovská 35, 71000 Slezská Ostrava)"], + [-1,'Třinec'], + [309,"Gymnázium Třinec (Komenského 713, 73961 Třinec)"], + [-1,'Vrbno pod Pradědem'], + [73,"Sportovní gymnázium (nám. Sv. Michala 12, 79326 Vrbno pod Pradědem)"], + ], + 7: [ + [0,'--- Vyber si školu ---'], + [-1,'Hranice'], + [14,"Gymnázium Hranice (Zborovská 293, 75311 Hranice)"], + [162,"Soukromá SOŠ (Jaselská 832, 75301 Hranice)"], + [-1,'Jeseník'], + [270,"Gymnázium Jeseník (Komenského 281, 79001 Jeseník)"], + [-1,'Kojetín'], + [266,"Gymnázium Kojetín (Svatopluka Čecha 683, 75201 Kojetín)"], + [-1,'Kostelec na Hané'], + [196,"ZŠ a MŠ Kostelec na Hané (Sportovní 850, 79841 Kostelec na Hané)"], + [-1,'Litovel'], + [133,"Gymnázium Jana Opletala (Opletalova 189, 78401 Litovel)"], + [70,"SOU Litovel (Komenského 677, 78401 Litovel)"], + [-1,'Mohelnice'], + [481,"Obchodní akademie, Mohelnice, Olomoucká 82 (Olomoucká 82, 78985 Mohelnice)"], + [-1,'Olomouc'], + [91,"Gymnázium Olomouc - Hejčín (Tomkova 45, 77900 Olomouc - Hejčín)"], + [226,"Slovanské gymnázium (tř. Jiřího z Poděbrad 13, 77111 Olomouc)"], + [332,"VOŠ a SPŠE Olomouc (Božetěchova 3, 772 00 Olomouc)"], + [-1,'Přerov'], + [63,"Gymnázium Jakuba Škody (Komenského 29, 75002 Přerov)"], + [495,"Gymnázium Jana Blahoslava a Střední pedagogická škola (Denisova 3, 75152 Přerov)"], + [524,"Střední průmyslová škola Přerov (Havlíčkova 2, 75152 Přerov)"], + [-1,'Prostějov'], + [496,"Cyrilometodějské gymnázium, základní škola a mateřská škola v Prostějově (Komenského 17, 796 01 Prostějov)"], + [21,"Gymnázium Jiřího Wolkera (Kollárova 3, 79601 Prostějov)"], + [-1,'Šternberk'], + [303,"Gymnázium Šternberk (Horní náměstí 5, 78501 Šternberk)"], + [-1,'Šumperk'], + [350,"Gymnázium Šumperk (Masarykovo nám. 8, 78758 Šumperk)"], + [143,"VOŠ a SPŠ Šumperk (Generála Krátkého 1, 78729 Šumperk)"], + [199,"ZŠ Šumperk (8. května 63, 78701 Šumperk)"], + [-1,'Uničov'], + [392,"Gymnázium Uničov (Gymnazijní 257, 78391 Uničov)"], + [-1,'Zábřeh'], + [551,"Gymnázium Zábřeh (Náměstí Osvobození 257/20, Zábřeh)"], + ], + 8: [ + [0,'--- Vyber si školu ---'], + [-1,'Česká Třebová'], + [67,"Gymnázium Česká Třebová (Tyršovo náměstí 970, 56002 Česká Třebová)"], + [-1,'Chrudim'], + [119,"Gymnázium Josefa Ressela (Olbrachtova 291, 53701 Chrudim)"], + [347,"SOŠ a SOU obchodu a služeb (Čáslavská 205, 53701 Chrudim)"], + [274,"SPŠ Chrudim (Čáslavská 973, 53701 Chrudim)"], + [-1,'Hlinsko'], + [290,"Gymnázium K. V. Raise (Adámkova 55, 53901 Hlinsko)"], + [-1,'Holice'], + [173,"Gymnázium Dr. Emila Holuba (Na Mušce 1110, 53401 Holice)"], + [-1,'Lanškroun'], + [50,"Gymnázium Lanškroun (Náměstí Jana Marka Marků 113, 56312 Lanškroun)"], + [-1,'Litomyšl'], + [264,"Gymnázium Aloise Jiráska (T. G. Masaryka 590, 57001 Litomyšl)"], + [-1,'Moravská Třebová'], + [30,"Gymnázium Moravská Třebová (Svitavská 310, 57101 Moravská Třebová)"], + [-1,'Pardubice'], + [36,"Gymnázium Pardubice (Dašická 1083, 53003 Pardubice)"], + [182,"Polabská soukromá OA a VOŠ, s. r. o. (Gorkého 867, 53002 Pardubice)"], + [71,"SOŠ elektrotechnická a strojní a SOU (Do Nového 1131, 53003 Pardubice)"], + [247,"SPŠE a VOŠ Pardubice (Karla IV. 13, 53169 Pardubice)"], + [418,"Střední škola informatiky a ekonomie a Mateřská škola s. r. o. (Ke Kamenci 151, 53003 Pardubice)"], + [461,"ZŠ Polabiny 1, Družstevní 305 (Pardubice, Družstevní 305)"], + [-1,'Polička'], + [186,"Gymnázium Polička (nábřeží Svobody 306, 57201 Polička)"], + [-1,'Přelouč'], + [79,"SOU technické Přelouč (Dukelské náměstí 1513, 53501 Přelouč)"], + [-1,'Ronov nad Doubravou'], + [523,"ZŠ Ronov nad Doubravou (Chittussiho nám. 153, 53842 Ronov nad Doubravou)"], + [-1,'Rybitví'], + [433,"EDUCAnet - Střední odborná škola Pardubice, s. r. o. (Školní 143, 53354 Rybitví)"], + [-1,'Svitavy'], + [3,"Gymnázium a Jazyková škola s právem SJZ Svitavy (Sokolovská 1638, 56802 Svitavy)"], + [-1,'Ústí nad Orlicí'], + [425,"Gymnázium Ústí nad Orlicí (T. G. Masaryka 106, 562 01, Ústí nad Orlicí)"], + [-1,'Vysoké Mýto'], + [509,"Gymnázium Vysoké Mýto (Nám. Vaňorného 163, 56601 Vysoké Mýto)"], + [-1,'Žamberk'], + [330,"Gymnázium Žamberk (Nádražní 48, 56401 Žamberk)"], + ], + 9: [ + [0,'--- Vyber si školu ---'], + [-1,'Praha 1'], + [7,"Akademické gymnázium (Štěpánská 22, 11000 Praha 1)"], + [125,"Gymnázium Jana Nerudy (Hellichova 3, 11800 Praha 1-Malá Strana)"], + [435,"Gymnázium Jiřího Gutha-Jarkovského (Truhlářská 22, 110 00 Praha 1)"], + [228,"Gymnázium prof. J. Patočky (Jindřišská 36, 11000 Praha 1)"], + [193,"Malostranské gymnázium (Josefská 7, 11800 Praha 1-Malá Strana)"], + [74,"SPŠ sdělovací techniky (Panská 3, 11000 Praha 1)"], + [455,"VOŠ a SPŠ elektrotechnická Františka Křižíka (Na Příkopě 16, Praha 1)"], + [304,"ZŠ Uhelný trh (Uhelný trh 4, 11000 Praha 1)"], + [-1,'Praha 10'], + [333,"Gymnázium Omská (Omská 1300, 10000 Praha Vršovice)"], + [344,"Gymnázium Přípotoční (Přípotoční 1337, 10130 Praha 10 - Vršovice)"], + [56,"Gymnázium Voděradská (Voděradská 2, 10000 Praha 10 - Strašnice)"], + [25,"SPŠE V Úžlabině (V Úžlabině 320, 10000 Praha 10)"], + [-1,'Praha 2'], + [203,"Arcibiskupské gymnázium (Korunní 2, 12000 Praha 2)"], + [114,"Gymnázium Botičská (Botičská 1, 12000 Praha 2)"], + [562,"Obchodní Akademie Vinohradská (Vinohradská 1971/38, 12000 Praha 2)"], + [285,"SPŠE Ječná (Ječná 517/30, 12136 Praha 2)"], + [532,"ZŠ Kladská (Kladská 1201/1, Praha 2)"], + [444,"ZŠ Masarykova (Jana Masaryka 21, 12000 Praha 2)"], + [-1,'Praha 3'], + [451,"Gymnázium a Hudební škola (Komenského náměstí 400/9, 13000 Praha 3)"], + [104,"Gymnázium Karla Sladkovského (Sladkovského náměstí 8, 13000 Praha 3-Žižkov)"], + [252,"Gymnázium Na Pražačce (Nad Ohradou 2825/23, 13000 Praha 3 – Žižkov)"], + [-1,'Praha 4'], + [282,"Gymnasium Jižní Město (Tererova 17/2135, 14900 Praha 4)"], + [82,"Gymnázium Budějovická (Budějovická 680, 14000 Praha 4)"], + [127,"Gymnázium Elišky Krásnohorské (Ohradní 55, 14500 Praha 4-Michle)"], + [556,"Gymnázium Evolution Jižní Město (Tererova 2135/17, 149 00, Praha 4)"], + [383,"Gymnázium Milady Horákové (Na planině 1393/13, 140 00, Praha 4)"], + [170,"Gymnázium Na Vítězné pláni (Na Vítězné pláni 1160, 14000 Praha 4)"], + [411,"Gymnázium Opatov (Konstantinova 1500, 14900 Praha)"], + [360,"Gymnázium Písnická (Písnická 760, 14200 Praha 4)"], + [68,"Klasické gymnázium (Rakovského 3136/II, 14300 Praha 4)"], + [501,"Nový PORG (Pod Krčským lesem 1300/25, 14200 Praha 4)"], + [500,"Škola mezinárodních a veřejných vztahů, SOŠ, s.r.o (Michelská 12, 14000 Praha 4)"], + [488,"Waldorfské lyceum (Křejpského 1503, 14900 Praha 4)"], + [233,"ZŠ Jílovská (Jílovská 1100/16, 14200 Praha 4 - Braník)"], + [-1,'Praha 5'], + [58,"Gymnázium Christiana Dopplera (Zborovská 45, 15000 Praha 5)"], + [24,"Gymnázium J. Heyrovského (Mezi Školami 2475, 15800 Praha 5)"], + [132,"Gymnázium Na Zatlance (Na Zatlance 11, 15000 Praha 5)"], + [16,"Gymnázium Nad Kavalírkou (Nad Kavalírkou 1, 15000 Praha 5 - Košíře)"], + [106,"Gymnázium Oty Pavla (Loučanská 520, 15300 Praha 5-Radotín)"], + [514,"Smíchovská střední průmyslová škola (Preslova 25, 150 21 Praha 5 - Smíchov)"], + [-1,'Praha 6'], + [105,"Gymnázium Arabská (Arabská 682/14, 16000 Praha 6)"], + [149,"Gymnázium Jana Keplera (Parléřova 2, 16900 Praha 6)"], + [41,"Gymnázium Nad Alejí (Nad Alejí 1952, 16200 Praha 6)"], + [335,"Mensa gymnázium, o. p. s. (Španielova 1111/19, 16300 Praha 6 - Řepy)"], + [183,"VOŠ, SOŠP a Gymnázium Evropská (Evropská 33, 16000 Praha 6)"], + [409,"ZŠ Bílá (Bílá 1784/1, 16000 Praha 6)"], + [-1,'Praha 7'], + [126,"Gymnázium Nad Štolou (Nad Štolou 1/1510, 17000 Praha 7)"], + [-1,'Praha 8'], + [28,"Gymnázium Bernarda Bolzana, o. p. s. (V Holešovičkách 2, 180 00 Praha 8)"], + [83,"Gymnázium U Libeňského zámku (U Libeňského zámku 1, 18000 Praha 8)"], + [43,"Gymnázium Ústavní (Ústavní 400, 18100 Praha 8 - Bohnice)"], + [321,"PORG (Lindnerova 3, 18000 Praha 8 - Libeň)"], + [370,"Soukromá střední odborná škola (1.KŠPA) Praha s. r. o. (Pernerova 29/383, 18600 Praha 8)"], + [-1,'Praha 9'], + [208,"Gymnázium Čakovice (náměstí 25. března 100, 19600 Praha 9)"], + [154,"Gymnázium Českolipská (Českolipská 373, 19000 Praha 9)"], + [234,"Gymnázium Chodovická (Chodovická 2250, 19300 Praha 9 - Horní Počernice)"], + [184,"Gymnázium Jaroslava Seiferta, o. p. s. (Vysočanské nám. 500, 19000 Praha 9)"], + [202,"Gymnázium Litoměřická (Litoměřická 726, 19000 Praha 9)"], + [187,"Gymnázium Špitálská (Špitálská 2/700, 19000 Praha 9-Vysočany)"], + [188,"Soukromá SŠ výpočetní techniky (Litvínovská 600, 19000 Praha 9 - Prosek)"], + [512,"Soukromá ZŠ Univerzum (Českolipská 373, 19000 Praha 9)"], + [269,"Soukromé gymnázium ARCUS Praha 9, s. r. o. (Bří Venclíků 1140, 19800 Praha 9)"], + [471,"SPŠ na Proseku (Novoborská 2, 19000 Praha 9)"], + [382,"ZŠ Generála Janouška (Generála Janouška 1006, 19800 Praha)"], + [-1,'Praha Lipence'], + [191,"ZŠ Lipence (Černošická 168, 15531 Praha)"], + ], + 10: [ + [0,'--- Vyber si školu ---'], + [-1,'Domažlice'], + [136,"Gymnázium J. Š. Baara (Pivovarská 323, 34442 Domažlice)"], + [-1,'Klatovy'], + [48,"Gymnázium Jaroslava Vrchlického (Národních mučedníků 347, 33901 Klatovy)"], + [80,"SPŠ Klatovy (nábřeží Kpt. Nálepky 362, 33901 Klatovy 3)"], + [-1,'Plasy'], + [230,"Gymnázium Plasy (Stará cesta 363, 33101 Plasy)"], + [-1,'Plzeň'], + [343,"15. ZŠ (Terezie Brzkové 33-35, 31800 Plzeň)"], + [521,"20. základní škola (Brojova 13, 32600 Plzeň)"], + [527,"21. základná škola (Slovanská alej 13, 32600 Plzeň)"], + [424,"Církevní gymnázium (Mikulášské náměstí 15, 32600 Plzeň)"], + [519,"Gymnázium Franiška Křižíka (Sokolovská 54, 32300 Plzeň)"], + [389,"Gymnázium Luďka Pika (Opavská 21, 31217 Plzeň)"], + [167,"Gymnázium Mikulášské náměstí (Mikulášské náměstí 23, 30154 Plzeň)"], + [175,"Masarykovo gymnázium (Petákova 2, 30100 Plzeň)"], + [520,"Soukromá ZŠ Elementária (Jesenická 11, 32323 Plzeň)"], + [100,"Sportovní gymnázium Plzeň (Táborská 28, 32600 Plzeň)"], + [522,"SPŠ Strojnická a SOŠ Prof. Švejcara (Klatovská 109, 30100 Plzeň)"], + [390,"Střední škola informatiky a finančních služeb (Klatovská 200 G, 30100 Plzeň)"], + [96,"VOŠ a SPŠ elektrotechnická (Koterovská 85, 32600 Plzeň)"], + [-1,'Rokycany'], + [518,"Gymnázium a SOŠ (Mládežníků 1115, 33701 Rokycany)"], + [513,"Gymnázium a SOŠ Rokycany (Mládežníků 1115, 33701 Rokycany)"], + [-1,'Sušice'], + [292,"Gymnázium Sušice (Fr. Procházky 324, 34201 Sušice)"], + [-1,'Tachov'], + [317,"Gymnázium Tachov (Tachov, Pionýrská 1370, 34701 Tachov)"], + [147,"ZŠ Kostelní (Kostelní 583, 34701 Tachov)"], + ], + 11: [ + [0,'--- Vyber si školu ---'], + [-1,'Babice'], + [420,"OPEN GATE - gymnázium a základní škola, s. r. o. (Babice 5, 25101 Říčany u Prahy)"], + [-1,'Benešov'], + [246,"Gymnázium Benešov (Husova 470, 25601 Benešov)"], + [-1,'Beroun'], + [9,"Gymnázium Joachima Barranda (Talichova ulice 824, 26601 Beroun)"], + [-1,'Brandýs nad Labem'], + [169,"Gymnázium J. S. Machara (Královická 668, 25050 Brandýs nad Labem - Stará Boleslav)"], + [554,"Střední zemědělská škola Brandýs nad Label (Zápská 302, 250 01 Brandýs nad Labem)"], + [-1,'Brandýš nad Labem'], + [552,"Střední zemědělská škola Brandýs nad Labem (Zápská 302, 25001 Brandýs nad Labem)"], + [-1,'Čáslav'], + [121,"Gymnázium a SPgŠ (Masarykova 248, 28601 Čáslav)"], + [-1,'Český Brod'], + [337,"Gymnázium Český Brod (Vítězná 616, 28227 Český Brod)"], + [559,"SOŠ Český Brod - Liblice (Školní 145, Český Brod - Liblice)"], + [426,"ZŠ Tyršova (Tyršova 68, 282 01 Český Brod)"], + [-1,'Dobříš'], + [160,"Gymnázium Karla Čapka (Školní 1530, 26301 Dobříš)"], + [-1,'Hořovice'], + [218,"Gymnázium Václava Hraběte (Jiráskova 617, 26801 Hořovice)"], + [-1,'Hostivice'], + [503,"Gymnázium Hostivice (Komenského 141 253 01 Hostivice)"], + [-1,'Kladno'], + [47,"Gymnázium Kladno (náměstí Edvarda Beneše 1573, 27201 Kladno)"], + [432,"SPŠ a VOŠ Kladno (Jana Palacha 1840, 272 01 Kladno)"], + [-1,'Kolín'], + [53,"Gymnázium Kolín (Žižkova 162, 28031 Kolín 3)"], + [378,"SOŠ informatiky a spojů a SOU Kolín (Jaselská 826, 28090 Kolín)"], + [-1,'Kralupy nad Vltavou'], + [8,"Dvořákovo gymnázium a SOŠ ekonomická Kralupy nad Vltavou (Dvořákovo náměstí 800, 27801 Kralupy nad Vltavou)"], + [-1,'Krhanice'], + [346,"ZŠ Krhanice (Krhanice 149, 25742 Krhanice)"], + [-1,'Kutná Hora'], + [168,"Gymnázium Jiřího Ortena (Jaselská 932, 28480 Kutná Hora)"], + [249,"SPŠ Kutná Hora (Masarykova 197, 28411 Kutná hora)"], + [-1,'Mělník'], + [294,"Gymnázium Jana Palacha (Pod Vrchem 3421, 27601 Mělník)"], + [-1,'Mladá Boleslav'], + [422,"Gymnázium Dr. Josefa Pekaře (Palackého 211, 29301 Mladá Boleslav)"], + [272,"Gymnázium Palackého (Palackého 191/1, 29301 Mladá Boleslav)"], + [267,"OA, VOŠE a JŠ s právem SJZ (T. G. Masaryka 14, 29380 Mladá Boleslav)"], + [-1,'Mnichovo Hradiště'], + [77,"Gymnázium Mnichovo Hradiště (Studentská 896, 29501 Mnichovo Hradiště)"], + [-1,'Neratovice'], + [180,"Gymnázium Františka Palackého (Masarykova 450, 27711 Neratovice)"], + [-1,'Nymburk'], + [89,"Gymnázium Bohumila Hrabala v Nymburce (Komenského 779, 28840 Nymburk)"], + [423,"SOŠ a SOU Nymburk (V Kolonii 1804, 28846 Nymburk)"], + [-1,'Poděbrady'], + [214,"Gymnázium Jiřího z Poděbrad (Studentská 166, 29001 Poděbrady)"], + [-1,'Příbram'], + [302,"Gymnázium Příbram (Legionářů 402, 26101 Příbram 7)"], + [-1,'Rakovník'], + [283,"Gymnázium Z. Wintra Rakovník (náměstí Jana Žižky 186, 26901 Rakovník)"], + [223,"Masarykova OA (Pražská 1222, 26920 Rakovník)"], + [-1,'Říčany'], + [296,"Gymnázium Říčany (Komenského nám. 1280, 25101 Říčany)"], + [536,"Masarykovo klasické gymnázium, s.r.o (Táborská 1685/47, 25101, Říčany)"], + [-1,'Sedlčany'], + [64,"Gymnázium a SOŠE (Nádražní 90, 26401 Sedlčany)"], + [-1,'Slaný'], + [277,"Gymnázium Václava Beneše Třebízského (Smetanovo nám. 1310, 27401 Slaný)"], + [-1,'Strančice'], + [464,"ZŠ Strančice (Revoluční 170, 25163 Strančice)"], + [-1,'Vlašim'], + [150,"Gymnázium Vlašim (Tylova 271, 25801 Vlašim)"], + ], + 12: [ + [0,'--- Vyber si školu ---'], + [-1,'Bílina'], + [486,"Gymnázium Bílina (Břežánská 9, Bílina 41801)"], + [-1,'Chomutov'], + [327,"OA, SOŠG a SOU Chomutov (Černovická 2901/26, 43003 Chomutov)"], + [341,"SPŠ a VOŠ Chomutov (Školní 1060/50, 43001 Chomutov)"], + [-1,'Děčín'], + [297,"Gymnázium Děčín (Komenského náměstí 4, 40501 Děčín)"], + [-1,'Kadaň'], + [359,"Gymnázium Kadaň (5. května 620, 43201 Kadaň)"], + [-1,'Klášterec nad Ohří'], + [190,"Gymnázium a SOŠ Klášterec nad Ohří (Chomutovská 459, 43151 Klášterec nad Ohří)"], + [-1,'Krupka'], + [103,"Biskupské gymnázium a ZŠ Bohosudov (Koněvova 34, 41742 Krupka 1)"], + [-1,'Litoměřice'], + [166,"Gymnázium Josefa Jungmanna (Svojsíkova 1, 41201 Litoměřice)"], + [-1,'Litvínov'], + [185,"Gymnázium T. G. Masaryka (Studentská 640, 43667 Litvínov)"], + [146,"SOŠ pro ochranu a obnovu životního prostředí - SCHOLA HUMANITAS (Ukrajinská 379, 43664 Litvínov)"], + [-1,'Litvínov - Hamr'], + [484,"Zš Litvínov - Hamr (Mládežnická 220, 43542 Litvnínov - Hamr)"], + [-1,'Louny'], + [268,"Gymnázium Václava Hlavatého Louny (Poděbradova 661, 44001 Louny)"], + [-1,'Lovosice'], + [549,"Gymnázium Lovosice (Sady Pionýrů 600/6, Lovosice, 41002)"], + [-1,'Meziboří'], + [140,"Střední škola EDUCHEM, a. s. (Okružní 128, 43513 Meziboří)"], + [-1,'Most'], + [86,"Gymnázium Most (Čs. armády 1530, 43446 Most)"], + [447,"VOŠ, OA, SPgŠ a SZŠ Most (Zdeňka Fibicha 2778, 43401 Most)"], + [-1,'Podbořany'], + [442,"Gymnázium a SOŠ Podbořany (Kpt. Jaroše 862, 44128 Podbořany)"], + [-1,'Roudnice nad Labem'], + [145,"Gymnázium Roudnice nad Labem (Havlíčkova 175, 41311 Roudnice nad Labem)"], + [-1,'Rumburk'], + [458,"Gymnázium Rumburk (Komenského 10, Rumburk)"], + [-1,'Teplice'], + [288,"Gymnázium Teplice (Čs. Dobrovolců 530/11, 41502 Teplice)"], + [291,"Střední škola technická AGC a. s. (Rooseveltovo nám. 5, 41503 Teplice 3)"], + [-1,'Ústí nad Labem'], + [483,"Gymnázium a SOŠ dr. V. Šmejakala (Stavbařů 5, 40011 Ústí nad Labem)"], + [129,"Gymnázium Ústí nad Labem (Jateční 22, 40001 Ústí nad Labem)"], + [295,"SPŠ strojní a elektrotechnická Resslova (Resslova 5, 40001 Ústí nad Labem)"], + [-1,'Varnsdorf'], + [385,"VOŠ a SŠ Varnsdorf (Bratislavská 2166, 40747 Varnsdorf)"], + [-1,'Žatec'], + [306,"Gymnázium Žatec (Studentská 1075, 43801 Žatec)"], + ], + 13: [ + [0,'--- Vyber si školu ---'], + [-1,'Bystřice nad Pernštejnem'], + [505,"Gymnázium Bystřice nad Pernštejnem (Nádražní 760, 59301 Bystřice nad Pernštejnem)"], + [-1,'Havlíčkův Brod'], + [315,"Gymnázium Havlíčkův Brod (Štáflova 2063, 58001 Havlíčkův Brod)"], + [165,"Havlíčkovo gymnázium (Štáflova 2063, 58001 Havlíčkův Brod)"], + [-1,'Humpolec'], + [20,"Gymnázium dr. A. Hrdličky (Komenského 147, 39601 Humpolec)"], + [-1,'Jihlava'], + [46,"Gymnázium Jihlava (Jana Masaryka 1, 58601 Jihlava)"], + [258,"Soukromé gymnázium AD FONTES, o. p. s. (Fibichova 18, 58601 Jihlava)"], + [78,"SPŠ Jihlava (tř. Legionářů 3, 58601 Jihlava)"], + [-1,'Ledeč nad Sázavou'], + [51,"Gymnázium SOŠ a VOŠ (Husovo náměstí 1, 58401 Ledeč nad Sázavou)"], + [-1,'Moravské Budějovice'], + [116,"Gymnázium a SOŠ Moravské Budějovice (Tyršova 365, 67619 Moravské Budějovice)"], + [-1,'Nové Město na Moravě'], + [117,"Gymnázium V. Makovského (Leandra Čecha 152, 59231 Nové Město na Moravě)"], + [-1,'Pelhřimov'], + [61,"Gymnázium Pelhřimov (Jirsíkova 244, 39301 Pelhřimov)"], + [394,"SPŠ a Střední odborné učiliště Pelhřimov (Friedova 1469, 39301 Pelhřimov)"], + [-1,'Světlá nad Sázavou'], + [95,"VOŠ, Gymnázium a SOŠ umělockoprůmyslová (Sázavská 547, 58291 Světlá nad Sázavou)"], + [197,"ZŠ Světlá nad Sázavou (Komenského 234, 58291 Světlá nad Sázavou)"], + [-1,'Telč'], + [284,"Gymnázium Otokara Březiny a SOŠ Telč (Hradecká 235, 58856 Telč)"], + [-1,'Třebíč'], + [102,"Gymnázium Třebíč (Masarykovo nám. 116/9, 67401 Třebíč)"], + [72,"SPŠ technická Třebíč (Manželů Curieových 734, 67401 Třebíč)"], + [-1,'Velké Meziříčí'], + [393,"Gymnázium Velké Meziříčí (Sokolovská 27/235, 59401 Velké Meziříčí)"], + [-1,'Žďár nad Sázavou'], + [534,"Biskupské gymnázium (U Klafárku 3, Žďár nad Sázavou 59101)"], + [-1,'Ždár nad Sázavou'], + [542,"Biskupské gymnázium (U Klafárku 3, Žďár nad Sázavou)"], + [-1,'Žďár nad Sázavou'], + [44,"Gymnázium Žďár nad Sázavou (Neumannova 2, 59101 Žďár nad Sázavou)"], + [504,"VOŠ a SPŠ Žďár nad Sázavou (Studentská 1, 59101 Žďár nad Sázavou)"], + [-1,'Ždár nad Sázavou'], + [472,"Základní škola Komenského 2 (Komenského 2, 59101 Žďár nad Sázavou)"], + [-1,'Ždírec nad Doubravou'], + [462,"ZŠ a MŠ Ždírec nad Doubravou (Chrudimská 77, 58263 Ždírec nad Doubravou)"], + ], + 14: [ + [0,'--- Vyber si školu ---'], + [-1,'Březová'], + [561,"Školy Březová – SOŠ, ZŠ a MŠ (Březová 102, 687 67 Březová)"], + [-1,'Dolní Němčí'], + [200,"ZŠ a ZUŠ Dolní Němčí (Školní 606, 68762 Dolní Němčí)"], + [-1,'Holešov'], + [13,"Gymnázium Ladislava Jaroše (Palackého 524, 76901 Holešov)"], + [-1,'Kroměříž'], + [476,"Arcibiskupské gymnázium v Kroměříži (Pilařova 3, 76701 Kroměříž)"], + [49,"Gymnázium Kroměříž (Masarykovo náměstí 496, 76701 Kroměříž)"], + [-1,'Kunovice'], + [224,"Soukromé gymnázium, SOŠ a jazyková škola, s. r. o. (Osvobození 699, 68604 Kunovice)"], + [-1,'Otrokovice'], + [192,"Gymnázium Otrokovice (třída Spojenců 907, 76513 Otrokovice)"], + [238,"SPŠ Otrokovice (třída T. Bati 331, 76502 Otrokovice)"], + [-1,'Rožnov pod Radhoštěm'], + [134,"Gymnázium Rožnov pod Radhoštěm (Koryčanské Paseky 1725, 75661 Rožnov pod Radhoštěm)"], + [144,"SŠ informatiky, elektroniky a řemesel (Školní 1610, 75661 Rožnov pod Radhoštěm)"], + [-1,'Slavičín'], + [122,"Gymnázium Jana Pivečky Slavičín (Školní 822, 76321 Slavičín)"], + [-1,'Uherské Hradiště'], + [97,"Gymnázium Uherské Hradiště (Velehradská třída 218, 68601 Uherské Hradiště)"], + [256,"SŠ průmyslová, hotelová a zdravotnická Uherské Hradiště (Kollárova 617, 68601 Uherské Hradiště)"], + [-1,'Uherský Brod'], + [35,"Gymnázium J. A. Komenského a Jaz. škola Uherský Brod (Komenského 169, 68801 Uherský Brod)"], + [-1,'Valašské Klobouky'], + [69,"Gymnázium Valašské Klobouky (Komenského 60, 76601 Valašské Klobouky)"], + [189,"ZŠ Valašské Klobouky (Školní 856, 76601 Valašské Klobouky)"], + [-1,'Valašské Meziříčí'], + [201,"Gymnázium Františka Palackého (Husova 146, 75737 Valašské Meziříčí)"], + [-1,'Vsetín'], + [152,"Masarykovo gymnázium a jazyková škola s právem SJZ Vsetín (Tyršova 1069, 75501 Vsetín)"], + [181,"SPŠ strojnická Vsetín (Pod Strání 1776, 75515 Vsetín)"], + [-1,'Zlín'], + [220,"Gymnázium a Jazyková škola s právem SJZ Zlín (náměstí T. G. Masaryka 2734, 76001 Zlín)"], + [113,"Gymnázium Zlín - Lesní čtvrť (Lesní čtvrť 1364, 76137 Zlín)"], + [176,"SPŠ Zlín (třída Tomáše Bati 4187, 76247 Zlín)"], + [560,"Střední škola filmová, multimediální a počítačových technologií, s.r.o. (Filmová 174, 76001 Zlín)"], + ], + 15: [ + [0,'--- Vyber si školu ---'], + [-1,'Bratislava'], + [164,"Gymnázium Bratislava (Grösslingova 18, 81109 Bratislava 1)"], + [413,"Gymnázium Jána Papánka (Vazovova 6, 81107 Bratislava 1)"], + [526,"Gymnázium Jura Hronca (Novohradská 3, 82109 Bratislava)"], + [177,"Gymnázium Matky Alexie (Jesenského 4, 81102 Bratislava 1)"], + [506,"Gymnázium Metodova (Metodova 2, Bratislava)"], + [452,"Gymnazium ul. Ladislava Sáru (Ladislava Sáru 1, Bratislava)"], + [373,"Prvé súkromné gymnázium (Bajkalská 20, 82108 Bratislava)"], + [329,"Škola pre mimoriadne nadané deti a gymnázium (Teplická 7, 83102 Bratislava)"], + [453,"SpŠ sv. Františka z Assisi (Karloveská 32, Bratislava)"], + [-1,'Pezinok'], + [438,"Gymnázium Pezinok (Senecká 2, 90201 Pezinok)"], + ], + 16: [ + [0,'--- Vyber si školu ---'], + [-1,'Banská Bystrica'], + [110,"Gymnázium J. G. Tajovského (Tajovského 25, 97401 Banská Bystrica)"], + [-1,'Brezno'], + [265,"SPŠ Brezno (Laskomerského 3, 97746 Brezno)"], + [-1,'Krupina'], + [489,"Gymnázium Andreja Sládkoviča (Milana Rastislava Štefánika 8, 96301 Krupina)"], + [-1,'Lučenec'], + [529,"Cirkevná základná škola sv. Jána Bosca (T. G. Masaryka 9, 98401 Lučenec)"], + [525,"Církevná ZŠ sv. Jána Bosca (T. G. Masaryka 9, 98401 Lučenec)"], + [158,"Gymnázium B. S. Timravy (Haličská cesta 9, 98403 Lučenec)"], + [-1,'Zvolen'], + [123,"Gymnázium Ľudovíta Štúra (Hronská 1467/3, 96049 Zvolen)"], + ], + 17: [ + [0,'--- Vyber si školu ---'], + [-1,'Košice'], + [45,"Gymnázium Alejová (Alejová 1, 04149 Košice)"], + [219,"Gymnázium M. R. Štefánika (Námestie L. Novomeského 4, 04224 Košice)"], + [430,"Gymnázium Park mládeže (Park mládeže 5, 04001 Košice)"], + [42,"Gymnázium Poštová (Poštová 9, 04001 Košice)"], + [307,"Gymnázium Šrobárova (Šrobárova 1, 04001 Košice)"], + [250,"Gymnázium Zbrojničná (Zbrojničná 3, 04001 Košice)"], + [345,"SPŠ elektrotechnická (Komenského 44, 04001 Košice)"], + [179,"SPŠ hutnícka (Alejová 1, 04011 Košice)"], + [-1,'Michalovce'], + [2,"Gymnázium Pavla Horova (Masarykova 1, 07179 Michalovce)"], + [142,"Stredná odborná škola technická (Partizánska 1, 07192 Michalovce)"], + [-1,'Rožňava'], + [178,"Gymnázium P. J. Šafárika (Akademika Hronca 1, 04801 Rožňava)"], + [-1,'Sobrance'], + [431,"Gymnázium Sobrance (Kpt. Nálepku 6, 07301 Sobrance)"], + [-1,'Spišská Nová Ves'], + [255,"Gymnázium Spišská Nová Ves (Školská 7, 05201 Spišská Nová Ves)"], + [-1,'Trebišov'], + [98,"Gymnázium Trebišov (Komenského 32, 07501 Trebišov)"], + [-1,'Veľké Kapušany'], + [93,"Gymnázium Veľké Kapušany (Zoltána Fábryho 1, 00791 Veľké Kapušany)"], + ], + 18: [ + [0,'--- Vyber si školu ---'], + [-1,'Levice'], + [243,"Gymnázium Andreja Vrábla (Mierová 5, 93403 Levice)"], + [-1,'Nitra'], + [37,"Gymnázium Golianova (Golianova 68, 95050 Nitra)"], + [99,"Gymnázium Párovská (Párovská 1, 95050 Nitra)"], + [138,"Gymnázium sv. Cyrila a Metóda (Farská 19, 94901 Nitra)"], + [229,"Piaristické gymnázium sv. J. Kalazanského (Piaristická 6, 94901 Nitra)"], + [320,"SPŠ Fraňa Kráľa (Fraňa Kráľa 20, 94901 Nitra)"], + [-1,'Nové Zámky'], + [300,"Gymnázium Nové Zámky (M. R. Štefánika 16, 94061 Nové Zámky)"], + [60,"Gymnázium Nové Zámky (M. R. Štefánika 16, 94061 Nové Zámky)"], + [429,"SPŠE S. A. Jedlíka a OA (Komárňanská 28, 94075 Nové Zámky)"], + [-1,'Šaľa'], + [439,"Gymnázium Juraja Fándlyho (Školská 3, 92701 Šaľa)"], + [-1,'Želiezovce'], + [215,"Gymnázium J. A. Komenského s VJM (Komenského 1, 93701 Želiezovce)"], + ], + 19: [ + [0,'--- Vyber si školu ---'], + [-1,'Bardejov'], + [487,"Gymnázium Leonarda Stöckela (Jiráskova 12, 08570 Bardejov)"], + [-1,'Poprad'], + [273,"Gymnázium Kukučínova (Kukučínova 4239/1, 05839 Poprad)"], + [445,"Spojená škola Dominika Tatarku (Dominika Tatarku 4666/7, 05801 Poprad)"], + [428,"Súkromná SOŠ Tatranská Akadémia (Ul. 29 augusta 4812, Poprad)"], + [-1,'Prešov'], + [239,"Gymnázium J. A. Raymana (Mudroňova 20, 08193 Prešov)"], + [62,"Gymnázium Konštantínova (Konštantínova 2, 08065 Prešov)"], + [280,"Gymnázium Sv. Mikuláša (Duklianská 16, 08001 Prešov)"], + [23,"Gymnázium svätej Moniky (Tarasa Ševčenka 1, 08001 Prešov)"], + [4,"Gymnázium T. Ševčenku s VJU (Sládkovičova 4, 08001 Prešov)"], + [32,"SPŠ elektrotechnická (Plzenská 1, 08047 Prešov)"], + [-1,'Sabinov'], + [261,"Gymnázium Antona Prídavka (Komenského 40, 08301 Sabinov)"], + [-1,'Stará Ľubovňa'], + [386,"Gymnázium Terézie Vansovej (17. novembra 6, 06401 Stará Ľubovňa)"], + [-1,'Svidník'], + [108,"Gymnázium duklianských hrdinov (Komenského 16, 08901 Svidník)"], + [-1,'Vranov'], + [262,"Gymnázium vo Vranove nad Topľou (Dr. C. Daxnera 88/3, 09380 Vranov nad Topľou)"], + ], + 20: [ + [0,'--- Vyber si školu ---'], + [-1,'Bánovce nad Bebravou'], + [410,"Gymnázium Janka Jesenského (Radlinského 665/2, 95701 Bánovce nad Bebravou)"], + [-1,'Dubnica nad Váhom'], + [253,"Gymnázium Dubnica nad Váhom (Školská 2, 01841 Dubnica nad Váhom)"], + [206,"Stredná priemyselná škola (Obrancov mieru 343/1, 01841 Dubnica nad Váhom)"], + [-1,'Myjava'], + [402,"SPŠ Myjava (Ul. SNP 413/8, 90701 Myjava)"], + [-1,'Nové Mesto nad Váhom'], + [26,"Gymnázium M. R. Štefánika (Športová 41, 91501 Nové Mesto nad Váhom)"], + [-1,'Partizánske'], + [468,"Gymnázium (Komenského 2/1074, 95801 Partizánske)"], + [-1,'Považská Bystrica'], + [159,"Gymnázium Považská Bystrica (Školská 234/8, 01701 Považská Bystrica)"], + [354,"SOŠ strojnícka (Športovcov 341/2, 01749 Považská Bystrica)"], + [-1,'Prievidza'], + [313,"Gymnázium V. B. Nedožerského (Matice slovenskej 16, 97101 Prievidza)"], + [-1,'Púchov'], + [311,"Gymnázium Púchov (Ul. 1. mája 905, 02015 Púchov)"], + [-1,'Stará Turá'], + [372,"Združená stredná škola elektrotechnická (Športová 675, 91601 Stará Turá)"], + [-1,'Trenčín'], + [5,"Gymnázium Ľudovíta Štúra (Ul. 1. mája 2, 91135 Trenčín)"], + ], + 21: [ + [0,'--- Vyber si školu ---'], + [-1,'Galanta'], + [478,"Gymnázium Janka Matúšku (Štvrť SNP 1004/43, 92401 Galanta)"], + [-1,'Hlohovec'], + [408,"Gymnázium Ivana Kupca (Komenského 211/13, 92001 Hlohovec)"], + [-1,'Piešťany'], + [112,"Gymnázium Pierra de Coubertina (Námestie SNP 9, 92126 Piešťany)"], + [-1,'Sereď'], + [395,"Gymnázium Vojtecha Mihálika Sereď (Kostolná 119, 92601 Sereď)"], + [-1,'Trnava'], + [467,"Gymnázium Angely Merici (Hviezdoslavova 10, 91701 Trnava)"], + [434,"SPŠ Komenského (Komenského 1, 91731 Trnava)"], + ], + 22: [ + [0,'--- Vyber si školu ---'], + [-1,'Čadca'], + [18,"Gymnázium J. M. Hurbana (17. novembra 1296, 02201 Čadca)"], + [-1,'Liptovský Hrádok'], + [436,"Gymnázium Liptovský Hrádok (Hradná 23, 03301 Liptovský Hrádok)"], + [-1,'Liptovský Mikuláš'], + [369,"Evanjelická spojená škola (Komenského 10, 03101 Liptovský Mikuláš)"], + [473,"Gymnázium M. M. Hodžu (Hodžova 860/9, 03136 Liptovský Mikuláš)"], + [-1,'Martin'], + [52,"Gymnázium V. P. Tótha (Malá Hora 3, 03601 Martin)"], + [-1,'Námestovo'], + [222,"Gymnázium A. Bernoláka (Mieru 307/23, 02901 Námestovo)"], + [-1,'Sučany'], + [141,"Bilingválne gymnázium Milana Hodžu (Komenského 215, 03852 Sučany)"], + [-1,'Trstená'], + [480,"Gymnázium Martina Hattalu v Trstenej (železničiarov 276, 02801 Trstená)"], + [-1,'Žilina'], + [54,"Gymnázium sv. Františka z Assisi (Hurbanova 44, 01001 Žilina)"], + [510,"Gymnázium Varšavská cesta 1 (Varšavská cesta 1, 010 08, Žilina)"], + [308,"Gymnázium Veľká okružná (Veľká okružná 22, 01001 Žilina)"], + [446,"Súkromné gymnázium Oravská (Oravska 11, 01001 Žilina)"], + ], + 23: [ + [0,'--- Vyber si školu ---'], + [-1,'Bath'], + [248,"Prior Park College (Ralph Allen Drive, Combe Down, Bath, BA25AH, United Kingdom)"], + [-1,'Bertrange'], + [547,"European School Luxembourg 2 (6 Rue Gaston Thorn L-8268 Bertrange)"], + [-1,'Dollar'], + [466,"Dollar Academy (Dollar, Clackmannanshire FK14 7DU, United Kingdom)"], + [-1,'Kyjev'], + [540,"Kyiv Natural Science Lyceum №145 (46 Shota Rustaveli Street, Kyiv, 01033, Ukraine)"], + [-1,'New Delhi'], + [371,"American Embassy School (Chandragupta Marg, Chanakyapuri, 110021 New Delhi)"], + [-1,'Neznámé'], + [414,"Neuvedená škola (Neuvedena)"], + [-1,'Vilnius'], + [541,"American International School of Vilnius (Subačiaus 41, Vilnius LT-11350, Lithuania)"], + ], +}; + + +function fill_options(sel, opts) +{ + while (sel.length > 0) { + sel.remove(sel.length-1); + } + while (sel.hasChildNodes()) { + sel.removeChild(sel.firstChild); + } + + var group = null; + for (i = 0; i < opts.length; i++) { + if (opts[i][0] < 0) { + group = document.createElement('optgroup'); + group.label = opts[i][1]; + sel.appendChild(group); + } else { + var opt = document.createElement('option'); + opt.value = opts[i][0]; + opt.text = opts[i][1]; // + ' (' + opts[i][0] + ')'; + if (group) { + group.appendChild(opt); + } else { + sel.add(opt, null); + } + } + } +} + +function region_changed() +{ + var reg = document.getElementById('id_kraj_select'); + var sch = document.getElementById('id_skola_select'); + var r = reg[reg.selectedIndex].value; + fill_options(sch, schools[r]); +} + +function country_changed() +{ + var ctry = document.getElementById('id_skola_stat_select'); + var reg = document.getElementById('id_kraj_select'); + var c = ctry[ctry.selectedIndex].value; + fill_options(reg, regions[c]); + region_changed(); +} + +function set_region_and_school(rid, sid) +{ + var ctry = document.getElementById('id_skola_stat_select'); + var c = ctry[ctry.selectedIndex].value; + var rr = regions[c]; + for (i=0; i= 0) { + cnt++; + } + } +} diff --git a/seminar/templates/seminar/prihlaska.html b/seminar/templates/seminar/prihlaska.html index 9e5fbbc8..28eb81b1 100644 --- a/seminar/templates/seminar/prihlaska.html +++ b/seminar/templates/seminar/prihlaska.html @@ -1,6 +1,10 @@ {% extends "seminar/zadani/base.html" %} {% load staticfiles %} +{% block script %} + +{% endblock %} + {% block content %}

{% block nadpis1a %}{% block nadpis1b %} @@ -25,6 +29,11 @@ + {% endblock %} From c57b99c015e2c8a54a1cd28cabce4ec3c1ee7889 Mon Sep 17 00:00:00 2001 From: "Tomas \"Jethro\" Pokorny" Date: Sat, 31 Aug 2019 19:36:12 +0200 Subject: [PATCH 20/92] Vytvareni osoby, usera a resitele pri registraci. --- seminar/forms.py | 25 +++++++++-------- seminar/views.py | 73 ++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 79 insertions(+), 19 deletions(-) diff --git a/seminar/forms.py b/seminar/forms.py index 2bc3ecee..d2a710cb 100644 --- a/seminar/forms.py +++ b/seminar/forms.py @@ -4,7 +4,9 @@ from seminar.models import Resitel class PrihlaskaForm(forms.Form): jmeno = forms.CharField(label='Jméno', max_length=256, required=True) prijmeni = forms.CharField(label='Příjmení', max_length=256, required=True) - pohlavi = forms.ChoiceField(label='Pohlaví', + username = forms.CharField(label='Přihlašovací jméno', max_length=256, required=True) + # TODO heslo? + pohlavi_muz = forms.ChoiceField(label='Pohlaví', choices = ((True,'muž'),(False,'žena')), required=True) email = forms.EmailField(label='E-mail',max_length=256, required=True) telefon = forms.CharField(label='Telefon',max_length=256, required=False) @@ -19,23 +21,24 @@ class PrihlaskaForm(forms.Form): required=False) - skola_stat_select = forms.ChoiceField(label='Stát', - choices = (('cz', 'Česká Republika'), - ('sk', 'Slovenská Republika'), - ('other', 'Jiné')), - required=True) - kraj_select = forms.ChoiceField(label='Kraj',required=True) - skola_select = forms.ChoiceField(label='Škola',required=True) +# skola_stat_select = forms.ChoiceField(label='Stát', +# choices = (('cz', 'Česká Republika'), +# ('sk', 'Slovenská Republika'), +# ('other', 'Jiné')), +# required=True) +# kraj_select = forms.ChoiceField(label='Kraj',required=True) +# skola_select = forms.ChoiceField(label='Škola',required=True) #kraj #škola - trida = forms.CharField(label='Třída',max_length=10, required=True) +# trida = forms.CharField(label='Třída',max_length=10, required=True) #název školy #adresa školy - skola_nazev = forms.CharField(label='Název školy', max_length=256, required=False) - skola_adresa = forms.CharField(label='Adresa školy', max_length=256, required=False) +# skola_nazev = forms.CharField(label='Název školy', max_length=256, required=False) +# skola_adresa = forms.CharField(label='Adresa školy', max_length=256, required=False) rok_maturity = forms.IntegerField(label='Rok maturity', min_value=2019, required=True) zasilat = forms.ChoiceField(label='Kam zasílat čísla a řešení',choices = Resitel.ZASILAT_CHOICES, required=True) gdpr = forms.BooleanField(label='Souhlasím se zpracováním osobních údajů', required=True) + spam = forms.BooleanField(label='Souhlasím se zasíláním materiálů od MFF UK', required=False) diff --git a/seminar/views.py b/seminar/views.py index f0f6049d..d64ce300 100644 --- a/seminar/views.py +++ b/seminar/views.py @@ -9,9 +9,9 @@ from django.utils.translation import ugettext as _ from django.http import Http404,HttpResponseBadRequest,HttpResponseRedirect from django.db.models import Q from django.views.decorators.csrf import ensure_csrf_cookie -from django.contrib.auth import authenticate, login +from django.contrib.auth import authenticate, login, get_user_model -from .models import Problem, Cislo, Reseni, Nastaveni, Rocnik, Soustredeni, Organizator, Resitel, Novinky, Soustredeni_Ucastnici, Pohadka, Tema, Clanek +from .models import Problem, Cislo, Reseni, Nastaveni, Rocnik, Soustredeni, Organizator, Resitel, Novinky, Soustredeni_Ucastnici, Pohadka, Tema, Clanek, Osoba #from .models import VysledkyZaCislo, VysledkyKCisluZaRocnik, VysledkyKCisluOdjakziva from . import utils from .unicodecsv import UnicodeWriter @@ -951,15 +951,72 @@ def texDownloadView(request, rocnik, cislo): ## Formulare def prihlaskaView(request): - # if this is a POST request we need to process the form data if request.method == 'POST': - # create a form instance and populate it with data from the request: form = PrihlaskaForm(request.POST) - # check whether it's valid: + # TODO vyresit, co se bude v jakych situacich zobrazovat if form.is_valid(): - # process the data in form.cleaned_data as required - # ... - # redirect to a new URL: + print("Form valid") + try: + # mame jiz email v databazi? + o = Osoba.objects.get(email=form.cleaned_data['email']) + print("Email existuje: {}".format(form.cleaned_data)) + # TODO seřvat a nepustit dál + return HttpResponseRedirect('/thanks/') + except ObjectDoesNotExist: + pass + + User = get_user_model() + try: + u = User.objects.get(username=form.cleaned_data['username']) + print("Username existuje: {}".format(form.cleaned_data)) + # TODO seřvat a nepustit dál + return HttpResponseRedirect('/thanks/') + + except ObjectDoesNotExist: + pass + + u = User(username=form.cleaned_data['username']) + u.save() + + o = Osoba( + jmeno = form.cleaned_data['jmeno'], + prijmeni = form.cleaned_data['prijmeni'], + pohlavi_muz = form.cleaned_data['pohlavi_muz'], + email = form.cleaned_data['email'], + telefon = form.cleaned_data.get('telefon',''), + datum_narozeni = form.cleaned_data.get('datum_narozeni',None), + datum_souhlasu_udaje = date.today(), + datum_registrace = date.today(), + ulice = form.cleaned_data.get('ulice',''), + mesto = form.cleaned_data.get('mesto',''), + psc = form.cleaned_data.get('psc',''), + poznamka = str(form.cleaned_data) + ) + if form.cleaned_data.get('spam',False): + o.datum_souhlasu_zasilani = date.today() + if form.cleaned_data.get('stat','') in ('CZ','SK'): + o.stat = form.cleaned_data['stat'] + else: + pass + #TODO jak budeme resit jine staty? + + o.save() + o.user = u + o.save() + + r = Resitel( + rok_maturity = form.cleaned_data['rok_maturity'], + zasilat = form.cleaned_data['zasilat'] + ) + + r.save() + r.osoba = o + #TODO doplnit skolu + r.save() + + + # TODO logovat jednotlive validni formulare do souboru + print(form.cleaned_data) return HttpResponseRedirect('/thanks/') # if a GET (or any other method) we'll create a blank form From 9b78920dd4626470b8c3a3af1569a6c62efce932 Mon Sep 17 00:00:00 2001 From: "Tomas \"Jethro\" Pokorny" Date: Sat, 31 Aug 2019 22:16:16 +0200 Subject: [PATCH 21/92] Odstranen autocomplete v2, pridan v3. Autocomplete light v galerii nahrazen nativnim admin autocompletem. Pridan autocomplete light v3 pro vyber skoly v prihlasce. --- galerie/admin.py | 4 ++-- ....py => autocomplete_light_registry.py.old} | 0 mamweb/settings_common.py | 3 ++- mamweb/templates/admin/base_site.html | 1 - mamweb/templates/base.html | 1 - mamweb/urls.py | 1 - requirements.txt | 2 +- ....py => autocomplete_light_registry.py.old} | 0 seminar/forms.py | 10 +++++++++ seminar/templates/seminar/prihlaska.html | 4 ++++ seminar/urls.py | 1 + seminar/views.py | 22 +++++++++++++++++-- 12 files changed, 40 insertions(+), 9 deletions(-) rename galerie/{autocomplete_light_registry.py => autocomplete_light_registry.py.old} (100%) rename seminar/{autocomplete_light_registry.py => autocomplete_light_registry.py.old} (100%) diff --git a/galerie/admin.py b/galerie/admin.py index 98c83ea9..f0ac6e28 100644 --- a/galerie/admin.py +++ b/galerie/admin.py @@ -5,7 +5,6 @@ from django.contrib import admin from django.http import HttpResponseRedirect from django import forms from django.db import models -from autocomplete_light import shortcuts as autocomplete_light # akction @@ -39,11 +38,12 @@ class GalerieInline(admin.TabularInline): class ObrazekAdmin(admin.ModelAdmin): list_display = ('obrazek_velky', 'nazev', 'popis', 'obrazek_maly_tag') + search_fields = ['nazev','popis'] class GalerieAdmin(admin.ModelAdmin): - form = autocomplete_light.modelform_factory(Galerie, autocomplete_fields=['titulni_obrazek'], fields=['titulni_obrazek']) model = Galerie fields = ('zobrazit', 'nazev', 'titulni_obrazek', 'popis', 'galerie_up', 'soustredeni', 'poradi') + autocomplete_fields = ['titulni_obrazek'] list_display = ('nazev', 'soustredeni', 'galerie_up', 'poradi', 'zobrazit', 'datum_zmeny') inlines = [GalerieInline] actions = [zverejnit_fotogalerii, prepnout_fotogalerii_do_org_rezimu] diff --git a/galerie/autocomplete_light_registry.py b/galerie/autocomplete_light_registry.py.old similarity index 100% rename from galerie/autocomplete_light_registry.py rename to galerie/autocomplete_light_registry.py.old diff --git a/mamweb/settings_common.py b/mamweb/settings_common.py index ce471e70..e686fcd6 100644 --- a/mamweb/settings_common.py +++ b/mamweb/settings_common.py @@ -103,7 +103,8 @@ INSTALLED_APPS = ( 'ckeditor', 'ckeditor_uploader', 'taggit', - 'autocomplete_light', + 'dal', + 'dal_select2', 'fluent_comments', 'crispy_forms', diff --git a/mamweb/templates/admin/base_site.html b/mamweb/templates/admin/base_site.html index 2b364bca..7e8707ef 100644 --- a/mamweb/templates/admin/base_site.html +++ b/mamweb/templates/admin/base_site.html @@ -4,7 +4,6 @@ {% block extrahead %} -{% include 'autocomplete_light/static.html' %} {% endblock %} {% block branding %} diff --git a/mamweb/templates/base.html b/mamweb/templates/base.html index aeb5f51b..208f797f 100644 --- a/mamweb/templates/base.html +++ b/mamweb/templates/base.html @@ -11,7 +11,6 @@ - {% include 'autocomplete_light/static.html' %} diff --git a/mamweb/urls.py b/mamweb/urls.py index 6294fac4..0c8877a2 100644 --- a/mamweb/urls.py +++ b/mamweb/urls.py @@ -11,7 +11,6 @@ urlpatterns = [ # Admin a nastroje path('admin/', admin.site.urls), # NOQA path('ckeditor/', include('ckeditor_uploader.urls')), - path('autocomplete/', include('autocomplete_light.urls')), # Seminarova aplikace (ma vlastni podadresare) path('', include('seminar.urls')), diff --git a/requirements.txt b/requirements.txt index 2bcec862..99794896 100644 --- a/requirements.txt +++ b/requirements.txt @@ -22,7 +22,7 @@ django-solo django-ckeditor django-flat-theme django-taggit -django-autocomplete-light==2.3.6 +django-autocomplete-light django-crispy-forms django-imagekit django-polymorphic diff --git a/seminar/autocomplete_light_registry.py b/seminar/autocomplete_light_registry.py.old similarity index 100% rename from seminar/autocomplete_light_registry.py rename to seminar/autocomplete_light_registry.py.old diff --git a/seminar/forms.py b/seminar/forms.py index d2a710cb..b0aa6f72 100644 --- a/seminar/forms.py +++ b/seminar/forms.py @@ -1,6 +1,12 @@ from django import forms +from dal import autocomplete +from .models import Skola + from seminar.models import Resitel + + + class PrihlaskaForm(forms.Form): jmeno = forms.CharField(label='Jméno', max_length=256, required=True) prijmeni = forms.CharField(label='Příjmení', max_length=256, required=True) @@ -20,6 +26,10 @@ class PrihlaskaForm(forms.Form): ('other', 'Jiné')), required=False) + skola = forms.ModelChoiceField( + queryset=Skola.objects.all(), + widget=autocomplete.ModelSelect2(url='autocomplete_skola') + ) # skola_stat_select = forms.ChoiceField(label='Stát', # choices = (('cz', 'Česká Republika'), diff --git a/seminar/templates/seminar/prihlaska.html b/seminar/templates/seminar/prihlaska.html index 28eb81b1..35e49163 100644 --- a/seminar/templates/seminar/prihlaska.html +++ b/seminar/templates/seminar/prihlaska.html @@ -1,8 +1,10 @@ {% extends "seminar/zadani/base.html" %} {% load staticfiles %} +{% load static %} {% block script %} + {% endblock %} {% block content %} @@ -35,5 +37,7 @@ $("#id_kraj_select").on("change",region_changed); //$("#id_skola_stat_select").on("change",country_changed); +{{form.media}} + {% endblock %} diff --git a/seminar/urls.py b/seminar/urls.py index d3b8c645..a8d4ff76 100644 --- a/seminar/urls.py +++ b/seminar/urls.py @@ -100,6 +100,7 @@ urlpatterns = [ path('prihlaska/',views.prihlaskaView), path('', views.TitulniStranaView.as_view(), name='titulni_strana'), + path('autocomplete/skola/',views.SkolaAutocomplete.as_view(), name='autocomplete_skola') # Ceka na autocomplete v3 # path('autocomplete/organizatori/', # staff_member_required(views.OrganizatorAutocomplete.as_view()), diff --git a/seminar/views.py b/seminar/views.py index d64ce300..69d110b0 100644 --- a/seminar/views.py +++ b/seminar/views.py @@ -10,8 +10,9 @@ from django.http import Http404,HttpResponseBadRequest,HttpResponseRedirect from django.db.models import Q from django.views.decorators.csrf import ensure_csrf_cookie from django.contrib.auth import authenticate, login, get_user_model +from dal import autocomplete -from .models import Problem, Cislo, Reseni, Nastaveni, Rocnik, Soustredeni, Organizator, Resitel, Novinky, Soustredeni_Ucastnici, Pohadka, Tema, Clanek, Osoba +from .models import Problem, Cislo, Reseni, Nastaveni, Rocnik, Soustredeni, Organizator, Resitel, Novinky, Soustredeni_Ucastnici, Pohadka, Tema, Clanek, Osoba, Skola #from .models import VysledkyZaCislo, VysledkyKCisluZaRocnik, VysledkyKCisluOdjakziva from . import utils from .unicodecsv import UnicodeWriter @@ -1011,7 +1012,11 @@ def prihlaskaView(request): r.save() r.osoba = o - #TODO doplnit skolu + if form.cleaned_data.get('skola'): + r.skola = form.cleaned_data['skola'] + else: + pass + #TODO doplnit skolu, kdyz neni v seznamu r.save() @@ -1025,6 +1030,19 @@ def prihlaskaView(request): return render(request, 'seminar/prihlaska.html', {'form': form}) +class SkolaAutocomplete(autocomplete.Select2QuerySetView): + def get_queryset(self): + # Don't forget to filter out results depending on the visitor ! + qs = Skola.objects.all() + if self.q: + qs = qs.filter( + Q(nazev__istartswith=self.q)| + Q(kratky_nazev__istartswith=self.q)| + Q(ulice__istartswith=self.q)| + Q(mesto__istartswith=self.q)) + + return qs + # Ceka na autocomplete v3 # class OrganizatorAutocomplete(autocomplete.Select2QuerySetView): # def get_queryset(self): From 6ad9cc5e0c90af01ab2eed36c0e1a120608ce7ef Mon Sep 17 00:00:00 2001 From: "Tomas \"Jethro\" Pokorny" Date: Sun, 1 Sep 2019 16:35:20 +0200 Subject: [PATCH 22/92] Prace na prihlasce, bugfixy. Prihlaska uz je pomerne funkcni. MatJax presunut na jine CDN (stezoval si). --- .gitignore | 2 +- mamweb/settings_common.py | 10 + mamweb/templates/base.html | 4 +- seminar/forms.py | 60 +- seminar/static/seminar/prihlaska.js | 32 + seminar/static/seminar/skoly.js | 939 ------------------ seminar/templates/seminar/prihlaska.html | 109 +- .../templates/seminar/prihlaska_field.html | 4 + seminar/views.py | 89 +- 9 files changed, 218 insertions(+), 1031 deletions(-) create mode 100644 seminar/static/seminar/prihlaska.js delete mode 100644 seminar/static/seminar/skoly.js create mode 100644 seminar/templates/seminar/prihlaska_field.html diff --git a/.gitignore b/.gitignore index 826b07e2..36b0b565 100644 --- a/.gitignore +++ b/.gitignore @@ -10,7 +10,7 @@ # aux files *.pyc -*.swp +*.sw[mnop] # secrets /django.secret diff --git a/mamweb/settings_common.py b/mamweb/settings_common.py index e686fcd6..1a8984e3 100644 --- a/mamweb/settings_common.py +++ b/mamweb/settings_common.py @@ -215,6 +215,10 @@ LOGGING = { 'handlers': ['console'], 'level': 'DEBUG', }, + 'seminar.prihlaska':{ + 'handlers': ['console','registration_logfile'], + 'level': 'INFO' + }, # Catch-all logger '': { @@ -237,6 +241,12 @@ LOGGING = { 'class': 'django.utils.log.AdminEmailHandler', 'formatter': 'verbose', }, + 'registration_logfile':{ + 'level': 'INFO', + 'class': 'logging.FileHandler', + 'filename': 'registration.log', + 'formatter': 'verbose', + } }, } diff --git a/mamweb/templates/base.html b/mamweb/templates/base.html index 208f797f..310234da 100644 --- a/mamweb/templates/base.html +++ b/mamweb/templates/base.html @@ -24,8 +24,8 @@ } }); - {# script specifický pro stránku #} diff --git a/seminar/forms.py b/seminar/forms.py index b0aa6f72..4455515e 100644 --- a/seminar/forms.py +++ b/seminar/forms.py @@ -1,8 +1,9 @@ from django import forms from dal import autocomplete -from .models import Skola -from seminar.models import Resitel +from .models import Skola, Resitel + +from datetime import date @@ -10,7 +11,10 @@ from seminar.models import Resitel class PrihlaskaForm(forms.Form): jmeno = forms.CharField(label='Jméno', max_length=256, required=True) prijmeni = forms.CharField(label='Příjmení', max_length=256, required=True) - username = forms.CharField(label='Přihlašovací jméno', max_length=256, required=True) + username = forms.CharField(label='Přihlašovací jméno', + max_length=256, + required=True, + help_text='Tímto jménem se následně budeš přihlašovat pro odevzdání řešení a další činnosti v semináři') # TODO heslo? pohlavi_muz = forms.ChoiceField(label='Pohlaví', choices = ((True,'muž'),(False,'žena')), required=True) @@ -25,30 +29,44 @@ class PrihlaskaForm(forms.Form): ('SK', 'Slovenská Republika'), ('other', 'Jiné')), required=False) + stat_text = forms.CharField(label='Stát', max_length=256, required=False) - skola = forms.ModelChoiceField( + skola = forms.ModelChoiceField(label="Škola", queryset=Skola.objects.all(), - widget=autocomplete.ModelSelect2(url='autocomplete_skola') - ) - -# skola_stat_select = forms.ChoiceField(label='Stát', -# choices = (('cz', 'Česká Republika'), -# ('sk', 'Slovenská Republika'), -# ('other', 'Jiné')), -# required=True) -# kraj_select = forms.ChoiceField(label='Kraj',required=True) -# skola_select = forms.ChoiceField(label='Škola',required=True) - #kraj - #škola + widget=autocomplete.ModelSelect2( + url='autocomplete_skola', + attrs = {'data-placeholder--id': '-1', + 'data-placeholder--text' : '---', + 'data-allow-clear': 'true'}) + ,required=False) + + skola_nazev = forms.CharField(label='Název školy', max_length=256, required=False) + skola_adresa = forms.CharField(label='Adresa školy', max_length=256, required=False) + # trida = forms.CharField(label='Třída',max_length=10, required=True) - #název školy - #adresa školy -# skola_nazev = forms.CharField(label='Název školy', max_length=256, required=False) -# skola_adresa = forms.CharField(label='Adresa školy', max_length=256, required=False) - rok_maturity = forms.IntegerField(label='Rok maturity', min_value=2019, required=True) + rok_maturity = forms.IntegerField( + label='Rok maturity', + min_value=date.today().year, + max_value=date.today().year+8, + required=True) zasilat = forms.ChoiceField(label='Kam zasílat čísla a řešení',choices = Resitel.ZASILAT_CHOICES, required=True) gdpr = forms.BooleanField(label='Souhlasím se zpracováním osobních údajů', required=True) spam = forms.BooleanField(label='Souhlasím se zasíláním materiálů od MFF UK', required=False) + def clean(self): + super().clean() + data = self.cleaned_data + if data.get('stat') != '' and data.get('stat_text') != '': + self.add_error('stat',forms.ValidationError('Nelze mít vybraný stát z menu a zároven zapsaný textem')) + if data.get('skola') and (data.get('skola_nazev') or data.get('skola_adresa')): + self.add_error('skola',forms.ValidationError('Pokud je škola v seznamu, nevypisujte ji ručně, pokud není, zrušte výběr ze seznamu (křížek vpravo)')) + if not data.get('skola'): + if data.get('skola_nazev')=='' and data.get('skola_adresa')=='': + self.add_error('skola',forms.ValidationError('Je nutné vyplnit školu')) + elif data.get('skola_nazev')=='': + self.add_error('skola_nazev',forms.ValidationError('Je nutné vyplnit název školy')) + elif data.get('skola_adresa')=='': + self.add_error('skola_adresa',forms.ValidationError('Je nutné vyplnit adresu školy')) +from seminar.models import Resitel diff --git a/seminar/static/seminar/prihlaska.js b/seminar/static/seminar/prihlaska.js new file mode 100644 index 00000000..81f91d28 --- /dev/null +++ b/seminar/static/seminar/prihlaska.js @@ -0,0 +1,32 @@ +function addrCountryChanged(){ + var stat_select = document.getElementById('id_stat'); + var stat_text = document.getElementById('id_li_stat_text'); + var stat = stat_select[stat_select.selectedIndex].value; + if (stat === "other"){ + stat_text.style.display="block"; + } else { + stat_text.style.display="none"; + $('#id_stat_text').val(""); + } +} +function hideSchoolTextfields(){ + var skola_nazev = document.getElementById('id_li_skola_nazev'); + var skola_adresa = document.getElementById('id_li_skola_adresa'); + skola_nazev.style.display="none"; + skola_adresa.style.display="none"; + +} +function schoolNotInList(){ + var skola_nazev = document.getElementById('id_li_skola_nazev'); + var skola_adresa = document.getElementById('id_li_skola_adresa'); + // FIXME nefunguje a nevim proc (TypeError: $(...).select2 is not a function) + //var skola_select = $('#id_skola').select2(); + //skola_select.val(null).trigger('change'); + skola_nazev.style.display="block"; + skola_adresa.style.display="block"; +} + +document.addEventListener("DOMContentLoaded", function(){ + addrCountryChanged(); + hideSchoolTextfields(); +}); diff --git a/seminar/static/seminar/skoly.js b/seminar/static/seminar/skoly.js deleted file mode 100644 index f617bc94..00000000 --- a/seminar/static/seminar/skoly.js +++ /dev/null @@ -1,939 +0,0 @@ -var regions = { - 'cz': [ - [0, '--- Vyber si kraj ---'], - [2, 'Jihomoravský kraj'], - [1, 'Jihočeský kraj'], - [3, 'Karlovarský kraj'], - [13, 'Kraj Vysočina'], - [4, 'Královéhradecký kraj'], - [5, 'Liberecký kraj'], - [6, 'Moravskoslezský kraj'], - [7, 'Olomoucký kraj'], - [8, 'Pardubický kraj'], - [10, 'Plzeňský kraj'], - [9, 'Praha'], - [11, 'Středočeský kraj'], - [14, 'Zlínský kraj'], - [12, 'Ústecký kraj'], - ], - 'sk': [ - [0, '--- Vyber si kraj ---'], - [16, 'Banskobystrický kraj'], - [15, 'Bratislavský kraj'], - [17, 'Košický kraj'], - [18, 'Nitriansky kraj'], - [19, 'Prešovský kraj'], - [20, 'Trenčiansky kraj'], - [21, 'Trnavský kraj'], - [22, 'Žilinský kraj'], - ], - 'xx': [ - [0, '--- Vyber si kraj ---'], - [23, 'Mimo ČR/SR'], - ], -}; - -var schools = { - 0: [ - [0,'--- Vyber si školu ---'], - ], - 1: [ - [0,'--- Vyber si školu ---'], - [-1,'Blatná'], - [172,"Střední odborná škola (V Jezárkách 745, 38817 Blatná)"], - [-1,'České Budějovice'], - [493,"Biskupské gymnázium J. N. Neumanna a Církevní základní škola (Jirsíkova 420/5, 370 01 České Budějovice)"], - [490,"EDUCAnet – SŠ a ZŠ České Budějovice, s.r.o. (Lannova tř. 1595/29a 37001 České Budějovice)"], - [204,"Gymnázium Česká (Česká 64, 37021 České Budějovice)"], - [227,"Gymnázium Jana Valeriána Jirsíka (Fráni Šrámka 23, 37001 České Budějovice)"], - [130,"Gymnázium Jírovcova (Jírovcova 8, 37161 České Budějovice)"], - [375,"Střední škola informatiky a právních studií, o. p. s. (Žižkova 4, 37001 České Budějovice)"], - [469,"Střední škola obchodu, služeb a podnikání a VOŠ (Kněžskodvorská 33/A, 37004 České Budějovice)"], - [459,"Základní škola Oskara Nedbala (Oskara Nedbala 30, České Budějovice)"], - [419,"ZŠ Dukelská (Dukelská 11, 37001 České Budějovice)"], - [-1,'Český Krumlov'], - [241,"Gymnázium Český Krumlov (Chvalšinská 112, 38101 Český Krumlov)"], - [-1,'Čkyně'], - [492,"ZŠ a MŠ Čkyně (č. p. 155, 38441 Čkyně)"], - [-1,'Dačice'], - [399,"Gymnázium Dačice (Boženy Němcové 213/V, 38001 Dačice)"], - [-1,'Hluboká nad Vltavou'], - [236,"Střední odborná škola elektrotechnická COP (Zvolenovská 537, 37341 Hluboká nad Vltavou)"], - [-1,'Jindřichův Hradec'], - [115,"Gymnázium Vítězslava Nováka (Husova 333, 37715 Jindřichův Hradec)"], - [528,"Střední zdravotnická škola (Klášterská 77/II, 377 01 Jindřichův Hradec)"], - [-1,'Kaplice'], - [174,"Gymnázium, SOŠE a SOU Kaplice (Pohorská 86, 38241 Kaplice)"], - [-1,'Milevsko'], - [400,"Gymnázium Milevsko (Masarykova 183, 39901 Milevsko)"], - [-1,'Písek'], - [156,"Gymnázium Písek (Komenského 89/20, 39701 Písek)"], - [6,"SPŠ a VOŠ Písek (Karla Čapka 402, 39711 Písek)"], - [-1,'Prachatice'], - [157,"Gymnázium Prachatice (Zlatá stezka 137, 38301 Prachatice)"], - [-1,'Soběslav'], - [271,"Gymnázium Soběslav (tř. Dr. Edvarda Beneše 449/20, 39201 Soběslav II)"], - [-1,'Strakonice'], - [17,"Gymnázium Strakonice (Máchova 174, 38648 Strakonice)"], - [322,"ZŠ Dukelská (Dukelská 166, 38601 Strakonice)"], - [-1,'Tábor'], - [88,"Gymnázium Pierra de Coubertina (Náměstí Františka Křižíka 860, 39030 Tábor)"], - [-1,'Třeboň'], - [477,"Gymnázium Třeboň, Na sadech 308 (Na Sadech 308, 37926 Třeboň)"], - [-1,'Týn nad Vltavou'], - [135,"Gymnázium Týn nad Vltavou (Havlíčkova 13, 37501 Týn nad Vltavou)"], - [-1,'Vimperk'], - [15,"Gymnázium a SOŠ ekonomická (Pivovarská 69, 38501 Vimperk)"], - ], - 2: [ - [0,'--- Vyber si školu ---'], - [-1,'Blansko'], - [281,"Gymnázium Blansko (Seifertova 13, 67801 Blansko)"], - [-1,'Boskovice'], - [120,"Gymnázium Boskovice (Palackého náměstí 1, 68001 Boskovice)"], - [-1,'Břeclav'], - [10,"Gymnázium a jazyková škola s právem SJZ (Sady 28. října 1, 69002 Břeclav)"], - [-1,'Brno'], - [257,"Biskupské gymnázium Brno (Barvičova 85, 60200 Brno)"], - [557,"Cyrilometodějské gymnázium a střední odborná škola pedagogická (Lerchova 63, 602 00 Brno)"], - [325,"EDUCAnet Brno, o. p. s. (Arménská 573/21, 62500 Brno)"], - [171,"EKO gymnázium Brno o. p. s. (Labská 27, 62500 Brno)"], - [39,"Gymnázium Brno (tř. Kapitána Jaroše 14, 65870 Brno)"], - [298,"Gymnázium Brno-Řečkovice (Terezy Novákové 2, 62100 Brno - Řečkovice)"], - [286,"Gymnázium Elgartova (Elgartova 3, 61400 Brno)"], - [213,"Gymnázium Křenová (Křenová 36, 60200 Brno)"], - [40,"Gymnázium Matyáše Lercha (Žižkova 55, 61600 Brno)"], - [379,"Gymnázium Slovanské náměstí (Slovanské náměstí 7, 61200 Brno)"], - [209,"Gymnázium Terezy Novákové (Terezy Novákové 2, 62100 Brno-Řečkovice)"], - [216,"Gymnázium Vídeňská (Vídeňská 47, 63900 Brno)"], - [485,"Klasické a španělské gymnázium Brno-Bystrc (Vejrostova 2, 63500 Brno)"], - [558,"Mateřská škola, základní škola a střední škola Gellnerka Brno, příspěvková organizace (Gellnerova 1, 637 00 Brno)"], - [207,"OA, SOŠ a VOŠ Kotlářská (Kotlářská 9, 61153 Brno)"], - [240,"SPŠ chemická (Vranovská 65, 61400 Brno)"], - [211,"SŠ inf. technologií a soc. péče (Purkyňova 97, 61200 Brno - Královo Pole)"], - [474,"Střední průmyslová škola a VOŠ Brno (Sokolská 1, 60200 Brno)"], - [543,"Střední škola grafická Brno (Kudelova 6, 602 00 Brno)"], - [377,"Střední škola informatiky, poštovnictví a finančnictví Brno (Čichnova 23, 62400 Brno)"], - [479,"Vzdělávací institut INTEGRA BRNO (Rašelinová 2433/11, 62800 Brno-Líšeň)"], - [416,"ZŠ a MŠ Křídlovická (Křídlovická 30b, 60300 Brno)"], - [-1,'Bučovice'], - [376,"Gymnázium a OA Bučovice (Součkova 500, 68501 Bučovice)"], - [-1,'Hodonín'], - [12,"Gymnázium Hodonín (P. O. BOX 38, 69511 Hodonín)"], - [-1,'Hustopeče'], - [251,"Gymnázium T.G.Masaryka (Dukelské náměstí 7, 69331 Hustopeče)"], - [-1,'Jedovnice'], - [275,"SPŠ Jedovnice (Na Větřáku 463, 67906 Jedovnice)"], - [-1,'Klobouky u Brna'], - [415,"Městské víceleté gymnázium Klobouky u Brna (Vinařská 29, 69172 Klobouky u Brna)"], - [-1,'Kyjov'], - [470,"Klvaňovo gymnázium a SZŠ Kyjov (Třída Komenského 549, 69701 Kyjov)"], - [-1,'Moravský Krumlov'], - [66,"Gymnázium Moravský Krumlov (Smetanova 168, 67201 Moravský Krumlov)"], - [-1,'Šlapanice'], - [231,"Gymnázium a ZUŠ (Riegrova 17, 66451 Šlapanice)"], - [-1,'Strážnice'], - [81,"Purkyňovo gymnázium Strážnice (Masarykova 379, 69662 Strážnice)"], - [-1,'Tišnov'], - [161,"Gymnázium Tišnov (Na Hrádku 20, 66601 Tišnov)"], - [-1,'Velké Bílovice'], - [463,"ZŠ Velké Bílovice (Fabián 1215, 69102 Velké Bílovice)"], - [-1,'Vyškov'], - [357,"Gymnázium Vyškov (Komenského 16, 68201 Vyškov)"], - [-1,'Zastávka'], - [232,"Gymnázium T. G. Masaryka (U Školy 39, 66484 Zastávka)"], - [-1,'Znojmo'], - [499,"Gymnázium Dr. Karla Polesného (Komenského náměstí 4, 66975 Znojmo)"], - [323,"SOŠ stavební (Jarošova 1335/14, 66902 Znojmo)"], - ], - 3: [ - [0,'--- Vyber si školu ---'], - [-1,'Cheb'], - [437,"Gymnázium Cheb (Nerudova 2283/7, 35002 Cheb)"], - [475,"Svobodná chebská škola (Jánské náměstí 15, 35002 Cheb)"], - [-1,'Chodov'], - [440,"Gymnázium a obchodní akademie Chodov (Smetanova 738, 35735 Chodov)"], - [-1,'Karlovy Vary'], - [90,"První české gymnázium v K. Varech (Národní 25, 36020 Karlovy Vary)"], - [-1,'Mariánské Lázně'], - [374,"Gymnázium a OA Mariánské Lázně (Ruská 355, 35369 Mariánské Lázně)"], - [259,"OA Mariánské Lázně (Lužická 412, 35324 Mariánské Lázně)"], - [-1,'Nové Sedlo'], - [293,"ZŠ Nové Sedlo (Masarykova 425, 35734 Nové Sedlo)"], - [-1,'Ostrov'], - [101,"Gymnázium Ostrov (Studentská 1205, 36301 Ostrov)"], - [31,"SPŠ Ostrov (Jáchymovská 1, 36311 Ostrov)"], - [-1,'Sokolov'], - [151,"Gymnázium Sokolov (Husitská 2053, 35611 Sokolov)"], - ], - 4: [ - [0,'--- Vyber si školu ---'], - [-1,'Broumov'], - [235,"Gymnázium Broumov (Hradební 218, 55001 Broumov)"], - [-1,'Dobruška'], - [336,"Gymnázium Dobruška (Pulická 779, 51801 Dobruška)"], - [278,"SPŠ elektrotechniky a informačních technologií (Čs. odboje 670, 58001 Dobruška)"], - [-1,'Dvůr Králové nad Labem'], - [92,"SPŠ Dvůr Králové nad Labem (nábřeží J. Wolkera 132, 54411 Dvůr Králové nad Labem)"], - [-1,'Hořice'], - [205,"Gymnázium a SOŠ Hořice (Husova 1414, 50822 Hořice)"], - [-1,'Hradec Králové'], - [318,"Biskupské gymnázium Bohuslava Balbína (Orlické nábřeží 356/1, 50003 Hradec Králové)"], - [225,"Gymnázium Boženy Němcové (Pospíšilova třída 324, 50002 Hradec Králové)"], - [131,"Gymnázium J. K. Tyla (Tylovo nábřeží 682, 50002 Hradec Králové)"], - [441,"První soukromé jazykové gymnázium spol. s r.o. (Brandlova 875, 50003 Hradec Králové)"], - [340,"SOŠ veterinární (Pražská 68, 50101 Hradec Králové - Kukleny)"], - [94,"SŠ aplikované kybernetiky (Hradecká 1151, 50002 Hradec Králové)"], - [531,"Střední škola Sion High School (Na Kotli 1201, 500 09 Hradec Králové)"], - [-1,'Jaroměř'], - [263,"Gymnázium a SOŠ Jaroměř (Lužická 423, 55123 Jaroměř)"], - [-1,'Jičín'], - [217,"Lepařovo gymnázium (Jiráskova 30, 50601 Jičín)"], - [84,"VOŠ a SPŠ Jičín (Pod Koželuhy 100, 50641 Jičín)"], - [-1,'Náchod'], - [301,"Jiráskovo Gymnázium (Řezníčkova 451, 54744 Náchod)"], - [-1,'Nová Paka'], - [118,"Gymnázium a SOŠPg (Kumburská 740, 50901 Nová Paka)"], - [-1,'Nový Bydžov'], - [155,"Gymnázium Nový Bydžov (Komenského 77, 50401 Nový Bydžov)"], - [-1,'Rychnov nad Kněžnou'], - [276,"Gymnázium F.M. Pelcla (Hrdinů odboje 36, 51601 Rychnov nad Kněžnou)"], - [-1,'Sobotka'], - [482,"ZŠ Sobotka (Jičínská 136, 50743 Sobotka)"], - [-1,'Trutnov'], - [107,"Gymnázium Trutnov (Jiráskovo náměstí 325, 54101 Trutnov)"], - [348,"SPŠ Trutnov (Školní 101, 54101 Trutnov)"], - [-1,'Úpice'], - [299,"Městské gymnázium a střední odborná škola Úpice (Havlíčkova 812, 54232 Úpice)"], - [-1,'Vrchlabí'], - [59,"Gymnázium Vrchlabí (Komenského 586, 54301 Vrchlabí)"], - [-1,'Žacléř'], - [465,"ZŠ Žacléř (Komenského 339, 54201 Žacléř)"], - ], - 5: [ - [0,'--- Vyber si školu ---'], - [-1,'Česká Lípa'], - [11,"Gymnázium Česká Lípa (Žitavská 2969, 47006 Česká Lípa)"], - [-1,'Jablonec nad Nisou'], - [128,"Gymnázium Jablonec (U Balvanu 16, 46601 Jablonec nad Nisou)"], - [319,"SPŠT (Belgická 4852, 46601 Jablonec nad Nisou)"], - [153,"Víceleté a sportovní gymnázium (Dr. Randy 13, 46601 Jablonec nad Nisou)"], - [-1,'Liberec'], - [75,"Gymnázium a SOŠPg (Jeronýmova 27, 46007 Liberec 7)"], - [109,"Gymnázium F. X. Šaldy (Partyzánská 530, 46011 Liberec 11)"], - [163,"SPŠ strojní a elektrotechnická a VOŠ (Masarykova 460/3, 46084 Liberec 1)"], - [421,"SŠ strojní, stavební a dopravní Liberec (Ještědská 358/106, 46008 Liberec 8)"], - [-1,'Semily'], - [279,"Gymnázium I. Olbrachta (Nad Špejcharem 574, 51301 Semily)"], - [-1,'Tanvald'], - [27,"Gymnázium Tanvald (Školní 305, 46841 Tanvald)"], - [-1,'Turnov'], - [111,"Gymnázium Turnov (Jana Palacha 804, 51101 Turnov)"], - ], - 6: [ - [0,'--- Vyber si školu ---'], - [-1,'Bílovec'], - [76,"Gymnázium M. Koperníka (17. listopadu 526, 74311 Bílovec)"], - [-1,'Bohumín'], - [260,"Gymnázium Františka Živného (Jana Palacha 794, 73581 Bohumín)"], - [-1,'Bruntál'], - [22,"SPŠ Bruntál (Kavalcova 1, 79201 Bruntál)"], - [1,"ZŠ a městské osmileté gymnázium Bruntál (Školní 2, 79201 Bruntál)"], - [-1,'Český Těšín'], - [546,"Gymnázium Josefa Božka, Český Těšín, příspěvková organizace (Frýdecká 30, 73701 Český Těšín)"], - [124,"Gymnázium s polským jazykem vyučovacím Český Těšín (Havlíčkova 213/13, 73701 Český Těšín)"], - [-1,'Frenštát pod Radhoštěm'], - [417,"Gymnázium a SPŠ Frenštát pod Radhoštěm (Křižíkova 1258, 74401 Frenštát pod Radhoštěm)"], - [33,"Gymnázium Frenštát pod Radhoštěm (Martinská čtvrť 1172, 74401 Frenštát pod Radhoštěm)"], - [-1,'Frýdek'], - [85,"Gymnázium a SOŠ (Cihelní 410, 73801 Frýdek-Místek)"], - [34,"Gymnázium Petra Bezruče (ČSA 517, 73802 Frýdek - Místek)"], - [198,"Střední škola informačních technologií, s. r. o. (třída Pionýrů 2069, 73802 Frýdek-Místek)"], - [-1,'Frýdlant nad Ostravicí'], - [237,"Gymnázium Frýdlant nad Ostravicí (nám. T. G. Masaryka 1260, 73911 Frýdlant nad Ostravicí)"], - [-1,'Havířov'], - [212,"Gymnázium Havířov (Komenského 2, 73601 Havířov-Město)"], - [454,"Gymnázium Havířov-Podlesí (Studentská 1198/11, 73601 Havířov)"], - [137,"SPŠE Havířov (Makarenkova 1, 73601 Havířov - Město)"], - [460,"ZŠ Generála Svobody (Generála Svobody 16, Havířov - Šumbark)"], - [195,"ZŠ Havířov (Školní 1/814, 73564 Havířov-Šumburk)"], - [-1,'Hlučín'], - [289,"Gymnázium Josefa Kainara (Dr. Edvarda Beneše 7/586, 74801 Hlučín)"], - [498,"Základní škola dr. Miroslava Tyrše (Tyršova 1062/2, 74801 Hlučín)"], - [-1,'Karviná'], - [245,"Gymnázium Karviná (Mírová 1442, 73506 Karviná - Nové Město)"], - [139,"SPŠ Karviná (Žižkova 1818, 73301 Karviná - Hranice)"], - [-1,'Kopřivnice'], - [331,"VOŠ, SOŠ a SOU Kopřivnice (Husova 1302, 74221 Kopřivnice)"], - [-1,'Krnov'], - [404,"Gymnázium Krnov (Smetanův okruh 19/2, 79401 Krnov)"], - [-1,'Nový Jičín'], - [342,"Gymnázium a SOŠ Nový Jičín (Palackého 50/52, 74111 Nový Jičín)"], - [-1,'Opava'], - [65,"Mendelovo gymnázium (Komenského 5, 74601 Opava)"], - [-1,'Orlová'], - [221,"Gymnázium Orlová (Masarykova třída 1313, 73514 Orlová - Lutyně)"], - [-1,'Ostrava'], - [210,"Biskupské gymnázium (Karla Pokorného 1284, 70800 Ostrava - Poruba)"], - [491,"Gymnázium Hladnov a Jazyková škola s právem státní jazykové zkoušky Ostrava (Hladnovská 35, 710 00 Slezská Ostrava)"], - [396,"Gymnázium Olgy Havlové (Marie Majerové 1691, 708 00 Ostrava-Poruba)"], - [553,"Gymnázium Ostrava-Hrabůvka p.o. (Františka Hajdy 1429/34 700 30 Ostrava-Hrabůvka)"], - [57,"Gymnázium Ostrava-Zábřeh (Volgogradská 6a, 70400 Ostrava - Zábřeh)"], - [242,"Matiční gymnázium (Dr. Šmerala 25, 72804 Ostrava)"], - [312,"SPŠ elektrotechniky a informatiky (Kratochvílova 7, 70200 Ostrava - Moravská Ostrava)"], - [530,"Střední umělecká škola (Poděbradova 33, 702 00 Moravská Ostrava a Přívoz)"], - [244,"Wichterlovo gymnázium (Čs. exilu 669, 70800 Ostrava-Poruba)"], - [-1,'Příbor'], - [87,"Masarykovo gymnázium (Jičínská 528, 74258 Příbor)"], - [-1,'Rýmařov'], - [502,"Gymnázium a SOŠ Rýmařov (Sokolovská 466/34, 79501 Rýmařov)"], - [-1,'Slezská Ostrava'], - [19,"Gymnázium Hladnov a Jazyková škola s právem SJZ (Hladnovská 35, 71000 Slezská Ostrava)"], - [-1,'Třinec'], - [309,"Gymnázium Třinec (Komenského 713, 73961 Třinec)"], - [-1,'Vrbno pod Pradědem'], - [73,"Sportovní gymnázium (nám. Sv. Michala 12, 79326 Vrbno pod Pradědem)"], - ], - 7: [ - [0,'--- Vyber si školu ---'], - [-1,'Hranice'], - [14,"Gymnázium Hranice (Zborovská 293, 75311 Hranice)"], - [162,"Soukromá SOŠ (Jaselská 832, 75301 Hranice)"], - [-1,'Jeseník'], - [270,"Gymnázium Jeseník (Komenského 281, 79001 Jeseník)"], - [-1,'Kojetín'], - [266,"Gymnázium Kojetín (Svatopluka Čecha 683, 75201 Kojetín)"], - [-1,'Kostelec na Hané'], - [196,"ZŠ a MŠ Kostelec na Hané (Sportovní 850, 79841 Kostelec na Hané)"], - [-1,'Litovel'], - [133,"Gymnázium Jana Opletala (Opletalova 189, 78401 Litovel)"], - [70,"SOU Litovel (Komenského 677, 78401 Litovel)"], - [-1,'Mohelnice'], - [481,"Obchodní akademie, Mohelnice, Olomoucká 82 (Olomoucká 82, 78985 Mohelnice)"], - [-1,'Olomouc'], - [91,"Gymnázium Olomouc - Hejčín (Tomkova 45, 77900 Olomouc - Hejčín)"], - [226,"Slovanské gymnázium (tř. Jiřího z Poděbrad 13, 77111 Olomouc)"], - [332,"VOŠ a SPŠE Olomouc (Božetěchova 3, 772 00 Olomouc)"], - [-1,'Přerov'], - [63,"Gymnázium Jakuba Škody (Komenského 29, 75002 Přerov)"], - [495,"Gymnázium Jana Blahoslava a Střední pedagogická škola (Denisova 3, 75152 Přerov)"], - [524,"Střední průmyslová škola Přerov (Havlíčkova 2, 75152 Přerov)"], - [-1,'Prostějov'], - [496,"Cyrilometodějské gymnázium, základní škola a mateřská škola v Prostějově (Komenského 17, 796 01 Prostějov)"], - [21,"Gymnázium Jiřího Wolkera (Kollárova 3, 79601 Prostějov)"], - [-1,'Šternberk'], - [303,"Gymnázium Šternberk (Horní náměstí 5, 78501 Šternberk)"], - [-1,'Šumperk'], - [350,"Gymnázium Šumperk (Masarykovo nám. 8, 78758 Šumperk)"], - [143,"VOŠ a SPŠ Šumperk (Generála Krátkého 1, 78729 Šumperk)"], - [199,"ZŠ Šumperk (8. května 63, 78701 Šumperk)"], - [-1,'Uničov'], - [392,"Gymnázium Uničov (Gymnazijní 257, 78391 Uničov)"], - [-1,'Zábřeh'], - [551,"Gymnázium Zábřeh (Náměstí Osvobození 257/20, Zábřeh)"], - ], - 8: [ - [0,'--- Vyber si školu ---'], - [-1,'Česká Třebová'], - [67,"Gymnázium Česká Třebová (Tyršovo náměstí 970, 56002 Česká Třebová)"], - [-1,'Chrudim'], - [119,"Gymnázium Josefa Ressela (Olbrachtova 291, 53701 Chrudim)"], - [347,"SOŠ a SOU obchodu a služeb (Čáslavská 205, 53701 Chrudim)"], - [274,"SPŠ Chrudim (Čáslavská 973, 53701 Chrudim)"], - [-1,'Hlinsko'], - [290,"Gymnázium K. V. Raise (Adámkova 55, 53901 Hlinsko)"], - [-1,'Holice'], - [173,"Gymnázium Dr. Emila Holuba (Na Mušce 1110, 53401 Holice)"], - [-1,'Lanškroun'], - [50,"Gymnázium Lanškroun (Náměstí Jana Marka Marků 113, 56312 Lanškroun)"], - [-1,'Litomyšl'], - [264,"Gymnázium Aloise Jiráska (T. G. Masaryka 590, 57001 Litomyšl)"], - [-1,'Moravská Třebová'], - [30,"Gymnázium Moravská Třebová (Svitavská 310, 57101 Moravská Třebová)"], - [-1,'Pardubice'], - [36,"Gymnázium Pardubice (Dašická 1083, 53003 Pardubice)"], - [182,"Polabská soukromá OA a VOŠ, s. r. o. (Gorkého 867, 53002 Pardubice)"], - [71,"SOŠ elektrotechnická a strojní a SOU (Do Nového 1131, 53003 Pardubice)"], - [247,"SPŠE a VOŠ Pardubice (Karla IV. 13, 53169 Pardubice)"], - [418,"Střední škola informatiky a ekonomie a Mateřská škola s. r. o. (Ke Kamenci 151, 53003 Pardubice)"], - [461,"ZŠ Polabiny 1, Družstevní 305 (Pardubice, Družstevní 305)"], - [-1,'Polička'], - [186,"Gymnázium Polička (nábřeží Svobody 306, 57201 Polička)"], - [-1,'Přelouč'], - [79,"SOU technické Přelouč (Dukelské náměstí 1513, 53501 Přelouč)"], - [-1,'Ronov nad Doubravou'], - [523,"ZŠ Ronov nad Doubravou (Chittussiho nám. 153, 53842 Ronov nad Doubravou)"], - [-1,'Rybitví'], - [433,"EDUCAnet - Střední odborná škola Pardubice, s. r. o. (Školní 143, 53354 Rybitví)"], - [-1,'Svitavy'], - [3,"Gymnázium a Jazyková škola s právem SJZ Svitavy (Sokolovská 1638, 56802 Svitavy)"], - [-1,'Ústí nad Orlicí'], - [425,"Gymnázium Ústí nad Orlicí (T. G. Masaryka 106, 562 01, Ústí nad Orlicí)"], - [-1,'Vysoké Mýto'], - [509,"Gymnázium Vysoké Mýto (Nám. Vaňorného 163, 56601 Vysoké Mýto)"], - [-1,'Žamberk'], - [330,"Gymnázium Žamberk (Nádražní 48, 56401 Žamberk)"], - ], - 9: [ - [0,'--- Vyber si školu ---'], - [-1,'Praha 1'], - [7,"Akademické gymnázium (Štěpánská 22, 11000 Praha 1)"], - [125,"Gymnázium Jana Nerudy (Hellichova 3, 11800 Praha 1-Malá Strana)"], - [435,"Gymnázium Jiřího Gutha-Jarkovského (Truhlářská 22, 110 00 Praha 1)"], - [228,"Gymnázium prof. J. Patočky (Jindřišská 36, 11000 Praha 1)"], - [193,"Malostranské gymnázium (Josefská 7, 11800 Praha 1-Malá Strana)"], - [74,"SPŠ sdělovací techniky (Panská 3, 11000 Praha 1)"], - [455,"VOŠ a SPŠ elektrotechnická Františka Křižíka (Na Příkopě 16, Praha 1)"], - [304,"ZŠ Uhelný trh (Uhelný trh 4, 11000 Praha 1)"], - [-1,'Praha 10'], - [333,"Gymnázium Omská (Omská 1300, 10000 Praha Vršovice)"], - [344,"Gymnázium Přípotoční (Přípotoční 1337, 10130 Praha 10 - Vršovice)"], - [56,"Gymnázium Voděradská (Voděradská 2, 10000 Praha 10 - Strašnice)"], - [25,"SPŠE V Úžlabině (V Úžlabině 320, 10000 Praha 10)"], - [-1,'Praha 2'], - [203,"Arcibiskupské gymnázium (Korunní 2, 12000 Praha 2)"], - [114,"Gymnázium Botičská (Botičská 1, 12000 Praha 2)"], - [562,"Obchodní Akademie Vinohradská (Vinohradská 1971/38, 12000 Praha 2)"], - [285,"SPŠE Ječná (Ječná 517/30, 12136 Praha 2)"], - [532,"ZŠ Kladská (Kladská 1201/1, Praha 2)"], - [444,"ZŠ Masarykova (Jana Masaryka 21, 12000 Praha 2)"], - [-1,'Praha 3'], - [451,"Gymnázium a Hudební škola (Komenského náměstí 400/9, 13000 Praha 3)"], - [104,"Gymnázium Karla Sladkovského (Sladkovského náměstí 8, 13000 Praha 3-Žižkov)"], - [252,"Gymnázium Na Pražačce (Nad Ohradou 2825/23, 13000 Praha 3 – Žižkov)"], - [-1,'Praha 4'], - [282,"Gymnasium Jižní Město (Tererova 17/2135, 14900 Praha 4)"], - [82,"Gymnázium Budějovická (Budějovická 680, 14000 Praha 4)"], - [127,"Gymnázium Elišky Krásnohorské (Ohradní 55, 14500 Praha 4-Michle)"], - [556,"Gymnázium Evolution Jižní Město (Tererova 2135/17, 149 00, Praha 4)"], - [383,"Gymnázium Milady Horákové (Na planině 1393/13, 140 00, Praha 4)"], - [170,"Gymnázium Na Vítězné pláni (Na Vítězné pláni 1160, 14000 Praha 4)"], - [411,"Gymnázium Opatov (Konstantinova 1500, 14900 Praha)"], - [360,"Gymnázium Písnická (Písnická 760, 14200 Praha 4)"], - [68,"Klasické gymnázium (Rakovského 3136/II, 14300 Praha 4)"], - [501,"Nový PORG (Pod Krčským lesem 1300/25, 14200 Praha 4)"], - [500,"Škola mezinárodních a veřejných vztahů, SOŠ, s.r.o (Michelská 12, 14000 Praha 4)"], - [488,"Waldorfské lyceum (Křejpského 1503, 14900 Praha 4)"], - [233,"ZŠ Jílovská (Jílovská 1100/16, 14200 Praha 4 - Braník)"], - [-1,'Praha 5'], - [58,"Gymnázium Christiana Dopplera (Zborovská 45, 15000 Praha 5)"], - [24,"Gymnázium J. Heyrovského (Mezi Školami 2475, 15800 Praha 5)"], - [132,"Gymnázium Na Zatlance (Na Zatlance 11, 15000 Praha 5)"], - [16,"Gymnázium Nad Kavalírkou (Nad Kavalírkou 1, 15000 Praha 5 - Košíře)"], - [106,"Gymnázium Oty Pavla (Loučanská 520, 15300 Praha 5-Radotín)"], - [514,"Smíchovská střední průmyslová škola (Preslova 25, 150 21 Praha 5 - Smíchov)"], - [-1,'Praha 6'], - [105,"Gymnázium Arabská (Arabská 682/14, 16000 Praha 6)"], - [149,"Gymnázium Jana Keplera (Parléřova 2, 16900 Praha 6)"], - [41,"Gymnázium Nad Alejí (Nad Alejí 1952, 16200 Praha 6)"], - [335,"Mensa gymnázium, o. p. s. (Španielova 1111/19, 16300 Praha 6 - Řepy)"], - [183,"VOŠ, SOŠP a Gymnázium Evropská (Evropská 33, 16000 Praha 6)"], - [409,"ZŠ Bílá (Bílá 1784/1, 16000 Praha 6)"], - [-1,'Praha 7'], - [126,"Gymnázium Nad Štolou (Nad Štolou 1/1510, 17000 Praha 7)"], - [-1,'Praha 8'], - [28,"Gymnázium Bernarda Bolzana, o. p. s. (V Holešovičkách 2, 180 00 Praha 8)"], - [83,"Gymnázium U Libeňského zámku (U Libeňského zámku 1, 18000 Praha 8)"], - [43,"Gymnázium Ústavní (Ústavní 400, 18100 Praha 8 - Bohnice)"], - [321,"PORG (Lindnerova 3, 18000 Praha 8 - Libeň)"], - [370,"Soukromá střední odborná škola (1.KŠPA) Praha s. r. o. (Pernerova 29/383, 18600 Praha 8)"], - [-1,'Praha 9'], - [208,"Gymnázium Čakovice (náměstí 25. března 100, 19600 Praha 9)"], - [154,"Gymnázium Českolipská (Českolipská 373, 19000 Praha 9)"], - [234,"Gymnázium Chodovická (Chodovická 2250, 19300 Praha 9 - Horní Počernice)"], - [184,"Gymnázium Jaroslava Seiferta, o. p. s. (Vysočanské nám. 500, 19000 Praha 9)"], - [202,"Gymnázium Litoměřická (Litoměřická 726, 19000 Praha 9)"], - [187,"Gymnázium Špitálská (Špitálská 2/700, 19000 Praha 9-Vysočany)"], - [188,"Soukromá SŠ výpočetní techniky (Litvínovská 600, 19000 Praha 9 - Prosek)"], - [512,"Soukromá ZŠ Univerzum (Českolipská 373, 19000 Praha 9)"], - [269,"Soukromé gymnázium ARCUS Praha 9, s. r. o. (Bří Venclíků 1140, 19800 Praha 9)"], - [471,"SPŠ na Proseku (Novoborská 2, 19000 Praha 9)"], - [382,"ZŠ Generála Janouška (Generála Janouška 1006, 19800 Praha)"], - [-1,'Praha Lipence'], - [191,"ZŠ Lipence (Černošická 168, 15531 Praha)"], - ], - 10: [ - [0,'--- Vyber si školu ---'], - [-1,'Domažlice'], - [136,"Gymnázium J. Š. Baara (Pivovarská 323, 34442 Domažlice)"], - [-1,'Klatovy'], - [48,"Gymnázium Jaroslava Vrchlického (Národních mučedníků 347, 33901 Klatovy)"], - [80,"SPŠ Klatovy (nábřeží Kpt. Nálepky 362, 33901 Klatovy 3)"], - [-1,'Plasy'], - [230,"Gymnázium Plasy (Stará cesta 363, 33101 Plasy)"], - [-1,'Plzeň'], - [343,"15. ZŠ (Terezie Brzkové 33-35, 31800 Plzeň)"], - [521,"20. základní škola (Brojova 13, 32600 Plzeň)"], - [527,"21. základná škola (Slovanská alej 13, 32600 Plzeň)"], - [424,"Církevní gymnázium (Mikulášské náměstí 15, 32600 Plzeň)"], - [519,"Gymnázium Franiška Křižíka (Sokolovská 54, 32300 Plzeň)"], - [389,"Gymnázium Luďka Pika (Opavská 21, 31217 Plzeň)"], - [167,"Gymnázium Mikulášské náměstí (Mikulášské náměstí 23, 30154 Plzeň)"], - [175,"Masarykovo gymnázium (Petákova 2, 30100 Plzeň)"], - [520,"Soukromá ZŠ Elementária (Jesenická 11, 32323 Plzeň)"], - [100,"Sportovní gymnázium Plzeň (Táborská 28, 32600 Plzeň)"], - [522,"SPŠ Strojnická a SOŠ Prof. Švejcara (Klatovská 109, 30100 Plzeň)"], - [390,"Střední škola informatiky a finančních služeb (Klatovská 200 G, 30100 Plzeň)"], - [96,"VOŠ a SPŠ elektrotechnická (Koterovská 85, 32600 Plzeň)"], - [-1,'Rokycany'], - [518,"Gymnázium a SOŠ (Mládežníků 1115, 33701 Rokycany)"], - [513,"Gymnázium a SOŠ Rokycany (Mládežníků 1115, 33701 Rokycany)"], - [-1,'Sušice'], - [292,"Gymnázium Sušice (Fr. Procházky 324, 34201 Sušice)"], - [-1,'Tachov'], - [317,"Gymnázium Tachov (Tachov, Pionýrská 1370, 34701 Tachov)"], - [147,"ZŠ Kostelní (Kostelní 583, 34701 Tachov)"], - ], - 11: [ - [0,'--- Vyber si školu ---'], - [-1,'Babice'], - [420,"OPEN GATE - gymnázium a základní škola, s. r. o. (Babice 5, 25101 Říčany u Prahy)"], - [-1,'Benešov'], - [246,"Gymnázium Benešov (Husova 470, 25601 Benešov)"], - [-1,'Beroun'], - [9,"Gymnázium Joachima Barranda (Talichova ulice 824, 26601 Beroun)"], - [-1,'Brandýs nad Labem'], - [169,"Gymnázium J. S. Machara (Královická 668, 25050 Brandýs nad Labem - Stará Boleslav)"], - [554,"Střední zemědělská škola Brandýs nad Label (Zápská 302, 250 01 Brandýs nad Labem)"], - [-1,'Brandýš nad Labem'], - [552,"Střední zemědělská škola Brandýs nad Labem (Zápská 302, 25001 Brandýs nad Labem)"], - [-1,'Čáslav'], - [121,"Gymnázium a SPgŠ (Masarykova 248, 28601 Čáslav)"], - [-1,'Český Brod'], - [337,"Gymnázium Český Brod (Vítězná 616, 28227 Český Brod)"], - [559,"SOŠ Český Brod - Liblice (Školní 145, Český Brod - Liblice)"], - [426,"ZŠ Tyršova (Tyršova 68, 282 01 Český Brod)"], - [-1,'Dobříš'], - [160,"Gymnázium Karla Čapka (Školní 1530, 26301 Dobříš)"], - [-1,'Hořovice'], - [218,"Gymnázium Václava Hraběte (Jiráskova 617, 26801 Hořovice)"], - [-1,'Hostivice'], - [503,"Gymnázium Hostivice (Komenského 141 253 01 Hostivice)"], - [-1,'Kladno'], - [47,"Gymnázium Kladno (náměstí Edvarda Beneše 1573, 27201 Kladno)"], - [432,"SPŠ a VOŠ Kladno (Jana Palacha 1840, 272 01 Kladno)"], - [-1,'Kolín'], - [53,"Gymnázium Kolín (Žižkova 162, 28031 Kolín 3)"], - [378,"SOŠ informatiky a spojů a SOU Kolín (Jaselská 826, 28090 Kolín)"], - [-1,'Kralupy nad Vltavou'], - [8,"Dvořákovo gymnázium a SOŠ ekonomická Kralupy nad Vltavou (Dvořákovo náměstí 800, 27801 Kralupy nad Vltavou)"], - [-1,'Krhanice'], - [346,"ZŠ Krhanice (Krhanice 149, 25742 Krhanice)"], - [-1,'Kutná Hora'], - [168,"Gymnázium Jiřího Ortena (Jaselská 932, 28480 Kutná Hora)"], - [249,"SPŠ Kutná Hora (Masarykova 197, 28411 Kutná hora)"], - [-1,'Mělník'], - [294,"Gymnázium Jana Palacha (Pod Vrchem 3421, 27601 Mělník)"], - [-1,'Mladá Boleslav'], - [422,"Gymnázium Dr. Josefa Pekaře (Palackého 211, 29301 Mladá Boleslav)"], - [272,"Gymnázium Palackého (Palackého 191/1, 29301 Mladá Boleslav)"], - [267,"OA, VOŠE a JŠ s právem SJZ (T. G. Masaryka 14, 29380 Mladá Boleslav)"], - [-1,'Mnichovo Hradiště'], - [77,"Gymnázium Mnichovo Hradiště (Studentská 896, 29501 Mnichovo Hradiště)"], - [-1,'Neratovice'], - [180,"Gymnázium Františka Palackého (Masarykova 450, 27711 Neratovice)"], - [-1,'Nymburk'], - [89,"Gymnázium Bohumila Hrabala v Nymburce (Komenského 779, 28840 Nymburk)"], - [423,"SOŠ a SOU Nymburk (V Kolonii 1804, 28846 Nymburk)"], - [-1,'Poděbrady'], - [214,"Gymnázium Jiřího z Poděbrad (Studentská 166, 29001 Poděbrady)"], - [-1,'Příbram'], - [302,"Gymnázium Příbram (Legionářů 402, 26101 Příbram 7)"], - [-1,'Rakovník'], - [283,"Gymnázium Z. Wintra Rakovník (náměstí Jana Žižky 186, 26901 Rakovník)"], - [223,"Masarykova OA (Pražská 1222, 26920 Rakovník)"], - [-1,'Říčany'], - [296,"Gymnázium Říčany (Komenského nám. 1280, 25101 Říčany)"], - [536,"Masarykovo klasické gymnázium, s.r.o (Táborská 1685/47, 25101, Říčany)"], - [-1,'Sedlčany'], - [64,"Gymnázium a SOŠE (Nádražní 90, 26401 Sedlčany)"], - [-1,'Slaný'], - [277,"Gymnázium Václava Beneše Třebízského (Smetanovo nám. 1310, 27401 Slaný)"], - [-1,'Strančice'], - [464,"ZŠ Strančice (Revoluční 170, 25163 Strančice)"], - [-1,'Vlašim'], - [150,"Gymnázium Vlašim (Tylova 271, 25801 Vlašim)"], - ], - 12: [ - [0,'--- Vyber si školu ---'], - [-1,'Bílina'], - [486,"Gymnázium Bílina (Břežánská 9, Bílina 41801)"], - [-1,'Chomutov'], - [327,"OA, SOŠG a SOU Chomutov (Černovická 2901/26, 43003 Chomutov)"], - [341,"SPŠ a VOŠ Chomutov (Školní 1060/50, 43001 Chomutov)"], - [-1,'Děčín'], - [297,"Gymnázium Děčín (Komenského náměstí 4, 40501 Děčín)"], - [-1,'Kadaň'], - [359,"Gymnázium Kadaň (5. května 620, 43201 Kadaň)"], - [-1,'Klášterec nad Ohří'], - [190,"Gymnázium a SOŠ Klášterec nad Ohří (Chomutovská 459, 43151 Klášterec nad Ohří)"], - [-1,'Krupka'], - [103,"Biskupské gymnázium a ZŠ Bohosudov (Koněvova 34, 41742 Krupka 1)"], - [-1,'Litoměřice'], - [166,"Gymnázium Josefa Jungmanna (Svojsíkova 1, 41201 Litoměřice)"], - [-1,'Litvínov'], - [185,"Gymnázium T. G. Masaryka (Studentská 640, 43667 Litvínov)"], - [146,"SOŠ pro ochranu a obnovu životního prostředí - SCHOLA HUMANITAS (Ukrajinská 379, 43664 Litvínov)"], - [-1,'Litvínov - Hamr'], - [484,"Zš Litvínov - Hamr (Mládežnická 220, 43542 Litvnínov - Hamr)"], - [-1,'Louny'], - [268,"Gymnázium Václava Hlavatého Louny (Poděbradova 661, 44001 Louny)"], - [-1,'Lovosice'], - [549,"Gymnázium Lovosice (Sady Pionýrů 600/6, Lovosice, 41002)"], - [-1,'Meziboří'], - [140,"Střední škola EDUCHEM, a. s. (Okružní 128, 43513 Meziboří)"], - [-1,'Most'], - [86,"Gymnázium Most (Čs. armády 1530, 43446 Most)"], - [447,"VOŠ, OA, SPgŠ a SZŠ Most (Zdeňka Fibicha 2778, 43401 Most)"], - [-1,'Podbořany'], - [442,"Gymnázium a SOŠ Podbořany (Kpt. Jaroše 862, 44128 Podbořany)"], - [-1,'Roudnice nad Labem'], - [145,"Gymnázium Roudnice nad Labem (Havlíčkova 175, 41311 Roudnice nad Labem)"], - [-1,'Rumburk'], - [458,"Gymnázium Rumburk (Komenského 10, Rumburk)"], - [-1,'Teplice'], - [288,"Gymnázium Teplice (Čs. Dobrovolců 530/11, 41502 Teplice)"], - [291,"Střední škola technická AGC a. s. (Rooseveltovo nám. 5, 41503 Teplice 3)"], - [-1,'Ústí nad Labem'], - [483,"Gymnázium a SOŠ dr. V. Šmejakala (Stavbařů 5, 40011 Ústí nad Labem)"], - [129,"Gymnázium Ústí nad Labem (Jateční 22, 40001 Ústí nad Labem)"], - [295,"SPŠ strojní a elektrotechnická Resslova (Resslova 5, 40001 Ústí nad Labem)"], - [-1,'Varnsdorf'], - [385,"VOŠ a SŠ Varnsdorf (Bratislavská 2166, 40747 Varnsdorf)"], - [-1,'Žatec'], - [306,"Gymnázium Žatec (Studentská 1075, 43801 Žatec)"], - ], - 13: [ - [0,'--- Vyber si školu ---'], - [-1,'Bystřice nad Pernštejnem'], - [505,"Gymnázium Bystřice nad Pernštejnem (Nádražní 760, 59301 Bystřice nad Pernštejnem)"], - [-1,'Havlíčkův Brod'], - [315,"Gymnázium Havlíčkův Brod (Štáflova 2063, 58001 Havlíčkův Brod)"], - [165,"Havlíčkovo gymnázium (Štáflova 2063, 58001 Havlíčkův Brod)"], - [-1,'Humpolec'], - [20,"Gymnázium dr. A. Hrdličky (Komenského 147, 39601 Humpolec)"], - [-1,'Jihlava'], - [46,"Gymnázium Jihlava (Jana Masaryka 1, 58601 Jihlava)"], - [258,"Soukromé gymnázium AD FONTES, o. p. s. (Fibichova 18, 58601 Jihlava)"], - [78,"SPŠ Jihlava (tř. Legionářů 3, 58601 Jihlava)"], - [-1,'Ledeč nad Sázavou'], - [51,"Gymnázium SOŠ a VOŠ (Husovo náměstí 1, 58401 Ledeč nad Sázavou)"], - [-1,'Moravské Budějovice'], - [116,"Gymnázium a SOŠ Moravské Budějovice (Tyršova 365, 67619 Moravské Budějovice)"], - [-1,'Nové Město na Moravě'], - [117,"Gymnázium V. Makovského (Leandra Čecha 152, 59231 Nové Město na Moravě)"], - [-1,'Pelhřimov'], - [61,"Gymnázium Pelhřimov (Jirsíkova 244, 39301 Pelhřimov)"], - [394,"SPŠ a Střední odborné učiliště Pelhřimov (Friedova 1469, 39301 Pelhřimov)"], - [-1,'Světlá nad Sázavou'], - [95,"VOŠ, Gymnázium a SOŠ umělockoprůmyslová (Sázavská 547, 58291 Světlá nad Sázavou)"], - [197,"ZŠ Světlá nad Sázavou (Komenského 234, 58291 Světlá nad Sázavou)"], - [-1,'Telč'], - [284,"Gymnázium Otokara Březiny a SOŠ Telč (Hradecká 235, 58856 Telč)"], - [-1,'Třebíč'], - [102,"Gymnázium Třebíč (Masarykovo nám. 116/9, 67401 Třebíč)"], - [72,"SPŠ technická Třebíč (Manželů Curieových 734, 67401 Třebíč)"], - [-1,'Velké Meziříčí'], - [393,"Gymnázium Velké Meziříčí (Sokolovská 27/235, 59401 Velké Meziříčí)"], - [-1,'Žďár nad Sázavou'], - [534,"Biskupské gymnázium (U Klafárku 3, Žďár nad Sázavou 59101)"], - [-1,'Ždár nad Sázavou'], - [542,"Biskupské gymnázium (U Klafárku 3, Žďár nad Sázavou)"], - [-1,'Žďár nad Sázavou'], - [44,"Gymnázium Žďár nad Sázavou (Neumannova 2, 59101 Žďár nad Sázavou)"], - [504,"VOŠ a SPŠ Žďár nad Sázavou (Studentská 1, 59101 Žďár nad Sázavou)"], - [-1,'Ždár nad Sázavou'], - [472,"Základní škola Komenského 2 (Komenského 2, 59101 Žďár nad Sázavou)"], - [-1,'Ždírec nad Doubravou'], - [462,"ZŠ a MŠ Ždírec nad Doubravou (Chrudimská 77, 58263 Ždírec nad Doubravou)"], - ], - 14: [ - [0,'--- Vyber si školu ---'], - [-1,'Březová'], - [561,"Školy Březová – SOŠ, ZŠ a MŠ (Březová 102, 687 67 Březová)"], - [-1,'Dolní Němčí'], - [200,"ZŠ a ZUŠ Dolní Němčí (Školní 606, 68762 Dolní Němčí)"], - [-1,'Holešov'], - [13,"Gymnázium Ladislava Jaroše (Palackého 524, 76901 Holešov)"], - [-1,'Kroměříž'], - [476,"Arcibiskupské gymnázium v Kroměříži (Pilařova 3, 76701 Kroměříž)"], - [49,"Gymnázium Kroměříž (Masarykovo náměstí 496, 76701 Kroměříž)"], - [-1,'Kunovice'], - [224,"Soukromé gymnázium, SOŠ a jazyková škola, s. r. o. (Osvobození 699, 68604 Kunovice)"], - [-1,'Otrokovice'], - [192,"Gymnázium Otrokovice (třída Spojenců 907, 76513 Otrokovice)"], - [238,"SPŠ Otrokovice (třída T. Bati 331, 76502 Otrokovice)"], - [-1,'Rožnov pod Radhoštěm'], - [134,"Gymnázium Rožnov pod Radhoštěm (Koryčanské Paseky 1725, 75661 Rožnov pod Radhoštěm)"], - [144,"SŠ informatiky, elektroniky a řemesel (Školní 1610, 75661 Rožnov pod Radhoštěm)"], - [-1,'Slavičín'], - [122,"Gymnázium Jana Pivečky Slavičín (Školní 822, 76321 Slavičín)"], - [-1,'Uherské Hradiště'], - [97,"Gymnázium Uherské Hradiště (Velehradská třída 218, 68601 Uherské Hradiště)"], - [256,"SŠ průmyslová, hotelová a zdravotnická Uherské Hradiště (Kollárova 617, 68601 Uherské Hradiště)"], - [-1,'Uherský Brod'], - [35,"Gymnázium J. A. Komenského a Jaz. škola Uherský Brod (Komenského 169, 68801 Uherský Brod)"], - [-1,'Valašské Klobouky'], - [69,"Gymnázium Valašské Klobouky (Komenského 60, 76601 Valašské Klobouky)"], - [189,"ZŠ Valašské Klobouky (Školní 856, 76601 Valašské Klobouky)"], - [-1,'Valašské Meziříčí'], - [201,"Gymnázium Františka Palackého (Husova 146, 75737 Valašské Meziříčí)"], - [-1,'Vsetín'], - [152,"Masarykovo gymnázium a jazyková škola s právem SJZ Vsetín (Tyršova 1069, 75501 Vsetín)"], - [181,"SPŠ strojnická Vsetín (Pod Strání 1776, 75515 Vsetín)"], - [-1,'Zlín'], - [220,"Gymnázium a Jazyková škola s právem SJZ Zlín (náměstí T. G. Masaryka 2734, 76001 Zlín)"], - [113,"Gymnázium Zlín - Lesní čtvrť (Lesní čtvrť 1364, 76137 Zlín)"], - [176,"SPŠ Zlín (třída Tomáše Bati 4187, 76247 Zlín)"], - [560,"Střední škola filmová, multimediální a počítačových technologií, s.r.o. (Filmová 174, 76001 Zlín)"], - ], - 15: [ - [0,'--- Vyber si školu ---'], - [-1,'Bratislava'], - [164,"Gymnázium Bratislava (Grösslingova 18, 81109 Bratislava 1)"], - [413,"Gymnázium Jána Papánka (Vazovova 6, 81107 Bratislava 1)"], - [526,"Gymnázium Jura Hronca (Novohradská 3, 82109 Bratislava)"], - [177,"Gymnázium Matky Alexie (Jesenského 4, 81102 Bratislava 1)"], - [506,"Gymnázium Metodova (Metodova 2, Bratislava)"], - [452,"Gymnazium ul. Ladislava Sáru (Ladislava Sáru 1, Bratislava)"], - [373,"Prvé súkromné gymnázium (Bajkalská 20, 82108 Bratislava)"], - [329,"Škola pre mimoriadne nadané deti a gymnázium (Teplická 7, 83102 Bratislava)"], - [453,"SpŠ sv. Františka z Assisi (Karloveská 32, Bratislava)"], - [-1,'Pezinok'], - [438,"Gymnázium Pezinok (Senecká 2, 90201 Pezinok)"], - ], - 16: [ - [0,'--- Vyber si školu ---'], - [-1,'Banská Bystrica'], - [110,"Gymnázium J. G. Tajovského (Tajovského 25, 97401 Banská Bystrica)"], - [-1,'Brezno'], - [265,"SPŠ Brezno (Laskomerského 3, 97746 Brezno)"], - [-1,'Krupina'], - [489,"Gymnázium Andreja Sládkoviča (Milana Rastislava Štefánika 8, 96301 Krupina)"], - [-1,'Lučenec'], - [529,"Cirkevná základná škola sv. Jána Bosca (T. G. Masaryka 9, 98401 Lučenec)"], - [525,"Církevná ZŠ sv. Jána Bosca (T. G. Masaryka 9, 98401 Lučenec)"], - [158,"Gymnázium B. S. Timravy (Haličská cesta 9, 98403 Lučenec)"], - [-1,'Zvolen'], - [123,"Gymnázium Ľudovíta Štúra (Hronská 1467/3, 96049 Zvolen)"], - ], - 17: [ - [0,'--- Vyber si školu ---'], - [-1,'Košice'], - [45,"Gymnázium Alejová (Alejová 1, 04149 Košice)"], - [219,"Gymnázium M. R. Štefánika (Námestie L. Novomeského 4, 04224 Košice)"], - [430,"Gymnázium Park mládeže (Park mládeže 5, 04001 Košice)"], - [42,"Gymnázium Poštová (Poštová 9, 04001 Košice)"], - [307,"Gymnázium Šrobárova (Šrobárova 1, 04001 Košice)"], - [250,"Gymnázium Zbrojničná (Zbrojničná 3, 04001 Košice)"], - [345,"SPŠ elektrotechnická (Komenského 44, 04001 Košice)"], - [179,"SPŠ hutnícka (Alejová 1, 04011 Košice)"], - [-1,'Michalovce'], - [2,"Gymnázium Pavla Horova (Masarykova 1, 07179 Michalovce)"], - [142,"Stredná odborná škola technická (Partizánska 1, 07192 Michalovce)"], - [-1,'Rožňava'], - [178,"Gymnázium P. J. Šafárika (Akademika Hronca 1, 04801 Rožňava)"], - [-1,'Sobrance'], - [431,"Gymnázium Sobrance (Kpt. Nálepku 6, 07301 Sobrance)"], - [-1,'Spišská Nová Ves'], - [255,"Gymnázium Spišská Nová Ves (Školská 7, 05201 Spišská Nová Ves)"], - [-1,'Trebišov'], - [98,"Gymnázium Trebišov (Komenského 32, 07501 Trebišov)"], - [-1,'Veľké Kapušany'], - [93,"Gymnázium Veľké Kapušany (Zoltána Fábryho 1, 00791 Veľké Kapušany)"], - ], - 18: [ - [0,'--- Vyber si školu ---'], - [-1,'Levice'], - [243,"Gymnázium Andreja Vrábla (Mierová 5, 93403 Levice)"], - [-1,'Nitra'], - [37,"Gymnázium Golianova (Golianova 68, 95050 Nitra)"], - [99,"Gymnázium Párovská (Párovská 1, 95050 Nitra)"], - [138,"Gymnázium sv. Cyrila a Metóda (Farská 19, 94901 Nitra)"], - [229,"Piaristické gymnázium sv. J. Kalazanského (Piaristická 6, 94901 Nitra)"], - [320,"SPŠ Fraňa Kráľa (Fraňa Kráľa 20, 94901 Nitra)"], - [-1,'Nové Zámky'], - [300,"Gymnázium Nové Zámky (M. R. Štefánika 16, 94061 Nové Zámky)"], - [60,"Gymnázium Nové Zámky (M. R. Štefánika 16, 94061 Nové Zámky)"], - [429,"SPŠE S. A. Jedlíka a OA (Komárňanská 28, 94075 Nové Zámky)"], - [-1,'Šaľa'], - [439,"Gymnázium Juraja Fándlyho (Školská 3, 92701 Šaľa)"], - [-1,'Želiezovce'], - [215,"Gymnázium J. A. Komenského s VJM (Komenského 1, 93701 Želiezovce)"], - ], - 19: [ - [0,'--- Vyber si školu ---'], - [-1,'Bardejov'], - [487,"Gymnázium Leonarda Stöckela (Jiráskova 12, 08570 Bardejov)"], - [-1,'Poprad'], - [273,"Gymnázium Kukučínova (Kukučínova 4239/1, 05839 Poprad)"], - [445,"Spojená škola Dominika Tatarku (Dominika Tatarku 4666/7, 05801 Poprad)"], - [428,"Súkromná SOŠ Tatranská Akadémia (Ul. 29 augusta 4812, Poprad)"], - [-1,'Prešov'], - [239,"Gymnázium J. A. Raymana (Mudroňova 20, 08193 Prešov)"], - [62,"Gymnázium Konštantínova (Konštantínova 2, 08065 Prešov)"], - [280,"Gymnázium Sv. Mikuláša (Duklianská 16, 08001 Prešov)"], - [23,"Gymnázium svätej Moniky (Tarasa Ševčenka 1, 08001 Prešov)"], - [4,"Gymnázium T. Ševčenku s VJU (Sládkovičova 4, 08001 Prešov)"], - [32,"SPŠ elektrotechnická (Plzenská 1, 08047 Prešov)"], - [-1,'Sabinov'], - [261,"Gymnázium Antona Prídavka (Komenského 40, 08301 Sabinov)"], - [-1,'Stará Ľubovňa'], - [386,"Gymnázium Terézie Vansovej (17. novembra 6, 06401 Stará Ľubovňa)"], - [-1,'Svidník'], - [108,"Gymnázium duklianských hrdinov (Komenského 16, 08901 Svidník)"], - [-1,'Vranov'], - [262,"Gymnázium vo Vranove nad Topľou (Dr. C. Daxnera 88/3, 09380 Vranov nad Topľou)"], - ], - 20: [ - [0,'--- Vyber si školu ---'], - [-1,'Bánovce nad Bebravou'], - [410,"Gymnázium Janka Jesenského (Radlinského 665/2, 95701 Bánovce nad Bebravou)"], - [-1,'Dubnica nad Váhom'], - [253,"Gymnázium Dubnica nad Váhom (Školská 2, 01841 Dubnica nad Váhom)"], - [206,"Stredná priemyselná škola (Obrancov mieru 343/1, 01841 Dubnica nad Váhom)"], - [-1,'Myjava'], - [402,"SPŠ Myjava (Ul. SNP 413/8, 90701 Myjava)"], - [-1,'Nové Mesto nad Váhom'], - [26,"Gymnázium M. R. Štefánika (Športová 41, 91501 Nové Mesto nad Váhom)"], - [-1,'Partizánske'], - [468,"Gymnázium (Komenského 2/1074, 95801 Partizánske)"], - [-1,'Považská Bystrica'], - [159,"Gymnázium Považská Bystrica (Školská 234/8, 01701 Považská Bystrica)"], - [354,"SOŠ strojnícka (Športovcov 341/2, 01749 Považská Bystrica)"], - [-1,'Prievidza'], - [313,"Gymnázium V. B. Nedožerského (Matice slovenskej 16, 97101 Prievidza)"], - [-1,'Púchov'], - [311,"Gymnázium Púchov (Ul. 1. mája 905, 02015 Púchov)"], - [-1,'Stará Turá'], - [372,"Združená stredná škola elektrotechnická (Športová 675, 91601 Stará Turá)"], - [-1,'Trenčín'], - [5,"Gymnázium Ľudovíta Štúra (Ul. 1. mája 2, 91135 Trenčín)"], - ], - 21: [ - [0,'--- Vyber si školu ---'], - [-1,'Galanta'], - [478,"Gymnázium Janka Matúšku (Štvrť SNP 1004/43, 92401 Galanta)"], - [-1,'Hlohovec'], - [408,"Gymnázium Ivana Kupca (Komenského 211/13, 92001 Hlohovec)"], - [-1,'Piešťany'], - [112,"Gymnázium Pierra de Coubertina (Námestie SNP 9, 92126 Piešťany)"], - [-1,'Sereď'], - [395,"Gymnázium Vojtecha Mihálika Sereď (Kostolná 119, 92601 Sereď)"], - [-1,'Trnava'], - [467,"Gymnázium Angely Merici (Hviezdoslavova 10, 91701 Trnava)"], - [434,"SPŠ Komenského (Komenského 1, 91731 Trnava)"], - ], - 22: [ - [0,'--- Vyber si školu ---'], - [-1,'Čadca'], - [18,"Gymnázium J. M. Hurbana (17. novembra 1296, 02201 Čadca)"], - [-1,'Liptovský Hrádok'], - [436,"Gymnázium Liptovský Hrádok (Hradná 23, 03301 Liptovský Hrádok)"], - [-1,'Liptovský Mikuláš'], - [369,"Evanjelická spojená škola (Komenského 10, 03101 Liptovský Mikuláš)"], - [473,"Gymnázium M. M. Hodžu (Hodžova 860/9, 03136 Liptovský Mikuláš)"], - [-1,'Martin'], - [52,"Gymnázium V. P. Tótha (Malá Hora 3, 03601 Martin)"], - [-1,'Námestovo'], - [222,"Gymnázium A. Bernoláka (Mieru 307/23, 02901 Námestovo)"], - [-1,'Sučany'], - [141,"Bilingválne gymnázium Milana Hodžu (Komenského 215, 03852 Sučany)"], - [-1,'Trstená'], - [480,"Gymnázium Martina Hattalu v Trstenej (železničiarov 276, 02801 Trstená)"], - [-1,'Žilina'], - [54,"Gymnázium sv. Františka z Assisi (Hurbanova 44, 01001 Žilina)"], - [510,"Gymnázium Varšavská cesta 1 (Varšavská cesta 1, 010 08, Žilina)"], - [308,"Gymnázium Veľká okružná (Veľká okružná 22, 01001 Žilina)"], - [446,"Súkromné gymnázium Oravská (Oravska 11, 01001 Žilina)"], - ], - 23: [ - [0,'--- Vyber si školu ---'], - [-1,'Bath'], - [248,"Prior Park College (Ralph Allen Drive, Combe Down, Bath, BA25AH, United Kingdom)"], - [-1,'Bertrange'], - [547,"European School Luxembourg 2 (6 Rue Gaston Thorn L-8268 Bertrange)"], - [-1,'Dollar'], - [466,"Dollar Academy (Dollar, Clackmannanshire FK14 7DU, United Kingdom)"], - [-1,'Kyjev'], - [540,"Kyiv Natural Science Lyceum №145 (46 Shota Rustaveli Street, Kyiv, 01033, Ukraine)"], - [-1,'New Delhi'], - [371,"American Embassy School (Chandragupta Marg, Chanakyapuri, 110021 New Delhi)"], - [-1,'Neznámé'], - [414,"Neuvedená škola (Neuvedena)"], - [-1,'Vilnius'], - [541,"American International School of Vilnius (Subačiaus 41, Vilnius LT-11350, Lithuania)"], - ], -}; - - -function fill_options(sel, opts) -{ - while (sel.length > 0) { - sel.remove(sel.length-1); - } - while (sel.hasChildNodes()) { - sel.removeChild(sel.firstChild); - } - - var group = null; - for (i = 0; i < opts.length; i++) { - if (opts[i][0] < 0) { - group = document.createElement('optgroup'); - group.label = opts[i][1]; - sel.appendChild(group); - } else { - var opt = document.createElement('option'); - opt.value = opts[i][0]; - opt.text = opts[i][1]; // + ' (' + opts[i][0] + ')'; - if (group) { - group.appendChild(opt); - } else { - sel.add(opt, null); - } - } - } -} - -function region_changed() -{ - var reg = document.getElementById('id_kraj_select'); - var sch = document.getElementById('id_skola_select'); - var r = reg[reg.selectedIndex].value; - fill_options(sch, schools[r]); -} - -function country_changed() -{ - var ctry = document.getElementById('id_skola_stat_select'); - var reg = document.getElementById('id_kraj_select'); - var c = ctry[ctry.selectedIndex].value; - fill_options(reg, regions[c]); - region_changed(); -} - -function set_region_and_school(rid, sid) -{ - var ctry = document.getElementById('id_skola_stat_select'); - var c = ctry[ctry.selectedIndex].value; - var rr = regions[c]; - for (i=0; i= 0) { - cnt++; - } - } -} diff --git a/seminar/templates/seminar/prihlaska.html b/seminar/templates/seminar/prihlaska.html index 35e49163..d15c04d0 100644 --- a/seminar/templates/seminar/prihlaska.html +++ b/seminar/templates/seminar/prihlaska.html @@ -1,43 +1,100 @@ {% extends "seminar/zadani/base.html" %} {% load staticfiles %} -{% load static %} {% block script %} - - + + {{form.media}} + {% endblock %} {% block content %} -

- {% block nadpis1a %}{% block nadpis1b %} - Přihláška do semináře - {% endblock %}{% endblock %} -

+

+ {% block nadpis1a %}{% block nadpis1b %} + Přihláška do semináře + {% endblock %}{% endblock %} +

+ +
- {% csrf_token %} - {{form.non_field_errors}} -
    - {% for field in form %} -
  • - {% if forloop.last %} - {% include "seminar/gdpr.html" %} - {% endif %} - - {{ field }} - {% if field.help_text %}{{ field.help_text|safe }}{% endif %} - {% if field.errors %}{{ field.errors }}{% endif %} -
  • - {% endfor %} + {% csrf_token %} + {{form.non_field_errors}} +
      +
    • + {% include "seminar/prihlaska_field.html" with field=form.jmeno %} +
    • +
    • + {% include "seminar/prihlaska_field.html" with field=form.prijmeni %} +
    • +
    • + {% include "seminar/prihlaska_field.html" with field=form.username %} +
    • +
    • + {% include "seminar/prihlaska_field.html" with field=form.pohlavi_muz%} +
    • +
    • + {% include "seminar/prihlaska_field.html" with field=form.email %} +
    • +
    • + {% include "seminar/prihlaska_field.html" with field=form.telefon %} +
    • +
    • + {% include "seminar/prihlaska_field.html" with field=form.datum_narozeni %} +
    • +
    • +
      + Bydliště +
    • +
    • + {% include "seminar/prihlaska_field.html" with field=form.ulice %} +
    • +
    • + {% include "seminar/prihlaska_field.html" with field=form.mesto %} +
    • +
    • + {% include "seminar/prihlaska_field.html" with field=form.psc %} +
    • +
    • + {% include "seminar/prihlaska_field.html" with field=form.stat %} +
    • +
    • + {% include "seminar/prihlaska_field.html" with field=form.stat_text %} +
    • + +
    • +
      + {% include "seminar/prihlaska_field.html" with field=form.skola %} +
    • +
    • + +
    • +
    • + Vyplň prosím celý název a adresu školy.
      + {% include "seminar/prihlaska_field.html" with field=form.skola_nazev %} +
    • +
    • + {% include "seminar/prihlaska_field.html" with field=form.skola_adresa %} +
    • +
    • + {% include "seminar/prihlaska_field.html" with field=form.rok_maturity %} +
    • +
    • + {% include "seminar/prihlaska_field.html" with field=form.zasilat %} +
    • +
    • + {% include "seminar/gdpr.html" %} + {% include "seminar/prihlaska_field.html" with field=form.gdpr %} +
    • +
    • + {% include "seminar/prihlaska_field.html" with field=form.spam %} +
    -{{form.media}} {% endblock %} diff --git a/seminar/templates/seminar/prihlaska_field.html b/seminar/templates/seminar/prihlaska_field.html new file mode 100644 index 00000000..e37549ed --- /dev/null +++ b/seminar/templates/seminar/prihlaska_field.html @@ -0,0 +1,4 @@ + + {{field}} + {% if field.help_text %}{{ field.help_text|safe }}{% endif %} + {% if field.errors %}{{ field.errors }}{% endif %} diff --git a/seminar/views.py b/seminar/views.py index 69d110b0..c7bff438 100644 --- a/seminar/views.py +++ b/seminar/views.py @@ -10,6 +10,7 @@ from django.http import Http404,HttpResponseBadRequest,HttpResponseRedirect from django.db.models import Q from django.views.decorators.csrf import ensure_csrf_cookie from django.contrib.auth import authenticate, login, get_user_model +from django.db import transaction from dal import autocomplete from .models import Problem, Cislo, Reseni, Nastaveni, Rocnik, Soustredeni, Organizator, Resitel, Novinky, Soustredeni_Ucastnici, Pohadka, Tema, Clanek, Osoba, Skola @@ -32,6 +33,7 @@ import json import traceback import sys import csv +import logging def verejna_temata(rocnik): @@ -952,6 +954,7 @@ def texDownloadView(request, rocnik, cislo): ## Formulare def prihlaskaView(request): + logger = logging.getLogger('seminar.prihlaska') if request.method == 'POST': form = PrihlaskaForm(request.POST) # TODO vyresit, co se bude v jakych situacich zobrazovat @@ -975,53 +978,55 @@ def prihlaskaView(request): except ObjectDoesNotExist: pass - - u = User(username=form.cleaned_data['username']) - u.save() - - o = Osoba( - jmeno = form.cleaned_data['jmeno'], - prijmeni = form.cleaned_data['prijmeni'], - pohlavi_muz = form.cleaned_data['pohlavi_muz'], - email = form.cleaned_data['email'], - telefon = form.cleaned_data.get('telefon',''), - datum_narozeni = form.cleaned_data.get('datum_narozeni',None), - datum_souhlasu_udaje = date.today(), - datum_registrace = date.today(), - ulice = form.cleaned_data.get('ulice',''), - mesto = form.cleaned_data.get('mesto',''), - psc = form.cleaned_data.get('psc',''), - poznamka = str(form.cleaned_data) - ) - if form.cleaned_data.get('spam',False): - o.datum_souhlasu_zasilani = date.today() - if form.cleaned_data.get('stat','') in ('CZ','SK'): - o.stat = form.cleaned_data['stat'] - else: - pass - #TODO jak budeme resit jine staty? - - o.save() - o.user = u - o.save() - - r = Resitel( - rok_maturity = form.cleaned_data['rok_maturity'], - zasilat = form.cleaned_data['zasilat'] - ) - r.save() - r.osoba = o - if form.cleaned_data.get('skola'): - r.skola = form.cleaned_data['skola'] - else: - pass - #TODO doplnit skolu, kdyz neni v seznamu - r.save() + with transaction.atomic(): + u = User(username=form.cleaned_data['username']) + u.save() + + o = Osoba( + jmeno = form.cleaned_data['jmeno'], + prijmeni = form.cleaned_data['prijmeni'], + pohlavi_muz = form.cleaned_data['pohlavi_muz'], + email = form.cleaned_data['email'], + telefon = form.cleaned_data.get('telefon',''), + datum_narozeni = form.cleaned_data.get('datum_narozeni',None), + datum_souhlasu_udaje = date.today(), + datum_registrace = date.today(), + ulice = form.cleaned_data.get('ulice',''), + mesto = form.cleaned_data.get('mesto',''), + psc = form.cleaned_data.get('psc',''), + poznamka = str(form.cleaned_data) + ) + if form.cleaned_data.get('spam',False): + o.datum_souhlasu_zasilani = date.today() + if form.cleaned_data.get('stat','') in ('CZ','SK'): + o.stat = form.cleaned_data['stat'] + else: + pass + #TODO jak budeme resit jine staty? + + o.save() + o.user = u + o.save() + + r = Resitel( + rok_maturity = form.cleaned_data['rok_maturity'], + zasilat = form.cleaned_data['zasilat'] + ) + + r.save() + r.osoba = o + if form.cleaned_data.get('skola'): + r.skola = form.cleaned_data['skola'] + else: + pass + #TODO doplnit skolu, kdyz neni v seznamu + r.save() # TODO logovat jednotlive validni formulare do souboru print(form.cleaned_data) + logger.info(form.cleaned_data) return HttpResponseRedirect('/thanks/') # if a GET (or any other method) we'll create a blank form From 0f7b401a163f5281b40787eb96319f9bb4ba1dee Mon Sep 17 00:00:00 2001 From: "Tomas \"Jethro\" Pokorny" Date: Sun, 1 Sep 2019 22:59:05 +0200 Subject: [PATCH 23/92] Prihlaseni a odhlaseni uzivatele --- seminar/forms.py | 28 +++++++++++++++--- seminar/templates/seminar/login.html | 33 ++++++++++++++++++++++ seminar/templates/seminar/prihlaska.html | 18 ++++++++++-- seminar/urls.py | 7 +++-- seminar/views.py | 36 ++++++++++++++++++++++-- 5 files changed, 110 insertions(+), 12 deletions(-) create mode 100644 seminar/templates/seminar/login.html diff --git a/seminar/forms.py b/seminar/forms.py index 4455515e..830203a2 100644 --- a/seminar/forms.py +++ b/seminar/forms.py @@ -5,17 +5,35 @@ from .models import Skola, Resitel from datetime import date - +class LoginForm(forms.Form): + username = forms.CharField(label='Přihlašovací jméno', + max_length=256, + required=True) + password = forms.CharField( + label='Heslo', + max_length=256, + required=True, + widget=forms.PasswordInput()) class PrihlaskaForm(forms.Form): - jmeno = forms.CharField(label='Jméno', max_length=256, required=True) - prijmeni = forms.CharField(label='Příjmení', max_length=256, required=True) username = forms.CharField(label='Přihlašovací jméno', max_length=256, required=True, help_text='Tímto jménem se následně budeš přihlašovat pro odevzdání řešení a další činnosti v semináři') - # TODO heslo? + password = forms.CharField( + label='Heslo', + max_length=256, + required=True, + widget=forms.PasswordInput()) + password_check = forms.CharField( + label='Ověření hesla', + max_length=256, + required=True, + widget=forms.PasswordInput()) + + jmeno = forms.CharField(label='Jméno', max_length=256, required=True) + prijmeni = forms.CharField(label='Příjmení', max_length=256, required=True) pohlavi_muz = forms.ChoiceField(label='Pohlaví', choices = ((True,'muž'),(False,'žena')), required=True) email = forms.EmailField(label='E-mail',max_length=256, required=True) @@ -56,6 +74,8 @@ class PrihlaskaForm(forms.Form): def clean(self): super().clean() data = self.cleaned_data + if data.get('password') != data.get('password_check'): + self.add_error('password_check',forms.ValidationError('Hesla se neshodují')) if data.get('stat') != '' and data.get('stat_text') != '': self.add_error('stat',forms.ValidationError('Nelze mít vybraný stát z menu a zároven zapsaný textem')) if data.get('skola') and (data.get('skola_nazev') or data.get('skola_adresa')): diff --git a/seminar/templates/seminar/login.html b/seminar/templates/seminar/login.html new file mode 100644 index 00000000..dbed7a17 --- /dev/null +++ b/seminar/templates/seminar/login.html @@ -0,0 +1,33 @@ +{% extends "seminar/zadani/base.html" %} +{% load staticfiles %} + + +{% block content %} +

    + {% block nadpis1a %}{% block nadpis1b %} + Přihlášení + {% endblock %}{% endblock %} +

    +{% if login_error %} +{{login_error}} +{% endif %} +
    + {% csrf_token %} + {{form.non_field_errors}} +
      +
    • + {% include "seminar/prihlaska_field.html" with field=form.username %} +
    • +
    • + {% include "seminar/prihlaska_field.html" with field=form.password %} +
    • +
    + +
    + +Zapomněl jsem heslo
    +Zaregistrovat
    + + +{% endblock %} + diff --git a/seminar/templates/seminar/prihlaska.html b/seminar/templates/seminar/prihlaska.html index d15c04d0..c77bd4fc 100644 --- a/seminar/templates/seminar/prihlaska.html +++ b/seminar/templates/seminar/prihlaska.html @@ -20,13 +20,25 @@ {{form.non_field_errors}}
    • - {% include "seminar/prihlaska_field.html" with field=form.jmeno %} + Přihlašovací údaje
    • - {% include "seminar/prihlaska_field.html" with field=form.prijmeni %} + {% include "seminar/prihlaska_field.html" with field=form.username %}
    • - {% include "seminar/prihlaska_field.html" with field=form.username %} + {% include "seminar/prihlaska_field.html" with field=form.password %} +
    • +
    • + {% include "seminar/prihlaska_field.html" with field=form.password_check %} +
    • +
    • + Osobní údaje +
    • +
    • + {% include "seminar/prihlaska_field.html" with field=form.jmeno %} +
    • +
    • + {% include "seminar/prihlaska_field.html" with field=form.prijmeni %}
    • {% include "seminar/prihlaska_field.html" with field=form.pohlavi_muz%} diff --git a/seminar/urls.py b/seminar/urls.py index a8d4ff76..b7e39f47 100644 --- a/seminar/urls.py +++ b/seminar/urls.py @@ -3,6 +3,7 @@ from django.contrib.auth.decorators import user_passes_test from . import views, export from .utils import staff_member_required from django.views.generic.base import RedirectView +from django.contrib.auth import views as auth_views staff_member_required = user_passes_test(lambda u: u.is_staff) @@ -97,10 +98,12 @@ urlpatterns = [ staff_member_required(views.texUploadView), name='seminar_tex_upload' ), - path('prihlaska/',views.prihlaskaView), + path('prihlaska/',views.prihlaskaView, name='seminar_prihlaska'), + path('login/', views.loginView, name='login'), + path('logout/', views.logoutView, name='logout'), + path('autocomplete/skola/',views.SkolaAutocomplete.as_view(), name='autocomplete_skola'), path('', views.TitulniStranaView.as_view(), name='titulni_strana'), - path('autocomplete/skola/',views.SkolaAutocomplete.as_view(), name='autocomplete_skola') # Ceka na autocomplete v3 # path('autocomplete/organizatori/', # staff_member_required(views.OrganizatorAutocomplete.as_view()), diff --git a/seminar/views.py b/seminar/views.py index c7bff438..ee4dbc3a 100644 --- a/seminar/views.py +++ b/seminar/views.py @@ -9,7 +9,7 @@ from django.utils.translation import ugettext as _ from django.http import Http404,HttpResponseBadRequest,HttpResponseRedirect from django.db.models import Q from django.views.decorators.csrf import ensure_csrf_cookie -from django.contrib.auth import authenticate, login, get_user_model +from django.contrib.auth import authenticate, login, get_user_model, logout from django.db import transaction from dal import autocomplete @@ -17,7 +17,7 @@ from .models import Problem, Cislo, Reseni, Nastaveni, Rocnik, Soustredeni, Orga #from .models import VysledkyZaCislo, VysledkyKCisluZaRocnik, VysledkyKCisluOdjakziva from . import utils from .unicodecsv import UnicodeWriter -from .forms import PrihlaskaForm +from .forms import PrihlaskaForm, LoginForm from datetime import timedelta, date, datetime from django.utils import timezone @@ -952,6 +952,33 @@ def texDownloadView(request, rocnik, cislo): return JsonResponse(response) ## Formulare +def loginView(request): + if request.method == 'POST': + form = LoginForm(request.POST) + if form.is_valid(): + user = authenticate(request, + username=form.cleaned_data['username'], + password=form.cleaned_data['password']) + print(form.cleaned_data) + if user is not None: + login(request,user) + return HttpResponseRedirect('/') + else: + return render(request, + 'seminar/login.html', + {'form': form, 'login_error': 'Neplatné jméno nebo heslo'}) + + else: + form = LoginForm() + return render(request, 'seminar/login.html', {'form': form}) + +def logoutView(request): + form = LoginForm() + if request.user.is_authenticated: + logout(request) + return render(request, 'seminar/login.html', {'form': form, 'login_error': 'Byli jste úspěšně odhlášeni'}) + return render(request, 'seminar/login.html', {'form': form}) + def prihlaskaView(request): logger = logging.getLogger('seminar.prihlaska') @@ -980,7 +1007,10 @@ def prihlaskaView(request): pass with transaction.atomic(): - u = User(username=form.cleaned_data['username']) + u = User.objects.create_user( + username=form.cleaned_data['username'], + password=form.cleaned_data['password'], + email = form.cleaned_data['email']) u.save() o = Osoba( From 4091e25ee167cef7079b1c642f4e7a702af16734 Mon Sep 17 00:00:00 2001 From: "Tomas \"Jethro\" Pokorny" Date: Mon, 2 Sep 2019 00:01:39 +0200 Subject: [PATCH 24/92] Pridana stranka uzivatele a dummy views MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Dummy views - reset hesla, změna údajů Absolutni URL prevedeny na reverse lookup. --- seminar/templates/seminar/login.html | 6 +++--- seminar/templates/seminar/prihlaska.html | 2 +- seminar/templates/seminar/resitel.html | 17 +++++++++++++++++ seminar/urls.py | 9 ++++++--- seminar/views.py | 14 ++++++++++++++ 5 files changed, 41 insertions(+), 7 deletions(-) create mode 100644 seminar/templates/seminar/resitel.html diff --git a/seminar/templates/seminar/login.html b/seminar/templates/seminar/login.html index dbed7a17..88cd364f 100644 --- a/seminar/templates/seminar/login.html +++ b/seminar/templates/seminar/login.html @@ -11,7 +11,7 @@ {% if login_error %} {{login_error}} {% endif %} -
      + {% csrf_token %} {{form.non_field_errors}}
        @@ -25,8 +25,8 @@ -Zapomněl jsem heslo
        -Zaregistrovat
        +Zapomněl jsem heslo
        +Zaregistrovat
        {% endblock %} diff --git a/seminar/templates/seminar/prihlaska.html b/seminar/templates/seminar/prihlaska.html index c77bd4fc..8b17c0bd 100644 --- a/seminar/templates/seminar/prihlaska.html +++ b/seminar/templates/seminar/prihlaska.html @@ -15,7 +15,7 @@

-
+ {% csrf_token %} {{form.non_field_errors}}
    diff --git a/seminar/templates/seminar/resitel.html b/seminar/templates/seminar/resitel.html new file mode 100644 index 00000000..3a38a085 --- /dev/null +++ b/seminar/templates/seminar/resitel.html @@ -0,0 +1,17 @@ +{% extends "seminar/zadani/base.html" %} +{% load staticfiles %} + + +{% block content %} +

    + {% block nadpis1a %}{% block nadpis1b %} + Stránka řešitele - {{ object.osoba.jmeno }} {{ object.osoba.prijmeni }} + {% endblock %}{% endblock %} +

    + +Odhlásit se
    +Upravit údaje
    + + +{% endblock %} + diff --git a/seminar/urls.py b/seminar/urls.py index b7e39f47..c37d1357 100644 --- a/seminar/urls.py +++ b/seminar/urls.py @@ -98,10 +98,13 @@ urlpatterns = [ staff_member_required(views.texUploadView), name='seminar_tex_upload' ), - path('prihlaska/',views.prihlaskaView, name='seminar_prihlaska'), - path('login/', views.loginView, name='login'), - path('logout/', views.logoutView, name='logout'), + path('auth/prihlaska/',views.prihlaskaView, name='seminar_prihlaska'), + path('auth/login/', views.loginView, name='login'), + path('auth/logout/', views.logoutView, name='logout'), + path('auth/resitel/', views.ResitelView.as_view(), name='seminar_resitel'), path('autocomplete/skola/',views.SkolaAutocomplete.as_view(), name='autocomplete_skola'), + path('auth/reset_password', views.resetPasswordView, name='reset_password'), + path('auth/resitel_edit', views.resitelEditView, name='seminar_resitel_edit'), path('', views.TitulniStranaView.as_view(), name='titulni_strana'), # Ceka na autocomplete v3 diff --git a/seminar/views.py b/seminar/views.py index ee4dbc3a..60c75a1f 100644 --- a/seminar/views.py +++ b/seminar/views.py @@ -10,6 +10,7 @@ from django.http import Http404,HttpResponseBadRequest,HttpResponseRedirect from django.db.models import Q from django.views.decorators.csrf import ensure_csrf_cookie from django.contrib.auth import authenticate, login, get_user_model, logout +from django.contrib.auth.mixins import LoginRequiredMixin from django.db import transaction from dal import autocomplete @@ -951,7 +952,20 @@ def texDownloadView(request, rocnik, cislo): cislo.save() return JsonResponse(response) +class ResitelView(LoginRequiredMixin,generic.DetailView): + model = Resitel + template_name = 'seminar/resitel.html' + + def get_object(self, queryset=None): + print(self.request.user) + return Resitel.objects.get(osoba__user=self.request.user) + ## Formulare +def resitelEditView(request): + pass +def resetPasswordView(request): + pass + def loginView(request): if request.method == 'POST': form = LoginForm(request.POST) From 57a9822f684f389175d6de2773d19f7fecbb59dd Mon Sep 17 00:00:00 2001 From: Pavel 'LEdoian' Turinsky Date: Thu, 26 Sep 2019 20:46:14 +0200 Subject: [PATCH 25/92] =?UTF-8?q?Opraveno=20zobrazov=C3=A1n=C3=AD=20jmen?= =?UTF-8?q?=20TreeNod=C5=AF.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Teď ještě zmažu další stringy, zruším polymorfismus ap. --- seminar/models.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/seminar/models.py b/seminar/models.py index 42460c9a..ddd24b5c 100644 --- a/seminar/models.py +++ b/seminar/models.py @@ -1164,6 +1164,9 @@ class TreeNode(PolymorphicModel): blank = True, on_delete=models.SET_NULL, verbose_name="další element na stejné úrovni") + nazev = models.TextField("název tohoto node", + help_text = "Tento název se zobrazuje v nabídkách pro výběr vhodného TreeNode", + blank=False, null=True) def print_tree(self,indent=0): print("{}TreeNode({})".format(" "*indent,self.id)) @@ -1173,7 +1176,7 @@ class TreeNode(PolymorphicModel): self.succ.print_tree(indent=indent) def __str__(self): - return "Generický TreeNode!" + return self.nazev class RocnikNode(TreeNode): class Meta: From 84017f8ca594243600f4b1e7617cf3e25327c4e9 Mon Sep 17 00:00:00 2001 From: Anet Date: Wed, 16 Oct 2019 20:11:02 +0200 Subject: [PATCH 26/92] Rozpracovane upravy views. --- seminar/views.py | 131 +++++++++++++++++++++++++++++------------------ 1 file changed, 81 insertions(+), 50 deletions(-) diff --git a/seminar/views.py b/seminar/views.py index 57c85b65..be80a4df 100644 --- a/seminar/views.py +++ b/seminar/views.py @@ -252,6 +252,7 @@ class ArchivView(generic.ListView): context["nahledy"] = "\n".join(tags) return context +### Výsledky def sloupec_s_poradim(vysledky): # počet řešitelů ve výsledkovce nad aktuálním @@ -264,14 +265,80 @@ def sloupec_s_poradim(vysledky): # připravíme si obsahy buněk ve sloupci pořadí pro skupinu if len(skupina) == 1: poradi_l += ["{}.".format(lepsich_resitelu + 1)] - # je-li účastníků se stejným počtem bodů víc, pořadí (rozsah X.-Y.) je jen u prvního + # je-li účastníků se stejným počtem bodů víc, + # pořadí (rozsah X.-Y.) je jen u prvního else: - poradi_l += [u"{}.–{}.".format(lepsich_resitelu + 1, lepsich_resitelu + len(skupina))] + [""] * (len(skupina)-1) + poradi_l += ["{}.–{}.".format(lepsich_resitelu + 1, lepsich_resitelu + len(skupina))] + [""] * (len(skupina)-1) lepsich_resitelu += len(skupina) #pomlcka je opravdu pomlcka v unicode!!dulezite pro vysledkovku v TeXu return poradi_l +# spočítá součet bodů získaných daným řešitelem za zadaný problém a všechny jeho podproblémy +def __soucet_resitele_problemu(problem, resitel, soucet): + # FIXME: správně je nadproblem_(typ problemu), ale to by bylo potřeba nějak + # zjistit, jaký typ nodu to vlastně je a aplikovat to ve volání funkce + + # sečteme body za daný problém přes všechna řešení daného problému + # od daného řešitele + reseni_resitele = problem.hodnoceni_set.filter(reseni_resitele__contains=resitel) + for r in reseni_resitele: + soucet += r.body + + for p in problem.nadproblem_set: + # i přes jméno by to měla být množina jeho podproblémů + soucet += __soucet_resitele_problemu(p, resitel, soucet) + return soucet + +# spočítá součet všech bodů ze všech podproblémů daného problému daného řešitele +def body_resitele_problemu_v_cisle(problem, resitel, cislo): + return __soucet_resitele_problemu(problem, resitel, 0) + +# vrátí list všech problémů s body v daném čísle, které již nemají nadproblém +def hlavni_problemy_cisla(cislo): + hodnoceni = cislo.hodnoceni_set # hodnocení, která se vážou k danému číslu + + reseni = [h.reseni for h in hodnoceni] + problemy = [h.problem for h in hodnoceni] + problemy_set = set(problemy) # chceme každý problém unikátně, + problemy = (list(problemy_set)) # převedení na množinu a zpět to zaručí + + # hlavní problémy čísla + # (mají vlastní sloupeček ve výsledkovce, nemají nadproblém) + hlavni_problemy = [] + for p in problemy: + while not(p.nadproblem == None): + p = p.nadproblem + hlavni_problemy.append(p) + + # zunikátnění + hlavni_problemy_set = set(hlavni_problemy) + hlavni_problemy = list(hlavni_problemy_set) + + return hlavni_problemy + + +# spočítá součet všech bodů řešitele za dané číslo +def body_resitele_v_cisle(resitel, cislo): + hlavni_problemy = hlavni_problemy_cisla(cislo) + for h in hlavni_problemy: + body_resitele = body_resitele + body_resitele_problemu_v_cisle(resitel, cislo) + # TODO: je rozdíl mezi odevzdanou úlohou za 0 a tím, když řešitel nic neodevzdal + # řešit přes kontrolu velikosti množiny řešení daného problému do daného čísla? + # Tady to ale nevadí, tady se počítá součet za číslo. + return body_resitele + +# spočítá součet všech bodů řešitele za daný rok (nebo jen do daného čísla včetně) +def body_resitele_v_rocniku(resitel, rocnik_node, do_cisla=None) + # pokud do_cisla=None, tak do posledního čísla v ročníku + # do_cisla je objekt Cislo + cislo_node = rocnik_node.firstChild + body = 0 + while not (cislo_node = None or cislo_node.cislo = do_cisla.CisloNode.next): + # druhá část zaručuje, že máme výsledky do daného čísla včetně + body = body + body_resitele_v_cisle(resitel, cislo_node.cislo) + cislo_node = cislo_node.next + return body #def vysledkovka_rocniku(rocnik, jen_verejne=True): # """Přebírá ročník (např. context["rocnik"]) a vrací výsledkovou listinu ve @@ -380,11 +447,11 @@ class ProblemView(generic.DetailView): class VysledkyResitele(object): """Pro daného řešitele ukládá počet bodů za jednotlivé úlohy a celkový - počet bodů za číslo.""" + počet bodů za konkrétní číslo.""" - def __init__(self, jmeno, prijmeni): - resitel_jmeno = jmeno - resitel_prijmeni = prijmeni + def __init__(self, resitel): + resitel_jmeno = resitel.osoba.jmeno + resitel_prijmeni = resitel.osoba.prijmeni body = {} body_cislo = 0 @@ -410,50 +477,12 @@ class CisloView(generic.DetailView): {'verbose_name': queryset.model._meta.verbose_name}) return obj - # spočítá součet bodů získaných daným řešitelem za zadaný problém a všechny jeho podproblémy - def __soucet_resitele_problemu(problem, resitel, soucet): - # FIXME: správně je nadproblem_(typ problemu), ale to by bylo potřeba nějak - # zjistit, jaký typ nodu to vlastně je a aplikovat to ve volání funkce - - # sečteme body za daný problém přes všechna řešení daného problému - # od daného řešitele - reseni_resitele = problem.hodnoceni_set.filter(reseni_resitele__contains=resitel) - for r in reseni_resitele: - soucet += r.body - - for p in problem.nadproblem_set: - # i přes jméno by to měla být množina jeho podproblémů - soucet += __soucet_resitele_problemu(p, resitel, soucet) - return soucet - - - def vysledky_resitele_problemu(problem, resitel, cislo): - return __soucet_resitele_problemu(problem, resitel, 0) - - def get_context_data(self, **kwargs): context = super(CisloView, self).get_context_data(**kwargs) ## TODO upravit dle nového modelu cislo = context['cislo'] - hodnoceni = cislo.hodnoceni_set # hodnocení, která se vážou k danému číslu - - reseni = [h.reseni for h in hodnoceni] - problemy = [h.problem for h in hodnoceni] - problemy_set = set(problemy) # chceme každý problém unikátně, - problemy = (list(problemy_set)) # převedení na množinu a zpět to zaručí - - # hlavní problémy čísla - # (mají vlastní sloupeček ve výsledkovce, nemají nadproblém) - hlavni_problemy = [] - for p in problemy: - while not(p.nadproblem == None): - p = nadproblem - hlavni_problemy.append(p) - - # zunikátnění - hlavni_problemy_set = set(hlavni_problemy) - hlavni_problemy = list(hlavni_problemy_set) + hlavni_problemy = hlavni_problemy_cisla(cislo) ## TODO dostat pro tyto problémy součet v daném čísle pro daného řešitele ## TODO možná chytřeji vybírat aktivní řešitele @@ -463,15 +492,16 @@ class CisloView(generic.DetailView): #.filter(hodnoceni_set__rocnik__eq=cislo_rocnik) radky_vysledkovky = [] for ar in aktivni_resitele: - vr = VysledkyResitele(ar.jmeno, ar.prijmeni) + vr = VysledkyResitele(ar) for h in hlavni_problemy: - body = vysledky_resitele_problemu(h, ar, cislo) - vr.body[h.kod_v_rocniku] = body + body = body_resitele_problemu_v_cisle(h, ar, cislo) +# vr.body[h.kod_v_rocniku] = body vr.body_cislo = vr.body_cislo + body radky_vysledkovky.append(vr) ## TODO: spočítat počet bodů řešitele v daném ročníku a seřadit je podle toho - ## TODO: možná použít tyto funkce i v RocnikVysledkovkaView (a umístit sem nebo tam)? + ## řazení viz fce výše - pochopit a případně přepsat + ## počet bodů udělat ve fce body_resitele_v_rocniku # vysledky = VysledkyKCisluZaRocnik.objects.filter(cislo = context['cislo']).\ @@ -487,6 +517,7 @@ class CisloView(generic.DetailView): # # poradi_typu = { # Problem.TYP_ULOHA: 1, + # Problem.TYP_SERIAL: 2, # Problem.TYP_ORG_CLANEK: 3, # Problem.TYP_TEMA: 4, @@ -529,7 +560,7 @@ class CisloView(generic.DetailView): # context['problemy'] = problemy # context['v_cisle_zadane'] = v_cisle_zadane # context['resene_problemy'] = resene_problemy -# return context + return context class ArchivTemataView(generic.ListView): model = Problem From 91714c756582e277a87567a15999cd292969a2b3 Mon Sep 17 00:00:00 2001 From: "Tomas \"Jethro\" Pokorny" Date: Wed, 16 Oct 2019 22:27:57 +0200 Subject: [PATCH 27/92] =?UTF-8?q?Nov=C3=A1=20aplikace=20na=20menu.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mamweb/settings_common.py | 3 +++ mamweb/templates/base.html | 21 +++++++++++++++++++++ requirements.txt | 1 + 3 files changed, 25 insertions(+) diff --git a/mamweb/settings_common.py b/mamweb/settings_common.py index 1a8984e3..7bdd6abf 100644 --- a/mamweb/settings_common.py +++ b/mamweb/settings_common.py @@ -74,6 +74,7 @@ TEMPLATES = [ 'OPTIONS': { 'context_processors': ( 'django.contrib.auth.context_processors.auth', + 'django.template.context_processors.request', 'django.contrib.messages.context_processors.messages', 'sekizai.context_processors.sekizai', 'mamweb.context_processors.vzhled', @@ -114,6 +115,8 @@ INSTALLED_APPS = ( 'django.contrib.flatpages', 'django.contrib.humanize', + 'sitetree', + 'imagekit', 'polymorphic', diff --git a/mamweb/templates/base.html b/mamweb/templates/base.html index 310234da..50a865bd 100644 --- a/mamweb/templates/base.html +++ b/mamweb/templates/base.html @@ -1,4 +1,5 @@ {% load staticfiles sekizai_tags %} +{% load sitetree %} @@ -96,6 +97,26 @@
    + {% sitetree_menu from "main_menu" include "trunk" %} + + {# + {% for item in menu_top %} +
  • + {{ item.name }} +
  • + {% if item.submenu %} + + {% endif %} + {% endfor %} + #} + +
    {% block content %} {% endblock content %} diff --git a/requirements.txt b/requirements.txt index 99794896..f2fd4306 100644 --- a/requirements.txt +++ b/requirements.txt @@ -26,6 +26,7 @@ django-autocomplete-light django-crispy-forms django-imagekit django-polymorphic +django-sitetree # Comments akismet==1.0.1 From a8438a588c7a8f99fb82cf7d970f399695bbcffa Mon Sep 17 00:00:00 2001 From: "Tomas \"Jethro\" Pokorny" Date: Wed, 16 Oct 2019 22:28:46 +0200 Subject: [PATCH 28/92] Zobrazovat chyby od werkzeugu, abychom vedeli PIN --- mamweb/settings_local.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mamweb/settings_local.py b/mamweb/settings_local.py index e5011926..517772ee 100644 --- a/mamweb/settings_local.py +++ b/mamweb/settings_local.py @@ -72,6 +72,11 @@ LOGGING = { }, }, 'loggers': { + 'werkzeug': { + 'handlers': ['console'], + 'level': 'DEBUG', + 'propagate': True, + }, '': { 'handlers': ['console'], 'level': 'DEBUG', From 82cfb95323bb90c66c2817ca965b2d99de627b9e Mon Sep 17 00:00:00 2001 From: Anet Date: Wed, 16 Oct 2019 23:04:51 +0200 Subject: [PATCH 29/92] =?UTF-8?q?Oprava=20syntaktick=C3=BDch=20chyb.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/seminar/views.py b/seminar/views.py index 5a80bdf7..1b540197 100644 --- a/seminar/views.py +++ b/seminar/views.py @@ -334,12 +334,12 @@ def body_resitele_v_cisle(resitel, cislo): return body_resitele # spočítá součet všech bodů řešitele za daný rok (nebo jen do daného čísla včetně) -def body_resitele_v_rocniku(resitel, rocnik_node, do_cisla=None) +def body_resitele_v_rocniku(resitel, rocnik_node, do_cisla=None): # pokud do_cisla=None, tak do posledního čísla v ročníku # do_cisla je objekt Cislo cislo_node = rocnik_node.firstChild body = 0 - while not (cislo_node = None or cislo_node.cislo = do_cisla.CisloNode.next): + while not (cislo_node == None or cislo_node.cislo == do_cisla.CisloNode.next): # druhá část zaručuje, že máme výsledky do daného čísla včetně body = body + body_resitele_v_cisle(resitel, cislo_node.cislo) cislo_node = cislo_node.next From c61a5d1bd92518fbd59dd1c63ba46f18c3606ffb Mon Sep 17 00:00:00 2001 From: Anet Date: Wed, 16 Oct 2019 23:06:46 +0200 Subject: [PATCH 30/92] Zalomeni komentare na dalsi radek. --- seminar/testutils.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/seminar/testutils.py b/seminar/testutils.py index bb60c11e..83a5ae4b 100644 --- a/seminar/testutils.py +++ b/seminar/testutils.py @@ -474,7 +474,8 @@ def gen_ulohy_k_tematum(rnd, rocniky, rocnik_cisla, rocnik_temata, organizatori) zad = TextNode.objects.create(text = text_zadani) uloha_zadani = UlohaZadaniNode.objects.create(uloha=p, first_child = zad) p.ulohazadaninode = uloha_zadani - otec_syn(mozna_tema_vcn, uloha_zadani) # TODO dělá se podproblém takto??? TODO + otec_syn(mozna_tema_vcn, uloha_zadani) + # TODO dělá se podproblém takto??? TODO text_vzoraku = Text.objects.create( na_web = rnd.choice(reseni), From 430d696c350839d0c853cda6fbd927e5f63ccb6a Mon Sep 17 00:00:00 2001 From: Anet Date: Wed, 16 Oct 2019 23:07:09 +0200 Subject: [PATCH 31/92] Pridany prikaz na stahovani aktualnich flatpages z produkce. --- Makefile | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Makefile b/Makefile index d01fb576..c553e86f 100644 --- a/Makefile +++ b/Makefile @@ -94,6 +94,15 @@ deploy_prod: venv_check @echo Done. +sync_prod_flatpages: + @echo Downloading current version of flatpages from mamweb-prod. + ssh mam-web@gimli.ms.mff.cuni.cz \ + "cd /akce/mam/www/mamweb-prod; ./manage.py dumpdata flatpages --indent=2 > flat.json" + rsync -ave ssh mam-web@gimli.ms.mff.cuni.cz:/akce/mam/www/mamweb-prod/flat.json ./flat.json + @echo "Applying downloaded flatpages." + ./manage.py loaddata flat.json + @echo "Done." + # Sync test media directory with production sync_test_media: @if [ ${USER} != "mam-web" ]; then echo "Only possible by user mam-web"; exit 1; fi From 281c66df1150eba59e15ad256823fc08fd0b7199 Mon Sep 17 00:00:00 2001 From: Pavel 'LEdoian' Turinsky Date: Tue, 22 Oct 2019 21:39:34 +0200 Subject: [PATCH 32/92] Part1 --- seminar/models.py | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/seminar/models.py b/seminar/models.py index ddd24b5c..a3c69512 100644 --- a/seminar/models.py +++ b/seminar/models.py @@ -1147,6 +1147,7 @@ class TreeNode(PolymorphicModel): verbose_name = "TreeNode" verbose_name_plural = "TreeNody" + # TODO: Nechceme radši jako root vyžadovat přímo RocnikNode? root = models.ForeignKey('TreeNode', related_name="potomci_set", null = True, @@ -1176,7 +1177,11 @@ class TreeNode(PolymorphicModel): self.succ.print_tree(indent=indent) def __str__(self): - return self.nazev + if self.nazev: + return self.nazev + else: + #TODO: logování + return "Nepojmenovaný Treenode" class RocnikNode(TreeNode): class Meta: @@ -1186,8 +1191,6 @@ class RocnikNode(TreeNode): rocnik = models.OneToOneField(Rocnik, on_delete = models.PROTECT, # Pokud chci mazat ročník, musím si Node pořešit ručně verbose_name = "ročník") - def __str__(self): - return 'RocnikNode: '+str(self.rocnik) class CisloNode(TreeNode): class Meta: @@ -1197,16 +1200,12 @@ class CisloNode(TreeNode): cislo = models.OneToOneField(Cislo, on_delete = models.PROTECT, # Pokud chci mazat číslo, musím si Node pořešit ručně verbose_name = "číslo") - def __str__(self): - return 'CisloNode: '+str(self.cislo) class MezicisloNode(TreeNode): class Meta: db_table = 'seminar_nodes_mezicislo' verbose_name = 'Mezičíslo (Node)' verbose_name_plural = 'Mezičísla (Node)' - def __str__(self): - return 'MezicisloNode' class TemaVCisleNode(TreeNode): """ Obsahuje příspěvky k tématu v daném čísle """ @@ -1217,8 +1216,6 @@ class TemaVCisleNode(TreeNode): tema = models.ForeignKey(Tema, on_delete=models.PROTECT, # Pokud chci mazat téma, musím si Node pořešit ručně verbose_name = "téma v čísle") - def __str__(self): - return 'TemaVCisleNode: tema: '+str(self.tema) class KonferaNode(TreeNode): class Meta: @@ -1230,8 +1227,6 @@ class KonferaNode(TreeNode): verbose_name = "konfera", null=True, blank=False) - def __str__(self): - return 'KonferaNode: '+str(self.konfera) class ClanekNode(TreeNode): class Meta: @@ -1243,8 +1238,6 @@ class ClanekNode(TreeNode): verbose_name = "článek", null=True, blank=False) - def __str__(self): - return 'ClanekNode: '+str(self.clanek) class UlohaZadaniNode(TreeNode): class Meta: @@ -1256,8 +1249,6 @@ class UlohaZadaniNode(TreeNode): verbose_name = "úloha", null=True, blank=False) - def __str__(self): - return 'UlohaZadaniNode: '+str(self.uloha) class PohadkaNode(TreeNode): class Meta: @@ -1268,8 +1259,6 @@ class PohadkaNode(TreeNode): on_delete=models.PROTECT, # Pokud chci mazat pohádku, musím si Node pořešit ručně verbose_name = "pohádka", ) - def __str__(self): - return 'PohadkaNode: '+str(self.pohadka) class UlohaVzorakNode(TreeNode): class Meta: @@ -1281,8 +1270,6 @@ class UlohaVzorakNode(TreeNode): verbose_name = "úloha", null=True, blank=False) - def __str__(self): - return 'UlohaVzorakNode: '+str(self.uloha) class TextNode(TreeNode): class Meta: @@ -1292,8 +1279,6 @@ class TextNode(TreeNode): text = models.ForeignKey(Text, on_delete=models.PROTECT, verbose_name = 'text') - def __str__(self): - return 'TextNode: '+str(self.text) ## FIXME: Logiku přesunout do views. #class VysledkyBase(SeminarModelBase): From 34b785e235a846bb405949295ce717402ac9e10a Mon Sep 17 00:00:00 2001 From: Pavel 'LEdoian' Turinsky Date: Tue, 22 Oct 2019 21:51:16 +0200 Subject: [PATCH 33/92] A Migration --- seminar/migrations/0002_treenode_nazev.py | 104 ++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 seminar/migrations/0002_treenode_nazev.py diff --git a/seminar/migrations/0002_treenode_nazev.py b/seminar/migrations/0002_treenode_nazev.py new file mode 100644 index 00000000..ede4b697 --- /dev/null +++ b/seminar/migrations/0002_treenode_nazev.py @@ -0,0 +1,104 @@ +# Generated by Django 2.2.5 on 2019-09-26 19:35 + +from django.db import migrations, models + +def fix_RocnikNode_names(apps,schema_editor): + Objects = apps.get_model('seminar', 'RocnikNode') + for obj in Objects.objects.all(): + obj.nazev = str(obj.rocnik)+" (RocnikNode)" + obj.save() + +def fix_CisloNode_names(apps,schema_editor): + Objects = apps.get_model('seminar', 'CisloNode') + for obj in Objects.objects.all(): + obj.nazev = str(obj.cislo)+" (CisloNode)" + obj.save() + +def fix_MezicisloNode_names(apps,schema_editor): + Objects = apps.get_model('seminar', 'MezicisloNode') + for obj in Objects.objects.all(): + if obj.prev: + if (obj.prev.get_real_instance_class() != CisloNode and + obj.prev.get_real_instance_class() != MezicisloNode): + raise ValueError("Předchůdce není číslo!") + posledni = obj.prev.cislo + obj.nazev = "Mezičíslo po čísle"+str(posledni)+" (MezicisloNode)" + elif obj.root: + if obj.root.get_real_instance_class() != RocnikNode: + raise ValueError("Kořen stromu není ročník!") + rocnik = obj.root.rocnik + obj.nazev = "První mezičíslo ročníku "+" (MezicisloNode)" + else: + print("!!!!! Nějaké neidentifikované mezičíslo !!!!!") + obj.nazev = "Neidentifikovatelné mezičíslo! (MezicisloNode)" + obj.save() + +def fix_TemaVCisleNode_names(apps,schema_editor): + Objects = apps.get_model('seminar', 'TemaVCisleNode') + for obj in Objects.objects.all(): + obj.nazev = str(obj.tema)+" (TemaVCisleNode)" + obj.save() + +def fix_KonferaNode_names(apps,schema_editor): + Objects = apps.get_model('seminar', 'KonferaNode') + for obj in Objects.objects.all(): + obj.nazev = str(obj.konfera)+" (KonferaNode)" + obj.save() + +def fix_ClanekNode_names(apps,schema_editor): + Objects = apps.get_model('seminar', 'ClanekNode') + for obj in Objects.objects.all(): + obj.nazev = str(obj.clanek)+" (ClanekNode)" + obj.save() + +def fix_UlohaZadaniNode_names(apps,schema_editor): + Objects = apps.get_model('seminar', 'UlohaZadaniNode') + for obj in Objects.objects.all(): + obj.nazev = str(obj.uloha)+" (UlohaZadaniNode)" + obj.save() + +def fix_PohadkaNode_names(apps,schema_editor): + Objects = apps.get_model('seminar', 'PohadkaNode') + for obj in Objects.objects.all(): + obj.nazev = str(obj.pohadka)+" (PohadkaNode)" + obj.save() + +def fix_UlohaVzorakNode_names(apps,schema_editor): + Objects = apps.get_model('seminar', 'UlohaVzorakNode') + for obj in Objects.objects.all(): + obj.nazev = str(obj.uloha)+" (UlohaVzorakNode)" + obj.save() + +def fix_TextNode_names(apps,schema_editor): + Objects = apps.get_model('seminar', 'TextNode') + for obj in Objects.objects.all(): + obj.nazev = str(obj.text)+" (TextNode)" + obj.save() + +def fix_all_names(apps,schema_editor): + fix_RocnikNode_names(apps,schema_editor) + fix_CisloNode_names(apps,schema_editor) + fix_MezicisloNode_names(apps,schema_editor) + fix_TemaVCisleNode_names(apps,schema_editor) + fix_KonferaNode_names(apps,schema_editor) + fix_ClanekNode_names(apps,schema_editor) + fix_UlohaZadaniNode_names(apps,schema_editor) + fix_PohadkaNode_names(apps,schema_editor) + fix_UlohaVzorakNode_names(apps,schema_editor) + fix_TextNode_names(apps,schema_editor) + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0001_reset'), + ] + + operations = [ + migrations.AddField( + model_name='treenode', + name='nazev', + field=models.TextField(help_text='Tento název se zobrazuje v nabídkách pro výběr vhodného TreeNode', null=True, verbose_name='název tohoto node'), + ), + migrations.RunPython(fix_all_names), + ] From 4f499330b13bf3e8a182acd4e913c4268f4838e5 Mon Sep 17 00:00:00 2001 From: Pavel 'LEdoian' Turinsky Date: Wed, 23 Oct 2019 22:24:07 +0200 Subject: [PATCH 34/92] =?UTF-8?q?P=C5=99id=C3=A1na=20funkce=20na=20aktuali?= =?UTF-8?q?zaci=20n=C3=A1zvu=20*Nod=C5=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/migrations/0002_treenode_nazev.py | 101 ++++------------------ seminar/models.py | 53 ++++++++++++ 2 files changed, 70 insertions(+), 84 deletions(-) diff --git a/seminar/migrations/0002_treenode_nazev.py b/seminar/migrations/0002_treenode_nazev.py index ede4b697..896ca744 100644 --- a/seminar/migrations/0002_treenode_nazev.py +++ b/seminar/migrations/0002_treenode_nazev.py @@ -2,91 +2,24 @@ from django.db import migrations, models -def fix_RocnikNode_names(apps,schema_editor): - Objects = apps.get_model('seminar', 'RocnikNode') - for obj in Objects.objects.all(): - obj.nazev = str(obj.rocnik)+" (RocnikNode)" - obj.save() - -def fix_CisloNode_names(apps,schema_editor): - Objects = apps.get_model('seminar', 'CisloNode') - for obj in Objects.objects.all(): - obj.nazev = str(obj.cislo)+" (CisloNode)" - obj.save() - -def fix_MezicisloNode_names(apps,schema_editor): - Objects = apps.get_model('seminar', 'MezicisloNode') - for obj in Objects.objects.all(): - if obj.prev: - if (obj.prev.get_real_instance_class() != CisloNode and - obj.prev.get_real_instance_class() != MezicisloNode): - raise ValueError("Předchůdce není číslo!") - posledni = obj.prev.cislo - obj.nazev = "Mezičíslo po čísle"+str(posledni)+" (MezicisloNode)" - elif obj.root: - if obj.root.get_real_instance_class() != RocnikNode: - raise ValueError("Kořen stromu není ročník!") - rocnik = obj.root.rocnik - obj.nazev = "První mezičíslo ročníku "+" (MezicisloNode)" - else: - print("!!!!! Nějaké neidentifikované mezičíslo !!!!!") - obj.nazev = "Neidentifikovatelné mezičíslo! (MezicisloNode)" - obj.save() - -def fix_TemaVCisleNode_names(apps,schema_editor): - Objects = apps.get_model('seminar', 'TemaVCisleNode') - for obj in Objects.objects.all(): - obj.nazev = str(obj.tema)+" (TemaVCisleNode)" - obj.save() - -def fix_KonferaNode_names(apps,schema_editor): - Objects = apps.get_model('seminar', 'KonferaNode') - for obj in Objects.objects.all(): - obj.nazev = str(obj.konfera)+" (KonferaNode)" - obj.save() - -def fix_ClanekNode_names(apps,schema_editor): - Objects = apps.get_model('seminar', 'ClanekNode') - for obj in Objects.objects.all(): - obj.nazev = str(obj.clanek)+" (ClanekNode)" - obj.save() - -def fix_UlohaZadaniNode_names(apps,schema_editor): - Objects = apps.get_model('seminar', 'UlohaZadaniNode') - for obj in Objects.objects.all(): - obj.nazev = str(obj.uloha)+" (UlohaZadaniNode)" - obj.save() - -def fix_PohadkaNode_names(apps,schema_editor): - Objects = apps.get_model('seminar', 'PohadkaNode') - for obj in Objects.objects.all(): - obj.nazev = str(obj.pohadka)+" (PohadkaNode)" - obj.save() - -def fix_UlohaVzorakNode_names(apps,schema_editor): - Objects = apps.get_model('seminar', 'UlohaVzorakNode') - for obj in Objects.objects.all(): - obj.nazev = str(obj.uloha)+" (UlohaVzorakNode)" - obj.save() - -def fix_TextNode_names(apps,schema_editor): - Objects = apps.get_model('seminar', 'TextNode') - for obj in Objects.objects.all(): - obj.nazev = str(obj.text)+" (TextNode)" - obj.save() - def fix_all_names(apps,schema_editor): - fix_RocnikNode_names(apps,schema_editor) - fix_CisloNode_names(apps,schema_editor) - fix_MezicisloNode_names(apps,schema_editor) - fix_TemaVCisleNode_names(apps,schema_editor) - fix_KonferaNode_names(apps,schema_editor) - fix_ClanekNode_names(apps,schema_editor) - fix_UlohaZadaniNode_names(apps,schema_editor) - fix_PohadkaNode_names(apps,schema_editor) - fix_UlohaVzorakNode_names(apps,schema_editor) - fix_TextNode_names(apps,schema_editor) - + for objtype in [ + "RocnikNode", + "CisloNode", + "MezicisloNode", + "TemaVCisleNode", + "KonferaNode", + "ClanekNode", + "UlohaZadaniNode", + "PohadkaNode", + "UlohaVzorakNode", + "TextNode", + ]: + Objects = apps.get_model('seminar', objtype) + for obj in Objects.objects.all(): + obj.aktualizuj_nazev() + # Better save than sorry + obj.save() class Migration(migrations.Migration): diff --git a/seminar/models.py b/seminar/models.py index a3c69512..9eefdec4 100644 --- a/seminar/models.py +++ b/seminar/models.py @@ -1192,6 +1192,10 @@ class RocnikNode(TreeNode): on_delete = models.PROTECT, # Pokud chci mazat ročník, musím si Node pořešit ručně verbose_name = "ročník") + def aktualizuj_nazev(self): + self.nazev = "RocnikNode: "+str(self.rocnik) + self.save() + class CisloNode(TreeNode): class Meta: db_table = 'seminar_nodes_cislo' @@ -1201,12 +1205,33 @@ class CisloNode(TreeNode): on_delete = models.PROTECT, # Pokud chci mazat číslo, musím si Node pořešit ručně verbose_name = "číslo") + def aktualizuj_nazev(self): + self.nazev = "CisloNode: "+str(self.cislo) + self.save() + class MezicisloNode(TreeNode): class Meta: db_table = 'seminar_nodes_mezicislo' verbose_name = 'Mezičíslo (Node)' verbose_name_plural = 'Mezičísla (Node)' + def aktualizuj_nazev(self): + if self.prev: + if (self.prev.get_real_instance_class() != CisloNode and + self.prev.get_real_instance_class() != MezicisloNode): + raise ValueError("Předchůdce není číslo!") + posledni = self.prev.cislo + self.nazev = "MezicisloNode: Mezičíslo po čísle"+str(posledni) + elif self.root: + if self.root.get_real_instance_class() != RocnikNode: + raise ValueError("Kořen stromu není ročník!") + rocnik = self.root.rocnik + self.nazev = "MezicisloNode: První mezičíslo ročníku "+str(rocnik) + else: + print("!!!!! Nějaké neidentifikované mezičíslo !!!!!") + self.nazev = "MezicisloNode: Neidentifikovatelné mezičíslo!" + self.save() + class TemaVCisleNode(TreeNode): """ Obsahuje příspěvky k tématu v daném čísle """ class Meta: @@ -1217,6 +1242,10 @@ class TemaVCisleNode(TreeNode): on_delete=models.PROTECT, # Pokud chci mazat téma, musím si Node pořešit ručně verbose_name = "téma v čísle") + def aktualizuj_nazev(self): + self.nazev = "TemaVCisleNode: "+str(self.tema) + self.save() + class KonferaNode(TreeNode): class Meta: db_table = 'seminar_nodes_konfera' @@ -1228,6 +1257,10 @@ class KonferaNode(TreeNode): null=True, blank=False) + def aktualizuj_nazev(self): + self.nazev = "KonferaNode: "+str(self.konfera) + self.save() + class ClanekNode(TreeNode): class Meta: db_table = 'seminar_nodes_clanek' @@ -1239,6 +1272,10 @@ class ClanekNode(TreeNode): null=True, blank=False) + def aktualizuj_nazev(self): + self.nazev = "ClanekNode: "+str(self.clanek) + self.save() + class UlohaZadaniNode(TreeNode): class Meta: db_table = 'seminar_nodes_uloha_zadani' @@ -1250,6 +1287,10 @@ class UlohaZadaniNode(TreeNode): null=True, blank=False) + def aktualizuj_nazev(self): + self.nazev = "UlohaZadaniNode: "+str(self.uloha) + self.save() + class PohadkaNode(TreeNode): class Meta: db_table = 'seminar_nodes_pohadka' @@ -1260,6 +1301,10 @@ class PohadkaNode(TreeNode): verbose_name = "pohádka", ) + def aktualizuj_nazev(self): + self.nazev = "PohadkaNode: "+str(self.pohadka) + self.save() + class UlohaVzorakNode(TreeNode): class Meta: db_table = 'seminar_nodes_uloha_vzorak' @@ -1271,6 +1316,10 @@ class UlohaVzorakNode(TreeNode): null=True, blank=False) + def aktualizuj_nazev(self): + self.nazev = "UlohaVzorakNode: "+str(self.uloha) + self.save() + class TextNode(TreeNode): class Meta: db_table = 'seminar_nodes_obsah' @@ -1279,6 +1328,10 @@ class TextNode(TreeNode): text = models.ForeignKey(Text, on_delete=models.PROTECT, verbose_name = 'text') + + def aktualizuj_nazev(self): + self.nazev = "TextNode: "+str(self.text) + self.save() ## FIXME: Logiku přesunout do views. #class VysledkyBase(SeminarModelBase): From 75cf0e188fcb1dde403433ec72cdac3f5808b7f6 Mon Sep 17 00:00:00 2001 From: Anet Date: Wed, 23 Oct 2019 23:23:54 +0200 Subject: [PATCH 35/92] Prepsani pocitani bodu v rocniku, aby se nepouzivaly Nody. --- seminar/views.py | 44 ++++++++++++++------------------------------ 1 file changed, 14 insertions(+), 30 deletions(-) diff --git a/seminar/views.py b/seminar/views.py index 1b540197..383dc3ff 100644 --- a/seminar/views.py +++ b/seminar/views.py @@ -334,15 +334,15 @@ def body_resitele_v_cisle(resitel, cislo): return body_resitele # spočítá součet všech bodů řešitele za daný rok (nebo jen do daného čísla včetně) -def body_resitele_v_rocniku(resitel, rocnik_node, do_cisla=None): +def body_resitele_v_rocniku(resitel, rocnik, do_cisla=None): # pokud do_cisla=None, tak do posledního čísla v ročníku # do_cisla je objekt Cislo - cislo_node = rocnik_node.firstChild + cisla = rocnik.cisla body = 0 - while not (cislo_node == None or cislo_node.cislo == do_cisla.CisloNode.next): + for cislo in cisla: + if cislo == do_cisla: break # druhá část zaručuje, že máme výsledky do daného čísla včetně body = body + body_resitele_v_cisle(resitel, cislo_node.cislo) - cislo_node = cislo_node.next return body #def vysledkovka_rocniku(rocnik, jen_verejne=True): @@ -458,11 +458,14 @@ class VysledkyResitele(object): resitel_jmeno = resitel.osoba.jmeno resitel_prijmeni = resitel.osoba.prijmeni body = {} - body_cislo = 0 + body_rocnik = 0 def body_za_cislo(self): return sum(body.values()) + def body_za_rocnik(self): + return body_rocnik + class CisloView(generic.DetailView): model = Cislo template_name = 'seminar/archiv/cislo.html' @@ -497,37 +500,18 @@ class CisloView(generic.DetailView): #.filter(hodnoceni_set__rocnik__eq=cislo_rocnik) radky_vysledkovky = [] for ar in aktivni_resitele: + # získáme výsledky řešitele - součty přes jednotlivé hlavní problémy vr = VysledkyResitele(ar) - for h in hlavni_problemy: - body = body_resitele_problemu_v_cisle(h, ar, cislo) -# vr.body[h.kod_v_rocniku] = body - vr.body_cislo = vr.body_cislo + body + # ukládání součtu bodů za všechny hlavní problémy => součet bodů za číslo + vr.body_cislo = body_resitele_v_cisle(ar, cislo) + # výpočet bodů za ročník do daného čísla (aby fungovalo i pro starší čísla) + vr.body_rocnik = body_resitele_v_rocniku(ar, cislo.rocnik, cislo) radky_vysledkovky.append(vr) - ## TODO: spočítat počet bodů řešitele v daném ročníku a seřadit je podle toho + ## TODO: seřadit řešitele podle bodů v daném ročníku ## řazení viz fce výše - pochopit a případně přepsat - ## počet bodů udělat ve fce body_resitele_v_rocniku -# vysledky = VysledkyKCisluZaRocnik.objects.filter(cislo = context['cislo']).\ -# order_by('-body', 'resitel__prijmeni', 'resitel__jmeno') -# reseni = Reseni.objects.filter(cislo_body = context['cislo']).select_related("resitel") - - # typy úloh, které se mají zobrazovat u čísla, tj. těch, které byly - # v čísle skutečně zadány -# typy_skutecne_zadanych = [Problem.TYP_ULOHA, Problem.TYP_SERIAL, Problem.TYP_ORG_CLANEK] -# v_cisle_zadane = Problem.objects.filter(cislo_zadani=context['cislo']).filter(typ__in=typy_skutecne_zadanych).order_by('kod') - -# resene_problemy = Problem.objects.filter(cislo_reseni=context['cislo']).filter(typ__in=typy_skutecne_zadanych).order_by('cislo_zadani__cislo', 'kod') -# -# poradi_typu = { -# Problem.TYP_ULOHA: 1, - -# Problem.TYP_SERIAL: 2, -# Problem.TYP_ORG_CLANEK: 3, -# Problem.TYP_TEMA: 4, -# Problem.TYP_RES_CLANEK: 5 -# } # problemy = sorted(set(r.problem for r in reseni), key=lambda x:(poradi_typu[x.typ], x.kod_v_rocniku())) # #setridi problemy podle typu a poradi zadani # problem_index = {} From b965084202e838538b2fd3009130d15feeb6c8d0 Mon Sep 17 00:00:00 2001 From: Anet Date: Wed, 23 Oct 2019 23:42:04 +0200 Subject: [PATCH 36/92] Pridane info k ./manage.py shell. --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 057de635..fd67c511 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,8 @@ Make commands * `./manage.py test` - run the tests. +* `./manage.py shell` - run commands, list elemements of database, check syntax + by importing files, etc. Configurations -------------- From 171d1f8f3749fb75c936339ca5af7fe8d9dfe87e Mon Sep 17 00:00:00 2001 From: Anet Date: Wed, 30 Oct 2019 22:56:45 +0100 Subject: [PATCH 37/92] models.py: Cislo.cislo -> Cislo.poradi, Problem.nadproblem related_name: nadproblem_%(class)s -> podproblem --- seminar/models.py | 26 +++++++++++++------------- seminar/views.py | 21 ++++++++++++--------- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/seminar/models.py b/seminar/models.py index ddd24b5c..45e5885e 100644 --- a/seminar/models.py +++ b/seminar/models.py @@ -353,7 +353,7 @@ class Rocnik(SeminarModelBase): def verejna_cisla(self): vc = [c for c in self.cisla.all() if c.verejne()] - vc.sort(key=lambda c: c.cislo) + vc.sort(key=lambda c: c.poradi) return vc def posledni_verejne_cislo(self): @@ -362,7 +362,7 @@ class Rocnik(SeminarModelBase): def verejne_vysledkovky_cisla(self): vc = list(self.cisla.filter(verejna_vysledkovka=True)) - vc.sort(key=lambda c: c.cislo) + vc.sort(key=lambda c: c.poradi) return vc def posledni_zverejnena_vysledkovka_cislo(self): @@ -387,7 +387,7 @@ class Rocnik(SeminarModelBase): def cislo_pdf_filename(self, filename): rocnik = str(self.rocnik.rocnik) - return os.path.join('cislo', 'pdf', rocnik, '{}-{}.pdf'.format(rocnik, self.cislo)) + return os.path.join('cislo', 'pdf', rocnik, '{}-{}.pdf'.format(rocnik, self.poradi)) @reversion.register(ignore_duplicates=True) class Cislo(SeminarModelBase): @@ -396,7 +396,7 @@ class Cislo(SeminarModelBase): db_table = 'seminar_cisla' verbose_name = 'Číslo' verbose_name_plural = 'Čísla' - ordering = ['-rocnik__rocnik', '-cislo'] + ordering = ['-rocnik__rocnik', '-poradi'] # Interní ID id = models.AutoField(primary_key = True) @@ -404,7 +404,7 @@ class Cislo(SeminarModelBase): rocnik = models.ForeignKey(Rocnik, verbose_name='ročník', related_name='cisla', db_index=True,on_delete=models.PROTECT) - cislo = models.CharField('název čísla', max_length=32, db_index=True, + poradi = models.CharField('název čísla', max_length=32, db_index=True, help_text='Většinou jen "1", vyjímečně "7-8", lexikograficky určuje pořadí v ročníku!') datum_vydani = models.DateField('datum vydání', blank=True, null=True, @@ -437,20 +437,20 @@ class Cislo(SeminarModelBase): # CisloNode def kod(self): - return '%s.%s' % (self.rocnik.rocnik, self.cislo) + return '%s.%s' % (self.rocnik.rocnik, self.poradi) kod.short_description = 'Kód čísla' def __str__(self): # Potenciální DB HOG, pokud by se ročník necachoval r = Rocnik.cached_rocnik(self.rocnik_id) - return '{}.{}'.format(r.rocnik, self.cislo) + return '{}.{}'.format(r.rocnik, self.poradi) def verejne(self): return self.verejne_db verejne.boolean = True def verejne_url(self): - return reverse('seminar_cislo', kwargs={'rocnik': self.rocnik.rocnik, 'cislo': self.cislo}) + return reverse('seminar_cislo', kwargs={'rocnik': self.rocnik.rocnik, 'cislo': self.poradi}) def nasledujici(self): "Vrací None, pokud je toto poslední" @@ -607,7 +607,7 @@ class Problem(SeminarModelBase,PolymorphicModel): # Problém má podproblémy nadproblem = models.ForeignKey('self', verbose_name='nadřazený problém', - related_name='nadproblem_%(class)s', null=True, blank=True, + related_name='podproblem', null=True, blank=True, on_delete=models.SET_NULL) STAV_NAVRH = 'navrh' @@ -772,7 +772,7 @@ class Uloha(Problem): def kod_v_rocniku(self): if self.stav == 'zadany': - name="{}.u{}".format(self.cislo_zadani.cislo,self.kod) + name="{}.u{}".format(self.cislo_zadani.poradi,self.kod) if self.nadproblem: return self.nadproblem.kod_v_rocniku()+name return name @@ -1198,7 +1198,7 @@ class CisloNode(TreeNode): on_delete = models.PROTECT, # Pokud chci mazat číslo, musím si Node pořešit ručně verbose_name = "číslo") def __str__(self): - return 'CisloNode: '+str(self.cislo) + return 'CisloNode: '+str(self.poradi) class MezicisloNode(TreeNode): class Meta: @@ -1319,7 +1319,7 @@ class TextNode(TreeNode): # # def __str__(self): # return "%s: %sb (%s)".format(self.resitel.plne_jmeno(), self.body, -# str(self.cislo)) +# str(self.poradi)) # # NOTE: DB zatez pri vypisu (ale nepouzivany) @@ -1369,7 +1369,7 @@ class TextNode(TreeNode): # # def __str__(self): # # NOTE: DB HOG (ale nepouzivany) -# return "%s: %sb / %sb (do %s)" % (self.resitel.plne_jmeno(), self.body, self.body_celkem, str(self.cislo)) +# return "%s: %sb / %sb (do %s)" % (self.resitel.plne_jmeno(), self.body, self.body_celkem, str(self.poradi)) ##mozna potreba upravit diff --git a/seminar/views.py b/seminar/views.py index 383dc3ff..57dc4009 100644 --- a/seminar/views.py +++ b/seminar/views.py @@ -280,16 +280,18 @@ def sloupec_s_poradim(vysledky): return poradi_l # spočítá součet bodů získaných daným řešitelem za zadaný problém a všechny jeho podproblémy -def __soucet_resitele_problemu(problem, resitel, soucet): +def __soucet_resitele_problemu(problem, resitel, cislo, soucet): # FIXME: správně je nadproblem_(typ problemu), ale to by bylo potřeba nějak # zjistit, jaký typ nodu to vlastně je a aplikovat to ve volání funkce # sečteme body za daný problém přes všechna řešení daného problému # od daného řešitele - reseni_resitele = problem.hodnoceni_set.filter(reseni_resitele__contains=resitel) + reseni_resitele = problem.hodnoceni_set.filter(reseni_resitele__contains=resitel, + cislo_body=cislo) for r in reseni_resitele: soucet += r.body + # a přičteme k tomu hodnocení všech podproblémů for p in problem.nadproblem_set: # i přes jméno by to měla být množina jeho podproblémů soucet += __soucet_resitele_problemu(p, resitel, soucet) @@ -297,7 +299,8 @@ def __soucet_resitele_problemu(problem, resitel, soucet): # spočítá součet všech bodů ze všech podproblémů daného problému daného řešitele def body_resitele_problemu_v_cisle(problem, resitel, cislo): - return __soucet_resitele_problemu(problem, resitel, 0) + # probably FIXED: nezohledňuje číslo, do kterého se body počítají + return __soucet_resitele_problemu(problem, resitel, cislo, 0) # vrátí list všech problémů s body v daném čísle, které již nemají nadproblém def hlavni_problemy_cisla(cislo): @@ -337,12 +340,12 @@ def body_resitele_v_cisle(resitel, cislo): def body_resitele_v_rocniku(resitel, rocnik, do_cisla=None): # pokud do_cisla=None, tak do posledního čísla v ročníku # do_cisla je objekt Cislo - cisla = rocnik.cisla + cisla = rocnik.cisla # funkce vrátí pole objektů Cislo už lexikograficky setřízené, viz models body = 0 for cislo in cisla: - if cislo == do_cisla: break + if cislo.poradi == do_cisla.poradi: break # druhá část zaručuje, že máme výsledky do daného čísla včetně - body = body + body_resitele_v_cisle(resitel, cislo_node.cislo) + body = body + body_resitele_v_cisle(resitel, cislo) return body #def vysledkovka_rocniku(rocnik, jen_verejne=True): @@ -360,7 +363,7 @@ def body_resitele_v_rocniku(resitel, rocnik, do_cisla=None): # return None # # #vybere vsechny vysledky z posledniho (verejneho) cisla a setridi sestupne dle bodu -# vysledky = list(cisla_v_rocniku.filter(cislo = cisla_v_rocniku[0].cislo).order_by('-body', 'resitel__prijmeni', 'resitel__jmeno').select_related('resitel')) +# vysledky = list(cisla_v_rocniku.filter(cislo = cisla_v_rocniku[0].poradi).order_by('-body', 'resitel__prijmeni', 'resitel__jmeno').select_related('resitel')) # # class Vysledkovka: # def __init__(self): @@ -376,7 +379,7 @@ def body_resitele_v_rocniku(resitel, rocnik, do_cisla=None): # v.poradi = poradi # v.resitel.rocnik = v.resitel.rocnik(rocnik) # -# verejne_vysl_odjakziva = VysledkyKCisluOdjakziva.objects.filter(cislo__rocnik=rocnik, cislo=cisla_v_rocniku[0].cislo) +# verejne_vysl_odjakziva = VysledkyKCisluOdjakziva.objects.filter(cislo__rocnik=rocnik, cislo=cisla_v_rocniku[0].poradi) # if jen_verejne: # verejne_vysl_odjakziva = verejne_vysl_odjakziva.filter(cislo__verejna_vysledkovka=True) # @@ -958,7 +961,7 @@ def texDownloadView(request, rocnik, cislo): "body": p.body, "zadani": p.text_zadani, "reseni": p.text_reseni, - "cislo_zadani": p.cislo_zadani.cislo, + "cislo_zadani": p.cislo_zadani.poradi, } for p in resene ], } From ba546353d864eae5c61afa709f143287bb64cb72 Mon Sep 17 00:00:00 2001 From: Pavel 'LEdoian' Turinsky Date: Wed, 30 Oct 2019 23:26:59 +0100 Subject: [PATCH 38/92] =?UTF-8?q?Prvn=C3=AD=20pokus=20o=20squash.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../0001_squashed_0067_auto_20190814_0805.py | 2236 +++++++++++++++++ 1 file changed, 2236 insertions(+) create mode 100644 seminar/migrations/0001_squashed_0067_auto_20190814_0805.py diff --git a/seminar/migrations/0001_squashed_0067_auto_20190814_0805.py b/seminar/migrations/0001_squashed_0067_auto_20190814_0805.py new file mode 100644 index 00000000..f1f046af --- /dev/null +++ b/seminar/migrations/0001_squashed_0067_auto_20190814_0805.py @@ -0,0 +1,2236 @@ +# Generated by Django 2.2.6 on 2019-10-30 20:20 + +from django.conf import settings +from django.db import migrations, models +import django.db.migrations.operations.special +import django.db.models.deletion +import django.utils.timezone +import django_countries.fields +import imagekit.models.fields +import seminar.models +import taggit.managers + + +# Functions from the following migrations need manual copying. +# Move them and any dependencies into this file, then update the +# RunPython operations to refer to the local versions: + +# seminar.migrations.0051_resitel_to_osoba + +def resitel_to_osoba(apps,schema_editor): + Resitel = apps.get_model('seminar','Resitel') + Osoba = apps.get_model('seminar','Osoba') + for r in Resitel.objects.all(): + o = Osoba() + o.datum_narozeni = r.datum_narozeni + o.datum_registrace = r.datum_prihlaseni + o.datum_souhlasu_udaje = r.datum_souhlasu_udaje + o.datum_souhlasu_zasilani = r.datum_souhlasu_zasilani + o.email = r.email + o.jmeno = r.jmeno + o.mesto = r.mesto + o.pohlavi_muz = r.pohlavi_muz + o.prijmeni = r.prijmeni + o.psc = r.psc + o.stat = r.stat + o.telefon = r.telefon + o.ulice = r.ulice + o.user = r.user + if o.user: + u = o.user + if u.first_name: + if not o.jmeno: + o.jmeno = u.first_name + u.first_name = 'Použij osobu!' + elif o.jmeno == u.first_name: + u.first_name = 'Použij osobu!' + else: + raise ValueError('jmeno a first_name rozdílné: "{}" vs. "{}"'.format(o.jmeno, u.first_name)) + if u.last_name: + if not o.prijmeni: + o.prijmeni = u.last_name + u.last_name = 'Použij osobu!' + elif o.prijmeni == u.last_name: + u.last_name = 'Použij osobu!' + else: + raise ValueError('prijmeni a last_name rozdílné: "{}" vs. "{}"'.format(o.prijmeni, u.last_name)) + if u.email: + if not o.email: + o.email = u.email + u.email = 'Použij osobu!' + elif o.email == u.email: + u.email = 'Použij osobu!' + else: + raise ValueError('o.email a u.email rozdílné: "{}" vs. "{}"'.format(o.email, u.email)) + u.save() + + + o.save() + r.osoba = o + r.save() + +def osoba_to_resitel(apps, schema_editor): + Resitel = apps.get_model('seminar','Resitel') + Osoba = apps.get_model('seminar','Osoba') + for r in Resitel.objects.all(): + o = r.osoba + r.datum_narozeni = o.datum_narozeni + r.datum_prihlaseni = o.datum_registrace + r.datum_souhlasu_udaje = o.datum_souhlasu_udaje + r.datum_souhlasu_zasilani = o.datum_souhlasu_zasilani + r.email = o.email + r.jmeno = o.jmeno + r.mesto = o.mesto + r.pohlavi_muz = o.pohlavi_muz + r.prijmeni = o.prijmeni + r.psc = o.psc + r.stat = o.stat + r.telefon = o.telefon + r.ulice = o.ulice + r.user = o.user + r.save() + o.delete() + + +# seminar.migrations.0052_user_to_organizator + +def spoj_k_organizatorum_osoby(apps, scema_editor): + Organizator = apps.get_model('seminar', 'Organizator') + Resitel = apps.get_model('seminar', 'Resitel') + Osoba = apps.get_model('seminar', 'Osoba') + for org in Organizator.objects.all(): + + # Spárování organizátora s osobou + user = org.user + resitele = Resitel.objects.filter(user=user) + if resitele.count() != 0: + osoba = resitele.first().osoba + else: + osoba = Osoba(user=user) + + # Přesun informací z usera do osoby + # pro řešitele již v minule migraci + osoba.jmeno = user.first_name + osoba.prijmeni = user.last_name + osoba.email = user.email + user.jmeno = "Použij osobu!" + user.prijmeni = "Použij osobu!" + user.email = "Použij osobu!" + user.save() + + # Přesun informací z organizátora do jeho osoby + osoba.prezdivka = org.prezdivka if org.prezdivka is not None else '' + osoba.foto = org.foto + + # Všechno uložit + osoba.save() + org.osoba = osoba + org.save() + +def fix_problem(apps, schema_editor): + Problem = apps.get_model('seminar', 'Problem') + Organizator = apps.get_model('seminar', 'Organizator') + for pr in Problem.objects.all(): + if pr.autor_old is not None: + pr.autor = Organizator.objects.filter(osoba__user=pr.autor_old).first() + else: + pr.autor = None + if pr.opravovatel is not None: + pr.opravovatele.add(Organizator.objects.filter(osoba__user=pr.opravovatel).first()) + pr.save() + +def fix_pohadka(apps, schema_editor): + Pohadka = apps.get_model('seminar', 'Pohadka') + Organizator = apps.get_model('seminar', 'Organizator') + for poh in Pohadka.objects.all(): + if poh.autor_old is not None: + poh.autor = Organizator.objects.filter(osoba__user=poh.autor_old).first() + else: + poh.autor = None + poh.save() + +def fix_novinka(apps, schema_editor): + Novinky = apps.get_model('seminar', 'Novinky') + Organizator = apps.get_model('seminar', 'Organizator') + for nov in Novinky.objects.all(): + nov.autor = Organizator.objects.filter(osoba__user=nov.autor_old).first() + nov.save() + +# seminar.migrations.0053_organizator_organizuje_od_do + +def rok_to_datetime(apps,schema_editor): + Organizator = apps.get_model('seminar','Organizator') + for o in Organizator.objects.all(): + rok = o.organizuje_od_roku + if rok: + o.organizuje_od = dt.datetime(rok,1,1) + rok = o.organizuje_do_roku + if rok: + o.organizuje_do = dt.datetime(rok,12,31) + o.save() + +def datetime_to_rok(apps,schema_editor): + Organizator = apps.get_model('seminar','Organizator') + for o in Organizator.objects.all(): + o.organizuje_od_roku = o.organizuje_od.year + o.organizuje_do_roku = o.organizuje_do.year + o.save() + +# seminar.migrations.0056_vrcholy_pro_rocniky_a_cisla + +def generuj_RocnikNody_a_CisloNody(apps,schema_editor): + Rocnik = apps.get_model('seminar', 'Rocnik') + RocnikNode = apps.get_model('seminar', 'RocnikNode') + Cislo = apps.get_model('seminar', 'Cislo') + CisloNode = apps.get_model('seminar', 'CisloNode') + + last_rn = None # last_* slouží k navázání následníků + for r in Rocnik.objects.all(): + rn = RocnikNode.objects.create(rocnik=r) + rn.save() + rn.root = rn + rn.save() + if last_rn: + last_rn.succ = rn + last_rn.save() + last_rn = rn + + last_cn = None + for c in Cislo.objects.filter(rocnik=r): + cn = CisloNode.objects.create(cislo=c, root=rn) + cn.save() + if last_cn: # Jsme něčí následník + last_cn.succ = cn + last_cn.save() + else: # Jsme první v řadě, takže se musíme přidat jako first_child RočníkNodu + rn.first_child = cn + rn.save() + last_cn = cn + +# seminar.migrations.0057_reseni_to_reseni_hodnoceni + +def reseni_to_Reseni(apps, schema_editor): + Reseni = apps.get_model('seminar','Reseni') + Reseni_Resitele = apps.get_model('seminar','Reseni_Resitele') + Hodnoceni = apps.get_model('seminar','Hodnoceni') + + for r in Reseni.objects.all(): + rr = Reseni_Resitele.objects.create(resitele = r.resitel, reseni=r) + if r.body == None: + print("!!!!!!!!!!!!!!!") + print(r.id,r) + print("!!!!!!!!!!!!!!!") + else: + h = Hodnoceni.objects.create( + body=r.body, + cislo_body = r.cislo_body, + problem = r.problem_old, + reseni = r) + +# seminar.migrations.0058_problem_to_uloha_tema_clanek + +def poskladej_strom(apps, rodic, *texty): + Text = apps.get_model('seminar', 'Text') + TextNode = apps.get_model('seminar', 'TextNode') + if not rodic: + raise ValueError("Rodič musí být definovaný") + + uz_ma_deti = False + tn = None + for txt in texty: + if not txt: + continue + # Přidej do stromu: + textobj = Text.objects.create(na_web = txt) + textobj.save() + textnode = TextNode.objects.create(text = textobj) + textnode.save() + if not uz_ma_deti: + rodic.first_child = textnode + rodic.save() + tn = rodic.first_child + uz_ma_deti = True + else: + tn.succ = textnode + tn.save() + tn = tn.succ + +def uloha_to_Uloha(apps,schema_editor): + Problem = apps.get_model('seminar', 'Problem') + Uloha = apps.get_model('seminar', 'Uloha') + Text = apps.get_model('seminar', 'Text') + UlohaZadaniNode = apps.get_model('seminar', 'UlohaZadaniNode') + UlohaVzorakNode = apps.get_model('seminar', 'UlohaVzorakNode') + TextNode = apps.get_model('seminar', 'TextNode') + + ulohy = Problem.objects.filter(typ = 'uloha') + for uold in ulohy: + unew = Uloha.objects.create( + problem_ptr = uold, + # Zakomentované fieldy by se už měly nacházet v příslušném problému + #nazev = uold.nazev, + #stav = uold.stav, + #zamereni = uold.zamereni, + #poznamka = uold.poznamka, + #autor = uold.autor, + #kod = uold.kod, + cislo_zadani = uold.cislo_zadani_old, + cislo_reseni = uold.cislo_reseni_old, + max_body = uold.body, + #vytvoreno = uold.vytvoreno, + ) +# unew.opravovatele.add(*uold.opravovatele.all()) + unew.save() + + # Nody: + zadani_node = UlohaZadaniNode.objects.create(uloha = unew) + poskladej_strom(apps, zadani_node, uold.text_zadani) + zadani_node.save() + vzorak_node = UlohaVzorakNode.objects.create(uloha = unew) + poskladej_strom(apps, vzorak_node, uold.text_reseni) + vzorak_node.save() + +def konfery_rucne(apps, schema_editor): + # Tohle dělat nebudu, máme aktuálně celou jednu. Ale "Errors should never pass silently" + Problem = apps.get_model('seminar', 'Problem') + pocet_konfer = Problem.objects.filter(typ = 'konfera').count() + if pocet_konfer > 0: + raise NotImplementedError("Zkonvertuj {} konfer na objekt Konfera ručně, prosím".format(pocet_konfer)) + +def clanek_to_Clanek(apps,schema_editor): + Problem = apps.get_model('seminar', 'Problem') + Clanek = apps.get_model('seminar', 'Clanek') + ClanekNode = apps.get_model('seminar', 'ClanekNode') + Text = apps.get_model('seminar', 'Text') + TextNode = apps.get_model('seminar', 'TextNode') + + clanky = Problem.objects.filter(Q(typ='org-clanek') | Q(typ='res-clanek')) + for cl in clanky: + # Vybereme vhodné číslo pro článek z čísla zadání a čísla řešení: + if cl.cislo_zadani_old is None: + cislo = cl.cislo_reseni_old + elif cl.cislo_reseni_old is None: + cislo = cl.cislo_zadani_old + elif cl.cislo_reseni_old == cl.cislo_zadani_old: + cislo = cl.cislo_zadani_old + else: + raise ValueError("Různá čísla zadání a řešení u článku! (Článek: {})".format(cl.nazev)) + + clnew = Clanek.objects.create( + problem_ptr = cl, + # Problém by nemělo být potřeba upravovat + cislo = cislo, + # Body ignorujeme, protože už jsou v hodnocení + ) + clnew.save() + + # Aktuálně nemáme v modelu informaci o tom, jestli je to org-článek + # nebo řešitelský článek. Aby se neztratila informace, poznamenám to do + # poznámky. + cl.poznamka += "\nTyp:\t{}".format(cl.typ) + cl.save() + + # Vyrobíme nody: + clnode = ClanekNode(clanek = clnew) + poskladej_strom(apps, clnode, cl.text_zadani, cl.text_reseni) + clnode.save() + +def tema_to_Tema(apps, schema_editor): + Problem = apps.get_model('seminar', 'Problem') + Tema = apps.get_model('seminar', 'Tema') + TemaVCisleNode = apps.get_model('seminar', 'TemaVCisleNode') + Text = apps.get_model('seminar', 'Text') + TextNode = apps.get_model('seminar', 'TextNode') + + temata = Problem.objects.filter(Q(typ = 'tema') | Q(typ='serial')) + for t in temata: + # Vymyslíme správně ročník: + if t.cislo_zadani_old is None and t.cislo_reseni_old is None: + rocnik = None + elif t.cislo_zadani_old is None: + rocnik = t.cislo_reseni_old.rocnik + elif t.cislo_reseni_old is None: + rocnik = t.cislo_zadani_old.rocnik + elif t.cislo_reseni_old.rocnik == t.cislo_zadani_old.rocnik: + rocnik = t.cislo_zadani_old.rocnik + else: + raise ValueError("Nelze mít téma přes více ročníků! (Téma: {}".format(t.nazev)) + + tnew = Tema.objects.create( + problem_ptr = t, + tema_typ = t.typ, + rocnik = rocnik, + ) + tnew.save() + + # Nody: + tnode = TemaVCisleNode(tema = tnew) + poskladej_strom(apps, tnode, t.text_zadani, t.text_reseni) + tnode.save() + +# seminar.migrations.0059_vytvorit_pohadkanode + +def vytvor_pohadkanode(apps, schema_editor): + Pohadka = apps.get_model('seminar', 'Pohadka') + PohadkaNode = apps.get_model('seminar', 'PohadkaNode') + Text = apps.get_model('seminar', 'Text') + TextNode = apps.get_model('seminar', 'TextNode') + + for p in Pohadka.objects.all(): + t = Text.objects.create(na_web = p.text) + t.save() + tn = TextNode.objects.create(text = t) + tn.save() + pn = PohadkaNode.objects.create(pohadka = p, first_child = tn) + pn.save() + +# seminar.migrations.0060_spoj_stromy + +def pridej_potomka(rodic, potomek): + # Daný vrchol bude posledním potomkem rodiče + uz_ma_deti = False + posledni = None + + # Přidávaný potomek by neměl mít následovníka -- přidáváme potomka, ne podles. + if potomek.succ: + raise ValueError("Potomek má následovníka, to je velmi podezřelé!") + + # Najdeme aktuálně posledního potomka: + if rodic.first_child: + uz_ma_deti = True + posledni = rodic.first_child + while posledni.succ: + posledni = posledni.succ + + # Nastavíme kořen: + potomek.root = rodic.root + potomek.save() + + # Připojíme vrchol: + if uz_ma_deti: + posledni.succ = potomek + posledni.save() + else: + rodic.first_child = potomek + rodic.save() + +def pokacej_les(apps, schema_editor): + # Teď je potřeba všechny TreeNody příslušející k zadaným problémům připojit + # do hlavního stromu + # Tohle je jednoduchá verze: nejdřív témátka a seriály, pak úložky a pohádky, + # pak články a konfery, pak vzoráky, všechno setříděné podle kódu (FIXME?) + + # Kopírování je častým zdrojem chyb! + Cislo = apps.get_model('seminar', 'Cislo') + Tema = apps.get_model('seminar', 'Tema') + Konfera = apps.get_model('seminar', 'Konfera') + Clanek = apps.get_model('seminar', 'Clanek') + Uloha = apps.get_model('seminar', 'Uloha') + Problem = apps.get_model('seminar', 'Problem') + Pohadka = apps.get_model('seminar', 'Pohadka') + + for c in Cislo.objects.all().reverse(): + cnode = c.cislonode + + # Témata a seriály: + relevantni_temata = Tema.objects.filter(Q(cislo_zadani_old = c) | Q(cislo_reseni_old = c)).order_by('kod') + # Téma dáme do prvního čísla, kde se vyskytne + for t in relevantni_temata: + tnode = t.temavcislenode + if t.cislo_zadani_old and t.cislo_reseni_old: + assert(t.cislo_zadani_old <= t.cislo_reseni_old) + if t.cislo_reseni_old == c: + # Už by mělo být přidané do čísla zadání + continue + else: + # Patří sem (buď je to jediné číslo, nebo je to číslo zadání) + pridej_potomka(cnode, tnode) + + # Úložky (zadání) a pohádky + for u in Uloha.objects.filter(cislo_zadani = c).order_by('kod'): + unode = u.ulohazadaninode + pohadky_pred = Pohadka.objects.filter(uloha_old = u.problem_ptr, pred = True) + pohadky_po = Pohadka.objects.filter(uloha_old = u.problem_ptr, pred = False) + for p in pohadky_pred: + pnode = p.pohadkanode + pridej_potomka(cnode, pnode) + pridej_potomka(cnode, unode) + for p in pohadky_po: + pnode = p.pohadkanode + pridej_potomka(cnode, pnode) + + # Pohádky, které nejsou u úlohy jsou špatně: + if Pohadka.objects.exclude(uloha_old__typ='uloha').count(): + raise ValueError("Existuje pohádka, která není u úlohy") + + # Články + for cl in Clanek.objects.filter(cislo = c).order_by('kod'): + clnode = cl.claneknode + pridej_potomka(cnode, clnode) + + # Konfery + for k in Konfera.objects.all(): + knode = k.konferanode + if k.reseni and knode.root is None: + # Takováhle konfera nejspíš neexistuje + raise NotImplementedError("Konfery neumím zapojit do stromu") + + # Vzoráky + for u in Uloha.objects.filter(cislo_reseni = c).order_by('kod'): + unode = u.ulohavzoraknode + pridej_potomka(cnode, unode) + +# seminar.migrations.0065_treenode_polymorphic_ctype + +def vyrob_treenodum_ctypes(apps, schema_editor): + # Kód zkopírovaný z dokumentace: https://django-polymorphic.readthedocs.io/en/stable/migrating.html + # XXX: Nevím, jestli se tohle náhodou nemělo spustit na všech childech (jen/i) + TreeNode = apps.get_model('seminar', 'TreeNode') + ContentType = apps.get_model('contenttypes', 'ContentType') + + new_ct = ContentType.objects.get_for_model(TreeNode) + TreeNode.objects.filter(polymorphic_ctype__isnull=True).update(polymorphic_ctype=new_ct) + +# seminar.migrations.0066_problem_polymorphic_ctype + +def vyrob_problemum_ctypes(apps, schema_editor): + # Kód zkopírovaný z dokumentace: https://django-polymorphic.readthedocs.io/en/stable/migrating.html + # XXX: Nevím, jestli se tohle náhodou nemělo spustit na všech childech (jen/i) + Problem = apps.get_model('seminar', 'Problem') + ContentType = apps.get_model('contenttypes', 'ContentType') + + new_ct = ContentType.objects.get_for_model(Problem) + Problem.objects.filter(polymorphic_ctype__isnull=True).update(polymorphic_ctype=new_ct) + + +class Migration(migrations.Migration): + + replaces = [('seminar', '0001_initial'), ('seminar', '0002_add_body_views'), ('seminar', '0003_add_skola_zs_ss'), ('seminar', '0004_add_old_dakos_id'), ('seminar', '0005_alter_problem_autor'), ('seminar', '0006_problem_add_timestamp'), ('seminar', '0007_problem_zamereni'), ('seminar', '0008_reseni_forma'), ('seminar', '0009_rename_imported_IDs'), ('seminar', '0010_alter_rok_maturity'), ('seminar', '0011_alter_timestamp_def'), ('seminar', '0012_remove_soustredeni_ucastnici'), ('seminar', '0013_soustredeni_ucastnici_through_model'), ('seminar', '0014_uprava_poznamek'), ('seminar', '0015_soustredeni_text'), ('seminar', '0016_texty_problemu'), ('seminar', '0017_texty_problemu_minor'), ('seminar', '0018_problemnavrh_problemzadany'), ('seminar', '0019_rocnik_ciselne'), ('seminar', '0020_indexy_a_razeni'), ('seminar', '0021_cislo_verejna_vysledkovka'), ('seminar', '0022_decimal_body'), ('seminar', '0023_add_novinky'), ('seminar', '0024_add_organizator'), ('seminar', '0025_zmena_cesty_nahravani_obrazku'), ('seminar', '0026_soustredeni_typ'), ('seminar', '0027_export_flag_a_typ_akce'), ('seminar', '0028_add_body_celkem_views'), ('seminar', '0029_fix_body_celkem_views'), ('seminar', '0030_add_vysledky'), ('seminar', '0031_cislo_pdf'), ('seminar', '0032_cislo_pdf_blank_typos'), ('seminar', '0033_organizator_studuje_popisek'), ('seminar', '0034_reseni_forma_default_email'), ('seminar', '0035_django_imagekit'), ('seminar', '0036_add_org_to_soustredeni'), ('seminar', '0037_prispevek'), ('seminar', '0038_change_meta_prispevek'), ('seminar', '0039_pohadka'), ('seminar', '0040_pohadka_nepovinny_autor'), ('seminar', '0041_konfery'), ('seminar', '0042_cislo_faze'), ('seminar', '0043_uprava_faze'), ('seminar', '0044_uprava_faze'), ('seminar', '0045_cislo_pridani_faze_nahrano'), ('seminar', '0042_auto_20161005_0847'), ('seminar', '0046_merge'), ('seminar', '0047_auto_20170120_2118'), ('seminar', '0048_add_cislo_datum_deadline_soustredeni'), ('seminar', '0049_auto_20190430_2354'), ('seminar', '0050_auto_20190510_2228'), ('seminar', '0051_resitel_to_osoba'), ('seminar', '0052_user_to_organizator'), ('seminar', '0053_organizator_organizuje_od_do'), ('seminar', '0055_smazat_nemigrovane_zastarale_veci'), ('seminar', '0056_vrcholy_pro_rocniky_a_cisla'), ('seminar', '0057_reseni_to_reseni_hodnoceni'), ('seminar', '0058_problem_to_uloha_tema_clanek'), ('seminar', '0059_vytvorit_pohadkanode'), ('seminar', '0060_spoj_stromy'), ('seminar', '0061_kill_frankenstein'), ('seminar', '0062_redukce_modelu_pohadky'), ('seminar', '0063_procisteni_migraci'), ('seminar', '0064_auto_20190610_2358'), ('seminar', '0065_treenode_polymorphic_ctype'), ('seminar', '0066_problem_polymorphic_ctype'), ('seminar', '0067_auto_20190814_0805')] + + initial = True + + dependencies = [ + ('contenttypes', '0002_remove_content_type_name'), + ('taggit', '0001_initial'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='VysledkyKCislu', + fields=[ + ('dummy_id', models.CharField(db_column='id', max_length=32, primary_key=True, serialize=False, verbose_name='dummy ID pro view')), + ('body', models.IntegerField(db_column='body', verbose_name='body za číslo')), + ('body_celkem', models.IntegerField(db_column='body_celkem', verbose_name='body celkem do čísla')), + ], + options={ + 'abstract': False, + 'db_table': 'seminar_body_k_cislu', + 'managed': False, + }, + ), + migrations.CreateModel( + name='VysledkyZaCislo', + fields=[ + ('dummy_id', models.CharField(db_column='id', max_length=32, primary_key=True, serialize=False, verbose_name='dummy ID pro view')), + ('body', models.IntegerField(db_column='body', verbose_name='body za číslo')), + ], + options={ + 'abstract': False, + 'db_table': 'seminar_body_za_cislo', + 'managed': False, + }, + ), + migrations.CreateModel( + name='Cislo', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('cislo', models.CharField(help_text='Většinou jen "1", vyjímečně "7-8", lexikograficky určije pořadí v ročníku!', max_length=32, verbose_name='název čísla')), + ('datum_vydani', models.DateField(blank=True, help_text='Datum vydání finální verze', null=True, verbose_name='datum vydání')), + ('datum_deadline', models.DateField(blank=True, help_text='Datum pro příjem řešení úloh zadaných v tomto čísle', null=True, verbose_name='datum deadline')), + ('verejne_db', models.BooleanField(db_column='verejne', default=False, verbose_name='číslo zveřejněno')), + ], + options={ + 'ordering': ['rocnik__rocnik', 'cislo'], + 'db_table': 'seminar_cisla', + 'verbose_name': 'Číslo', + 'verbose_name_plural': 'Čísla', + }, + ), + migrations.CreateModel( + name='Problem', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('nazev', models.CharField(max_length=256, verbose_name='název')), + ('typ', models.CharField(choices=[(b'uloha', 'Úloha'), (b'tema', 'Téma'), (b'serial', 'Seriál'), (b'org-clanek', 'Organizátorský článek'), (b'res-clanek', 'Řesitelský článek')], default=b'uloha', max_length=32, verbose_name='typ problému')), + ('stav', models.CharField(choices=[(b'navrh', 'Návrh'), (b'zadany', 'Zadaný'), (b'smazany', 'Smazaný')], default=b'navrh', max_length=32, verbose_name='stav problému')), + ('text_problemu_org', models.TextField(blank=True, verbose_name='organizátorský (neveřejný) text')), + ('text_problemu', models.TextField(blank=True, verbose_name='veřejný text zadání a řešení')), + ('kod', models.CharField(blank=True, default=b'', help_text='Číslo/kód úlohy v čísle nebo kód tématu/článku/seriálu v ročníku', max_length=32, verbose_name='lokální kód')), + ('body', models.IntegerField(blank=True, null=True, verbose_name='maximum bodů')), + ('autor', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='autor_uloh', to=settings.AUTH_USER_MODEL, verbose_name='autor problému')), + ('cislo_reseni', models.ForeignKey(blank=True, help_text='Číslo s řešením úlohy, jen pro úlohy', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='resene_problemy', to='seminar.Cislo', verbose_name='číslo řešení')), + ('cislo_zadani', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='zadane_problemy', to='seminar.Cislo', verbose_name='číslo zadání')), + ('opravovatel', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='opravovatel_uloh', to=settings.AUTH_USER_MODEL, verbose_name='opravovatel')), + ], + options={ + 'db_table': 'seminar_problemy', + 'verbose_name': 'Problém', + 'verbose_name_plural': 'Problémy', + }, + ), + migrations.CreateModel( + name='Resitel', + 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í')), + ('pohlavi_muz', models.BooleanField(default=False, verbose_name='pohlaví (muž)')), + ('rok_maturity', models.IntegerField(verbose_name='rok maturity')), + ('email', models.EmailField(blank=True, default=b'', max_length=256, verbose_name='e-mail')), + ('telefon', models.CharField(blank=True, default=b'', 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_prihlaseni', models.DateField(default=django.utils.timezone.now, verbose_name='datum přihlášení')), + ('zasilat', models.CharField(choices=[(b'domu', 'Domů'), (b'do_skoly', 'Do školy'), (b'nikam', 'Nikam')], default=b'domu', max_length=32, verbose_name='kam zasílat')), + ('ulice', models.CharField(blank=True, default=b'', max_length=256, verbose_name='ulice')), + ('mesto', models.CharField(blank=True, default=b'', max_length=256, verbose_name='město')), + ('psc', models.CharField(blank=True, default=b'', max_length=32, verbose_name='PSČ')), + ('stat', django_countries.fields.CountryField(default=b'CZ', help_text='ISO 3166-1 kód země velkými písmeny (CZ, SK, ...)', max_length=2, verbose_name='stát')), + ('poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka k řešiteli (plain text)', verbose_name='neveřejná poznámka')), + ], + options={ + 'ordering': ['prijmeni', 'jmeno'], + 'db_table': 'seminar_resitele', + 'verbose_name': 'Řešitel', + 'verbose_name_plural': 'Řešitelé', + }, + ), + migrations.CreateModel( + name='Rocnik', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('prvni_rok', models.IntegerField(verbose_name='první rok')), + ('rocnik', models.CharField(max_length=16, verbose_name='číslo ročníku')), + ], + options={ + 'ordering': ['rocnik'], + 'db_table': 'seminar_rocniky', + 'verbose_name': 'Ročník', + 'verbose_name_plural': 'Ročníky', + }, + ), + migrations.CreateModel( + name='Skola', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('aesop_id', models.CharField(blank=True, default=b'', 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=b'Zkr\xc3\xa1cen\xc3\xbd n\xc3\xa1zev pro zobrazen\xc3\xad ve v\xc3\xbdsledkovce', 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=b'CZ', help_text='ISO 3166-1 kód zeme velkými písmeny (CZ, SK, ...)', max_length=2, verbose_name='stát')), + ('poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka ke škole (plain text)', verbose_name='neveřejná poznámka')), + ], + options={ + 'db_table': 'seminar_skoly', + 'verbose_name': 'Škola', + 'verbose_name_plural': 'Školy', + }, + ), + migrations.CreateModel( + name='Soustredeni', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('datum_zacatku', models.DateField(blank=True, help_text='První den soustředění', null=True, verbose_name='datum začátku')), + ('datum_konce', models.DateField(blank=True, help_text='Poslední den soustředění', null=True, verbose_name='datum konce')), + ('verejne_db', models.BooleanField(db_column='verejne', default=False, verbose_name='soustředění zveřejněno')), + ('misto', models.CharField(blank=True, default=b'', help_text='Místo (název obce, volitelně též objektu', max_length=256, verbose_name='místo soustředění')), + ('rocnik', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='soustredeni', to='seminar.Rocnik', verbose_name='ročník')), + ('ucastnici', models.ManyToManyField(db_table='seminar_soustredeni_ucastnici', help_text='Seznam účastníků soustředění', to='seminar.Resitel', verbose_name='účastníci soustředění')), + ], + options={ + 'ordering': ['rocnik__rocnik', 'datum_zacatku'], + 'db_table': 'seminar_soustredeni', + 'verbose_name': 'Soustředění', + 'verbose_name_plural': 'Soustředění', + }, + ), + migrations.AddField( + model_name='resitel', + name='skola', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='seminar.Skola', verbose_name='škola'), + ), + migrations.AddField( + model_name='resitel', + name='user', + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='uživatel'), + ), + migrations.CreateModel( + name='Reseni', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('body', models.IntegerField(blank=True, null=True, verbose_name='body')), + ('timestamp', models.DateTimeField(auto_now=True, verbose_name='vytvořeno')), + ('poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka k řešení (plain text)', verbose_name='neveřejná poznámka')), + ('cislo_body', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='bodovana_reseni', to='seminar.Cislo', verbose_name='číslo pro body')), + ('problem', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reseni', to='seminar.Problem', verbose_name='problém')), + ('resitel', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reseni', to='seminar.Resitel', verbose_name='řešitel')), + ], + options={ + 'ordering': ['problem', 'resitel'], + 'db_table': 'seminar_reseni', + 'verbose_name': 'Řešení', + 'verbose_name_plural': 'Řešení', + }, + ), + migrations.CreateModel( + name='PrilohaReseni', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('timestamp', models.DateTimeField(auto_now=True, verbose_name='vytvořeno')), + ('soubor', models.FileField(upload_to=seminar.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')), + ('reseni', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='prilohy', to='seminar.Reseni', verbose_name='řešení')), + ], + options={ + 'ordering': ['reseni', 'timestamp'], + 'db_table': 'seminar_priloha_reseni', + 'verbose_name': 'Příloha řešení', + 'verbose_name_plural': 'Přílohy řešení', + }, + ), + migrations.CreateModel( + name='Nastaveni', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('aktualni_cislo', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Cislo', verbose_name='poslední vydané číslo')), + ('aktualni_rocnik', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Rocnik', verbose_name='aktuální ročník')), + ], + options={ + 'db_table': 'seminar_nastaveni', + 'verbose_name': 'Nastavení semináře', + }, + ), + migrations.AddField( + model_name='cislo', + name='rocnik', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='cisla', to='seminar.Rocnik', verbose_name='ročník'), + ), + migrations.RunSQL( + sql="\ncreate view seminar_body_za_cislo as\n select\n sr.cislo_body_id || '-' || sr.resitel_id as id,\n sr.cislo_body_id as cislo_id,\n sr.resitel_id as resitel_id,\n sum(sr.body) as body\n from seminar_reseni as sr\n group by sr.cislo_body_id, sr.resitel_id\n order by body desc;\n\ncreate view seminar_body_k_cislu as\n select\n akt_c.id || '-' || min_bzc.resitel_id as id,\n akt_c.id as cislo_id,\n min_bzc.resitel_id as resitel_id,\n max(akt_bzc.body) as body,\n sum(min_bzc.body) as body_celkem\n from ((seminar_cisla as akt_c\n inner join seminar_cisla as min_c on min_c.rocnik_id = akt_c.rocnik_id and akt_c.cislo >= min_c.cislo)\n inner join seminar_body_za_cislo as min_bzc on min_c.id = min_bzc.cislo_id)\n left outer join seminar_body_za_cislo as akt_bzc on akt_bzc.cislo_id = akt_c.id and akt_bzc.resitel_id = min_bzc.resitel_id \n group by akt_c.id, min_bzc.resitel_id, akt_bzc.resitel_id\n order by body_celkem desc;\n", + reverse_sql='\ndrop view seminar_body_k_cislu;\ndrop view seminar_body_za_cislo;\n', + ), + migrations.AlterField( + model_name='reseni', + name='poznamka', + field=models.TextField(blank=True, help_text='Neveřejná poznámka k řešení (plain text, editace v detailu řešení)', verbose_name='neveřejná poznámka'), + ), + migrations.AddField( + model_name='skola', + name='je_ss', + field=models.BooleanField(default=True, verbose_name='střední stupeň'), + ), + migrations.AddField( + model_name='skola', + name='je_zs', + field=models.BooleanField(default=True, verbose_name='základní stupeň'), + ), + migrations.AlterField( + model_name='problem', + name='autor', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='autor_uloh', to=settings.AUTH_USER_MODEL, verbose_name='autor problému'), + ), + migrations.AddField( + model_name='problem', + name='zamereni', + field=taggit.managers.TaggableManager(blank=True, help_text=b'Zam\xc4\x9b\xc5\x99en\xc3\xad M/F/I/O probl\xc3\xa9mu, p\xc5\x99\xc3\xadp. dal\xc5\xa1\xc3\xad tagy', through='taggit.TaggedItem', to='taggit.Tag', verbose_name='zaměření'), + ), + migrations.AddField( + model_name='reseni', + name='forma', + field=models.CharField(choices=[(b'papir', 'Papírové řešení'), (b'email', 'Emailem'), (b'upload', 'Upload přes web')], default=b'papir', max_length=16, verbose_name='forma řešení'), + ), + migrations.AddField( + model_name='resitel', + name='import_mamoper_id', + field=models.CharField(blank=True, default=b'', help_text='MAMOPER.MM_RIESITELIA.ID z DAKOS importu, jen historický význam', max_length=32, verbose_name='importované MM_RIESITELIA.ID'), + ), + migrations.AddField( + model_name='skola', + name='import_dakos_id', + field=models.CharField(blank=True, default=b'', help_text='DKSROOT.V_SKOLA.ID z DAKOS importu, jen historický význam', max_length=32, verbose_name='importované DKSROOT.V_SKOLA.ID'), + ), + migrations.AlterField( + model_name='resitel', + name='rok_maturity', + field=models.IntegerField(blank=True, null=True, verbose_name='rok maturity'), + ), + migrations.AlterField( + model_name='prilohareseni', + name='timestamp', + field=models.DateTimeField(blank=True, default=django.utils.timezone.now, editable=False, verbose_name='vytvořeno'), + ), + migrations.AddField( + model_name='problem', + name='import_dakos_id', + field=models.CharField(blank=True, default=b'', help_text='ID z importu z DAKOSU s prefixem podle původu: "AZAD:xxx (MAMOPER.MM_AZAD), ""DOZ:xxx" (MAMOPER.MM_DOZ), "ZAD:rocnik.cislo.uloha.typ" (MAMOPER.MM_ZADANIA), "ULOHA:xxx" (MAMOPER.MM_ULOHY)', max_length=32, verbose_name='importované ID s typem'), + ), + migrations.AddField( + model_name='problem', + name='timestamp', + field=models.DateTimeField(blank=True, default=django.utils.timezone.now, editable=False, verbose_name='vytvořeno'), + ), + migrations.AlterField( + model_name='reseni', + name='timestamp', + field=models.DateTimeField(blank=True, default=django.utils.timezone.now, editable=False, verbose_name='vytvořeno'), + ), + migrations.RemoveField( + model_name='soustredeni', + name='ucastnici', + ), + migrations.CreateModel( + name='Soustredeni_Ucastnici', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka k účasti (plain text)', verbose_name='neveřejná poznámka')), + ('resitel', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Resitel', verbose_name='řešitel')), + ('soustredeni', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Soustredeni', verbose_name='soustředění')), + ], + options={ + 'ordering': ['soustredeni', 'resitel'], + 'db_table': 'seminar_soustredeni_ucastnici', + 'verbose_name': 'Účast na soustředění', + 'verbose_name_plural': 'Účasti na soustředění', + }, + ), + migrations.AddField( + model_name='soustredeni', + name='ucastnici', + field=models.ManyToManyField(help_text='Seznam účastníků soustředění', through='seminar.Soustredeni_Ucastnici', to='seminar.Resitel', verbose_name='účastníci soustředění'), + ), + migrations.AlterModelOptions( + name='problem', + options={'ordering': ['nazev'], 'verbose_name': 'Problém', 'verbose_name_plural': 'Problémy'}, + ), + migrations.AlterModelOptions( + name='reseni', + options={'ordering': ['problem_id', 'resitel_id'], 'verbose_name': 'Řešení', 'verbose_name_plural': 'Řešení'}, + ), + migrations.AlterModelOptions( + name='skola', + options={'ordering': ['mesto', 'nazev'], 'verbose_name': 'Škola', 'verbose_name_plural': 'Školy'}, + ), + migrations.AddField( + model_name='cislo', + name='poznamka', + field=models.TextField(blank=True, help_text='Neveřejná poznámka k číslu (plain text)', verbose_name='neveřejná poznámka'), + ), + migrations.AlterField( + model_name='reseni', + name='poznamka', + field=models.TextField(blank=True, help_text='Neveřejná poznámka k řešení (plain text)', verbose_name='neveřejná poznámka'), + ), + migrations.AddField( + model_name='soustredeni', + name='text', + field=models.TextField(blank=True, default=b'', verbose_name='text k soustředění (HTML)'), + ), + migrations.RenameField( + model_name='problem', + old_name='text_problemu_org', + new_name='text_org', + ), + migrations.AlterField( + model_name='problem', + name='text_org', + field=models.TextField(blank=True, verbose_name='neveřejné zadání a organizátorské a poznámky'), + ), + migrations.RenameField( + model_name='problem', + old_name='text_problemu', + new_name='text_zadani', + ), + migrations.AlterField( + model_name='problem', + name='text_org', + field=models.TextField(blank=True, help_text='Neveřejný návrh úlohy, návrh řešení, text zadání, poznámky ...', verbose_name='org poznámky (HTML)'), + ), + migrations.AlterField( + model_name='problem', + name='text_zadani', + field=models.TextField(blank=True, help_text='Veřejný text zadání (HTML)', verbose_name='veřejné zadání (HTML)'), + ), + migrations.AddField( + model_name='problem', + name='text_reseni', + field=models.TextField(blank=True, help_text='Veřejný text řešení (HTML, u témat i příspěvky a komentáře)', verbose_name='veřejné řešení (HTML)'), + ), + migrations.CreateModel( + name='ProblemNavrh', + fields=[ + ], + options={ + 'verbose_name': 'Problém (návrh)', + 'proxy': True, + 'verbose_name_plural': 'Problémy (návrhy)', + }, + bases=('seminar.problem',), + ), + migrations.CreateModel( + name='ProblemZadany', + fields=[ + ], + options={ + 'verbose_name': 'Problém (zadaný)', + 'proxy': True, + 'verbose_name_plural': 'Problémy (zadané)', + }, + bases=('seminar.problem',), + ), + migrations.AddField( + model_name='rocnik', + name='rocnik_n', + field=models.IntegerField(default=0, verbose_name='číslo ročníku'), + preserve_default=False, + ), + migrations.RunSQL( + sql='update seminar_rocniky set rocnik_n = cast (rocnik as integer)', + ), + migrations.RemoveField( + model_name='rocnik', + name='rocnik', + ), + migrations.RenameField( + model_name='rocnik', + old_name='rocnik_n', + new_name='rocnik', + ), + migrations.AlterModelOptions( + name='cislo', + options={'ordering': ['-rocnik__rocnik', '-cislo'], 'verbose_name': 'Číslo', 'verbose_name_plural': 'Čísla'}, + ), + migrations.AlterModelOptions( + name='reseni', + options={'ordering': ['problem_id', 'resitel__prijmeni', 'resitel__jmeno'], 'verbose_name': 'Řešení', 'verbose_name_plural': 'Řešení'}, + ), + migrations.AlterModelOptions( + name='rocnik', + options={'ordering': ['-rocnik'], 'verbose_name': 'Ročník', 'verbose_name_plural': 'Ročníky'}, + ), + migrations.AlterField( + model_name='cislo', + name='cislo', + field=models.CharField(db_index=True, help_text='Většinou jen "1", vyjímečně "7-8", lexikograficky určije pořadí v ročníku!', max_length=32, verbose_name='název čísla'), + ), + migrations.AlterField( + model_name='rocnik', + name='prvni_rok', + field=models.IntegerField(db_index=True, unique=True, verbose_name='první rok'), + ), + migrations.AlterField( + model_name='rocnik', + name='rocnik', + field=models.IntegerField(db_index=True, unique=True, verbose_name='číslo ročníku'), + ), + migrations.AddField( + model_name='cislo', + name='verejna_vysledkovka', + field=models.BooleanField(default=False, help_text='Je-li false u veřejného čísla, není výsledkovka zatím veřejná.', verbose_name='zveřejněna výsledkovka'), + ), + migrations.RunSQL( + sql='\ndrop view seminar_body_k_cislu;\ndrop view seminar_body_za_cislo;\n', + ), + migrations.AlterField( + model_name='problem', + name='body', + field=models.DecimalField(blank=True, decimal_places=1, max_digits=8, null=True, verbose_name='maximum bodů'), + ), + migrations.AlterField( + model_name='reseni', + name='body', + field=models.DecimalField(blank=True, decimal_places=1, max_digits=8, null=True, verbose_name='body'), + ), + migrations.RunSQL( + sql="\ncreate view seminar_body_za_cislo as\n select\n sr.cislo_body_id || '-' || sr.resitel_id as id,\n sr.cislo_body_id as cislo_id,\n sr.resitel_id as resitel_id,\n sum(sr.body) as body\n from seminar_reseni as sr\n group by sr.cislo_body_id, sr.resitel_id\n order by body desc;\n\ncreate view seminar_body_k_cislu as\n select\n akt_c.id || '-' || min_bzc.resitel_id as id,\n akt_c.id as cislo_id,\n min_bzc.resitel_id as resitel_id,\n max(akt_bzc.body) as body,\n sum(min_bzc.body) as body_celkem\n from ((seminar_cisla as akt_c\n inner join seminar_cisla as min_c on min_c.rocnik_id = akt_c.rocnik_id and akt_c.cislo >= min_c.cislo)\n inner join seminar_body_za_cislo as min_bzc on min_c.id = min_bzc.cislo_id)\n left outer join seminar_body_za_cislo as akt_bzc on akt_bzc.cislo_id = akt_c.id and akt_bzc.resitel_id = min_bzc.resitel_id \n group by akt_c.id, min_bzc.resitel_id, akt_bzc.resitel_id\n order by body_celkem desc;\n", + ), + migrations.CreateModel( + name='Novinky', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('datum', models.DateField(auto_now_add=True)), + ('text', models.TextField(blank=True, null=True, verbose_name=b'Text novinky')), + ('obrazek', models.ImageField(blank=True, null=True, upload_to=b'image_novinky/%Y/%m/%d/', verbose_name=b'Obr\xc3\xa1zek')), + ('zverejneno', models.BooleanField(default=False, verbose_name=b'Zve\xc5\x99ejn\xc4\x9bno')), + ('autor', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name=b'Autor novinky')), + ], + options={ + 'verbose_name': 'Novinka', + 'verbose_name_plural': 'Novinky', + }, + ), + migrations.CreateModel( + name='Organizator', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('prezdivka', models.CharField(blank=True, max_length=32, null=True, verbose_name=b'P\xc5\x99ezd\xc3\xadvka')), + ('organizuje_od_roku', models.IntegerField(blank=True, null=True, verbose_name=b'Organizuje od roku')), + ('organizuje_do_roku', models.IntegerField(blank=True, null=True, verbose_name=b'Organizuje do roku')), + ('studuje', models.CharField(blank=True, max_length=256, null=True, verbose_name=b'Studuje')), + ('strucny_popis_organizatora', models.TextField(blank=True, null=True, verbose_name=b'Stru\xc4\x8dn\xc3\xbd popis organiz\xc3\xa1tora')), + ('foto', models.ImageField(blank=True, help_text=b'Vlo\xc5\xbe fotografii organiz\xc3\xa1tora o libovon\xc3\xa9 velikosti', null=True, upload_to=b'image_organizatori/velke/%Y/', verbose_name=b'Fotografie organiz\xc3\xa1tora')), + ('foto_male', models.ImageField(blank=True, editable=False, null=True, upload_to=b'image_organizatori/male/%Y/')), + ('user', models.OneToOneField(help_text=b'Vyber \xc3\xba\xc4\x8det sp\xc5\x99a\xc5\xbeen\xc3\xbd s organiz\xc3\xa1torem.', on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name=b'Osoba')), + ], + options={ + 'verbose_name': 'Organizátor', + 'verbose_name_plural': 'Organizátoři', + }, + ), + migrations.AddField( + model_name='rocnik', + name='exportovat', + field=models.BooleanField(db_column='exportovat', default=False, help_text='Exportuje se jen podle tohoto flagu (ne veřejnosti), a to jen čísla s veřejnou výsledkovkou', verbose_name='export do AESOPa'), + ), + migrations.AddField( + model_name='soustredeni', + name='exportovat', + field=models.BooleanField(db_column='exportovat', default=False, help_text='Exportuje se jen podle tohoto flagu (ne veřejnosti)', verbose_name='export do AESOPa'), + ), + migrations.AddField( + model_name='soustredeni', + name='typ', + field=models.CharField(choices=[(b'jarni', 'Jarní soustředění'), (b'podzimni', 'Podzimní soustředění'), (b'vikend', 'Víkendový sraz')], default=b'podzimni', max_length=16, verbose_name='typ akce'), + ), + migrations.RunSQL( + sql="\ndrop view seminar_body_k_cislu;\ndrop view seminar_body_za_cislo;\n\ncreate view seminar_body_za_cislo as\n select\n seminar_reseni.cislo_body_id || '-' || seminar_reseni.resitel_id as id,\n seminar_reseni.cislo_body_id as cislo_id,\n seminar_reseni.resitel_id as resitel_id,\n seminar_cisla.cislo as cislo,\n seminar_cisla.rocnik_id as rocnik_id,\n seminar_rocniky.rocnik as rocnik,\n seminar_cisla.verejna_vysledkovka as verejna_vysledkovka,\n sum(seminar_reseni.body) as body\n from\n seminar_reseni\n inner join seminar_cisla on seminar_reseni.cislo_body_id = seminar_cisla.id\n inner join seminar_rocniky on seminar_cisla.rocnik_id = seminar_rocniky.id\n group by seminar_reseni.cislo_body_id, seminar_reseni.resitel_id, seminar_cisla.cislo,\n seminar_cisla.rocnik_id, seminar_rocniky.rocnik, seminar_cisla.verejna_vysledkovka\n order by body desc;\n\ncreate view seminar_body_k_cislu_rocnik as\n select\n akt_body.id as id,\n akt_body.cislo_id as cislo_id,\n akt_body.resitel_id as resitel_id,\n akt_body.body as body,\n sum(min_body.body) as body_celkem\n from\n seminar_body_za_cislo as akt_body\n inner join seminar_body_za_cislo as min_body on\n (akt_body.resitel_id = min_body.resitel_id and\n (akt_body.rocnik = min_body.rocnik and akt_body.cislo >= min_body.cislo)\n )\n group by akt_body.id, akt_body.cislo_id, akt_body.resitel_id, akt_body.body\n order by body_celkem desc;\n\ncreate view seminar_body_k_cislu_odjakziva as\n select\n akt_body.id as id,\n akt_body.cislo_id as cislo_id,\n akt_body.resitel_id as resitel_id,\n akt_body.body as body,\n sum(min_body.body) as body_celkem\n from\n seminar_body_za_cislo as akt_body\n inner join seminar_body_za_cislo as min_body on\n (akt_body.resitel_id = min_body.resitel_id and\n ((akt_body.rocnik = min_body.rocnik and akt_body.cislo >= min_body.cislo) or\n (akt_body.rocnik < min_body.rocnik)\n )\n )\n group by akt_body.id, akt_body.cislo_id, akt_body.resitel_id, akt_body.body\n order by body_celkem desc;\n\n", + ), + migrations.RunSQL( + sql="\n\ndrop view seminar_body_k_cislu_rocnik;\ncreate view seminar_body_k_cislu_rocnik as\n select\n seminar_cisla.id || '-' || min_body.resitel_id as id,\n seminar_cisla.id as cislo_id,\n min_body.resitel_id as resitel_id,\n sum(min_body.body) as body\n from\n seminar_cisla\n inner join seminar_body_za_cislo as min_body on\n (min_body.rocnik_id = seminar_cisla.rocnik_id and seminar_cisla.cislo >= min_body.cislo)\n group by seminar_cisla.id, min_body.resitel_id\n order by body desc;\n\ndrop view seminar_body_k_cislu_odjakziva;\ncreate view seminar_body_k_cislu_odjakziva as\n select\n seminar_cisla.id || '-' || min_body.resitel_id as id,\n seminar_cisla.id as cislo_id,\n min_body.resitel_id as resitel_id,\n sum(min_body.body) as body\n from\n seminar_cisla\n inner join seminar_rocniky on\n (seminar_cisla.rocnik_id = seminar_rocniky.id)\n inner join seminar_body_za_cislo as min_body on\n (min_body.rocnik_id = seminar_cisla.rocnik_id and seminar_cisla.cislo >= min_body.cislo) or\n (min_body.rocnik < seminar_rocniky.rocnik)\n group by seminar_cisla.id, min_body.resitel_id\n order by body desc;\n", + ), + migrations.CreateModel( + name='VysledkyCelkemKCislu', + fields=[ + ('dummy_id', models.CharField(db_column=b'id', max_length=32, primary_key=True, serialize=False, verbose_name='dummy ID pro view')), + ('body', models.DecimalField(db_column=b'body', decimal_places=1, max_digits=8, verbose_name='body za číslo')), + ('body_celkem', models.DecimalField(db_column=b'body_celkem', decimal_places=1, max_digits=8, verbose_name='body celkem do čísla včetně minulých ročníků')), + ], + options={ + 'abstract': False, + 'db_table': 'seminar_body_celkem_k_cislu', + 'managed': False, + }, + ), + migrations.CreateModel( + name='VysledkyKCisluOdjakziva', + fields=[ + ('dummy_id', models.CharField(db_column=b'id', max_length=32, primary_key=True, serialize=False, verbose_name='dummy ID pro view')), + ('body', models.DecimalField(db_column=b'body', decimal_places=1, max_digits=8, verbose_name='body za číslo')), + ], + options={ + 'abstract': False, + 'db_table': 'seminar_body_k_cislu_odjakziva', + 'managed': False, + }, + ), + migrations.CreateModel( + name='VysledkyKCisluZaRocnik', + fields=[ + ('dummy_id', models.CharField(db_column=b'id', max_length=32, primary_key=True, serialize=False, verbose_name='dummy ID pro view')), + ('body', models.DecimalField(db_column=b'body', decimal_places=1, max_digits=8, verbose_name='body za číslo')), + ], + options={ + 'abstract': False, + 'db_table': 'seminar_body_k_cislu_rocnik', + 'managed': False, + }, + ), + migrations.AlterField( + model_name='organizator', + name='foto', + field=models.ImageField(blank=True, help_text=b'Vlo\xc5\xbe fotografii organiz\xc3\xa1tora o libovoln\xc3\xa9 velikosti', null=True, upload_to=b'image_organizatori/velke/%Y/', verbose_name=b'Fotografie organiz\xc3\xa1tora'), + ), + migrations.AlterModelOptions( + name='soustredeni', + options={'ordering': ['-rocnik__rocnik', '-datum_zacatku'], 'verbose_name': 'Soustředění', 'verbose_name_plural': 'Soustředění'}, + ), + migrations.AlterField( + model_name='cislo', + name='cislo', + field=models.CharField(db_index=True, help_text='Většinou jen "1", vyjímečně "7-8", lexikograficky určuje pořadí v ročníku!', max_length=32, verbose_name='název čísla'), + ), + migrations.AddField( + model_name='cislo', + name='pdf', + field=models.FileField(blank=True, help_text='Pdf čísla, které si mohou řešitelé stáhnout', null=True, upload_to=seminar.models.cislo_pdf_filename, verbose_name='pdf'), + ), + migrations.AlterField( + model_name='problem', + name='typ', + field=models.CharField(choices=[(b'uloha', 'Úloha'), (b'tema', 'Téma'), (b'serial', 'Seriál'), (b'org-clanek', 'Organizátorský článek'), (b'res-clanek', 'Řešitelský článek')], default=b'uloha', max_length=32, verbose_name='typ problému'), + ), + migrations.AlterField( + model_name='skola', + name='stat', + field=django_countries.fields.CountryField(default=b'CZ', help_text='ISO 3166-1 kód země velkými písmeny (CZ, SK, ...)', max_length=2, verbose_name='stát'), + ), + migrations.AlterField( + model_name='organizator', + name='studuje', + field=models.CharField(blank=True, help_text=b"Nap\xc5\x99. 'Studuje Obecnou fyziku (Bc.), 3. ro\xc4\x8dn\xc3\xadk', 'Vystudovala Diskr\xc3\xa9tn\xc3\xad modely a algoritmy (Mgr.)' nebo 'P\xc5\x99edn\xc3\xa1\xc5\xa1\xc3\xad na MFF'", max_length=256, null=True, verbose_name=b'Studium aj.'), + ), + migrations.AlterField( + model_name='reseni', + name='forma', + field=models.CharField(choices=[(b'papir', 'Papírové řešení'), (b'email', 'Emailem'), (b'upload', 'Upload přes web')], default=b'email', max_length=16, verbose_name='forma řešení'), + ), + migrations.RemoveField( + model_name='organizator', + name='foto_male', + ), + migrations.AlterField( + model_name='organizator', + name='foto', + field=imagekit.models.fields.ProcessedImageField(blank=True, help_text=b'Vlo\xc5\xbe fotografii organiz\xc3\xa1tora o libovoln\xc3\xa9 velikosti', null=True, upload_to=b'image_organizatori/velke/%Y/', verbose_name=b'Fotografie organiz\xc3\xa1tora'), + ), + migrations.CreateModel( + name='Soustredeni_Organizatori', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka k účasti organizátora (plain text)', verbose_name='neveřejná poznámka')), + ('organizator', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Organizator', verbose_name='organizátor')), + ('soustredeni', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Soustredeni', verbose_name='soustředění')), + ], + options={ + 'ordering': ['soustredeni', 'organizator'], + 'db_table': 'seminar_soustredeni_organizatori', + 'verbose_name': 'Účast organizátorů na soustředění', + 'verbose_name_plural': 'Účasti organizátorů na soustředění', + }, + ), + migrations.AddField( + model_name='soustredeni', + name='organizatori', + field=models.ManyToManyField(help_text='Seznam organizátorů soustředění', through='seminar.Soustredeni_Organizatori', to='seminar.Organizator', verbose_name='Organizátoři soustředění'), + ), + migrations.CreateModel( + name='Prispevek', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('nazev', models.CharField(max_length=200, verbose_name=b'N\xc3\xa1zev')), + ('text_org', models.TextField(blank=True, null=True, verbose_name=b'Orgovsk\xc3\xbd text')), + ('text_resitel', models.TextField(blank=True, null=True, verbose_name=b'\xc5\x98e\xc5\xa1itelsk\xc3\xbd text')), + ('zverejnit', models.BooleanField(verbose_name=b'Zve\xc5\x99ejnit?')), + ('problem', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Problem', verbose_name=b'Probl\xc3\xa9m')), + ('reseni', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='seminar.Reseni', verbose_name=b'\xc5\x98e\xc5\xa1en\xc3\xad')), + ], + options={ + 'abstract': False, + 'verbose_name': 'Příspěvek k problému', + 'verbose_name_plural': 'Příspěvky k problémům', + }, + ), + migrations.CreateModel( + name='Konfera', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('nazev', models.CharField(help_text='Název konfery', max_length=40, verbose_name='název konfery')), + ('popis', models.TextField(blank=True, help_text='Popis konfery k zobrazení na webu', verbose_name='popis konfery')), + ('abstrakt', models.TextField(blank=True, help_text='Abstrakt konfery tak, jak byl uveden ve sborníku', verbose_name='abstrakt')), + ('org_poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka ke konfeře(plain text)', verbose_name='neveřejná poznámka')), + ('typ_prezentace', models.CharField(choices=[(b'veletrh', 'Veletrh (postery)'), (b'prezentace', 'Prezentace (přednáška)')], default=b'veletrh', max_length=16, verbose_name='typ prezentace')), + ('prezentace', models.FileField(help_text='Prezentace nebo fotka posteru', upload_to=seminar.models.generate_filename_konfera, verbose_name='prezentace')), + ('materialy', models.FileField(help_text='Další materiály ke konfeře zabalené do jednoho souboru', upload_to=seminar.models.generate_filename_konfera, verbose_name='materialy')), + ('organizator', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='konfery', to='seminar.Organizator', verbose_name='organizátor')), + ('soustredeni', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='konfery', to='seminar.Soustredeni', verbose_name='soustředění')), + ], + options={ + 'db_table': 'seminar_konfera', + 'verbose_name': 'Konfera', + 'verbose_name_plural': 'Konfery', + }, + ), + migrations.CreateModel( + name='Konfery_Ucastnici', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka k účasti (plain text)', verbose_name='neveřejná poznámka')), + ('konfera', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Konfera', verbose_name='konfera')), + ('resitel', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Resitel', verbose_name='řešitel')), + ], + options={ + 'ordering': ['konfera', 'resitel'], + 'db_table': 'seminar_konfery_ucastnici', + 'verbose_name': 'Účast na konfeře', + 'verbose_name_plural': 'Účasti na konfeře', + }, + ), + migrations.AlterField( + model_name='problem', + name='typ', + field=models.CharField(choices=[(b'uloha', 'Úloha'), (b'tema', 'Téma'), (b'serial', 'Seriál'), (b'konfera', 'Konfera'), (b'org-clanek', 'Organizátorský článek'), (b'res-clanek', 'Řešitelský článek')], default=b'uloha', max_length=32, verbose_name='typ problému'), + ), + migrations.AddField( + model_name='konfera', + name='ucastnici', + field=models.ManyToManyField(help_text='Seznam účastníků konfery', through='seminar.Konfery_Ucastnici', to='seminar.Resitel', verbose_name='účastníci konfery'), + ), + migrations.AlterField( + model_name='konfera', + name='materialy', + field=models.FileField(blank=True, help_text='Další materiály ke konfeře zabalené do jednoho souboru', upload_to=seminar.models.generate_filename_konfera, verbose_name='materialy'), + ), + migrations.AlterField( + model_name='konfera', + name='prezentace', + field=models.FileField(blank=True, help_text='Prezentace nebo fotka posteru', upload_to=seminar.models.generate_filename_konfera, verbose_name='prezentace'), + ), + migrations.AddField( + model_name='konfera', + name='prispevek', + field=models.ForeignKey(blank=True, help_text='Účastnický přípěvek o konfeře', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='konfery', to='seminar.Problem', verbose_name='příspěvek do čísla'), + ), + migrations.AddField( + model_name='cislo', + name='faze', + field=models.CharField(choices=[('admin', 'Úpravy na webu'), ('tex', 'Úpravy v TeXu'), ('nahrano', 'Nahráno na web')], default='admin', help_text='Během fáze "Úpravy na webu" se obsah čísla vytváří (a případně komentuje) ve webovém rozhraní. Během fáze "Úpravy v TeXu" už obsah ve webovém rozhraní editovat nelze a návrhy na úpravy se píší do korekturovátka a zanášejí do gitu. Z něj se pak vygeneruje verze pro web a číslo se přepne do fáze "Nahráno na web", což jen znamená, že už nejde automaticky stáhnout obsah pro založení čísla v TeXu.', max_length=32, verbose_name='Fáze vytváření obsahu'), + ), + migrations.AddField( + model_name='cislo', + name='datum_deadline_soustredeni', + field=models.DateField(blank=True, help_text='Datum pro příjem řešení pro účast na soustředění', null=True, verbose_name='datum deadline soustředění'), + ), + 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(max_length=256, 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')), + ('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.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='uživatel')), + ], + options={ + 'verbose_name': 'Osoba', + 'verbose_name_plural': 'Osoby', + 'db_table': 'seminar_osoby', + 'ordering': ['prijmeni', 'jmeno'], + }, + ), + 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')), + ('osoba', models.ForeignKey(help_text='Které osobě či na jakou adresu se mají zasílat čísla', on_delete=django.db.models.deletion.CASCADE, to='seminar.Osoba', verbose_name='komu')), + ], + options={ + 'verbose_name': 'příjemce', + 'verbose_name_plural': 'příjemce', + 'db_table': 'seminar_prijemce', + }, + ), + migrations.CreateModel( + name='Text', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('na_web', models.TextField(blank=True, help_text='Text ke zveřejnění na webu', verbose_name='text na web')), + ('do_cisla', models.TextField(blank=True, help_text='Text ke zveřejnění v čísle', verbose_name='text do čísla')), + ], + options={ + 'verbose_name': 'text', + 'verbose_name_plural': 'texty', + 'db_table': 'seminar_texty', + }, + ), + migrations.CreateModel( + name='Uloha', + fields=[ + ('problem_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.Problem')), + ('max_body', models.DecimalField(blank=True, decimal_places=1, max_digits=8, null=True, verbose_name='maximum bodů')), + ], + options={ + 'verbose_name': 'Úloha', + 'verbose_name_plural': 'Úlohy', + 'db_table': 'seminar_ulohy', + }, + bases=('seminar.problem',), + ), + migrations.AlterModelOptions( + name='novinky', + options={'ordering': ['-datum'], 'verbose_name': 'Novinka', 'verbose_name_plural': 'Novinky'}, + ), + migrations.AlterModelOptions( + name='prilohareseni', + options={'ordering': ['reseni', 'vytvoreno'], 'verbose_name': 'Příloha řešení', 'verbose_name_plural': 'Přílohy řešení'}, + ), + migrations.AlterModelOptions( + name='reseni', + options={'ordering': ['-cas_doruceni'], 'verbose_name': 'Řešení', 'verbose_name_plural': 'Řešení'}, + ), + migrations.AlterModelOptions( + name='resitel', + options={'ordering': ['osoba'], 'verbose_name': 'Řešitel', 'verbose_name_plural': 'Řešitelé'}, + ), + migrations.RenameField( + model_name='konfera', + old_name='org_poznamka', + new_name='poznamka', + ), + migrations.RenameField( + model_name='reseni', + old_name='timestamp', + new_name='cas_doruceni', + ), + migrations.RenameField( + model_name='prilohareseni', + old_name='timestamp', + new_name='vytvoreno', + ), + migrations.RenameField( + model_name='problem', + old_name='text_org', + new_name='poznamka', + ), + migrations.RenameField( + model_name='problem', + old_name='timestamp', + new_name='vytvoreno', + ), + migrations.RenameField( + model_name='problem', + old_name='cislo_zadani', + new_name='cislo_zadani_old', + ), + migrations.RenameField( + model_name='problem', + old_name='cislo_reseni', + new_name='cislo_reseni_old', + ), + migrations.AddField( + model_name='konfera', + name='anotace', + field=models.TextField(blank=True, help_text='Popis, o čem bude konfera.', verbose_name='anotace'), + ), + migrations.AddField( + model_name='organizator', + name='organizuje_do', + field=models.DateTimeField(blank=True, null=True, verbose_name='Organizuje do'), + ), + migrations.AddField( + model_name='organizator', + name='organizuje_od', + field=models.DateTimeField(blank=True, null=True, verbose_name='Organizuje od'), + ), + migrations.AddField( + model_name='organizator', + name='skola', + field=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'), + ), + migrations.AddField( + model_name='organizator', + name='vytvoreno', + field=models.DateTimeField(blank=True, default=django.utils.timezone.now, editable=False, verbose_name='Vytvořeno'), + ), + migrations.AddField( + model_name='problem', + name='garant', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='garant_problemu_problem', to='seminar.Organizator', verbose_name='garant zadaného problému'), + ), + migrations.AddField( + model_name='problem', + name='nadproblem', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='nadproblem_problem', to='seminar.Problem', verbose_name='nadřazený problém'), + ), + migrations.AddField( + model_name='problem', + name='opravovatele', + field=models.ManyToManyField(blank=True, related_name='opravovatele_problem', to='seminar.Organizator', verbose_name='opravovatelé'), + ), + migrations.AddField( + model_name='reseni', + name='zverejneno', + field=models.BooleanField(default=False, help_text='Udává, zda je řešení zveřejněno', verbose_name='řešení zveřejněno'), + ), + migrations.AlterField( + model_name='cislo', + name='verejna_vysledkovka', + field=models.BooleanField(default=False, help_text='Je-li false u veřejného čísla,\t\t\t\t není výsledkovka zatím veřejná.', verbose_name='zveřejněna výsledkovka'), + ), + migrations.AlterField( + model_name='cislo', + name='verejne_db', + field=models.BooleanField(db_column='verejne', default=False, verbose_name='číslo zveřejněno'), + ), + migrations.AlterField( + model_name='konfera', + name='typ_prezentace', + field=models.CharField(choices=[('veletrh', 'Veletrh (postery)'), ('prezentace', 'Prezentace (přednáška)')], default='veletrh', max_length=16, verbose_name='typ prezentace'), + ), + migrations.RenameField( + model_name='novinky', + old_name='autor', + new_name='autor_old', + ), + migrations.AddField( + model_name='novinky', + name='autor', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='seminar.Organizator', verbose_name='Autor novinky'), + ), + migrations.AlterField( + model_name='novinky', + name='obrazek', + field=models.ImageField(blank=True, null=True, upload_to='image_novinky/%Y/%m/%d/', verbose_name='Obrázek'), + ), + migrations.AlterField( + model_name='novinky', + name='text', + field=models.TextField(blank=True, null=True, verbose_name='Text novinky'), + ), + migrations.AlterField( + model_name='novinky', + name='zverejneno', + field=models.BooleanField(default=False, verbose_name='Zveřejněno'), + ), + migrations.AlterField( + model_name='organizator', + name='strucny_popis_organizatora', + field=models.TextField(blank=True, null=True, verbose_name='Stručný popis organizátora'), + ), + migrations.AlterField( + model_name='organizator', + name='studuje', + field=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.'), + ), + migrations.CreateModel( + name='Pohadka', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('text', models.TextField(verbose_name='Text pohádky')), + ('pred', models.BooleanField(default=True, verbose_name='Před úlohou')), + ('vytvoreno', models.DateTimeField(blank=True, default=django.utils.timezone.now, editable=False, verbose_name='Vytvořeno')), + ('autor_old', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name=b'Autor poh\xc3\xa1dky')), + ('uloha_old', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='pohadky', to='seminar.Problem', verbose_name='Úloha')), + ('autor', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='seminar.Organizator', verbose_name='Autor pohádky')), + ('uloha', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='pohadky', to='seminar.Uloha', verbose_name='Úloha')), + ], + options={ + 'ordering': ['uloha__cislo_zadani', 'uloha__kod', '-pred'], + 'db_table': 'seminar_pohadky', + 'verbose_name': 'Pohádka', + 'verbose_name_plural': 'Pohádky', + }, + ), + migrations.RenameField( + model_name='problem', + old_name='autor', + new_name='autor_old', + ), + migrations.AddField( + model_name='problem', + name='autor', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='autor_problemu_problem', to='seminar.Organizator', verbose_name='autor problému'), + ), + migrations.AlterField( + model_name='problem', + name='kod', + field=models.CharField(blank=True, default='', help_text='Číslo/kód úlohy v čísle nebo kód tématu/článku/seriálu v ročníku', max_length=32, verbose_name='lokální kód'), + ), + migrations.AlterField( + model_name='problem', + name='stav', + field=models.CharField(choices=[('navrh', 'Návrh'), ('zadany', 'Zadaný'), ('vyreseny', 'Vyřešený'), ('smazany', 'Smazaný')], default='navrh', max_length=32, verbose_name='stav problému'), + ), + migrations.AlterField( + model_name='problem', + name='zamereni', + field=taggit.managers.TaggableManager(blank=True, help_text='Zaměření M/F/I/O problému, příp. další tagy', through='taggit.TaggedItem', to='taggit.Tag', verbose_name='zaměření'), + ), + migrations.AlterField( + model_name='reseni', + name='forma', + field=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í'), + ), + migrations.RenameField( + model_name='reseni', + old_name='problem', + new_name='problem_old', + ), + migrations.AlterField( + model_name='resitel', + name='zasilat', + field=models.CharField(choices=[('domu', 'Domů'), ('do_skoly', 'Do školy'), ('nikam', 'Nikam')], default='domu', max_length=32, verbose_name='kam zasílat'), + ), + migrations.AlterField( + model_name='rocnik', + name='exportovat', + field=models.BooleanField(db_column='exportovat', default=False, help_text='Exportuje se jen podle tohoto flagu (ne veřejnosti), a to jen čísla s veřejnou výsledkovkou', verbose_name='export do AESOPa'), + ), + migrations.AlterField( + model_name='skola', + name='aesop_id', + field=models.CharField(blank=True, default='', help_text='Aesopi ID typu "izo:..." nebo "aesop:..."', max_length=32, verbose_name='Aesop ID'), + ), + migrations.AlterField( + model_name='skola', + name='kratky_nazev', + field=models.CharField(blank=True, help_text='Zkrácený název pro zobrazení ve výsledkovce', max_length=256, verbose_name='zkrácený název'), + ), + migrations.AlterField( + model_name='skola', + name='stat', + field=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'), + ), + migrations.AlterField( + model_name='soustredeni', + name='exportovat', + field=models.BooleanField(db_column='exportovat', default=False, help_text='Exportuje se jen podle tohoto flagu (ne veřejnosti)', verbose_name='export do AESOPa'), + ), + migrations.AlterField( + model_name='soustredeni', + name='misto', + field=models.CharField(blank=True, default='', help_text='Místo (název obce, volitelně též objektu', max_length=256, verbose_name='místo soustředění'), + ), + migrations.AlterField( + model_name='soustredeni', + name='text', + field=models.TextField(blank=True, default='', verbose_name='text k soustředění (HTML)'), + ), + migrations.AlterField( + model_name='soustredeni', + name='typ', + field=models.CharField(choices=[('jarni', 'Jarní soustředění'), ('podzimni', 'Podzimní soustředění'), ('vikend', 'Víkendový sraz')], default='podzimni', max_length=16, verbose_name='typ akce'), + ), + migrations.AlterField( + model_name='soustredeni', + name='verejne_db', + field=models.BooleanField(db_column='verejne', default=False, verbose_name='soustředění zveřejněno'), + ), + migrations.AlterModelTable( + name='problem', + table='seminar_problemy', + ), + migrations.AddField( + model_name='uloha', + name='cislo_deadline', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='deadlinove_ulohy', to='seminar.Cislo', verbose_name='číslo deadlinu'), + ), + migrations.AddField( + model_name='uloha', + name='cislo_reseni', + field=models.ForeignKey(blank=True, help_text='Číslo s řešením úlohy, jen pro úlohy', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='resene_ulohy', to='seminar.Cislo', verbose_name='číslo řešení'), + ), + migrations.AddField( + model_name='uloha', + name='cislo_zadani', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='zadane_ulohy', to='seminar.Cislo', verbose_name='číslo zadání'), + ), + migrations.CreateModel( + name='Tema', + fields=[ + ('problem_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.Problem')), + ('tema_typ', models.CharField(choices=[('tema', 'Téma'), ('serial', 'Seriál')], default='tema', max_length=16, verbose_name='Typ tématu')), + ('rocnik', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='seminar.Rocnik', verbose_name='ročník')), + ], + options={ + 'verbose_name': 'Téma', + 'verbose_name_plural': 'Témata', + 'db_table': 'seminar_temata', + }, + bases=('seminar.problem',), + ), + 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='seminar.Reseni', verbose_name='řešení')), + ('resitele', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Resitel', verbose_name='řešitel')), + ], + options={ + 'verbose_name': 'Řešení řešitelů', + 'verbose_name_plural': 'Řešení řešitelů', + 'db_table': 'seminar_reseni_resitele', + 'ordering': ['reseni', 'resitele'], + }, + ), + migrations.CreateModel( + name='Obrazek', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('na_web', models.ImageField(blank=True, null=True, upload_to='obrazky/%Y/%m/%d/', verbose_name='obrázek na web')), + ('do_cisla_barevny', models.FileField(blank=True, help_text='Barevná verze obrázku do čísla', null=True, upload_to='obrazky/%Y/%m/%d/', verbose_name='barevný obrázek do čísla')), + ('do_cisla_cernobily', models.FileField(blank=True, help_text='Černobílá verze obrázku do čísla', null=True, upload_to='obrazky/%Y/%m/%d/', verbose_name='černobílý obrázek do čísla')), + ('text', models.ForeignKey(help_text='text, ve kterém se obrázek vyskytuje', on_delete=django.db.models.deletion.CASCADE, to='seminar.Text', verbose_name='text')), + ], + options={ + 'verbose_name': 'obrázek', + 'verbose_name_plural': 'obrázky', + 'db_table': 'seminar_obrazky', + }, + ), + migrations.CreateModel( + name='Hodnoceni', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('body', models.DecimalField(decimal_places=1, max_digits=8, verbose_name='body')), + ('cislo_body', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='hodnoceni', to='seminar.Cislo', verbose_name='číslo pro body')), + ('problem', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Problem', verbose_name='problém')), + ('reseni', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Reseni', verbose_name='řešení')), + ], + options={ + 'verbose_name': 'Hodnocení', + 'verbose_name_plural': 'Hodnocení', + 'db_table': 'seminar_hodnoceni', + }, + ), + migrations.CreateModel( + name='Clanek', + fields=[ + ('problem_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.Problem')), + ('cislo', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='seminar.Cislo', verbose_name='číslo')), + ], + options={ + 'verbose_name': 'Článek', + 'verbose_name_plural': 'Články', + 'db_table': 'seminar_clanky', + }, + bases=('seminar.problem',), + ), + migrations.AddField( + model_name='reseni', + name='resitele', + field=models.ManyToManyField(help_text='Seznam autorů řešení', through='seminar.Reseni_Resitele', to='seminar.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.CASCADE, related_name='reseni_cely_set', to='seminar.Text', verbose_name='Plná verze textu řešení'), + ), + migrations.AddField( + model_name='reseni', + name='text_zkraceny', + field=models.ManyToManyField(help_text='Seznam úryvků z řešení', related_name='reseni_zkraceny_set', to='seminar.Text', verbose_name='zkrácené verze řešení'), + ), + migrations.AddField( + model_name='skola', + name='kontaktni_osoba', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='seminar.Osoba', verbose_name='Kontaktní osoba'), + ), + migrations.AddField( + model_name='reseni', + name='problem', + field=models.ManyToManyField(help_text='Problém', through='seminar.Hodnoceni', to='seminar.Problem', verbose_name='problém'), + ), + migrations.AddField( + model_name='konfera', + name='reseni', + field=models.OneToOneField(blank=True, help_text='Účastnický přípěvek o konfeře', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='konfery', to='seminar.Reseni', verbose_name='článek ke konfeře'), + ), + migrations.AddField( + model_name='organizator', + name='osoba', + field=models.OneToOneField(help_text='osobní údaje organizátora', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='org', to='seminar.Osoba', verbose_name='osoba'), + ), + migrations.AddField( + model_name='resitel', + name='osoba', + field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.CASCADE, to='seminar.Osoba', verbose_name='osoba'), + ), + migrations.CreateModel( + name='TreeNode', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('first_child', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='seminar.TreeNode', verbose_name='první potomek')), + ('root', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='potomci_set', to='seminar.TreeNode', verbose_name='kořen stromu')), + ('succ', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='prev', to='seminar.TreeNode', verbose_name='další element na stejné úrovni')), + ], + options={ + 'verbose_name': 'TreeNode', + 'verbose_name_plural': 'TreeNody', + 'db_table': 'seminar_nodes_treenode', + }, + ), + migrations.CreateModel( + name='CisloNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('cislo', models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, to='seminar.Cislo', verbose_name='číslo')), + ], + options={ + 'verbose_name': 'Číslo (Node)', + 'verbose_name_plural': 'Čísla (Node)', + 'db_table': 'seminar_nodes_cislo', + }, + bases=('seminar.treenode',), + ), + migrations.CreateModel( + name='ClanekNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('clanek', models.OneToOneField(null=True, on_delete=django.db.models.deletion.PROTECT, to='seminar.Clanek', verbose_name='článek')), + ], + options={ + 'verbose_name': 'Článek (Node)', + 'verbose_name_plural': 'Články (Node)', + 'db_table': 'seminar_nodes_clanek', + }, + bases=('seminar.treenode',), + ), + migrations.CreateModel( + name='KonferaNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('konfera', models.OneToOneField(null=True, on_delete=django.db.models.deletion.PROTECT, to='seminar.Konfera', verbose_name='konfera')), + ], + options={ + 'verbose_name': 'Konfera (Node)', + 'verbose_name_plural': 'Konfery (Node)', + 'db_table': 'seminar_nodes_konfera', + }, + bases=('seminar.treenode',), + ), + migrations.CreateModel( + name='MezicisloNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ], + options={ + 'verbose_name': 'Mezičíslo (Node)', + 'verbose_name_plural': 'Mezičísla (Node)', + 'db_table': 'seminar_nodes_mezicislo', + }, + bases=('seminar.treenode',), + ), + migrations.CreateModel( + name='RocnikNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('rocnik', models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, to='seminar.Rocnik', verbose_name='ročník')), + ], + options={ + 'verbose_name': 'Ročník (Node)', + 'verbose_name_plural': 'Ročníky (Node)', + 'db_table': 'seminar_nodes_rocnik', + }, + bases=('seminar.treenode',), + ), + migrations.CreateModel( + name='TemaVCisleNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('tema', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Tema', verbose_name='téma v čísle')), + ], + options={ + 'verbose_name': 'Téma v čísle (Node)', + 'verbose_name_plural': 'Témata v čísle (Node)', + 'db_table': 'seminar_nodes_temavcisle', + }, + bases=('seminar.treenode',), + ), + migrations.CreateModel( + name='TextNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('text', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Text', verbose_name='text')), + ], + options={ + 'verbose_name': 'Text (Node)', + 'verbose_name_plural': 'Text (Node)', + 'db_table': 'seminar_nodes_obsah', + }, + bases=('seminar.treenode',), + ), + migrations.CreateModel( + name='UlohaVzorakNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('uloha', models.OneToOneField(null=True, on_delete=django.db.models.deletion.PROTECT, to='seminar.Uloha', verbose_name='úloha')), + ], + options={ + 'verbose_name': 'Vzorák úlohy (Node)', + 'verbose_name_plural': 'Vzoráky úloh (Node)', + 'db_table': 'seminar_nodes_uloha_vzorak', + }, + bases=('seminar.treenode',), + ), + migrations.CreateModel( + name='UlohaZadaniNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('uloha', models.OneToOneField(null=True, on_delete=django.db.models.deletion.PROTECT, to='seminar.Uloha', verbose_name='úloha')), + ], + options={ + 'verbose_name': 'Zadání úlohy (Node)', + 'verbose_name_plural': 'Zadání úloh (Node)', + 'db_table': 'seminar_nodes_uloha_zadani', + }, + bases=('seminar.treenode',), + ), + migrations.CreateModel( + name='PohadkaNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('pohadka', models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, to='seminar.Pohadka', verbose_name='pohádka')), + ], + options={ + 'verbose_name': 'Pohádka (Node)', + 'verbose_name_plural': 'Pohádky (Node)', + 'db_table': 'seminar_nodes_pohadka', + }, + bases=('seminar.treenode',), + ), + + # migr 0051 + migrations.RunPython( + resitel_to_osoba, + reverse_code=osoba_to_resitel, + ), + + # migr 0052 + migrations.RunPython( + spoj_k_organizatorum_osoby, + ), + migrations.RunPython( + fix_problem, + ), + migrations.RunPython( + fix_pohadka, + ), + migrations.RunPython( + fix_novinka, + ), + + # migr 0053 + migrations.RunPython( + rok_to_datetime, + reverse_code=datetime_to_rok, + ), + + migrations.RemoveField( + model_name='prispevek', + name='problem', + ), + migrations.RemoveField( + model_name='prispevek', + name='reseni', + ), + migrations.DeleteModel( + name='ProblemNavrh', + ), + migrations.DeleteModel( + name='ProblemZadany', + ), + migrations.RemoveField( + model_name='cislo', + name='faze', + ), + migrations.RemoveField( + model_name='konfera', + name='popis', + ), + migrations.RemoveField( + model_name='konfera', + name='prispevek', + ), + migrations.RemoveField( + model_name='problem', + name='import_dakos_id', + ), + migrations.RemoveField( + model_name='resitel', + name='import_mamoper_id', + ), + migrations.RemoveField( + model_name='skola', + name='import_dakos_id', + ), + migrations.DeleteModel( + name='Prispevek', + ), + + # migr 0056 + migrations.RunPython( + generuj_RocnikNody_a_CisloNody, + ), + + # migr 0057 + migrations.RunPython( + reseni_to_Reseni, + ), + + # migr 0058 + migrations.RunPython( + uloha_to_Uloha, + ), + migrations.RunPython( + tema_to_Tema, + ), + migrations.RunPython( + clanek_to_Clanek, + ), + migrations.RunPython( + konfery_rucne, + ), + + # migr 0059 + migrations.RunPython( + vytvor_pohadkanode, + ), + + # migr 0060 + migrations.RunPython( + pokacej_les, + ), + + migrations.RemoveField( + model_name='novinky', + name='autor_old', + ), + migrations.RemoveField( + model_name='organizator', + name='foto', + ), + migrations.RemoveField( + model_name='organizator', + name='organizuje_do_roku', + ), + migrations.RemoveField( + model_name='organizator', + name='organizuje_od_roku', + ), + migrations.RemoveField( + model_name='organizator', + name='prezdivka', + ), + migrations.RemoveField( + model_name='organizator', + name='user', + ), + migrations.RemoveField( + model_name='pohadka', + name='autor_old', + ), + migrations.RemoveField( + model_name='pohadka', + name='uloha_old', + ), + migrations.RemoveField( + model_name='problem', + name='autor_old', + ), + migrations.RemoveField( + model_name='problem', + name='body', + ), + migrations.RemoveField( + model_name='problem', + name='cislo_reseni_old', + ), + migrations.RemoveField( + model_name='problem', + name='cislo_zadani_old', + ), + migrations.RemoveField( + model_name='problem', + name='opravovatel', + ), + migrations.RemoveField( + model_name='problem', + name='text_reseni', + ), + migrations.RemoveField( + model_name='problem', + name='text_zadani', + ), + migrations.RemoveField( + model_name='problem', + name='typ', + ), + migrations.RemoveField( + model_name='reseni', + name='body', + ), + migrations.RemoveField( + model_name='reseni', + name='cislo_body', + ), + migrations.RemoveField( + model_name='reseni', + name='problem_old', + ), + migrations.RemoveField( + model_name='reseni', + name='resitel', + ), + migrations.RemoveField( + model_name='resitel', + name='datum_narozeni', + ), + migrations.RemoveField( + model_name='resitel', + name='datum_prihlaseni', + ), + migrations.RemoveField( + model_name='resitel', + name='datum_souhlasu_udaje', + ), + migrations.RemoveField( + model_name='resitel', + name='datum_souhlasu_zasilani', + ), + migrations.RemoveField( + model_name='resitel', + name='email', + ), + migrations.RemoveField( + model_name='resitel', + name='jmeno', + ), + migrations.RemoveField( + model_name='resitel', + name='mesto', + ), + migrations.RemoveField( + model_name='resitel', + name='pohlavi_muz', + ), + migrations.RemoveField( + model_name='resitel', + name='prijmeni', + ), + migrations.RemoveField( + model_name='resitel', + name='psc', + ), + migrations.RemoveField( + model_name='resitel', + name='stat', + ), + migrations.RemoveField( + model_name='resitel', + name='telefon', + ), + migrations.RemoveField( + model_name='resitel', + name='ulice', + ), + migrations.RemoveField( + model_name='resitel', + name='user', + ), + migrations.AlterModelOptions( + name='pohadka', + options={'ordering': ['vytvoreno'], 'verbose_name': 'Pohádka', 'verbose_name_plural': 'Pohádky'}, + ), + migrations.RemoveField( + model_name='pohadka', + name='pred', + ), + migrations.RemoveField( + model_name='pohadka', + name='text', + ), + migrations.RemoveField( + model_name='pohadka', + name='uloha', + ), + migrations.AlterField( + model_name='cislo', + name='verejna_vysledkovka', + field=models.BooleanField(default=False, help_text='Je-li false u veřejného čísla, není výsledkovka zatím veřejná.', verbose_name='zveřejněna výsledkovka'), + ), + migrations.AlterField( + model_name='prijemce', + name='osoba', + field=models.OneToOneField(help_text='Které osobě či na jakou adresu se mají zasílat čísla', on_delete=django.db.models.deletion.CASCADE, to='seminar.Osoba', verbose_name='komu'), + ), + migrations.AlterField( + model_name='reseni', + name='cas_doruceni', + field=models.DateTimeField(blank=True, default=django.utils.timezone.now, verbose_name='čas_doručení'), + ), + migrations.AlterField( + model_name='cislo', + name='rocnik', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='cisla', to='seminar.Rocnik', verbose_name='ročník'), + ), + migrations.AlterField( + model_name='clanek', + name='cislo', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='seminar.Cislo', verbose_name='číslo'), + ), + migrations.AlterField( + model_name='hodnoceni', + name='cislo_body', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='hodnoceni', to='seminar.Cislo', verbose_name='číslo pro body'), + ), + migrations.AlterField( + model_name='hodnoceni', + name='problem', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Problem', verbose_name='problém'), + ), + migrations.AlterField( + model_name='konfery_ucastnici', + name='konfera', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Konfera', verbose_name='konfera'), + ), + migrations.AlterField( + model_name='konfery_ucastnici', + name='resitel', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Resitel', verbose_name='řešitel'), + ), + migrations.AlterField( + model_name='nastaveni', + name='aktualni_cislo', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Cislo', verbose_name='poslední vydané číslo'), + ), + migrations.AlterField( + model_name='nastaveni', + name='aktualni_rocnik', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Rocnik', verbose_name='aktuální ročník'), + ), + migrations.AlterField( + model_name='novinky', + name='autor', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='seminar.Organizator', verbose_name='Autor novinky'), + ), + migrations.AlterField( + model_name='organizator', + name='osoba', + field=models.OneToOneField(help_text='osobní údaje organizátora', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='org', to='seminar.Osoba', verbose_name='osoba'), + ), + migrations.AlterField( + model_name='osoba', + name='user', + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, to=settings.AUTH_USER_MODEL, verbose_name='uživatel'), + ), + migrations.AlterField( + model_name='pohadka', + name='autor', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='seminar.Organizator', verbose_name='Autor pohádky'), + ), + migrations.AlterField( + model_name='problem', + name='autor', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='autor_problemu_problem', to='seminar.Organizator', verbose_name='autor problému'), + ), + migrations.AlterField( + model_name='problem', + name='garant', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='garant_problemu_problem', to='seminar.Organizator', verbose_name='garant zadaného problému'), + ), + migrations.AlterField( + model_name='problem', + name='nadproblem', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='nadproblem_problem', to='seminar.Problem', verbose_name='nadřazený problém'), + ), + migrations.AlterField( + model_name='reseni', + name='text_cely', + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='reseni_cely_set', to='seminar.Text', verbose_name='Plná verze textu řešení'), + ), + migrations.AlterField( + model_name='reseni_resitele', + name='resitele', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Resitel', verbose_name='řešitel'), + ), + migrations.AlterField( + model_name='resitel', + name='osoba', + field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.SET_NULL, to='seminar.Osoba', verbose_name='osoba'), + ), + migrations.AlterField( + model_name='resitel', + name='skola', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='seminar.Skola', verbose_name='škola'), + ), + migrations.AlterField( + model_name='skola', + name='kontaktni_osoba', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='seminar.Osoba', verbose_name='Kontaktní osoba'), + ), + migrations.AlterField( + model_name='soustredeni', + name='rocnik', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='soustredeni', to='seminar.Rocnik', verbose_name='ročník'), + ), + migrations.AlterField( + model_name='soustredeni_organizatori', + name='organizator', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Organizator', verbose_name='organizátor'), + ), + migrations.AlterField( + model_name='soustredeni_organizatori', + name='soustredeni', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Soustredeni', verbose_name='soustředění'), + ), + migrations.AlterField( + model_name='soustredeni_ucastnici', + name='resitel', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Resitel', verbose_name='řešitel'), + ), + migrations.AlterField( + model_name='soustredeni_ucastnici', + name='soustredeni', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Soustredeni', verbose_name='soustředění'), + ), + migrations.AlterField( + model_name='tema', + name='rocnik', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='seminar.Rocnik', verbose_name='ročník'), + ), + migrations.AlterField( + model_name='uloha', + name='cislo_deadline', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='deadlinove_ulohy', to='seminar.Cislo', verbose_name='číslo deadlinu'), + ), + migrations.AlterField( + model_name='uloha', + name='cislo_reseni', + field=models.ForeignKey(blank=True, help_text='Číslo s řešením úlohy, jen pro úlohy', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='resene_ulohy', to='seminar.Cislo', verbose_name='číslo řešení'), + ), + migrations.AlterField( + model_name='uloha', + name='cislo_zadani', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='zadane_ulohy', to='seminar.Cislo', verbose_name='číslo zadání'), + ), + migrations.AddField( + model_name='treenode', + name='polymorphic_ctype', + field=models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_seminar.treenode_set+', to='contenttypes.ContentType'), + ), + migrations.RunPython( + vyrob_treenodum_ctypes, + reverse_code=migrations.RunPython.noop, + ), + migrations.AddField( + model_name='problem', + name='polymorphic_ctype', + field=models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_seminar.problem_set+', to='contenttypes.ContentType'), + ), + migrations.RunPython( + vyrob_problemum_ctypes, + reverse_code=migrations.RunPython.noop, + ), + migrations.AlterField( + model_name='konfera', + name='nazev', + field=models.CharField(help_text='Název konfery', max_length=100, verbose_name='název konfery'), + ), + ] From 910e34a51515a7825b7259d909eab2c9a1e299a9 Mon Sep 17 00:00:00 2001 From: Anet Date: Thu, 7 Nov 2019 20:24:44 +0100 Subject: [PATCH 39/92] =?UTF-8?q?models.py:=20$(class)=20je=20pot=C5=99eba?= =?UTF-8?q?=20u=20abstraktn=C3=AD=20t=C5=99=C3=ADdy=20v=20related=20name.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/seminar/models.py b/seminar/models.py index 45e5885e..67faff22 100644 --- a/seminar/models.py +++ b/seminar/models.py @@ -607,7 +607,7 @@ class Problem(SeminarModelBase,PolymorphicModel): # Problém má podproblémy nadproblem = models.ForeignKey('self', verbose_name='nadřazený problém', - related_name='podproblem', null=True, blank=True, + related_name='podproblem_%(class)s', null=True, blank=True, on_delete=models.SET_NULL) STAV_NAVRH = 'navrh' From 3815b5a8a879b7725f418ccde35ad2ec8fcac37a Mon Sep 17 00:00:00 2001 From: Pavel 'LEdoian' Turinsky Date: Thu, 7 Nov 2019 21:04:27 +0100 Subject: [PATCH 40/92] =?UTF-8?q?Zal=C3=A1man=C3=A9=20SQL,=20aby=20se=20da?= =?UTF-8?q?lo=20=C4=8D=C3=ADst?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../0001_squashed_0067_auto_20190814_0805.py | 148 +++++++++++++++++- 1 file changed, 143 insertions(+), 5 deletions(-) diff --git a/seminar/migrations/0001_squashed_0067_auto_20190814_0805.py b/seminar/migrations/0001_squashed_0067_auto_20190814_0805.py index f1f046af..3cc3be08 100644 --- a/seminar/migrations/0001_squashed_0067_auto_20190814_0805.py +++ b/seminar/migrations/0001_squashed_0067_auto_20190814_0805.py @@ -721,8 +721,35 @@ class Migration(migrations.Migration): field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='cisla', to='seminar.Rocnik', verbose_name='ročník'), ), migrations.RunSQL( - sql="\ncreate view seminar_body_za_cislo as\n select\n sr.cislo_body_id || '-' || sr.resitel_id as id,\n sr.cislo_body_id as cislo_id,\n sr.resitel_id as resitel_id,\n sum(sr.body) as body\n from seminar_reseni as sr\n group by sr.cislo_body_id, sr.resitel_id\n order by body desc;\n\ncreate view seminar_body_k_cislu as\n select\n akt_c.id || '-' || min_bzc.resitel_id as id,\n akt_c.id as cislo_id,\n min_bzc.resitel_id as resitel_id,\n max(akt_bzc.body) as body,\n sum(min_bzc.body) as body_celkem\n from ((seminar_cisla as akt_c\n inner join seminar_cisla as min_c on min_c.rocnik_id = akt_c.rocnik_id and akt_c.cislo >= min_c.cislo)\n inner join seminar_body_za_cislo as min_bzc on min_c.id = min_bzc.cislo_id)\n left outer join seminar_body_za_cislo as akt_bzc on akt_bzc.cislo_id = akt_c.id and akt_bzc.resitel_id = min_bzc.resitel_id \n group by akt_c.id, min_bzc.resitel_id, akt_bzc.resitel_id\n order by body_celkem desc;\n", - reverse_sql='\ndrop view seminar_body_k_cislu;\ndrop view seminar_body_za_cislo;\n', + sql=" + create view seminar_body_za_cislo as + select + sr.cislo_body_id || '-' || sr.resitel_id as id, + sr.cislo_body_id as cislo_id, + sr.resitel_id as resitel_id, + sum(sr.body) as body + from seminar_reseni as sr + group by sr.cislo_body_id, sr.resitel_id + order by body desc; + + create view seminar_body_k_cislu as + select + akt_c.id || '-' || min_bzc.resitel_id as id, + akt_c.id as cislo_id, + min_bzc.resitel_id as resitel_id, + max(akt_bzc.body) as body, + sum(min_bzc.body) as body_celkem + from ((seminar_cisla as akt_c + inner join seminar_cisla as min_c on min_c.rocnik_id = akt_c.rocnik_id and akt_c.cislo >= min_c.cislo) + inner join seminar_body_za_cislo as min_bzc on min_c.id = min_bzc.cislo_id) + left outer join seminar_body_za_cislo as akt_bzc on akt_bzc.cislo_id = akt_c.id and akt_bzc.resitel_id = min_bzc.resitel_id + group by akt_c.id, min_bzc.resitel_id, akt_bzc.resitel_id + order by body_celkem desc; + ", + reverse_sql=' + drop view seminar_body_k_cislu; + drop view seminar_body_za_cislo; + ', ), migrations.AlterField( model_name='reseni', @@ -956,7 +983,31 @@ class Migration(migrations.Migration): field=models.DecimalField(blank=True, decimal_places=1, max_digits=8, null=True, verbose_name='body'), ), migrations.RunSQL( - sql="\ncreate view seminar_body_za_cislo as\n select\n sr.cislo_body_id || '-' || sr.resitel_id as id,\n sr.cislo_body_id as cislo_id,\n sr.resitel_id as resitel_id,\n sum(sr.body) as body\n from seminar_reseni as sr\n group by sr.cislo_body_id, sr.resitel_id\n order by body desc;\n\ncreate view seminar_body_k_cislu as\n select\n akt_c.id || '-' || min_bzc.resitel_id as id,\n akt_c.id as cislo_id,\n min_bzc.resitel_id as resitel_id,\n max(akt_bzc.body) as body,\n sum(min_bzc.body) as body_celkem\n from ((seminar_cisla as akt_c\n inner join seminar_cisla as min_c on min_c.rocnik_id = akt_c.rocnik_id and akt_c.cislo >= min_c.cislo)\n inner join seminar_body_za_cislo as min_bzc on min_c.id = min_bzc.cislo_id)\n left outer join seminar_body_za_cislo as akt_bzc on akt_bzc.cislo_id = akt_c.id and akt_bzc.resitel_id = min_bzc.resitel_id \n group by akt_c.id, min_bzc.resitel_id, akt_bzc.resitel_id\n order by body_celkem desc;\n", + sql=" + create view seminar_body_za_cislo as + select + sr.cislo_body_id || '-' || sr.resitel_id as id, + sr.cislo_body_id as cislo_id, + sr.resitel_id as resitel_id, + sum(sr.body) as body + from seminar_reseni as sr + group by sr.cislo_body_id, sr.resitel_id + order by body desc; + + create view seminar_body_k_cislu as + select + akt_c.id || '-' || min_bzc.resitel_id as id, + akt_c.id as cislo_id, + min_bzc.resitel_id as resitel_id, + max(akt_bzc.body) as body, + sum(min_bzc.body) as body_celkem + from ((seminar_cisla as akt_c + inner join seminar_cisla as min_c on min_c.rocnik_id = akt_c.rocnik_id and akt_c.cislo >= min_c.cislo) + inner join seminar_body_za_cislo as min_bzc on min_c.id = min_bzc.cislo_id) + left outer join seminar_body_za_cislo as akt_bzc on akt_bzc.cislo_id = akt_c.id and akt_bzc.resitel_id = min_bzc.resitel_id + group by akt_c.id, min_bzc.resitel_id, akt_bzc.resitel_id + order by body_celkem desc; + ", ), migrations.CreateModel( name='Novinky', @@ -1007,10 +1058,97 @@ class Migration(migrations.Migration): field=models.CharField(choices=[(b'jarni', 'Jarní soustředění'), (b'podzimni', 'Podzimní soustředění'), (b'vikend', 'Víkendový sraz')], default=b'podzimni', max_length=16, verbose_name='typ akce'), ), migrations.RunSQL( - sql="\ndrop view seminar_body_k_cislu;\ndrop view seminar_body_za_cislo;\n\ncreate view seminar_body_za_cislo as\n select\n seminar_reseni.cislo_body_id || '-' || seminar_reseni.resitel_id as id,\n seminar_reseni.cislo_body_id as cislo_id,\n seminar_reseni.resitel_id as resitel_id,\n seminar_cisla.cislo as cislo,\n seminar_cisla.rocnik_id as rocnik_id,\n seminar_rocniky.rocnik as rocnik,\n seminar_cisla.verejna_vysledkovka as verejna_vysledkovka,\n sum(seminar_reseni.body) as body\n from\n seminar_reseni\n inner join seminar_cisla on seminar_reseni.cislo_body_id = seminar_cisla.id\n inner join seminar_rocniky on seminar_cisla.rocnik_id = seminar_rocniky.id\n group by seminar_reseni.cislo_body_id, seminar_reseni.resitel_id, seminar_cisla.cislo,\n seminar_cisla.rocnik_id, seminar_rocniky.rocnik, seminar_cisla.verejna_vysledkovka\n order by body desc;\n\ncreate view seminar_body_k_cislu_rocnik as\n select\n akt_body.id as id,\n akt_body.cislo_id as cislo_id,\n akt_body.resitel_id as resitel_id,\n akt_body.body as body,\n sum(min_body.body) as body_celkem\n from\n seminar_body_za_cislo as akt_body\n inner join seminar_body_za_cislo as min_body on\n (akt_body.resitel_id = min_body.resitel_id and\n (akt_body.rocnik = min_body.rocnik and akt_body.cislo >= min_body.cislo)\n )\n group by akt_body.id, akt_body.cislo_id, akt_body.resitel_id, akt_body.body\n order by body_celkem desc;\n\ncreate view seminar_body_k_cislu_odjakziva as\n select\n akt_body.id as id,\n akt_body.cislo_id as cislo_id,\n akt_body.resitel_id as resitel_id,\n akt_body.body as body,\n sum(min_body.body) as body_celkem\n from\n seminar_body_za_cislo as akt_body\n inner join seminar_body_za_cislo as min_body on\n (akt_body.resitel_id = min_body.resitel_id and\n ((akt_body.rocnik = min_body.rocnik and akt_body.cislo >= min_body.cislo) or\n (akt_body.rocnik < min_body.rocnik)\n )\n )\n group by akt_body.id, akt_body.cislo_id, akt_body.resitel_id, akt_body.body\n order by body_celkem desc;\n\n", + sql=" + drop view seminar_body_k_cislu; + drop view seminar_body_za_cislo; + + create view seminar_body_za_cislo as + select + seminar_reseni.cislo_body_id || '-' || seminar_reseni.resitel_id as id, + seminar_reseni.cislo_body_id as cislo_id, + seminar_reseni.resitel_id as resitel_id, + seminar_cisla.cislo as cislo, + seminar_cisla.rocnik_id as rocnik_id, + seminar_rocniky.rocnik as rocnik, + seminar_cisla.verejna_vysledkovka as verejna_vysledkovka, + sum(seminar_reseni.body) as body + from + seminar_reseni + inner join seminar_cisla on seminar_reseni.cislo_body_id = seminar_cisla.id + inner join seminar_rocniky on seminar_cisla.rocnik_id = seminar_rocniky.id + group by seminar_reseni.cislo_body_id, seminar_reseni.resitel_id, seminar_cisla.cislo, + seminar_cisla.rocnik_id, seminar_rocniky.rocnik, seminar_cisla.verejna_vysledkovka + order by body desc; + + create view seminar_body_k_cislu_rocnik as + select + akt_body.id as id, + akt_body.cislo_id as cislo_id, + akt_body.resitel_id as resitel_id, + akt_body.body as body, + sum(min_body.body) as body_celkem + from + seminar_body_za_cislo as akt_body + inner join seminar_body_za_cislo as min_body on + (akt_body.resitel_id = min_body.resitel_id and + (akt_body.rocnik = min_body.rocnik and akt_body.cislo >= min_body.cislo) + ) + group by akt_body.id, akt_body.cislo_id, akt_body.resitel_id, akt_body.body + order by body_celkem desc; + + create view seminar_body_k_cislu_odjakziva as + select + akt_body.id as id, + akt_body.cislo_id as cislo_id, + akt_body.resitel_id as resitel_id, + akt_body.body as body, + sum(min_body.body) as body_celkem + from + seminar_body_za_cislo as akt_body + inner join seminar_body_za_cislo as min_body on + (akt_body.resitel_id = min_body.resitel_id and + ((akt_body.rocnik = min_body.rocnik and akt_body.cislo >= min_body.cislo) or + (akt_body.rocnik < min_body.rocnik) + ) + ) + group by akt_body.id, akt_body.cislo_id, akt_body.resitel_id, akt_body.body + order by body_celkem desc; + + ", ), migrations.RunSQL( - sql="\n\ndrop view seminar_body_k_cislu_rocnik;\ncreate view seminar_body_k_cislu_rocnik as\n select\n seminar_cisla.id || '-' || min_body.resitel_id as id,\n seminar_cisla.id as cislo_id,\n min_body.resitel_id as resitel_id,\n sum(min_body.body) as body\n from\n seminar_cisla\n inner join seminar_body_za_cislo as min_body on\n (min_body.rocnik_id = seminar_cisla.rocnik_id and seminar_cisla.cislo >= min_body.cislo)\n group by seminar_cisla.id, min_body.resitel_id\n order by body desc;\n\ndrop view seminar_body_k_cislu_odjakziva;\ncreate view seminar_body_k_cislu_odjakziva as\n select\n seminar_cisla.id || '-' || min_body.resitel_id as id,\n seminar_cisla.id as cislo_id,\n min_body.resitel_id as resitel_id,\n sum(min_body.body) as body\n from\n seminar_cisla\n inner join seminar_rocniky on\n (seminar_cisla.rocnik_id = seminar_rocniky.id)\n inner join seminar_body_za_cislo as min_body on\n (min_body.rocnik_id = seminar_cisla.rocnik_id and seminar_cisla.cislo >= min_body.cislo) or\n (min_body.rocnik < seminar_rocniky.rocnik)\n group by seminar_cisla.id, min_body.resitel_id\n order by body desc;\n", + sql=" + drop view seminar_body_k_cislu_rocnik; + create view seminar_body_k_cislu_rocnik as + select + seminar_cisla.id || '-' || min_body.resitel_id as id, + seminar_cisla.id as cislo_id, + min_body.resitel_id as resitel_id, + sum(min_body.body) as body + from + seminar_cisla + inner join seminar_body_za_cislo as min_body on + (min_body.rocnik_id = seminar_cisla.rocnik_id and seminar_cisla.cislo >= min_body.cislo) + group by seminar_cisla.id, min_body.resitel_id + order by body desc; + + drop view seminar_body_k_cislu_odjakziva; + create view seminar_body_k_cislu_odjakziva as + select + seminar_cisla.id || '-' || min_body.resitel_id as id, + seminar_cisla.id as cislo_id, + min_body.resitel_id as resitel_id, + sum(min_body.body) as body + from + seminar_cisla + inner join seminar_rocniky on + (seminar_cisla.rocnik_id = seminar_rocniky.id) + inner join seminar_body_za_cislo as min_body on + (min_body.rocnik_id = seminar_cisla.rocnik_id and seminar_cisla.cislo >= min_body.cislo) or + (min_body.rocnik < seminar_rocniky.rocnik) + group by seminar_cisla.id, min_body.resitel_id + order by body desc; + ", ), migrations.CreateModel( name='VysledkyCelkemKCislu', From 6a93c1c7bb4aa0905bd93ab0c0197ef1c7924fa0 Mon Sep 17 00:00:00 2001 From: Pavel 'LEdoian' Turinsky Date: Thu, 7 Nov 2019 21:05:55 +0100 Subject: [PATCH 41/92] =?UTF-8?q?Smazal=20jsem=20v=C5=A1echy=20v=C3=BDsled?= =?UTF-8?q?ky=20a=20mo=C5=BEn=C3=A1=20jsem=20to=20nerozbil?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../0001_squashed_0067_auto_20190814_0805.py | 216 ------------------ 1 file changed, 216 deletions(-) diff --git a/seminar/migrations/0001_squashed_0067_auto_20190814_0805.py b/seminar/migrations/0001_squashed_0067_auto_20190814_0805.py index 3cc3be08..c1dc0c09 100644 --- a/seminar/migrations/0001_squashed_0067_auto_20190814_0805.py +++ b/seminar/migrations/0001_squashed_0067_auto_20190814_0805.py @@ -516,31 +516,6 @@ class Migration(migrations.Migration): ] operations = [ - migrations.CreateModel( - name='VysledkyKCislu', - fields=[ - ('dummy_id', models.CharField(db_column='id', max_length=32, primary_key=True, serialize=False, verbose_name='dummy ID pro view')), - ('body', models.IntegerField(db_column='body', verbose_name='body za číslo')), - ('body_celkem', models.IntegerField(db_column='body_celkem', verbose_name='body celkem do čísla')), - ], - options={ - 'abstract': False, - 'db_table': 'seminar_body_k_cislu', - 'managed': False, - }, - ), - migrations.CreateModel( - name='VysledkyZaCislo', - fields=[ - ('dummy_id', models.CharField(db_column='id', max_length=32, primary_key=True, serialize=False, verbose_name='dummy ID pro view')), - ('body', models.IntegerField(db_column='body', verbose_name='body za číslo')), - ], - options={ - 'abstract': False, - 'db_table': 'seminar_body_za_cislo', - 'managed': False, - }, - ), migrations.CreateModel( name='Cislo', fields=[ @@ -720,37 +695,6 @@ class Migration(migrations.Migration): name='rocnik', field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='cisla', to='seminar.Rocnik', verbose_name='ročník'), ), - migrations.RunSQL( - sql=" - create view seminar_body_za_cislo as - select - sr.cislo_body_id || '-' || sr.resitel_id as id, - sr.cislo_body_id as cislo_id, - sr.resitel_id as resitel_id, - sum(sr.body) as body - from seminar_reseni as sr - group by sr.cislo_body_id, sr.resitel_id - order by body desc; - - create view seminar_body_k_cislu as - select - akt_c.id || '-' || min_bzc.resitel_id as id, - akt_c.id as cislo_id, - min_bzc.resitel_id as resitel_id, - max(akt_bzc.body) as body, - sum(min_bzc.body) as body_celkem - from ((seminar_cisla as akt_c - inner join seminar_cisla as min_c on min_c.rocnik_id = akt_c.rocnik_id and akt_c.cislo >= min_c.cislo) - inner join seminar_body_za_cislo as min_bzc on min_c.id = min_bzc.cislo_id) - left outer join seminar_body_za_cislo as akt_bzc on akt_bzc.cislo_id = akt_c.id and akt_bzc.resitel_id = min_bzc.resitel_id - group by akt_c.id, min_bzc.resitel_id, akt_bzc.resitel_id - order by body_celkem desc; - ", - reverse_sql=' - drop view seminar_body_k_cislu; - drop view seminar_body_za_cislo; - ', - ), migrations.AlterField( model_name='reseni', name='poznamka', @@ -969,9 +913,6 @@ class Migration(migrations.Migration): name='verejna_vysledkovka', field=models.BooleanField(default=False, help_text='Je-li false u veřejného čísla, není výsledkovka zatím veřejná.', verbose_name='zveřejněna výsledkovka'), ), - migrations.RunSQL( - sql='\ndrop view seminar_body_k_cislu;\ndrop view seminar_body_za_cislo;\n', - ), migrations.AlterField( model_name='problem', name='body', @@ -982,33 +923,6 @@ class Migration(migrations.Migration): name='body', field=models.DecimalField(blank=True, decimal_places=1, max_digits=8, null=True, verbose_name='body'), ), - migrations.RunSQL( - sql=" - create view seminar_body_za_cislo as - select - sr.cislo_body_id || '-' || sr.resitel_id as id, - sr.cislo_body_id as cislo_id, - sr.resitel_id as resitel_id, - sum(sr.body) as body - from seminar_reseni as sr - group by sr.cislo_body_id, sr.resitel_id - order by body desc; - - create view seminar_body_k_cislu as - select - akt_c.id || '-' || min_bzc.resitel_id as id, - akt_c.id as cislo_id, - min_bzc.resitel_id as resitel_id, - max(akt_bzc.body) as body, - sum(min_bzc.body) as body_celkem - from ((seminar_cisla as akt_c - inner join seminar_cisla as min_c on min_c.rocnik_id = akt_c.rocnik_id and akt_c.cislo >= min_c.cislo) - inner join seminar_body_za_cislo as min_bzc on min_c.id = min_bzc.cislo_id) - left outer join seminar_body_za_cislo as akt_bzc on akt_bzc.cislo_id = akt_c.id and akt_bzc.resitel_id = min_bzc.resitel_id - group by akt_c.id, min_bzc.resitel_id, akt_bzc.resitel_id - order by body_celkem desc; - ", - ), migrations.CreateModel( name='Novinky', fields=[ @@ -1057,136 +971,6 @@ class Migration(migrations.Migration): name='typ', field=models.CharField(choices=[(b'jarni', 'Jarní soustředění'), (b'podzimni', 'Podzimní soustředění'), (b'vikend', 'Víkendový sraz')], default=b'podzimni', max_length=16, verbose_name='typ akce'), ), - migrations.RunSQL( - sql=" - drop view seminar_body_k_cislu; - drop view seminar_body_za_cislo; - - create view seminar_body_za_cislo as - select - seminar_reseni.cislo_body_id || '-' || seminar_reseni.resitel_id as id, - seminar_reseni.cislo_body_id as cislo_id, - seminar_reseni.resitel_id as resitel_id, - seminar_cisla.cislo as cislo, - seminar_cisla.rocnik_id as rocnik_id, - seminar_rocniky.rocnik as rocnik, - seminar_cisla.verejna_vysledkovka as verejna_vysledkovka, - sum(seminar_reseni.body) as body - from - seminar_reseni - inner join seminar_cisla on seminar_reseni.cislo_body_id = seminar_cisla.id - inner join seminar_rocniky on seminar_cisla.rocnik_id = seminar_rocniky.id - group by seminar_reseni.cislo_body_id, seminar_reseni.resitel_id, seminar_cisla.cislo, - seminar_cisla.rocnik_id, seminar_rocniky.rocnik, seminar_cisla.verejna_vysledkovka - order by body desc; - - create view seminar_body_k_cislu_rocnik as - select - akt_body.id as id, - akt_body.cislo_id as cislo_id, - akt_body.resitel_id as resitel_id, - akt_body.body as body, - sum(min_body.body) as body_celkem - from - seminar_body_za_cislo as akt_body - inner join seminar_body_za_cislo as min_body on - (akt_body.resitel_id = min_body.resitel_id and - (akt_body.rocnik = min_body.rocnik and akt_body.cislo >= min_body.cislo) - ) - group by akt_body.id, akt_body.cislo_id, akt_body.resitel_id, akt_body.body - order by body_celkem desc; - - create view seminar_body_k_cislu_odjakziva as - select - akt_body.id as id, - akt_body.cislo_id as cislo_id, - akt_body.resitel_id as resitel_id, - akt_body.body as body, - sum(min_body.body) as body_celkem - from - seminar_body_za_cislo as akt_body - inner join seminar_body_za_cislo as min_body on - (akt_body.resitel_id = min_body.resitel_id and - ((akt_body.rocnik = min_body.rocnik and akt_body.cislo >= min_body.cislo) or - (akt_body.rocnik < min_body.rocnik) - ) - ) - group by akt_body.id, akt_body.cislo_id, akt_body.resitel_id, akt_body.body - order by body_celkem desc; - - ", - ), - migrations.RunSQL( - sql=" - drop view seminar_body_k_cislu_rocnik; - create view seminar_body_k_cislu_rocnik as - select - seminar_cisla.id || '-' || min_body.resitel_id as id, - seminar_cisla.id as cislo_id, - min_body.resitel_id as resitel_id, - sum(min_body.body) as body - from - seminar_cisla - inner join seminar_body_za_cislo as min_body on - (min_body.rocnik_id = seminar_cisla.rocnik_id and seminar_cisla.cislo >= min_body.cislo) - group by seminar_cisla.id, min_body.resitel_id - order by body desc; - - drop view seminar_body_k_cislu_odjakziva; - create view seminar_body_k_cislu_odjakziva as - select - seminar_cisla.id || '-' || min_body.resitel_id as id, - seminar_cisla.id as cislo_id, - min_body.resitel_id as resitel_id, - sum(min_body.body) as body - from - seminar_cisla - inner join seminar_rocniky on - (seminar_cisla.rocnik_id = seminar_rocniky.id) - inner join seminar_body_za_cislo as min_body on - (min_body.rocnik_id = seminar_cisla.rocnik_id and seminar_cisla.cislo >= min_body.cislo) or - (min_body.rocnik < seminar_rocniky.rocnik) - group by seminar_cisla.id, min_body.resitel_id - order by body desc; - ", - ), - migrations.CreateModel( - name='VysledkyCelkemKCislu', - fields=[ - ('dummy_id', models.CharField(db_column=b'id', max_length=32, primary_key=True, serialize=False, verbose_name='dummy ID pro view')), - ('body', models.DecimalField(db_column=b'body', decimal_places=1, max_digits=8, verbose_name='body za číslo')), - ('body_celkem', models.DecimalField(db_column=b'body_celkem', decimal_places=1, max_digits=8, verbose_name='body celkem do čísla včetně minulých ročníků')), - ], - options={ - 'abstract': False, - 'db_table': 'seminar_body_celkem_k_cislu', - 'managed': False, - }, - ), - migrations.CreateModel( - name='VysledkyKCisluOdjakziva', - fields=[ - ('dummy_id', models.CharField(db_column=b'id', max_length=32, primary_key=True, serialize=False, verbose_name='dummy ID pro view')), - ('body', models.DecimalField(db_column=b'body', decimal_places=1, max_digits=8, verbose_name='body za číslo')), - ], - options={ - 'abstract': False, - 'db_table': 'seminar_body_k_cislu_odjakziva', - 'managed': False, - }, - ), - migrations.CreateModel( - name='VysledkyKCisluZaRocnik', - fields=[ - ('dummy_id', models.CharField(db_column=b'id', max_length=32, primary_key=True, serialize=False, verbose_name='dummy ID pro view')), - ('body', models.DecimalField(db_column=b'body', decimal_places=1, max_digits=8, verbose_name='body za číslo')), - ], - options={ - 'abstract': False, - 'db_table': 'seminar_body_k_cislu_rocnik', - 'managed': False, - }, - ), migrations.AlterField( model_name='organizator', name='foto', From b8a110f9687769efe05ff9119fd7b07eab552210 Mon Sep 17 00:00:00 2001 From: Anet Date: Thu, 7 Nov 2019 21:09:00 +0100 Subject: [PATCH 42/92] =?UTF-8?q?Revert=20"models.py:=20$(class)=20je=20po?= =?UTF-8?q?t=C5=99eba=20u=20abstraktn=C3=AD=20t=C5=99=C3=ADdy=20v=20relate?= =?UTF-8?q?d=20name."=20=3D>=20%(class)s=20je=20pot=C5=99eba=20jen=20u=20a?= =?UTF-8?q?bstraktn=C3=AD=20t=C5=99=C3=ADdy,=20to=20Problem=20nen=C3=AD.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 910e34a51515a7825b7259d909eab2c9a1e299a9. --- seminar/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/seminar/models.py b/seminar/models.py index 67faff22..45e5885e 100644 --- a/seminar/models.py +++ b/seminar/models.py @@ -607,7 +607,7 @@ class Problem(SeminarModelBase,PolymorphicModel): # Problém má podproblémy nadproblem = models.ForeignKey('self', verbose_name='nadřazený problém', - related_name='podproblem_%(class)s', null=True, blank=True, + related_name='podproblem', null=True, blank=True, on_delete=models.SET_NULL) STAV_NAVRH = 'navrh' From df4ae39a3f0ed098a81b0afeaaf83db78bf92b2e Mon Sep 17 00:00:00 2001 From: Pavel 'LEdoian' Turinsky Date: Thu, 7 Nov 2019 21:16:29 +0100 Subject: [PATCH 43/92] =?UTF-8?q?Django=20hraje=20squash=20=C5=A1patn?= =?UTF-8?q?=C4=9B,=20zapom=C3=ADn=C3=A1=20importovat?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/migrations/0001_squashed_0067_auto_20190814_0805.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/seminar/migrations/0001_squashed_0067_auto_20190814_0805.py b/seminar/migrations/0001_squashed_0067_auto_20190814_0805.py index c1dc0c09..287be0f1 100644 --- a/seminar/migrations/0001_squashed_0067_auto_20190814_0805.py +++ b/seminar/migrations/0001_squashed_0067_auto_20190814_0805.py @@ -10,6 +10,12 @@ import imagekit.models.fields import seminar.models import taggit.managers +# migr 0053 +import datetime as dt + +# migr 0058 +from django.db.models import Q + # Functions from the following migrations need manual copying. # Move them and any dependencies into this file, then update the From 783c01c4b8fcd2e0dfb18d72576ec53a5b55993d Mon Sep 17 00:00:00 2001 From: Pavel 'LEdoian' Turinsky Date: Thu, 7 Nov 2019 21:50:16 +0100 Subject: [PATCH 44/92] =?UTF-8?q?Revert=20"Migrace:=20Semin=C3=A1=C5=99ov?= =?UTF-8?q?=C3=A9=20migrace=20t=C3=ADmto=20resetov=C3=A1ny"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit d5860e532e9c024c558cc88f87d5a6fb7b31d7cc. --- galerie/migrations/0001_initial.py | 2 +- .../0010_Pridani_odkazu_na_organizatora.py | 2 +- korektury/migrations/0014_add_org_to_pdf.py | 2 +- prednasky/migrations/0001_initial.py | 2 +- .../migrations/0005_auto_20160929_0153.py | 2 +- seminar/migrations/0001_initial.py | 251 +++++++ seminar/migrations/0001_reset.py | 670 ------------------ seminar/migrations/0002_add_body_views.py | 48 ++ seminar/migrations/0003_add_skola_zs_ss.py | 32 + seminar/migrations/0004_add_old_dakos_id.py | 44 ++ .../migrations/0005_alter_problem_autor.py | 21 + .../migrations/0006_problem_add_timestamp.py | 28 + seminar/migrations/0007_problem_zamereni.py | 22 + seminar/migrations/0008_reseni_forma.py | 20 + .../migrations/0009_rename_imported_IDs.py | 47 ++ seminar/migrations/0010_alter_rok_maturity.py | 20 + .../migrations/0011_alter_timestamp_def.py | 39 + .../0012_remove_soustredeni_ucastnici.py | 18 + ...013_soustredeni_ucastnici_through_model.py | 36 + seminar/migrations/0014_uprava_poznamek.py | 50 ++ seminar/migrations/0015_soustredeni_text.py | 20 + seminar/migrations/0016_texty_problemu.py | 42 ++ .../migrations/0017_texty_problemu_minor.py | 20 + .../0018_problemnavrh_problemzadany.py | 36 + seminar/migrations/0019_rocnik_ciselne.py | 32 + seminar/migrations/0020_indexy_a_razeni.py | 44 ++ .../0021_cislo_verejna_vysledkovka.py | 20 + seminar/migrations/0022_decimal_body.py | 29 + seminar/migrations/0023_add_novinky.py | 32 + seminar/migrations/0024_add_organizator.py | 35 + .../0025_zmena_cesty_nahravani_obrazku.py | 20 + seminar/migrations/0026_soustredeni_typ.py | 20 + .../migrations/0027_export_flag_a_typ_akce.py | 32 + .../migrations/0028_add_body_celkem_views.py | 75 ++ .../migrations/0029_fix_body_celkem_views.py | 51 ++ seminar/migrations/0030_add_vysledky.py | 60 ++ seminar/migrations/0031_cislo_pdf.py | 21 + .../migrations/0032_cislo_pdf_blank_typos.py | 44 ++ .../0033_organizator_studuje_popisek.py | 20 + .../0034_reseni_forma_default_email.py | 20 + seminar/migrations/0035_django_imagekit.py | 25 + .../migrations/0036_add_org_to_soustredeni.py | 36 + seminar/migrations/0037_prispevek.py | 29 + .../migrations/0038_change_meta_prispevek.py | 18 + seminar/migrations/0039_pohadka.py | 34 + .../0040_pohadka_nepovinny_autor.py | 20 + seminar/migrations/0041_konfery.py | 71 ++ seminar/migrations/0042_auto_20161005_0847.py | 31 + seminar/migrations/0042_cislo_faze.py | 19 + seminar/migrations/0043_uprava_faze.py | 19 + seminar/migrations/0044_uprava_faze.py | 19 + .../0045_cislo_pridani_faze_nahrano.py | 19 + seminar/migrations/0046_merge.py | 15 + seminar/migrations/0047_auto_20170120_2118.py | 19 + ...48_add_cislo_datum_deadline_soustredeni.py | 19 + seminar/migrations/0049_auto_20190430_2354.py | 508 +++++++++++++ seminar/migrations/0050_auto_20190510_2228.py | 191 +++++ seminar/migrations/0051_resitel_to_osoba.py | 89 +++ .../migrations/0052_user_to_organizator.py | 82 +++ .../0053_organizator_organizuje_od_do.py | 36 + .../0055_smazat_nemigrovane_zastarale_veci.py | 56 ++ .../0056_vrcholy_pro_rocniky_a_cisla.py | 47 ++ .../0057_reseni_to_reseni_hodnoceni.py | 34 + .../0058_problem_to_uloha_tema_clanek.py | 161 +++++ .../migrations/0059_vytvorit_pohadkanode.py | 29 + seminar/migrations/0060_spoj_stromy.py | 112 +++ seminar/migrations/0061_kill_frankenstein.py | 153 ++++ .../migrations/0062_redukce_modelu_pohadky.py | 33 + seminar/migrations/0063_procisteni_migraci.py | 35 + seminar/migrations/0064_auto_20190610_2358.py | 162 +++++ .../0065_treenode_polymorphic_ctype.py | 31 + .../0066_problem_polymorphic_ctype.py | 29 + seminar/migrations/0067_auto_20190814_0805.py | 18 + 73 files changed, 3553 insertions(+), 675 deletions(-) create mode 100644 seminar/migrations/0001_initial.py delete mode 100644 seminar/migrations/0001_reset.py create mode 100644 seminar/migrations/0002_add_body_views.py create mode 100644 seminar/migrations/0003_add_skola_zs_ss.py create mode 100644 seminar/migrations/0004_add_old_dakos_id.py create mode 100644 seminar/migrations/0005_alter_problem_autor.py create mode 100644 seminar/migrations/0006_problem_add_timestamp.py create mode 100644 seminar/migrations/0007_problem_zamereni.py create mode 100644 seminar/migrations/0008_reseni_forma.py create mode 100644 seminar/migrations/0009_rename_imported_IDs.py create mode 100644 seminar/migrations/0010_alter_rok_maturity.py create mode 100644 seminar/migrations/0011_alter_timestamp_def.py create mode 100644 seminar/migrations/0012_remove_soustredeni_ucastnici.py create mode 100644 seminar/migrations/0013_soustredeni_ucastnici_through_model.py create mode 100644 seminar/migrations/0014_uprava_poznamek.py create mode 100644 seminar/migrations/0015_soustredeni_text.py create mode 100644 seminar/migrations/0016_texty_problemu.py create mode 100644 seminar/migrations/0017_texty_problemu_minor.py create mode 100644 seminar/migrations/0018_problemnavrh_problemzadany.py create mode 100644 seminar/migrations/0019_rocnik_ciselne.py create mode 100644 seminar/migrations/0020_indexy_a_razeni.py create mode 100644 seminar/migrations/0021_cislo_verejna_vysledkovka.py create mode 100644 seminar/migrations/0022_decimal_body.py create mode 100644 seminar/migrations/0023_add_novinky.py create mode 100644 seminar/migrations/0024_add_organizator.py create mode 100644 seminar/migrations/0025_zmena_cesty_nahravani_obrazku.py create mode 100644 seminar/migrations/0026_soustredeni_typ.py create mode 100644 seminar/migrations/0027_export_flag_a_typ_akce.py create mode 100644 seminar/migrations/0028_add_body_celkem_views.py create mode 100644 seminar/migrations/0029_fix_body_celkem_views.py create mode 100644 seminar/migrations/0030_add_vysledky.py create mode 100644 seminar/migrations/0031_cislo_pdf.py create mode 100644 seminar/migrations/0032_cislo_pdf_blank_typos.py create mode 100644 seminar/migrations/0033_organizator_studuje_popisek.py create mode 100644 seminar/migrations/0034_reseni_forma_default_email.py create mode 100644 seminar/migrations/0035_django_imagekit.py create mode 100644 seminar/migrations/0036_add_org_to_soustredeni.py create mode 100644 seminar/migrations/0037_prispevek.py create mode 100644 seminar/migrations/0038_change_meta_prispevek.py create mode 100644 seminar/migrations/0039_pohadka.py create mode 100644 seminar/migrations/0040_pohadka_nepovinny_autor.py create mode 100644 seminar/migrations/0041_konfery.py create mode 100644 seminar/migrations/0042_auto_20161005_0847.py create mode 100644 seminar/migrations/0042_cislo_faze.py create mode 100644 seminar/migrations/0043_uprava_faze.py create mode 100644 seminar/migrations/0044_uprava_faze.py create mode 100644 seminar/migrations/0045_cislo_pridani_faze_nahrano.py create mode 100644 seminar/migrations/0046_merge.py create mode 100644 seminar/migrations/0047_auto_20170120_2118.py create mode 100644 seminar/migrations/0048_add_cislo_datum_deadline_soustredeni.py create mode 100644 seminar/migrations/0049_auto_20190430_2354.py create mode 100644 seminar/migrations/0050_auto_20190510_2228.py create mode 100644 seminar/migrations/0051_resitel_to_osoba.py create mode 100644 seminar/migrations/0052_user_to_organizator.py create mode 100644 seminar/migrations/0053_organizator_organizuje_od_do.py create mode 100644 seminar/migrations/0055_smazat_nemigrovane_zastarale_veci.py create mode 100644 seminar/migrations/0056_vrcholy_pro_rocniky_a_cisla.py create mode 100644 seminar/migrations/0057_reseni_to_reseni_hodnoceni.py create mode 100644 seminar/migrations/0058_problem_to_uloha_tema_clanek.py create mode 100644 seminar/migrations/0059_vytvorit_pohadkanode.py create mode 100644 seminar/migrations/0060_spoj_stromy.py create mode 100644 seminar/migrations/0061_kill_frankenstein.py create mode 100644 seminar/migrations/0062_redukce_modelu_pohadky.py create mode 100644 seminar/migrations/0063_procisteni_migraci.py create mode 100644 seminar/migrations/0064_auto_20190610_2358.py create mode 100644 seminar/migrations/0065_treenode_polymorphic_ctype.py create mode 100644 seminar/migrations/0066_problem_polymorphic_ctype.py create mode 100644 seminar/migrations/0067_auto_20190814_0805.py diff --git a/galerie/migrations/0001_initial.py b/galerie/migrations/0001_initial.py index 23de992b..21701185 100644 --- a/galerie/migrations/0001_initial.py +++ b/galerie/migrations/0001_initial.py @@ -8,7 +8,7 @@ import django.db.models.deletion class Migration(migrations.Migration): dependencies = [ - ('seminar', '0001_reset'), + ('seminar', '0033_organizator_studuje_popisek'), ] operations = [ diff --git a/korektury/migrations/0010_Pridani_odkazu_na_organizatora.py b/korektury/migrations/0010_Pridani_odkazu_na_organizatora.py index a0579b4a..6b318cab 100644 --- a/korektury/migrations/0010_Pridani_odkazu_na_organizatora.py +++ b/korektury/migrations/0010_Pridani_odkazu_na_organizatora.py @@ -7,7 +7,7 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('seminar', '0001_reset'), + ('seminar', '0041_konfery'), ('korektury', '0009_trizeni_korektur_v_seznamu'), ] diff --git a/korektury/migrations/0014_add_org_to_pdf.py b/korektury/migrations/0014_add_org_to_pdf.py index 33cedd0d..afd939ba 100644 --- a/korektury/migrations/0014_add_org_to_pdf.py +++ b/korektury/migrations/0014_add_org_to_pdf.py @@ -7,7 +7,7 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('seminar', '0001_reset'), + ('seminar', '0041_konfery'), ('korektury', '0013_rename_autor_org'), ] diff --git a/prednasky/migrations/0001_initial.py b/prednasky/migrations/0001_initial.py index 80f33bc9..07da4a4e 100644 --- a/prednasky/migrations/0001_initial.py +++ b/prednasky/migrations/0001_initial.py @@ -7,7 +7,7 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('seminar', '0001_reset'), + ('seminar', '0036_add_org_to_soustredeni'), ] operations = [ diff --git a/prednasky/migrations/0005_auto_20160929_0153.py b/prednasky/migrations/0005_auto_20160929_0153.py index b67625d0..7ecff0a0 100644 --- a/prednasky/migrations/0005_auto_20160929_0153.py +++ b/prednasky/migrations/0005_auto_20160929_0153.py @@ -7,7 +7,7 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('seminar', '0001_reset'), + ('seminar', '0041_konfery'), ('prednasky', '0004_remove_prednaska_seznam'), ] diff --git a/seminar/migrations/0001_initial.py b/seminar/migrations/0001_initial.py new file mode 100644 index 00000000..088193b3 --- /dev/null +++ b/seminar/migrations/0001_initial.py @@ -0,0 +1,251 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations +import django_countries.fields +import seminar.models +import django.utils.timezone +from django.conf import settings + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='VysledkyKCislu', + fields=[ + ('dummy_id', models.CharField(max_length=32, serialize=False, verbose_name='dummy ID pro view', primary_key=True, db_column='id')), + ('body', models.IntegerField(verbose_name='body za \u010d\xedslo', db_column='body')), + ('body_celkem', models.IntegerField(verbose_name='body celkem do \u010d\xedsla', db_column='body_celkem')), + ], + options={ + 'abstract': False, + 'db_table': 'seminar_body_k_cislu', + 'managed': False, + }, + bases=(models.Model,), + ), + migrations.CreateModel( + name='VysledkyZaCislo', + fields=[ + ('dummy_id', models.CharField(max_length=32, serialize=False, verbose_name='dummy ID pro view', primary_key=True, db_column='id')), + ('body', models.IntegerField(verbose_name='body za \u010d\xedslo', db_column='body')), + ], + options={ + 'abstract': False, + 'db_table': 'seminar_body_za_cislo', + 'managed': False, + }, + bases=(models.Model,), + ), + migrations.CreateModel( + name='Cislo', + fields=[ + ('id', models.AutoField(serialize=False, primary_key=True)), + ('cislo', models.CharField(help_text='V\u011bt\u0161inou jen "1", vyj\xedme\u010dn\u011b "7-8", lexikograficky ur\u010dije po\u0159ad\xed v ro\u010dn\xedku!', max_length=32, verbose_name='n\xe1zev \u010d\xedsla')), + ('datum_vydani', models.DateField(help_text='Datum vyd\xe1n\xed fin\xe1ln\xed verze', null=True, verbose_name='datum vyd\xe1n\xed', blank=True)), + ('datum_deadline', models.DateField(help_text='Datum pro p\u0159\xedjem \u0159e\u0161en\xed \xfaloh zadan\xfdch v tomto \u010d\xedsle', null=True, verbose_name='datum deadline', blank=True)), + ('verejne_db', models.BooleanField(default=False, verbose_name='\u010d\xedslo zve\u0159ejn\u011bno', db_column='verejne')), + ], + options={ + 'ordering': ['rocnik__rocnik', 'cislo'], + 'db_table': 'seminar_cisla', + 'verbose_name': '\u010c\xedslo', + 'verbose_name_plural': '\u010c\xedsla', + }, + bases=(models.Model,), + ), + migrations.CreateModel( + name='Nastaveni', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('aktualni_cislo', models.ForeignKey(verbose_name='posledn\xed vydan\xe9 \u010d\xedslo', to='seminar.Cislo', on_delete=models.CASCADE)), + ], + options={ + 'db_table': 'seminar_nastaveni', + 'verbose_name': 'Nastaven\xed semin\xe1\u0159e', + }, + bases=(models.Model,), + ), + migrations.CreateModel( + name='PrilohaReseni', + fields=[ + ('id', models.AutoField(serialize=False, primary_key=True)), + ('timestamp', models.DateTimeField(auto_now=True, verbose_name='vytvo\u0159eno')), + ('soubor', models.FileField(upload_to=seminar.models.generate_filename, verbose_name='soubor')), + ('poznamka', models.TextField(help_text='Neve\u0159ejn\xe1 pozn\xe1mka k p\u0159\xedloze \u0159e\u0161en\xed (plain text), nap\u0159. o p\u016fvodu', verbose_name='neve\u0159ejn\xe1 pozn\xe1mka', blank=True)), + ], + options={ + 'ordering': ['reseni', 'timestamp'], + 'db_table': 'seminar_priloha_reseni', + 'verbose_name': 'P\u0159\xedloha \u0159e\u0161en\xed', + 'verbose_name_plural': 'P\u0159\xedlohy \u0159e\u0161en\xed', + }, + bases=(models.Model,), + ), + migrations.CreateModel( + name='Problem', + fields=[ + ('id', models.AutoField(serialize=False, primary_key=True)), + ('nazev', models.CharField(max_length=256, verbose_name='n\xe1zev')), + ('typ', models.CharField(default=b'uloha', max_length=32, verbose_name='typ probl\xe9mu', choices=[(b'uloha', '\xdaloha'), (b'tema', 'T\xe9ma'), (b'serial', 'Seri\xe1l'), (b'org-clanek', 'Organiz\xe1torsk\xfd \u010dl\xe1nek'), (b'res-clanek', '\u0158esitelsk\xfd \u010dl\xe1nek')])), + ('stav', models.CharField(default=b'navrh', max_length=32, verbose_name='stav probl\xe9mu', choices=[(b'navrh', 'N\xe1vrh'), (b'zadany', 'Zadan\xfd'), (b'smazany', 'Smazan\xfd')])), + ('text_problemu_org', models.TextField(verbose_name='organiz\xe1torsk\xfd (neve\u0159ejn\xfd) text', blank=True)), + ('text_problemu', models.TextField(verbose_name='ve\u0159ejn\xfd text zad\xe1n\xed a \u0159e\u0161en\xed', blank=True)), + ('kod', models.CharField(default=b'', help_text='\u010c\xedslo/k\xf3d \xfalohy v \u010d\xedsle nebo k\xf3d t\xe9matu/\u010dl\xe1nku/seri\xe1lu v ro\u010dn\xedku', max_length=32, verbose_name='lok\xe1ln\xed k\xf3d', blank=True)), + ('body', models.IntegerField(null=True, verbose_name='maximum bod\u016f', blank=True)), + ('autor', models.ForeignKey(related_name='autor_uloh', verbose_name='autor probl\xe9mu', to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), + ('cislo_reseni', models.ForeignKey(related_name='resene_problemy', blank=True, to='seminar.Cislo', help_text='\u010c\xedslo s \u0159e\u0161en\xedm \xfalohy, jen pro \xfalohy', null=True, verbose_name='\u010d\xedslo \u0159e\u0161en\xed', on_delete=models.CASCADE)), + ('cislo_zadani', models.ForeignKey(related_name='zadane_problemy', verbose_name='\u010d\xedslo zad\xe1n\xed', blank=True, to='seminar.Cislo', null=True, on_delete=models.CASCADE)), + ('opravovatel', models.ForeignKey(related_name='opravovatel_uloh', verbose_name='opravovatel', blank=True, to=settings.AUTH_USER_MODEL, null=True, on_delete=models.CASCADE)), + ], + options={ + 'db_table': 'seminar_problemy', + 'verbose_name': 'Probl\xe9m', + 'verbose_name_plural': 'Probl\xe9my', + }, + bases=(models.Model,), + ), + migrations.CreateModel( + name='Reseni', + fields=[ + ('id', models.AutoField(serialize=False, primary_key=True)), + ('body', models.IntegerField(null=True, verbose_name='body', blank=True)), + ('timestamp', models.DateTimeField(auto_now=True, verbose_name='vytvo\u0159eno')), + ('poznamka', models.TextField(help_text='Neve\u0159ejn\xe1 pozn\xe1mka k \u0159e\u0161en\xed (plain text)', verbose_name='neve\u0159ejn\xe1 pozn\xe1mka', blank=True)), + ('cislo_body', models.ForeignKey(related_name='bodovana_reseni', verbose_name='\u010d\xedslo pro body', blank=True, to='seminar.Cislo', null=True, on_delete=models.CASCADE)), + ('problem', models.ForeignKey(related_name='reseni', verbose_name='probl\xe9m', to='seminar.Problem', on_delete=models.CASCADE)), + ], + options={ + 'ordering': ['problem', 'resitel'], + 'db_table': 'seminar_reseni', + 'verbose_name': '\u0158e\u0161en\xed', + 'verbose_name_plural': '\u0158e\u0161en\xed', + }, + bases=(models.Model,), + ), + migrations.CreateModel( + name='Resitel', + fields=[ + ('id', models.AutoField(serialize=False, primary_key=True)), + ('jmeno', models.CharField(max_length=256, verbose_name='jm\xe9no')), + ('prijmeni', models.CharField(max_length=256, verbose_name='p\u0159\xedjmen\xed')), + ('pohlavi_muz', models.BooleanField(default=False, verbose_name='pohlav\xed (mu\u017e)')), + ('rok_maturity', models.IntegerField(verbose_name='rok maturity')), + ('email', models.EmailField(default=b'', max_length=256, verbose_name='e-mail', blank=True)), + ('telefon', models.CharField(default=b'', max_length=256, verbose_name='telefon', blank=True)), + ('datum_narozeni', models.DateField(null=True, verbose_name='datum narozen\xed', blank=True)), + ('datum_souhlasu_udaje', models.DateField(help_text='Datum souhlasu se zpracov\xe1n\xedm osobn\xedch \xfadaj\u016f', null=True, verbose_name='datum souhlasu (\xfadaje)', blank=True)), + ('datum_souhlasu_zasilani', models.DateField(help_text='Datum souhlasu se zas\xedl\xe1n\xedm MFF materi\xe1l\u016f', null=True, verbose_name='datum souhlasu (spam)', blank=True)), + ('datum_prihlaseni', models.DateField(default=django.utils.timezone.now, verbose_name='datum p\u0159ihl\xe1\u0161en\xed')), + ('zasilat', models.CharField(default=b'domu', max_length=32, verbose_name='kam zas\xedlat', choices=[(b'domu', 'Dom\u016f'), (b'do_skoly', 'Do \u0161koly'), (b'nikam', 'Nikam')])), + ('ulice', models.CharField(default=b'', max_length=256, verbose_name='ulice', blank=True)), + ('mesto', models.CharField(default=b'', max_length=256, verbose_name='m\u011bsto', blank=True)), + ('psc', models.CharField(default=b'', max_length=32, verbose_name='PS\u010c', blank=True)), + ('stat', django_countries.fields.CountryField(default=b'CZ', help_text='ISO 3166-1 k\xf3d zem\u011b velk\xfdmi p\xedsmeny (CZ, SK, ...)', max_length=2, verbose_name='st\xe1t')), + ('poznamka', models.TextField(help_text='Neve\u0159ejn\xe1 pozn\xe1mka k \u0159e\u0161iteli (plain text)', verbose_name='neve\u0159ejn\xe1 pozn\xe1mka', blank=True)), + ], + options={ + 'ordering': ['prijmeni', 'jmeno'], + 'db_table': 'seminar_resitele', + 'verbose_name': '\u0158e\u0161itel', + 'verbose_name_plural': '\u0158e\u0161itel\xe9', + }, + bases=(models.Model,), + ), + migrations.CreateModel( + name='Rocnik', + fields=[ + ('id', models.AutoField(serialize=False, primary_key=True)), + ('prvni_rok', models.IntegerField(verbose_name='prvn\xed rok')), + ('rocnik', models.CharField(max_length=16, verbose_name='\u010d\xedslo ro\u010dn\xedku')), + ], + options={ + 'ordering': ['rocnik'], + 'db_table': 'seminar_rocniky', + 'verbose_name': 'Ro\u010dn\xedk', + 'verbose_name_plural': 'Ro\u010dn\xedky', + }, + bases=(models.Model,), + ), + migrations.CreateModel( + name='Skola', + fields=[ + ('id', models.AutoField(serialize=False, primary_key=True)), + ('aesop_id', models.CharField(default=b'', help_text='Aesopi ID typu "izo:..." nebo "aesop:..."', max_length=32, verbose_name='Aesop ID', blank=True)), + ('izo', models.CharField(help_text='IZO \u0161koly (jen \u010desk\xe9 \u0161koly)', max_length=32, verbose_name='IZO', blank=True)), + ('nazev', models.CharField(help_text='Cel\xfd n\xe1zev \u0161koly', max_length=256, verbose_name='n\xe1zev')), + ('kratky_nazev', models.CharField(help_text=b'Zkr\xc3\xa1cen\xc3\xbd n\xc3\xa1zev pro zobrazen\xc3\xad ve v\xc3\xbdsledkovce', max_length=256, verbose_name='zkr\xe1cen\xfd n\xe1zev', blank=True)), + ('ulice', models.CharField(max_length=256, verbose_name='ulice')), + ('mesto', models.CharField(max_length=256, verbose_name='m\u011bsto')), + ('psc', models.CharField(max_length=32, verbose_name='PS\u010c')), + ('stat', django_countries.fields.CountryField(default=b'CZ', help_text='ISO 3166-1 k\xf3d zeme velk\xfdmi p\xedsmeny (CZ, SK, ...)', max_length=2, verbose_name='st\xe1t')), + ('poznamka', models.TextField(help_text='Neve\u0159ejn\xe1 pozn\xe1mka ke \u0161kole (plain text)', verbose_name='neve\u0159ejn\xe1 pozn\xe1mka', blank=True)), + ], + options={ + 'db_table': 'seminar_skoly', + 'verbose_name': '\u0160kola', + 'verbose_name_plural': '\u0160koly', + }, + bases=(models.Model,), + ), + migrations.CreateModel( + name='Soustredeni', + fields=[ + ('id', models.AutoField(serialize=False, primary_key=True)), + ('datum_zacatku', models.DateField(help_text='Prvn\xed den soust\u0159ed\u011bn\xed', null=True, verbose_name='datum za\u010d\xe1tku', blank=True)), + ('datum_konce', models.DateField(help_text='Posledn\xed den soust\u0159ed\u011bn\xed', null=True, verbose_name='datum konce', blank=True)), + ('verejne_db', models.BooleanField(default=False, verbose_name='soust\u0159ed\u011bn\xed zve\u0159ejn\u011bno', db_column='verejne')), + ('misto', models.CharField(default=b'', help_text='M\xedsto (n\xe1zev obce, voliteln\u011b t\xe9\u017e objektu', max_length=256, verbose_name='m\xedsto soust\u0159ed\u011bn\xed', blank=True)), + ('rocnik', models.ForeignKey(related_name='soustredeni', verbose_name='ro\u010dn\xedk', to='seminar.Rocnik', on_delete=models.CASCADE)), + ('ucastnici', models.ManyToManyField(help_text='Seznam \xfa\u010dastn\xedk\u016f soust\u0159ed\u011bn\xed', to='seminar.Resitel', db_table='seminar_soustredeni_ucastnici', verbose_name='\xfa\u010dastn\xedci soust\u0159ed\u011bn\xed')), + ], + options={ + 'ordering': ['rocnik__rocnik', 'datum_zacatku'], + 'db_table': 'seminar_soustredeni', + 'verbose_name': 'Soust\u0159ed\u011bn\xed', + 'verbose_name_plural': 'Soust\u0159ed\u011bn\xed', + }, + bases=(models.Model,), + ), + migrations.AddField( + model_name='resitel', + name='skola', + field=models.ForeignKey(verbose_name='\u0161kola', blank=True, to='seminar.Skola', null=True, on_delete=models.CASCADE), + preserve_default=True, + ), + migrations.AddField( + model_name='resitel', + name='user', + field=models.OneToOneField(null=True, blank=True, to=settings.AUTH_USER_MODEL, verbose_name='u\u017eivatel', on_delete=models.CASCADE), + preserve_default=True, + ), + migrations.AddField( + model_name='reseni', + name='resitel', + field=models.ForeignKey(related_name='reseni', verbose_name='\u0159e\u0161itel', to='seminar.Resitel', on_delete=models.CASCADE), + preserve_default=True, + ), + migrations.AddField( + model_name='prilohareseni', + name='reseni', + field=models.ForeignKey(related_name='prilohy', verbose_name='\u0159e\u0161en\xed', to='seminar.Reseni', on_delete=models.CASCADE), + preserve_default=True, + ), + migrations.AddField( + model_name='nastaveni', + name='aktualni_rocnik', + field=models.ForeignKey(verbose_name='aktu\xe1ln\xed ro\u010dn\xedk', to='seminar.Rocnik', on_delete=models.CASCADE), + preserve_default=True, + ), + migrations.AddField( + model_name='cislo', + name='rocnik', + field=models.ForeignKey(related_name='cisla', verbose_name='ro\u010dn\xedk', to='seminar.Rocnik', on_delete=models.CASCADE), + preserve_default=True, + ), + ] diff --git a/seminar/migrations/0001_reset.py b/seminar/migrations/0001_reset.py deleted file mode 100644 index 07ae6c65..00000000 --- a/seminar/migrations/0001_reset.py +++ /dev/null @@ -1,670 +0,0 @@ -# Generated by Django 2.2.4 on 2019-08-19 18:52 - -from django.conf import settings -from django.db import migrations, models -import django.db.models.deletion -import django.utils.timezone -import django_countries.fields -import imagekit.models.fields -import seminar.models -import taggit.managers - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [ - ('taggit', '0003_taggeditem_add_unique_index'), - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('contenttypes', '0002_remove_content_type_name'), - ] - - operations = [ - migrations.CreateModel( - name='Cislo', - fields=[ - ('id', models.AutoField(primary_key=True, serialize=False)), - ('cislo', models.CharField(db_index=True, help_text='Většinou jen "1", vyjímečně "7-8", lexikograficky určuje pořadí v ročníku!', max_length=32, verbose_name='název čísla')), - ('datum_vydani', models.DateField(blank=True, help_text='Datum vydání finální verze', null=True, verbose_name='datum vydání')), - ('datum_deadline', models.DateField(blank=True, help_text='Datum pro příjem řešení úloh zadaných v tomto čísle', null=True, verbose_name='datum deadline')), - ('datum_deadline_soustredeni', models.DateField(blank=True, help_text='Datum pro příjem řešení pro účast na soustředění', null=True, verbose_name='datum deadline soustředění')), - ('verejne_db', models.BooleanField(db_column='verejne', default=False, verbose_name='číslo zveřejněno')), - ('verejna_vysledkovka', models.BooleanField(default=False, help_text='Je-li false u veřejného čísla, není výsledkovka zatím veřejná.', verbose_name='zveřejněna výsledkovka')), - ('poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka k číslu (plain text)', verbose_name='neveřejná poznámka')), - ('pdf', models.FileField(blank=True, help_text='Pdf čísla, které si mohou řešitelé stáhnout', null=True, upload_to=seminar.models.cislo_pdf_filename, verbose_name='pdf')), - ], - options={ - 'verbose_name': 'Číslo', - 'verbose_name_plural': 'Čísla', - 'db_table': 'seminar_cisla', - 'ordering': ['-rocnik__rocnik', '-cislo'], - }, - ), - migrations.CreateModel( - name='Hodnoceni', - fields=[ - ('id', models.AutoField(primary_key=True, serialize=False)), - ('body', models.DecimalField(decimal_places=1, max_digits=8, verbose_name='body')), - ('cislo_body', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='hodnoceni', to='seminar.Cislo', verbose_name='číslo pro body')), - ], - options={ - 'verbose_name': 'Hodnocení', - 'verbose_name_plural': 'Hodnocení', - 'db_table': 'seminar_hodnoceni', - }, - ), - migrations.CreateModel( - name='Konfera', - fields=[ - ('id', models.AutoField(primary_key=True, serialize=False)), - ('nazev', models.CharField(help_text='Název konfery', max_length=100, verbose_name='název konfery')), - ('anotace', models.TextField(blank=True, help_text='Popis, o čem bude konfera.', verbose_name='anotace')), - ('abstrakt', models.TextField(blank=True, help_text='Abstrakt konfery tak, jak byl uveden ve sborníku', verbose_name='abstrakt')), - ('poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka ke konfeře(plain text)', verbose_name='neveřejná poznámka')), - ('typ_prezentace', models.CharField(choices=[('veletrh', 'Veletrh (postery)'), ('prezentace', 'Prezentace (přednáška)')], default='veletrh', max_length=16, verbose_name='typ prezentace')), - ('prezentace', models.FileField(blank=True, help_text='Prezentace nebo fotka posteru', upload_to=seminar.models.generate_filename_konfera, verbose_name='prezentace')), - ('materialy', models.FileField(blank=True, help_text='Další materiály ke konfeře zabalené do jednoho souboru', upload_to=seminar.models.generate_filename_konfera, verbose_name='materialy')), - ], - options={ - 'verbose_name': 'Konfera', - 'verbose_name_plural': 'Konfery', - 'db_table': 'seminar_konfera', - }, - ), - 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')), - ], - options={ - 'verbose_name': 'Organizátor', - 'verbose_name_plural': 'Organizátoři', - }, - ), - 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(max_length=256, 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')), - ('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': 'seminar_osoby', - 'ordering': ['prijmeni', 'jmeno'], - }, - ), - migrations.CreateModel( - name='Problem', - fields=[ - ('id', models.AutoField(primary_key=True, serialize=False)), - ('nazev', models.CharField(max_length=256, verbose_name='název')), - ('stav', models.CharField(choices=[('navrh', 'Návrh'), ('zadany', 'Zadaný'), ('vyreseny', 'Vyřešený'), ('smazany', 'Smazaný')], default='navrh', max_length=32, verbose_name='stav problému')), - ('poznamka', models.TextField(blank=True, help_text='Neveřejný návrh úlohy, návrh řešení, text zadání, poznámky ...', verbose_name='org poznámky (HTML)')), - ('kod', models.CharField(blank=True, default='', help_text='Číslo/kód úlohy v čísle nebo kód tématu/článku/seriálu v ročníku', max_length=32, verbose_name='lokální kód')), - ('vytvoreno', models.DateTimeField(blank=True, default=django.utils.timezone.now, editable=False, verbose_name='vytvořeno')), - ('autor', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='autor_problemu_problem', to='seminar.Organizator', verbose_name='autor problému')), - ('garant', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='garant_problemu_problem', to='seminar.Organizator', verbose_name='garant zadaného problému')), - ('nadproblem', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='nadproblem_problem', to='seminar.Problem', verbose_name='nadřazený problém')), - ('opravovatele', models.ManyToManyField(blank=True, related_name='opravovatele_problem', to='seminar.Organizator', verbose_name='opravovatelé')), - ('polymorphic_ctype', models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_seminar.problem_set+', to='contenttypes.ContentType')), - ('zamereni', taggit.managers.TaggableManager(blank=True, help_text='Zaměření M/F/I/O problému, příp. další tagy', through='taggit.TaggedItem', to='taggit.Tag', verbose_name='zaměření')), - ], - options={ - 'verbose_name': 'Problém', - 'verbose_name_plural': 'Problémy', - 'db_table': 'seminar_problemy', - 'ordering': ['nazev'], - }, - ), - 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='seminar.Hodnoceni', to='seminar.Problem', verbose_name='problém')), - ], - options={ - 'verbose_name': 'Řešení', - 'verbose_name_plural': 'Řešení', - 'db_table': 'seminar_reseni', - 'ordering': ['-cas_doruceni'], - }, - ), - migrations.CreateModel( - name='Resitel', - fields=[ - ('id', models.AutoField(primary_key=True, serialize=False)), - ('rok_maturity', models.IntegerField(blank=True, null=True, verbose_name='rok maturity')), - ('zasilat', models.CharField(choices=[('domu', 'Domů'), ('do_skoly', 'Do školy'), ('nikam', 'Nikam')], default='domu', max_length=32, verbose_name='kam zasílat')), - ('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(null=True, on_delete=django.db.models.deletion.SET_NULL, to='seminar.Osoba', verbose_name='osoba')), - ], - options={ - 'verbose_name': 'Řešitel', - 'verbose_name_plural': 'Řešitelé', - 'db_table': 'seminar_resitele', - 'ordering': ['osoba'], - }, - ), - migrations.CreateModel( - name='Rocnik', - fields=[ - ('id', models.AutoField(primary_key=True, serialize=False)), - ('prvni_rok', models.IntegerField(db_index=True, unique=True, verbose_name='první rok')), - ('rocnik', models.IntegerField(db_index=True, unique=True, verbose_name='číslo ročníku')), - ('exportovat', models.BooleanField(db_column='exportovat', default=False, help_text='Exportuje se jen podle tohoto flagu (ne veřejnosti), a to jen čísla s veřejnou výsledkovkou', verbose_name='export do AESOPa')), - ], - options={ - 'verbose_name': 'Ročník', - 'verbose_name_plural': 'Ročníky', - 'db_table': 'seminar_rocniky', - 'ordering': ['-rocnik'], - }, - ), - migrations.CreateModel( - name='Soustredeni', - fields=[ - ('id', models.AutoField(primary_key=True, serialize=False)), - ('datum_zacatku', models.DateField(blank=True, help_text='První den soustředění', null=True, verbose_name='datum začátku')), - ('datum_konce', models.DateField(blank=True, help_text='Poslední den soustředění', null=True, verbose_name='datum konce')), - ('verejne_db', models.BooleanField(db_column='verejne', default=False, verbose_name='soustředění zveřejněno')), - ('misto', models.CharField(blank=True, default='', help_text='Místo (název obce, volitelně též objektu', max_length=256, verbose_name='místo soustředění')), - ('text', models.TextField(blank=True, default='', verbose_name='text k soustředění (HTML)')), - ('typ', models.CharField(choices=[('jarni', 'Jarní soustředění'), ('podzimni', 'Podzimní soustředění'), ('vikend', 'Víkendový sraz')], default='podzimni', max_length=16, verbose_name='typ akce')), - ('exportovat', models.BooleanField(db_column='exportovat', default=False, help_text='Exportuje se jen podle tohoto flagu (ne veřejnosti)', verbose_name='export do AESOPa')), - ], - options={ - 'verbose_name': 'Soustředění', - 'verbose_name_plural': 'Soustředění', - 'db_table': 'seminar_soustredeni', - 'ordering': ['-rocnik__rocnik', '-datum_zacatku'], - }, - ), - migrations.CreateModel( - name='Text', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('na_web', models.TextField(blank=True, help_text='Text ke zveřejnění na webu', verbose_name='text na web')), - ('do_cisla', models.TextField(blank=True, help_text='Text ke zveřejnění v čísle', verbose_name='text do čísla')), - ], - options={ - 'verbose_name': 'text', - 'verbose_name_plural': 'texty', - 'db_table': 'seminar_texty', - }, - ), - migrations.CreateModel( - name='TreeNode', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('first_child', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='seminar.TreeNode', verbose_name='první potomek')), - ('polymorphic_ctype', models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_seminar.treenode_set+', to='contenttypes.ContentType')), - ('root', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='potomci_set', to='seminar.TreeNode', verbose_name='kořen stromu')), - ('succ', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='prev', to='seminar.TreeNode', verbose_name='další element na stejné úrovni')), - ], - options={ - 'verbose_name': 'TreeNode', - 'verbose_name_plural': 'TreeNody', - 'db_table': 'seminar_nodes_treenode', - }, - ), - migrations.CreateModel( - name='Clanek', - fields=[ - ('problem_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.Problem')), - ], - options={ - 'verbose_name': 'Článek', - 'verbose_name_plural': 'Články', - 'db_table': 'seminar_clanky', - }, - bases=('seminar.problem',), - ), - migrations.CreateModel( - name='MezicisloNode', - fields=[ - ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), - ], - options={ - 'verbose_name': 'Mezičíslo (Node)', - 'verbose_name_plural': 'Mezičísla (Node)', - 'db_table': 'seminar_nodes_mezicislo', - }, - bases=('seminar.treenode',), - ), - migrations.CreateModel( - name='Tema', - fields=[ - ('problem_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.Problem')), - ('tema_typ', models.CharField(choices=[('tema', 'Téma'), ('serial', 'Seriál')], default='tema', max_length=16, verbose_name='Typ tématu')), - ('rocnik', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='seminar.Rocnik', verbose_name='ročník')), - ], - options={ - 'verbose_name': 'Téma', - 'verbose_name_plural': 'Témata', - 'db_table': 'seminar_temata', - }, - bases=('seminar.problem',), - ), - migrations.CreateModel( - name='Uloha', - fields=[ - ('problem_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.Problem')), - ('max_body', models.DecimalField(blank=True, decimal_places=1, max_digits=8, null=True, verbose_name='maximum bodů')), - ], - options={ - 'verbose_name': 'Úloha', - 'verbose_name_plural': 'Úlohy', - 'db_table': 'seminar_ulohy', - }, - bases=('seminar.problem',), - ), - migrations.CreateModel( - name='Soustredeni_Ucastnici', - fields=[ - ('id', models.AutoField(primary_key=True, serialize=False)), - ('poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka k účasti (plain text)', verbose_name='neveřejná poznámka')), - ('resitel', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Resitel', verbose_name='řešitel')), - ('soustredeni', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Soustredeni', verbose_name='soustředění')), - ], - options={ - 'verbose_name': 'Účast na soustředění', - 'verbose_name_plural': 'Účasti na soustředění', - 'db_table': 'seminar_soustredeni_ucastnici', - 'ordering': ['soustredeni', 'resitel'], - }, - ), - migrations.CreateModel( - name='Soustredeni_Organizatori', - fields=[ - ('id', models.AutoField(primary_key=True, serialize=False)), - ('poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka k účasti organizátora (plain text)', verbose_name='neveřejná poznámka')), - ('organizator', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Organizator', verbose_name='organizátor')), - ('soustredeni', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Soustredeni', verbose_name='soustředění')), - ], - options={ - 'verbose_name': 'Účast organizátorů na soustředění', - 'verbose_name_plural': 'Účasti organizátorů na soustředění', - 'db_table': 'seminar_soustredeni_organizatori', - 'ordering': ['soustredeni', 'organizator'], - }, - ), - migrations.AddField( - model_name='soustredeni', - name='organizatori', - field=models.ManyToManyField(help_text='Seznam organizátorů soustředění', through='seminar.Soustredeni_Organizatori', to='seminar.Organizator', verbose_name='Organizátoři soustředění'), - ), - migrations.AddField( - model_name='soustredeni', - name='rocnik', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='soustredeni', to='seminar.Rocnik', verbose_name='ročník'), - ), - migrations.AddField( - model_name='soustredeni', - name='ucastnici', - field=models.ManyToManyField(help_text='Seznam účastníků soustředění', through='seminar.Soustredeni_Ucastnici', to='seminar.Resitel', verbose_name='účastníci soustředění'), - ), - 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='seminar.Osoba', verbose_name='Kontaktní osoba')), - ], - options={ - 'verbose_name': 'Škola', - 'verbose_name_plural': 'Školy', - 'db_table': 'seminar_skoly', - 'ordering': ['mesto', 'nazev'], - }, - ), - migrations.AddField( - model_name='resitel', - name='skola', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='seminar.Skola', verbose_name='škola'), - ), - 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='seminar.Reseni', verbose_name='řešení')), - ('resitele', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Resitel', verbose_name='řešitel')), - ], - options={ - 'verbose_name': 'Řešení řešitelů', - 'verbose_name_plural': 'Řešení řešitelů', - 'db_table': 'seminar_reseni_resitele', - 'ordering': ['reseni', 'resitele'], - }, - ), - migrations.AddField( - model_name='reseni', - name='resitele', - field=models.ManyToManyField(help_text='Seznam autorů řešení', through='seminar.Reseni_Resitele', to='seminar.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.SET_NULL, related_name='reseni_cely_set', to='seminar.Text', verbose_name='Plná verze textu řešení'), - ), - migrations.AddField( - model_name='reseni', - name='text_zkraceny', - field=models.ManyToManyField(help_text='Seznam úryvků z řešení', related_name='reseni_zkraceny_set', to='seminar.Text', verbose_name='zkrácené verze ř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=seminar.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')), - ('reseni', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='prilohy', to='seminar.Reseni', verbose_name='řešení')), - ], - options={ - 'verbose_name': 'Příloha řešení', - 'verbose_name_plural': 'Přílohy řešení', - 'db_table': 'seminar_priloha_reseni', - 'ordering': ['reseni', 'vytvoreno'], - }, - ), - 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')), - ('osoba', models.OneToOneField(help_text='Které osobě či na jakou adresu se mají zasílat čísla', on_delete=django.db.models.deletion.CASCADE, to='seminar.Osoba', verbose_name='komu')), - ], - options={ - 'verbose_name': 'příjemce', - 'verbose_name_plural': 'příjemce', - 'db_table': 'seminar_prijemce', - }, - ), - migrations.CreateModel( - name='Pohadka', - 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')), - ('autor', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='seminar.Organizator', verbose_name='Autor pohádky')), - ], - options={ - 'verbose_name': 'Pohádka', - 'verbose_name_plural': 'Pohádky', - 'db_table': 'seminar_pohadky', - 'ordering': ['vytvoreno'], - }, - ), - migrations.AddField( - model_name='organizator', - name='osoba', - field=models.OneToOneField(help_text='osobní údaje organizátora', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='org', to='seminar.Osoba', verbose_name='osoba'), - ), - migrations.CreateModel( - name='Obrazek', - fields=[ - ('id', models.AutoField(primary_key=True, serialize=False)), - ('na_web', models.ImageField(blank=True, null=True, upload_to='obrazky/%Y/%m/%d/', verbose_name='obrázek na web')), - ('do_cisla_barevny', models.FileField(blank=True, help_text='Barevná verze obrázku do čísla', null=True, upload_to='obrazky/%Y/%m/%d/', verbose_name='barevný obrázek do čísla')), - ('do_cisla_cernobily', models.FileField(blank=True, help_text='Černobílá verze obrázku do čísla', null=True, upload_to='obrazky/%Y/%m/%d/', verbose_name='černobílý obrázek do čísla')), - ('text', models.ForeignKey(help_text='text, ve kterém se obrázek vyskytuje', on_delete=django.db.models.deletion.CASCADE, to='seminar.Text', verbose_name='text')), - ], - options={ - 'verbose_name': 'obrázek', - 'verbose_name_plural': 'obrázky', - 'db_table': 'seminar_obrazky', - }, - ), - migrations.CreateModel( - name='Novinky', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('datum', models.DateField(auto_now_add=True)), - ('text', models.TextField(blank=True, null=True, verbose_name='Text novinky')), - ('obrazek', models.ImageField(blank=True, null=True, upload_to='image_novinky/%Y/%m/%d/', verbose_name='Obrázek')), - ('zverejneno', models.BooleanField(default=False, verbose_name='Zveřejněno')), - ('autor', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='seminar.Organizator', verbose_name='Autor novinky')), - ], - options={ - 'verbose_name': 'Novinka', - 'verbose_name_plural': 'Novinky', - 'ordering': ['-datum'], - }, - ), - migrations.CreateModel( - name='Nastaveni', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('aktualni_cislo', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Cislo', verbose_name='poslední vydané číslo')), - ('aktualni_rocnik', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Rocnik', verbose_name='aktuální ročník')), - ], - options={ - 'verbose_name': 'Nastavení semináře', - 'db_table': 'seminar_nastaveni', - }, - ), - migrations.CreateModel( - name='Konfery_Ucastnici', - fields=[ - ('id', models.AutoField(primary_key=True, serialize=False)), - ('poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka k účasti (plain text)', verbose_name='neveřejná poznámka')), - ('konfera', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Konfera', verbose_name='konfera')), - ('resitel', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Resitel', verbose_name='řešitel')), - ], - options={ - 'verbose_name': 'Účast na konfeře', - 'verbose_name_plural': 'Účasti na konfeře', - 'db_table': 'seminar_konfery_ucastnici', - 'ordering': ['konfera', 'resitel'], - }, - ), - migrations.AddField( - model_name='konfera', - name='organizator', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='konfery', to='seminar.Organizator', verbose_name='organizátor'), - ), - migrations.AddField( - model_name='konfera', - name='reseni', - field=models.OneToOneField(blank=True, help_text='Účastnický přípěvek o konfeře', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='konfery', to='seminar.Reseni', verbose_name='článek ke konfeře'), - ), - migrations.AddField( - model_name='konfera', - name='soustredeni', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='konfery', to='seminar.Soustredeni', verbose_name='soustředění'), - ), - migrations.AddField( - model_name='konfera', - name='ucastnici', - field=models.ManyToManyField(help_text='Seznam účastníků konfery', through='seminar.Konfery_Ucastnici', to='seminar.Resitel', verbose_name='účastníci konfery'), - ), - migrations.AddField( - model_name='hodnoceni', - name='problem', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Problem', verbose_name='problém'), - ), - migrations.AddField( - model_name='hodnoceni', - name='reseni', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Reseni', verbose_name='řešení'), - ), - migrations.AddField( - model_name='cislo', - name='rocnik', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='cisla', to='seminar.Rocnik', verbose_name='ročník'), - ), - migrations.CreateModel( - name='UlohaZadaniNode', - fields=[ - ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), - ('uloha', models.OneToOneField(null=True, on_delete=django.db.models.deletion.PROTECT, to='seminar.Uloha', verbose_name='úloha')), - ], - options={ - 'verbose_name': 'Zadání úlohy (Node)', - 'verbose_name_plural': 'Zadání úloh (Node)', - 'db_table': 'seminar_nodes_uloha_zadani', - }, - bases=('seminar.treenode',), - ), - migrations.CreateModel( - name='UlohaVzorakNode', - fields=[ - ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), - ('uloha', models.OneToOneField(null=True, on_delete=django.db.models.deletion.PROTECT, to='seminar.Uloha', verbose_name='úloha')), - ], - options={ - 'verbose_name': 'Vzorák úlohy (Node)', - 'verbose_name_plural': 'Vzoráky úloh (Node)', - 'db_table': 'seminar_nodes_uloha_vzorak', - }, - bases=('seminar.treenode',), - ), - migrations.AddField( - model_name='uloha', - name='cislo_deadline', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='deadlinove_ulohy', to='seminar.Cislo', verbose_name='číslo deadlinu'), - ), - migrations.AddField( - model_name='uloha', - name='cislo_reseni', - field=models.ForeignKey(blank=True, help_text='Číslo s řešením úlohy, jen pro úlohy', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='resene_ulohy', to='seminar.Cislo', verbose_name='číslo řešení'), - ), - migrations.AddField( - model_name='uloha', - name='cislo_zadani', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='zadane_ulohy', to='seminar.Cislo', verbose_name='číslo zadání'), - ), - migrations.CreateModel( - name='TextNode', - fields=[ - ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), - ('text', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Text', verbose_name='text')), - ], - options={ - 'verbose_name': 'Text (Node)', - 'verbose_name_plural': 'Text (Node)', - 'db_table': 'seminar_nodes_obsah', - }, - bases=('seminar.treenode',), - ), - migrations.CreateModel( - name='TemaVCisleNode', - fields=[ - ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), - ('tema', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Tema', verbose_name='téma v čísle')), - ], - options={ - 'verbose_name': 'Téma v čísle (Node)', - 'verbose_name_plural': 'Témata v čísle (Node)', - 'db_table': 'seminar_nodes_temavcisle', - }, - bases=('seminar.treenode',), - ), - migrations.CreateModel( - name='RocnikNode', - fields=[ - ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), - ('rocnik', models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, to='seminar.Rocnik', verbose_name='ročník')), - ], - options={ - 'verbose_name': 'Ročník (Node)', - 'verbose_name_plural': 'Ročníky (Node)', - 'db_table': 'seminar_nodes_rocnik', - }, - bases=('seminar.treenode',), - ), - migrations.CreateModel( - name='PohadkaNode', - fields=[ - ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), - ('pohadka', models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, to='seminar.Pohadka', verbose_name='pohádka')), - ], - options={ - 'verbose_name': 'Pohádka (Node)', - 'verbose_name_plural': 'Pohádky (Node)', - 'db_table': 'seminar_nodes_pohadka', - }, - bases=('seminar.treenode',), - ), - migrations.CreateModel( - name='KonferaNode', - fields=[ - ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), - ('konfera', models.OneToOneField(null=True, on_delete=django.db.models.deletion.PROTECT, to='seminar.Konfera', verbose_name='konfera')), - ], - options={ - 'verbose_name': 'Konfera (Node)', - 'verbose_name_plural': 'Konfery (Node)', - 'db_table': 'seminar_nodes_konfera', - }, - bases=('seminar.treenode',), - ), - migrations.CreateModel( - name='ClanekNode', - fields=[ - ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), - ('clanek', models.OneToOneField(null=True, on_delete=django.db.models.deletion.PROTECT, to='seminar.Clanek', verbose_name='článek')), - ], - options={ - 'verbose_name': 'Článek (Node)', - 'verbose_name_plural': 'Články (Node)', - 'db_table': 'seminar_nodes_clanek', - }, - bases=('seminar.treenode',), - ), - migrations.AddField( - model_name='clanek', - name='cislo', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='seminar.Cislo', verbose_name='číslo'), - ), - migrations.CreateModel( - name='CisloNode', - fields=[ - ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), - ('cislo', models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, to='seminar.Cislo', verbose_name='číslo')), - ], - options={ - 'verbose_name': 'Číslo (Node)', - 'verbose_name_plural': 'Čísla (Node)', - 'db_table': 'seminar_nodes_cislo', - }, - bases=('seminar.treenode',), - ), - ] diff --git a/seminar/migrations/0002_add_body_views.py b/seminar/migrations/0002_add_body_views.py new file mode 100644 index 00000000..3d128ab9 --- /dev/null +++ b/seminar/migrations/0002_add_body_views.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations +import django_countries.fields +import seminar.models +import django.utils.timezone +from django.conf import settings + +CREATE_VIEWS=""" +create view seminar_body_za_cislo as + select + sr.cislo_body_id || '-' || sr.resitel_id as id, + sr.cislo_body_id as cislo_id, + sr.resitel_id as resitel_id, + sum(sr.body) as body + from seminar_reseni as sr + group by sr.cislo_body_id, sr.resitel_id + order by body desc; + +create view seminar_body_k_cislu as + select + akt_c.id || '-' || min_bzc.resitel_id as id, + akt_c.id as cislo_id, + min_bzc.resitel_id as resitel_id, + max(akt_bzc.body) as body, + sum(min_bzc.body) as body_celkem + from ((seminar_cisla as akt_c + inner join seminar_cisla as min_c on min_c.rocnik_id = akt_c.rocnik_id and akt_c.cislo >= min_c.cislo) + inner join seminar_body_za_cislo as min_bzc on min_c.id = min_bzc.cislo_id) + left outer join seminar_body_za_cislo as akt_bzc on akt_bzc.cislo_id = akt_c.id and akt_bzc.resitel_id = min_bzc.resitel_id + group by akt_c.id, min_bzc.resitel_id, akt_bzc.resitel_id + order by body_celkem desc; +""" + +DROP_VIEWS=""" +drop view seminar_body_k_cislu; +drop view seminar_body_za_cislo; +""" + +class Migration(migrations.Migration): + + dependencies = [("seminar", "0001_initial")] + + operations = [ + migrations.RunSQL(sql=CREATE_VIEWS, reverse_sql=DROP_VIEWS) + ] + diff --git a/seminar/migrations/0003_add_skola_zs_ss.py b/seminar/migrations/0003_add_skola_zs_ss.py new file mode 100644 index 00000000..1b1fbb80 --- /dev/null +++ b/seminar/migrations/0003_add_skola_zs_ss.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0002_add_body_views'), + ] + + operations = [ + migrations.AddField( + model_name='skola', + name='je_ss', + field=models.BooleanField(default=True, verbose_name='st\u0159edn\xed stupe\u0148'), + preserve_default=False, + ), + migrations.AddField( + model_name='skola', + name='je_zs', + field=models.BooleanField(default=True, verbose_name='z\xe1kladn\xed stupe\u0148'), + preserve_default=False, + ), + migrations.AlterField( + model_name='reseni', + name='poznamka', + field=models.TextField(help_text='Neve\u0159ejn\xe1 pozn\xe1mka k \u0159e\u0161en\xed (plain text, editace v detailu \u0159e\u0161en\xed)', verbose_name='neve\u0159ejn\xe1 pozn\xe1mka', blank=True), + preserve_default=True, + ), + ] diff --git a/seminar/migrations/0004_add_old_dakos_id.py b/seminar/migrations/0004_add_old_dakos_id.py new file mode 100644 index 00000000..1ec28943 --- /dev/null +++ b/seminar/migrations/0004_add_old_dakos_id.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0003_add_skola_zs_ss'), + ] + + operations = [ + migrations.AddField( + model_name='problem', + name='dakos_id', + field=models.CharField(default=b'', help_text='DaKoS ID z exportu, s prefixem podle p\u016fvodu: "AZAD:xxx" (z MM_AZAD), "DOZ:xxx" (z MM_DOZ), "ZAD:xxx" (z MM_ZADANIA)', max_length=32, verbose_name='Star\xe9 DaKoS ID', blank=True), + preserve_default=True, + ), + migrations.AddField( + model_name='resitel', + name='dakos_id', + field=models.CharField(default=b'', help_text='DaKoS ID z exportu, jen historick\xfd v\xfdznam, podle tabulky mamoper.MM_RIESITELIA', max_length=32, verbose_name='Stare DaKoS ID', blank=True), + preserve_default=True, + ), + migrations.AddField( + model_name='skola', + name='dakos_id', + field=models.CharField(default=b'', help_text='DaKoS ID z exportu, jen historick\xfd v\xfdznam, podle tabulky dksroot.V_skola', max_length=32, verbose_name='Stare DaKoS ID', blank=True), + preserve_default=True, + ), + migrations.AlterField( + model_name='skola', + name='je_ss', + field=models.BooleanField(default=True, verbose_name='st\u0159edn\xed stupe\u0148'), + preserve_default=True, + ), + migrations.AlterField( + model_name='skola', + name='je_zs', + field=models.BooleanField(default=True, verbose_name='z\xe1kladn\xed stupe\u0148'), + preserve_default=True, + ), + ] diff --git a/seminar/migrations/0005_alter_problem_autor.py b/seminar/migrations/0005_alter_problem_autor.py new file mode 100644 index 00000000..d8a40585 --- /dev/null +++ b/seminar/migrations/0005_alter_problem_autor.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations +from django.conf import settings + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0004_add_old_dakos_id'), + ] + + operations = [ + migrations.AlterField( + model_name='problem', + name='autor', + field=models.ForeignKey(related_name='autor_uloh', verbose_name='autor probl\xe9mu', blank=True, to=settings.AUTH_USER_MODEL, null=True, on_delete=models.CASCADE), + preserve_default=True, + ), + ] diff --git a/seminar/migrations/0006_problem_add_timestamp.py b/seminar/migrations/0006_problem_add_timestamp.py new file mode 100644 index 00000000..3df8bfdb --- /dev/null +++ b/seminar/migrations/0006_problem_add_timestamp.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations +import datetime +from django.utils.timezone import utc + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0005_alter_problem_autor'), + ] + + operations = [ + migrations.AddField( + model_name='problem', + name='timestamp', + field=models.DateTimeField(default=datetime.datetime(2015, 5, 15, 8, 54, 56, 319985, tzinfo=utc), verbose_name='vytvo\u0159eno', auto_now=True), + preserve_default=False, + ), + migrations.AlterField( + model_name='problem', + name='dakos_id', + field=models.CharField(default=b'', help_text='DaKoS ID z exportu, s prefixem podle p\u016fvodu: "AZAD:xxx (z MM_AZAD), ""DOZ:xxx" (z MM_DOZ), "ZAD:rocnik.cislo.uloha.typ" (z MM_ZADANIA)', max_length=32, verbose_name='Star\xe9 DaKoS ID', blank=True), + preserve_default=True, + ), + ] diff --git a/seminar/migrations/0007_problem_zamereni.py b/seminar/migrations/0007_problem_zamereni.py new file mode 100644 index 00000000..10718bd7 --- /dev/null +++ b/seminar/migrations/0007_problem_zamereni.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations +import taggit.managers + + +class Migration(migrations.Migration): + + dependencies = [ + ('taggit', '0001_initial'), + ('seminar', '0006_problem_add_timestamp'), + ] + + operations = [ + migrations.AddField( + model_name='problem', + name='zamereni', + field=taggit.managers.TaggableManager(to='taggit.Tag', through='taggit.TaggedItem', blank=True, help_text=b'Zam\xc4\x9b\xc5\x99en\xc3\xad M/F/I/O probl\xc3\xa9mu, p\xc5\x99\xc3\xadp. dal\xc5\xa1\xc3\xad tagy', verbose_name='zam\u011b\u0159en\xed'), + preserve_default=True, + ), + ] diff --git a/seminar/migrations/0008_reseni_forma.py b/seminar/migrations/0008_reseni_forma.py new file mode 100644 index 00000000..399e81a9 --- /dev/null +++ b/seminar/migrations/0008_reseni_forma.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0007_problem_zamereni'), + ] + + operations = [ + migrations.AddField( + model_name='reseni', + name='forma', + field=models.CharField(default=b'papir', max_length=16, verbose_name='forma \u0159e\u0161en\xed', choices=[(b'papir', 'Pap\xedrov\xe9 \u0159e\u0161en\xed'), (b'email', 'Emailem'), (b'upload', 'Upload p\u0159es web')]), + preserve_default=True, + ), + ] diff --git a/seminar/migrations/0009_rename_imported_IDs.py b/seminar/migrations/0009_rename_imported_IDs.py new file mode 100644 index 00000000..997bc0ac --- /dev/null +++ b/seminar/migrations/0009_rename_imported_IDs.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0008_reseni_forma'), + ] + + operations = [ + migrations.RenameField( + model_name='problem', + old_name='dakos_id', + new_name='import_dakos_id', + ), + migrations.RenameField( + model_name='resitel', + old_name='dakos_id', + new_name='import_mamoper_id', + ), + migrations.RenameField( + model_name='skola', + old_name='dakos_id', + new_name='import_dakos_id', + ), + migrations.AlterField( + model_name='problem', + name='import_dakos_id', + field=models.CharField(default=b'', help_text='ID z importu z DAKOSU s prefixem podle p\u016fvodu: "AZAD:xxx (MAMOPER.MM_AZAD), ""DOZ:xxx" (MAMOPER.MM_DOZ), "ZAD:rocnik.cislo.uloha.typ" (MAMOPER.MM_ZADANIA)', max_length=32, verbose_name='importovan\xe9 ID s typem', blank=True), + preserve_default=True, + ), + migrations.AlterField( + model_name='resitel', + name='import_mamoper_id', + field=models.CharField(default=b'', help_text='MAMOPER.MM_RIESITELIA.ID z DAKOS importu, jen historick\xfd v\xfdznam', max_length=32, verbose_name='importovan\xe9 MM_RIESITELIA.ID', blank=True), + preserve_default=True, + ), + migrations.AlterField( + model_name='skola', + name='import_dakos_id', + field=models.CharField(default=b'', help_text='DKSROOT.V_SKOLA.ID z DAKOS importu, jen historick\xfd v\xfdznam', max_length=32, verbose_name='importovan\xe9 DKSROOT.V_SKOLA.ID', blank=True), + preserve_default=True, + ), + ] diff --git a/seminar/migrations/0010_alter_rok_maturity.py b/seminar/migrations/0010_alter_rok_maturity.py new file mode 100644 index 00000000..58c099fb --- /dev/null +++ b/seminar/migrations/0010_alter_rok_maturity.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0009_rename_imported_IDs'), + ] + + operations = [ + migrations.AlterField( + model_name='resitel', + name='rok_maturity', + field=models.IntegerField(null=True, verbose_name='rok maturity', blank=True), + preserve_default=True, + ), + ] diff --git a/seminar/migrations/0011_alter_timestamp_def.py b/seminar/migrations/0011_alter_timestamp_def.py new file mode 100644 index 00000000..238386a6 --- /dev/null +++ b/seminar/migrations/0011_alter_timestamp_def.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0010_alter_rok_maturity'), + ] + + operations = [ + migrations.AlterField( + model_name='prilohareseni', + name='timestamp', + field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='vytvo\u0159eno', editable=False, blank=True), + preserve_default=True, + ), + migrations.AlterField( + model_name='problem', + name='import_dakos_id', + field=models.CharField(default=b'', help_text='ID z importu z DAKOSU s prefixem podle p\u016fvodu: "AZAD:xxx (MAMOPER.MM_AZAD), ""DOZ:xxx" (MAMOPER.MM_DOZ), "ZAD:rocnik.cislo.uloha.typ" (MAMOPER.MM_ZADANIA), "ULOHA:xxx" (MAMOPER.MM_ULOHY)', max_length=32, verbose_name='importovan\xe9 ID s typem', blank=True), + preserve_default=True, + ), + migrations.AlterField( + model_name='problem', + name='timestamp', + field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='vytvo\u0159eno', editable=False, blank=True), + preserve_default=True, + ), + migrations.AlterField( + model_name='reseni', + name='timestamp', + field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='vytvo\u0159eno', editable=False, blank=True), + preserve_default=True, + ), + ] diff --git a/seminar/migrations/0012_remove_soustredeni_ucastnici.py b/seminar/migrations/0012_remove_soustredeni_ucastnici.py new file mode 100644 index 00000000..ddb61304 --- /dev/null +++ b/seminar/migrations/0012_remove_soustredeni_ucastnici.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0011_alter_timestamp_def'), + ] + + operations = [ + migrations.RemoveField( + model_name='soustredeni', + name='ucastnici', + ), + ] diff --git a/seminar/migrations/0013_soustredeni_ucastnici_through_model.py b/seminar/migrations/0013_soustredeni_ucastnici_through_model.py new file mode 100644 index 00000000..c725691d --- /dev/null +++ b/seminar/migrations/0013_soustredeni_ucastnici_through_model.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0012_remove_soustredeni_ucastnici'), + ] + + operations = [ + migrations.CreateModel( + name='Soustredeni_Ucastnici', + fields=[ + ('id', models.AutoField(serialize=False, primary_key=True)), + ('poznamka', models.CharField(default=b'', help_text='Neve\u0159ejn\xe1 pozn\xe1mka k \xfa\u010dasti (plain text)', max_length=64, verbose_name='neve\u0159ejn\xe1 pozn\xe1mka', blank=True)), + ('resitel', models.ForeignKey(verbose_name='\u0159e\u0161itel', to='seminar.Resitel', on_delete=models.CASCADE)), + ('soustredeni', models.ForeignKey(verbose_name='soust\u0159ed\u011bn\xed', to='seminar.Soustredeni',on_delete=models.CASCADE)), + ], + options={ + 'ordering': ['soustredeni', 'resitel'], + 'db_table': 'seminar_soustredeni_ucastnici', + 'verbose_name': '\xda\u010dast na soust\u0159ed\u011bn\xed', + 'verbose_name_plural': '\xda\u010dasti na soust\u0159ed\u011bn\xed', + }, + bases=(models.Model,), + ), + migrations.AddField( + model_name='soustredeni', + name='ucastnici', + field=models.ManyToManyField(help_text='Seznam \xfa\u010dastn\xedk\u016f soust\u0159ed\u011bn\xed', to='seminar.Resitel', verbose_name='\xfa\u010dastn\xedci soust\u0159ed\u011bn\xed', through='seminar.Soustredeni_Ucastnici'), + preserve_default=True, + ), + ] diff --git a/seminar/migrations/0014_uprava_poznamek.py b/seminar/migrations/0014_uprava_poznamek.py new file mode 100644 index 00000000..0eb34984 --- /dev/null +++ b/seminar/migrations/0014_uprava_poznamek.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0013_soustredeni_ucastnici_through_model'), + ] + + operations = [ + migrations.AlterModelOptions( + name='problem', + options={'ordering': ['nazev'], 'verbose_name': 'Probl\xe9m', 'verbose_name_plural': 'Probl\xe9my'}, + ), + migrations.AlterModelOptions( + name='reseni', + options={'ordering': ['problem_id', 'resitel_id'], 'verbose_name': '\u0158e\u0161en\xed', 'verbose_name_plural': '\u0158e\u0161en\xed'}, + ), + migrations.AlterModelOptions( + name='skola', + options={'ordering': ['mesto', 'nazev'], 'verbose_name': '\u0160kola', 'verbose_name_plural': '\u0160koly'}, + ), + migrations.AddField( + model_name='cislo', + name='poznamka', + field=models.TextField(help_text='Neve\u0159ejn\xe1 pozn\xe1mka k \u010d\xedslu (plain text)', verbose_name='neve\u0159ejn\xe1 pozn\xe1mka', blank=True), + preserve_default=True, + ), + migrations.AlterField( + model_name='problem', + name='text_problemu_org', + field=models.TextField(verbose_name='neve\u0159ejn\xe9 zad\xe1n\xed a organiz\xe1torsk\xe9 a pozn\xe1mky', blank=True), + preserve_default=True, + ), + migrations.AlterField( + model_name='reseni', + name='poznamka', + field=models.TextField(help_text='Neve\u0159ejn\xe1 pozn\xe1mka k \u0159e\u0161en\xed (plain text)', verbose_name='neve\u0159ejn\xe1 pozn\xe1mka', blank=True), + preserve_default=True, + ), + migrations.AlterField( + model_name='soustredeni_ucastnici', + name='poznamka', + field=models.TextField(help_text='Neve\u0159ejn\xe1 pozn\xe1mka k \xfa\u010dasti (plain text)', verbose_name='neve\u0159ejn\xe1 pozn\xe1mka', blank=True), + preserve_default=True, + ), + ] diff --git a/seminar/migrations/0015_soustredeni_text.py b/seminar/migrations/0015_soustredeni_text.py new file mode 100644 index 00000000..87298eba --- /dev/null +++ b/seminar/migrations/0015_soustredeni_text.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0014_uprava_poznamek'), + ] + + operations = [ + migrations.AddField( + model_name='soustredeni', + name='text', + field=models.TextField(default=b'', verbose_name='text k soust\u0159ed\u011bn\xed (HTML)', blank=True), + preserve_default=True, + ), + ] diff --git a/seminar/migrations/0016_texty_problemu.py b/seminar/migrations/0016_texty_problemu.py new file mode 100644 index 00000000..451c888e --- /dev/null +++ b/seminar/migrations/0016_texty_problemu.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0015_soustredeni_text'), + ] + + operations = [ + migrations.RenameField( + model_name='problem', + old_name='text_problemu_org', + new_name='text_org', + ), + migrations.RenameField( + model_name='problem', + old_name='text_problemu', + new_name='text_zadani', + ), + migrations.AddField( + model_name='problem', + name='text_reseni', + field=models.TextField(help_text='Ve\u0159ejn\xfd text \u0159e\u0161en\xed (HTML, u t\xe9mat i p\u0159\xedsp\u011bvky a koment\xe1\u0159e)', verbose_name='ve\u0159ejn\xe9 \u0159e\u0161en\xed (HTML)', blank=True), + preserve_default=True, + ), + migrations.AlterField( + model_name='problem', + name='text_org', + field=models.TextField(help_text='Neve\u0159ejn\xfd n\xe1vrh \xfalohy, n\xe1vrh \u0159e\u0161en\xed, text zad\xe1n\xed, pozn\xe1mky ...', verbose_name='org pozn\xe1mky (HTML)', blank=True), + preserve_default=True, + ), + migrations.AlterField( + model_name='problem', + name='text_zadani', + field=models.TextField(help_text='Ve\u0159ejn\xfd text zad\xe1n\xed (HTML)', verbose_name='ve\u0159ejn\xe9 zad\xe1n\xed (HTML)', blank=True), + preserve_default=True, + ), + ] diff --git a/seminar/migrations/0017_texty_problemu_minor.py b/seminar/migrations/0017_texty_problemu_minor.py new file mode 100644 index 00000000..f732c111 --- /dev/null +++ b/seminar/migrations/0017_texty_problemu_minor.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0016_texty_problemu'), + ] + + operations = [ + migrations.AlterField( + model_name='problem', + name='text_reseni', + field=models.TextField(help_text='Ve\u0159ejn\xfd text \u0159e\u0161en\xed (HTML, u t\xe9mat i p\u0159\xedsp\u011bvky a koment\xe1\u0159e)', verbose_name='ve\u0159ejn\xe9 \u0159e\u0161en\xed (HTML)', blank=True), + preserve_default=True, + ), + ] diff --git a/seminar/migrations/0018_problemnavrh_problemzadany.py b/seminar/migrations/0018_problemnavrh_problemzadany.py new file mode 100644 index 00000000..afdcfa8c --- /dev/null +++ b/seminar/migrations/0018_problemnavrh_problemzadany.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0017_texty_problemu_minor'), + ] + + operations = [ + migrations.CreateModel( + name='ProblemNavrh', + fields=[ + ], + options={ + 'verbose_name': 'Probl\xe9m (n\xe1vrh)', + 'proxy': True, + 'verbose_name_plural': 'Probl\xe9my (n\xe1vrhy)', + }, + bases=('seminar.problem',), + ), + migrations.CreateModel( + name='ProblemZadany', + fields=[ + ], + options={ + 'verbose_name': 'Probl\xe9m (zadan\xfd)', + 'proxy': True, + 'verbose_name_plural': 'Probl\xe9my (zadan\xe9)', + }, + bases=('seminar.problem',), + ), + ] diff --git a/seminar/migrations/0019_rocnik_ciselne.py b/seminar/migrations/0019_rocnik_ciselne.py new file mode 100644 index 00000000..42308b2f --- /dev/null +++ b/seminar/migrations/0019_rocnik_ciselne.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0018_problemnavrh_problemzadany'), + ] + + operations = [ + migrations.AddField( + model_name='rocnik', + name='rocnik_n', + field=models.IntegerField(default=0, verbose_name='\u010d\xedslo ro\u010dn\xedku'), + preserve_default=False, + ), + migrations.RunSQL( + sql="update seminar_rocniky set rocnik_n = cast (rocnik as integer)" + ), + migrations.RemoveField( + model_name='rocnik', + name='rocnik', + ), + migrations.RenameField( + model_name='rocnik', + old_name='rocnik_n', + new_name='rocnik', + ), + ] diff --git a/seminar/migrations/0020_indexy_a_razeni.py b/seminar/migrations/0020_indexy_a_razeni.py new file mode 100644 index 00000000..1e199f0e --- /dev/null +++ b/seminar/migrations/0020_indexy_a_razeni.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0019_rocnik_ciselne'), + ] + + operations = [ + migrations.AlterModelOptions( + name='cislo', + options={'ordering': ['-rocnik__rocnik', '-cislo'], 'verbose_name': '\u010c\xedslo', 'verbose_name_plural': '\u010c\xedsla'}, + ), + migrations.AlterModelOptions( + name='reseni', + options={'ordering': ['problem_id', 'resitel__prijmeni', 'resitel__jmeno'], 'verbose_name': '\u0158e\u0161en\xed', 'verbose_name_plural': '\u0158e\u0161en\xed'}, + ), + migrations.AlterModelOptions( + name='rocnik', + options={'ordering': ['-rocnik'], 'verbose_name': 'Ro\u010dn\xedk', 'verbose_name_plural': 'Ro\u010dn\xedky'}, + ), + migrations.AlterField( + model_name='cislo', + name='cislo', + field=models.CharField(help_text='V\u011bt\u0161inou jen "1", vyj\xedme\u010dn\u011b "7-8", lexikograficky ur\u010dije po\u0159ad\xed v ro\u010dn\xedku!', max_length=32, verbose_name='n\xe1zev \u010d\xedsla', db_index=True), + preserve_default=True, + ), + migrations.AlterField( + model_name='rocnik', + name='prvni_rok', + field=models.IntegerField(unique=True, verbose_name='prvn\xed rok', db_index=True), + preserve_default=True, + ), + migrations.AlterField( + model_name='rocnik', + name='rocnik', + field=models.IntegerField(unique=True, verbose_name='\u010d\xedslo ro\u010dn\xedku', db_index=True), + preserve_default=True, + ), + ] diff --git a/seminar/migrations/0021_cislo_verejna_vysledkovka.py b/seminar/migrations/0021_cislo_verejna_vysledkovka.py new file mode 100644 index 00000000..d4d34c7f --- /dev/null +++ b/seminar/migrations/0021_cislo_verejna_vysledkovka.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0020_indexy_a_razeni'), + ] + + operations = [ + migrations.AddField( + model_name='cislo', + name='verejna_vysledkovka', + field=models.BooleanField(default=False, help_text='Je-li false u ve\u0159ejn\xe9ho \u010d\xedsla, nen\xed v\xfdsledkovka zat\xedm ve\u0159ejn\xe1.', verbose_name='zve\u0159ejn\u011bna v\xfdsledkovka'), + preserve_default=True, + ), + ] diff --git a/seminar/migrations/0022_decimal_body.py b/seminar/migrations/0022_decimal_body.py new file mode 100644 index 00000000..ff92fcde --- /dev/null +++ b/seminar/migrations/0022_decimal_body.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals +import importlib + +from django.db import models, migrations + +migration_0022 = importlib.import_module('seminar.migrations.0002_add_body_views') + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0021_cislo_verejna_vysledkovka'), + ] + operations = [ + migrations.RunSQL(migration_0022.DROP_VIEWS), + migrations.AlterField( + model_name='problem', + name='body', + field=models.DecimalField(null=True, verbose_name='maximum bod\u016f', max_digits=8, decimal_places=1, blank=True), + preserve_default=True, + ), + migrations.AlterField( + model_name='reseni', + name='body', + field=models.DecimalField(null=True, verbose_name='body', max_digits=8, decimal_places=1, blank=True), + preserve_default=True, + ), + migrations.RunSQL(migration_0022.CREATE_VIEWS), + ] diff --git a/seminar/migrations/0023_add_novinky.py b/seminar/migrations/0023_add_novinky.py new file mode 100644 index 00000000..7db2a005 --- /dev/null +++ b/seminar/migrations/0023_add_novinky.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations +from django.conf import settings + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('seminar', '0022_decimal_body'), + ] + + operations = [ + migrations.CreateModel( + name='Novinky', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('datum', models.DateField(auto_now_add=True)), + ('text', models.TextField(null=True, verbose_name=b'Text novinky', blank=True)), + ('obrazek', models.ImageField(upload_to=b'image_novinky/%Y/%m/%d/', null=True, verbose_name=b'Obr\xc3\xa1zek', blank=True)), + ('zverejneno', models.BooleanField(default=False, verbose_name=b'Zve\xc5\x99ejn\xc4\x9bno')), + ('autor', models.ForeignKey(verbose_name=b'Autor novinky', to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)) + ], + options={ + 'verbose_name': 'Novinka', + 'verbose_name_plural': 'Novinky', + }, + bases=(models.Model,), + ), + ] diff --git a/seminar/migrations/0024_add_organizator.py b/seminar/migrations/0024_add_organizator.py new file mode 100644 index 00000000..16faee72 --- /dev/null +++ b/seminar/migrations/0024_add_organizator.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations +from django.conf import settings + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('seminar', '0023_add_novinky'), + ] + + operations = [ + migrations.CreateModel( + name='Organizator', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('prezdivka', models.CharField(max_length=32, null=True, verbose_name=b'P\xc5\x99ezd\xc3\xadvka', blank=True)), + ('organizuje_od_roku', models.IntegerField(null=True, verbose_name=b'Organizuje od roku', blank=True)), + ('organizuje_do_roku', models.IntegerField(null=True, verbose_name=b'Organizuje do roku', blank=True)), + ('studuje', models.CharField(max_length=256, null=True, verbose_name=b'Studuje', blank=True)), + ('strucny_popis_organizatora', models.TextField(null=True, verbose_name=b'Stru\xc4\x8dn\xc3\xbd popis organiz\xc3\xa1tora', blank=True)), + ('foto', models.ImageField(help_text=b'Vlo\xc5\xbe fotografii organiz\xc3\xa1tora o libovon\xc3\xa9 velikosti', upload_to=b'image_organizatori/%Y/', null=True, verbose_name=b'Fotografie organiz\xc3\xa1tora', blank=True)), + ('foto_male', models.ImageField(upload_to=b'image_organizatori/male/%Y/', null=True, editable=False, blank=True)), + ('user', models.OneToOneField(verbose_name=b'Osoba', to=settings.AUTH_USER_MODEL, help_text=b'Vyber \xc3\xba\xc4\x8det sp\xc5\x99a\xc5\xbeen\xc3\xbd s organiz\xc3\xa1torem.',on_delete=models.CASCADE)), + ], + options={ + 'verbose_name': 'Organiz\xe1tor', + 'verbose_name_plural': 'Organiz\xe1to\u0159i', + }, + bases=(models.Model,), + ), + ] diff --git a/seminar/migrations/0025_zmena_cesty_nahravani_obrazku.py b/seminar/migrations/0025_zmena_cesty_nahravani_obrazku.py new file mode 100644 index 00000000..23e02c95 --- /dev/null +++ b/seminar/migrations/0025_zmena_cesty_nahravani_obrazku.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0024_add_organizator'), + ] + + operations = [ + migrations.AlterField( + model_name='organizator', + name='foto', + field=models.ImageField(help_text=b'Vlo\xc5\xbe fotografii organiz\xc3\xa1tora o libovon\xc3\xa9 velikosti', upload_to=b'image_organizatori/velke/%Y/', null=True, verbose_name=b'Fotografie organiz\xc3\xa1tora', blank=True), + preserve_default=True, + ), + ] diff --git a/seminar/migrations/0026_soustredeni_typ.py b/seminar/migrations/0026_soustredeni_typ.py new file mode 100644 index 00000000..46d3416f --- /dev/null +++ b/seminar/migrations/0026_soustredeni_typ.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0025_zmena_cesty_nahravani_obrazku'), + ] + + operations = [ + migrations.AddField( + model_name='soustredeni', + name='typ', + field=models.CharField(default=b'podzimni', max_length=16, verbose_name='typ akce', choices=[(b'jarni', 'Jarn\xed soust\u0159ed\u011bn\xed'), (b'podzimni', 'Podzimn\xed soust\u0159ed\u011bn\xed'), (b'sraz', 'Nepravideln\xfd sraz')]), + preserve_default=True, + ), + ] diff --git a/seminar/migrations/0027_export_flag_a_typ_akce.py b/seminar/migrations/0027_export_flag_a_typ_akce.py new file mode 100644 index 00000000..e7172dcc --- /dev/null +++ b/seminar/migrations/0027_export_flag_a_typ_akce.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0026_soustredeni_typ'), + ] + + operations = [ + migrations.AddField( + model_name='rocnik', + name='exportovat', + field=models.BooleanField(default=False, help_text='Exportuje se jen podle tohoto flagu (ne ve\u0159ejnosti), a to jen \u010d\xedsla s ve\u0159ejnou v\xfdsledkovkou', verbose_name='export do AESOPa', db_column='exportovat'), + preserve_default=True, + ), + migrations.AddField( + model_name='soustredeni', + name='exportovat', + field=models.BooleanField(default=False, help_text='Exportuje se jen podle tohoto flagu (ne ve\u0159ejnosti)', verbose_name='export do AESOPa', db_column='exportovat'), + preserve_default=True, + ), + migrations.AlterField( + model_name='soustredeni', + name='typ', + field=models.CharField(default=b'podzimni', max_length=16, verbose_name='typ akce', choices=[(b'jarni', 'Jarn\xed soust\u0159ed\u011bn\xed'), (b'podzimni', 'Podzimn\xed soust\u0159ed\u011bn\xed'), (b'vikend', 'V\xedkendov\xfd sraz')]), + preserve_default=True, + ), + ] diff --git a/seminar/migrations/0028_add_body_celkem_views.py b/seminar/migrations/0028_add_body_celkem_views.py new file mode 100644 index 00000000..0f6799f0 --- /dev/null +++ b/seminar/migrations/0028_add_body_celkem_views.py @@ -0,0 +1,75 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations +import django_countries.fields +import seminar.models +import django.utils.timezone +from django.conf import settings + +CREATE_VIEWS=""" +drop view seminar_body_k_cislu; +drop view seminar_body_za_cislo; + +create view seminar_body_za_cislo as + select + seminar_reseni.cislo_body_id || '-' || seminar_reseni.resitel_id as id, + seminar_reseni.cislo_body_id as cislo_id, + seminar_reseni.resitel_id as resitel_id, + seminar_cisla.cislo as cislo, + seminar_cisla.rocnik_id as rocnik_id, + seminar_rocniky.rocnik as rocnik, + seminar_cisla.verejna_vysledkovka as verejna_vysledkovka, + sum(seminar_reseni.body) as body + from + seminar_reseni + inner join seminar_cisla on seminar_reseni.cislo_body_id = seminar_cisla.id + inner join seminar_rocniky on seminar_cisla.rocnik_id = seminar_rocniky.id + group by seminar_reseni.cislo_body_id, seminar_reseni.resitel_id, seminar_cisla.cislo, + seminar_cisla.rocnik_id, seminar_rocniky.rocnik, seminar_cisla.verejna_vysledkovka + order by body desc; + +create view seminar_body_k_cislu_rocnik as + select + akt_body.id as id, + akt_body.cislo_id as cislo_id, + akt_body.resitel_id as resitel_id, + akt_body.body as body, + sum(min_body.body) as body_celkem + from + seminar_body_za_cislo as akt_body + inner join seminar_body_za_cislo as min_body on + (akt_body.resitel_id = min_body.resitel_id and + (akt_body.rocnik = min_body.rocnik and akt_body.cislo >= min_body.cislo) + ) + group by akt_body.id, akt_body.cislo_id, akt_body.resitel_id, akt_body.body + order by body_celkem desc; + +create view seminar_body_k_cislu_odjakziva as + select + akt_body.id as id, + akt_body.cislo_id as cislo_id, + akt_body.resitel_id as resitel_id, + akt_body.body as body, + sum(min_body.body) as body_celkem + from + seminar_body_za_cislo as akt_body + inner join seminar_body_za_cislo as min_body on + (akt_body.resitel_id = min_body.resitel_id and + ((akt_body.rocnik = min_body.rocnik and akt_body.cislo >= min_body.cislo) or + (akt_body.rocnik < min_body.rocnik) + ) + ) + group by akt_body.id, akt_body.cislo_id, akt_body.resitel_id, akt_body.body + order by body_celkem desc; + +""" + +class Migration(migrations.Migration): + + dependencies = [("seminar", "0027_export_flag_a_typ_akce")] + + operations = [ + migrations.RunSQL(sql=CREATE_VIEWS) + ] + diff --git a/seminar/migrations/0029_fix_body_celkem_views.py b/seminar/migrations/0029_fix_body_celkem_views.py new file mode 100644 index 00000000..5e287747 --- /dev/null +++ b/seminar/migrations/0029_fix_body_celkem_views.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations +import django_countries.fields +import seminar.models +import django.utils.timezone +from django.conf import settings + +CREATE_VIEWS=""" + +drop view seminar_body_k_cislu_rocnik; +create view seminar_body_k_cislu_rocnik as + select + seminar_cisla.id || '-' || min_body.resitel_id as id, + seminar_cisla.id as cislo_id, + min_body.resitel_id as resitel_id, + sum(min_body.body) as body + from + seminar_cisla + inner join seminar_body_za_cislo as min_body on + (min_body.rocnik_id = seminar_cisla.rocnik_id and seminar_cisla.cislo >= min_body.cislo) + group by seminar_cisla.id, min_body.resitel_id + order by body desc; + +drop view seminar_body_k_cislu_odjakziva; +create view seminar_body_k_cislu_odjakziva as + select + seminar_cisla.id || '-' || min_body.resitel_id as id, + seminar_cisla.id as cislo_id, + min_body.resitel_id as resitel_id, + sum(min_body.body) as body + from + seminar_cisla + inner join seminar_rocniky on + (seminar_cisla.rocnik_id = seminar_rocniky.id) + inner join seminar_body_za_cislo as min_body on + (min_body.rocnik_id = seminar_cisla.rocnik_id and seminar_cisla.cislo >= min_body.cislo) or + (min_body.rocnik < seminar_rocniky.rocnik) + group by seminar_cisla.id, min_body.resitel_id + order by body desc; +""" + +class Migration(migrations.Migration): + + dependencies = [("seminar", "0028_add_body_celkem_views")] + + operations = [ + migrations.RunSQL(sql=CREATE_VIEWS) + ] + diff --git a/seminar/migrations/0030_add_vysledky.py b/seminar/migrations/0030_add_vysledky.py new file mode 100644 index 00000000..06842c6b --- /dev/null +++ b/seminar/migrations/0030_add_vysledky.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0029_fix_body_celkem_views'), + ] + + operations = [ + migrations.CreateModel( + name='VysledkyCelkemKCislu', + fields=[ + ('dummy_id', models.CharField(max_length=32, serialize=False, verbose_name='dummy ID pro view', primary_key=True, db_column=b'id')), + ('body', models.DecimalField(decimal_places=1, verbose_name='body za \u010d\xedslo', max_digits=8, db_column=b'body')), + ('body_celkem', models.DecimalField(decimal_places=1, verbose_name='body celkem do \u010d\xedsla v\u010detn\u011b minul\xfdch ro\u010dn\xedk\u016f', max_digits=8, db_column=b'body_celkem')), + ], + options={ + 'abstract': False, + 'db_table': 'seminar_body_celkem_k_cislu', + 'managed': False, + }, + bases=(models.Model,), + ), + migrations.CreateModel( + name='VysledkyKCisluOdjakziva', + fields=[ + ('dummy_id', models.CharField(max_length=32, serialize=False, verbose_name='dummy ID pro view', primary_key=True, db_column=b'id')), + ('body', models.DecimalField(decimal_places=1, verbose_name='body za \u010d\xedslo', max_digits=8, db_column=b'body')), + ], + options={ + 'abstract': False, + 'db_table': 'seminar_body_k_cislu_odjakziva', + 'managed': False, + }, + bases=(models.Model,), + ), + migrations.CreateModel( + name='VysledkyKCisluZaRocnik', + fields=[ + ('dummy_id', models.CharField(max_length=32, serialize=False, verbose_name='dummy ID pro view', primary_key=True, db_column=b'id')), + ('body', models.DecimalField(decimal_places=1, verbose_name='body za \u010d\xedslo', max_digits=8, db_column=b'body')), + ], + options={ + 'abstract': False, + 'db_table': 'seminar_body_k_cislu_rocnik', + 'managed': False, + }, + bases=(models.Model,), + ), + migrations.AlterField( + model_name='organizator', + name='foto', + field=models.ImageField(help_text=b'Vlo\xc5\xbe fotografii organiz\xc3\xa1tora o libovoln\xc3\xa9 velikosti', upload_to=b'image_organizatori/velke/%Y/', null=True, verbose_name=b'Fotografie organiz\xc3\xa1tora', blank=True), + preserve_default=True, + ), + ] diff --git a/seminar/migrations/0031_cislo_pdf.py b/seminar/migrations/0031_cislo_pdf.py new file mode 100644 index 00000000..c51570bf --- /dev/null +++ b/seminar/migrations/0031_cislo_pdf.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations +import seminar.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0030_add_vysledky'), + ] + + operations = [ + migrations.AddField( + model_name='cislo', + name='pdf', + field=models.FileField(help_text='Pdf \u010d\xedsla, kter\xe9 si mohou \u0159e\u0161itel\xe9 st\xe1hnout', upload_to=seminar.models.cislo_pdf_filename, null=True, verbose_name='pdf'), + preserve_default=True, + ), + ] diff --git a/seminar/migrations/0032_cislo_pdf_blank_typos.py b/seminar/migrations/0032_cislo_pdf_blank_typos.py new file mode 100644 index 00000000..b16c4501 --- /dev/null +++ b/seminar/migrations/0032_cislo_pdf_blank_typos.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations +import django_countries.fields +import seminar.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0031_cislo_pdf'), + ] + + operations = [ + migrations.AlterModelOptions( + name='soustredeni', + options={'ordering': ['-rocnik__rocnik', '-datum_zacatku'], 'verbose_name': 'Soust\u0159ed\u011bn\xed', 'verbose_name_plural': 'Soust\u0159ed\u011bn\xed'}, + ), + migrations.AlterField( + model_name='cislo', + name='cislo', + field=models.CharField(help_text='V\u011bt\u0161inou jen "1", vyj\xedme\u010dn\u011b "7-8", lexikograficky ur\u010duje po\u0159ad\xed v ro\u010dn\xedku!', max_length=32, verbose_name='n\xe1zev \u010d\xedsla', db_index=True), + preserve_default=True, + ), + migrations.AlterField( + model_name='cislo', + name='pdf', + field=models.FileField(help_text='Pdf \u010d\xedsla, kter\xe9 si mohou \u0159e\u0161itel\xe9 st\xe1hnout', upload_to=seminar.models.cislo_pdf_filename, null=True, verbose_name='pdf', blank=True), + preserve_default=True, + ), + migrations.AlterField( + model_name='problem', + name='typ', + field=models.CharField(default=b'uloha', max_length=32, verbose_name='typ probl\xe9mu', choices=[(b'uloha', '\xdaloha'), (b'tema', 'T\xe9ma'), (b'serial', 'Seri\xe1l'), (b'org-clanek', 'Organiz\xe1torsk\xfd \u010dl\xe1nek'), (b'res-clanek', '\u0158e\u0161itelsk\xfd \u010dl\xe1nek')]), + preserve_default=True, + ), + migrations.AlterField( + model_name='skola', + name='stat', + field=django_countries.fields.CountryField(default=b'CZ', help_text='ISO 3166-1 k\xf3d zem\u011b velk\xfdmi p\xedsmeny (CZ, SK, ...)', max_length=2, verbose_name='st\xe1t'), + preserve_default=True, + ), + ] diff --git a/seminar/migrations/0033_organizator_studuje_popisek.py b/seminar/migrations/0033_organizator_studuje_popisek.py new file mode 100644 index 00000000..07f15712 --- /dev/null +++ b/seminar/migrations/0033_organizator_studuje_popisek.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0032_cislo_pdf_blank_typos'), + ] + + operations = [ + migrations.AlterField( + model_name='organizator', + name='studuje', + field=models.CharField(help_text=b"Nap\xc5\x99. 'Studuje Obecnou fyziku (Bc.), 3. ro\xc4\x8dn\xc3\xadk', 'Vystudovala Diskr\xc3\xa9tn\xc3\xad modely a algoritmy (Mgr.)' nebo 'P\xc5\x99edn\xc3\xa1\xc5\xa1\xc3\xad na MFF'", max_length=256, null=True, verbose_name=b'Studium aj.', blank=True), + preserve_default=True, + ), + ] diff --git a/seminar/migrations/0034_reseni_forma_default_email.py b/seminar/migrations/0034_reseni_forma_default_email.py new file mode 100644 index 00000000..2d691b30 --- /dev/null +++ b/seminar/migrations/0034_reseni_forma_default_email.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0033_organizator_studuje_popisek'), + ] + + operations = [ + migrations.AlterField( + model_name='reseni', + name='forma', + field=models.CharField(default=b'email', max_length=16, verbose_name='forma \u0159e\u0161en\xed', choices=[(b'papir', 'Pap\xedrov\xe9 \u0159e\u0161en\xed'), (b'email', 'Emailem'), (b'upload', 'Upload p\u0159es web')]), + preserve_default=True, + ), + ] diff --git a/seminar/migrations/0035_django_imagekit.py b/seminar/migrations/0035_django_imagekit.py new file mode 100644 index 00000000..dd443018 --- /dev/null +++ b/seminar/migrations/0035_django_imagekit.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations +import imagekit.models.fields + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0034_reseni_forma_default_email'), + ] + + operations = [ + migrations.RemoveField( + model_name='organizator', + name='foto_male', + ), + migrations.AlterField( + model_name='organizator', + name='foto', + field=imagekit.models.fields.ProcessedImageField(help_text=b'Vlo\xc5\xbe fotografii organiz\xc3\xa1tora o libovoln\xc3\xa9 velikosti', upload_to=b'image_organizatori/velke/%Y/', null=True, verbose_name=b'Fotografie organiz\xc3\xa1tora', blank=True), + preserve_default=True, + ), + ] diff --git a/seminar/migrations/0036_add_org_to_soustredeni.py b/seminar/migrations/0036_add_org_to_soustredeni.py new file mode 100644 index 00000000..4db43239 --- /dev/null +++ b/seminar/migrations/0036_add_org_to_soustredeni.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0035_django_imagekit'), + ] + + operations = [ + migrations.CreateModel( + name='Soustredeni_Organizatori', + fields=[ + ('id', models.AutoField(serialize=False, primary_key=True)), + ('poznamka', models.TextField(help_text='Neve\u0159ejn\xe1 pozn\xe1mka k \xfa\u010dasti organiz\xe1tora (plain text)', verbose_name='neve\u0159ejn\xe1 pozn\xe1mka', blank=True)), + ('organizator', models.ForeignKey(verbose_name='organiz\xe1tor', to='seminar.Organizator', on_delete=models.CASCADE)), + ('soustredeni', models.ForeignKey(verbose_name='soust\u0159ed\u011bn\xed', to='seminar.Soustredeni', on_delete=models.CASCADE)), + ], + options={ + 'ordering': ['soustredeni', 'organizator'], + 'db_table': 'seminar_soustredeni_organizatori', + 'verbose_name': '\xda\u010dast organiz\xe1tor\u016f na soust\u0159ed\u011bn\xed', + 'verbose_name_plural': '\xda\u010dasti organiz\xe1tor\u016f na soust\u0159ed\u011bn\xed', + }, + bases=(models.Model,), + ), + migrations.AddField( + model_name='soustredeni', + name='organizatori', + field=models.ManyToManyField(help_text='Seznam organiz\xe1tor\u016f soust\u0159ed\u011bn\xed', to='seminar.Organizator', verbose_name='Organiz\xe1to\u0159i soust\u0159ed\u011bn\xed', through='seminar.Soustredeni_Organizatori'), + preserve_default=True, + ), + ] diff --git a/seminar/migrations/0037_prispevek.py b/seminar/migrations/0037_prispevek.py new file mode 100644 index 00000000..c4c3b867 --- /dev/null +++ b/seminar/migrations/0037_prispevek.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0036_add_org_to_soustredeni'), + ] + + operations = [ + migrations.CreateModel( + name='Prispevek', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('nazev', models.CharField(max_length=200, verbose_name=b'N\xc3\xa1zev')), + ('text_org', models.TextField(null=True, verbose_name=b'Orgovsk\xc3\xbd text', blank=True)), + ('text_resitel', models.TextField(null=True, verbose_name=b'\xc5\x98e\xc5\xa1itelsk\xc3\xbd text', blank=True)), + ('zverejnit', models.BooleanField(verbose_name=b'Zve\xc5\x99ejnit?')), + ('problem', models.ForeignKey(verbose_name=b'Probl\xc3\xa9m', to='seminar.Problem', on_delete=models.CASCADE)), + ('reseni', models.OneToOneField(null=True, blank=True, to='seminar.Reseni', verbose_name=b'\xc5\x98e\xc5\xa1en\xc3\xad', on_delete=models.CASCADE)), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/seminar/migrations/0038_change_meta_prispevek.py b/seminar/migrations/0038_change_meta_prispevek.py new file mode 100644 index 00000000..5378e57e --- /dev/null +++ b/seminar/migrations/0038_change_meta_prispevek.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0037_prispevek'), + ] + + operations = [ + migrations.AlterModelOptions( + name='prispevek', + options={'verbose_name': 'P\u0159\xedsp\u011bvek k probl\xe9mu', 'verbose_name_plural': 'P\u0159\xedsp\u011bvky k probl\xe9m\u016fm'}, + ), + ] diff --git a/seminar/migrations/0039_pohadka.py b/seminar/migrations/0039_pohadka.py new file mode 100644 index 00000000..f798bd75 --- /dev/null +++ b/seminar/migrations/0039_pohadka.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models +import django.utils.timezone +from django.conf import settings + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('seminar', '0038_change_meta_prispevek'), + ] + + operations = [ + migrations.CreateModel( + name='Pohadka', + fields=[ + ('id', models.AutoField(serialize=False, primary_key=True)), + ('text', models.TextField(verbose_name='Text poh\xe1dky')), + ('pred', models.BooleanField(default=True, verbose_name='P\u0159ed \xfalohou')), + ('timestamp', models.DateTimeField(default=django.utils.timezone.now, verbose_name='Vytvo\u0159eno', editable=False, blank=True)), + ('autor', models.ForeignKey(verbose_name=b'Autor poh\xc3\xa1dky', to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), + ('uloha', models.ForeignKey(related_name='pohadky', verbose_name='\xdaloha', to='seminar.Problem',on_delete=models.CASCADE)), + ], + options={ + 'ordering': ['uloha__cislo_zadani', 'uloha__kod', '-pred'], + 'db_table': 'seminar_pohadky', + 'verbose_name': 'Poh\xe1dka', + 'verbose_name_plural': 'Poh\xe1dky', + }, + ), + ] diff --git a/seminar/migrations/0040_pohadka_nepovinny_autor.py b/seminar/migrations/0040_pohadka_nepovinny_autor.py new file mode 100644 index 00000000..babf9b24 --- /dev/null +++ b/seminar/migrations/0040_pohadka_nepovinny_autor.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models +from django.conf import settings + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0039_pohadka'), + ] + + operations = [ + migrations.AlterField( + model_name='pohadka', + name='autor', + field=models.ForeignKey(verbose_name=b'Autor poh\xc3\xa1dky', to=settings.AUTH_USER_MODEL, null=True, on_delete=models.CASCADE), + ), + ] diff --git a/seminar/migrations/0041_konfery.py b/seminar/migrations/0041_konfery.py new file mode 100644 index 00000000..9fddbe17 --- /dev/null +++ b/seminar/migrations/0041_konfery.py @@ -0,0 +1,71 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion +import seminar.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0040_pohadka_nepovinny_autor'), + ] + + operations = [ + migrations.CreateModel( + name='Konfera', + fields=[ + ('id', models.AutoField(serialize=False, primary_key=True)), + ('nazev', models.CharField(help_text='N\xe1zev konfery', max_length=40, verbose_name='n\xe1zev konfery')), + ('popis', models.TextField(help_text='Popis konfery k zobrazen\xed na webu', verbose_name='popis konfery', blank=True)), + ('abstrakt', models.TextField(help_text='Abstrakt konfery tak, jak byl uveden ve sborn\xedku', verbose_name='abstrakt', blank=True)), + ('org_poznamka', models.TextField(help_text='Neve\u0159ejn\xe1 pozn\xe1mka ke konfe\u0159e(plain text)', verbose_name='neve\u0159ejn\xe1 pozn\xe1mka', blank=True)), + ('typ_prezentace', models.CharField(default=b'veletrh', max_length=16, verbose_name='typ prezentace', choices=[(b'veletrh', 'Veletrh (postery)'), (b'prezentace', 'Prezentace (p\u0159edn\xe1\u0161ka)')])), + ('prezentace', models.FileField(help_text='Prezentace nebo fotka posteru', upload_to=seminar.models.generate_filename_konfera, verbose_name='prezentace')), + ('materialy', models.FileField(help_text='Dal\u0161\xed materi\xe1ly ke konfe\u0159e zabalen\xe9 do jednoho souboru', upload_to=seminar.models.generate_filename_konfera, verbose_name='materialy')), + ('organizator', models.ForeignKey(related_name='konfery', on_delete=django.db.models.deletion.SET_NULL, verbose_name='organiz\xe1tor', to='seminar.Organizator', null=True)), + ], + options={ + 'db_table': 'seminar_konfera', + 'verbose_name': 'Konfera', + 'verbose_name_plural': 'Konfery', + }, + ), + migrations.CreateModel( + name='Konfery_Ucastnici', + fields=[ + ('id', models.AutoField(serialize=False, primary_key=True)), + ('poznamka', models.TextField(help_text='Neve\u0159ejn\xe1 pozn\xe1mka k \xfa\u010dasti (plain text)', verbose_name='neve\u0159ejn\xe1 pozn\xe1mka', blank=True)), + ('konfera', models.ForeignKey(verbose_name='konfera', to='seminar.Konfera', + on_delete=models.PROTECT)), + ('resitel', models.ForeignKey(verbose_name='\u0159e\u0161itel', to='seminar.Resitel',on_delete=models.CASCADE)), + ], + options={ + 'ordering': ['konfera', 'resitel'], + 'db_table': 'seminar_konfery_ucastnici', + 'verbose_name': '\xda\u010dast na konfe\u0159e', + 'verbose_name_plural': '\xda\u010dasti na konfe\u0159e', + }, + ), + migrations.AlterField( + model_name='problem', + name='typ', + field=models.CharField(default=b'uloha', max_length=32, verbose_name='typ probl\xe9mu', choices=[(b'uloha', '\xdaloha'), (b'tema', 'T\xe9ma'), (b'serial', 'Seri\xe1l'), (b'konfera', 'Konfera'), (b'org-clanek', 'Organiz\xe1torsk\xfd \u010dl\xe1nek'), (b'res-clanek', '\u0158e\u0161itelsk\xfd \u010dl\xe1nek')]), + ), + migrations.AddField( + model_name='konfera', + name='prispevek', + field=models.ForeignKey(related_name='konfery', on_delete=django.db.models.deletion.SET_NULL, verbose_name='p\u0159\xedsp\u011bvek do \u010d\xedsla', to='seminar.Problem', help_text='\xda\u010dastnick\xfd p\u0159\xedp\u011bvek o konfe\u0159e', null=True), + ), + migrations.AddField( + model_name='konfera', + name='soustredeni', + field=models.ForeignKey(related_name='konfery', on_delete=django.db.models.deletion.SET_NULL, verbose_name='soust\u0159ed\u011bn\xed', to='seminar.Soustredeni', null=True), + ), + migrations.AddField( + model_name='konfera', + name='ucastnici', + field=models.ManyToManyField(help_text='Seznam \xfa\u010dastn\xedk\u016f konfery', to='seminar.Resitel', verbose_name='\xfa\u010dastn\xedci konfery', through='seminar.Konfery_Ucastnici'), + ), + ] diff --git a/seminar/migrations/0042_auto_20161005_0847.py b/seminar/migrations/0042_auto_20161005_0847.py new file mode 100644 index 00000000..27930952 --- /dev/null +++ b/seminar/migrations/0042_auto_20161005_0847.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion +import seminar.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0041_konfery'), + ] + + operations = [ + migrations.AlterField( + model_name='konfera', + name='materialy', + field=models.FileField(help_text='Dal\u0161\xed materi\xe1ly ke konfe\u0159e zabalen\xe9 do jednoho souboru', upload_to=seminar.models.generate_filename_konfera, verbose_name='materialy', blank=True), + ), + migrations.AlterField( + model_name='konfera', + name='prezentace', + field=models.FileField(help_text='Prezentace nebo fotka posteru', upload_to=seminar.models.generate_filename_konfera, verbose_name='prezentace', blank=True), + ), + migrations.AlterField( + model_name='konfera', + name='prispevek', + field=models.ForeignKey(related_name='konfery', on_delete=django.db.models.deletion.SET_NULL, blank=True, to='seminar.Problem', help_text='\xda\u010dastnick\xfd p\u0159\xedp\u011bvek o konfe\u0159e', null=True, verbose_name='p\u0159\xedsp\u011bvek do \u010d\xedsla'), + ), + ] diff --git a/seminar/migrations/0042_cislo_faze.py b/seminar/migrations/0042_cislo_faze.py new file mode 100644 index 00000000..7d35ace5 --- /dev/null +++ b/seminar/migrations/0042_cislo_faze.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0041_konfery'), + ] + + operations = [ + migrations.AddField( + model_name='cislo', + name='faze', + field=models.CharField(default='admin', help_text='B\u011bhem f\xe1ze "admin" se obsah \u010d\xedsla vytv\xe1\u0159\xed (a p\u0159\xedpadn\u011b komentuje) ve webov\xe9m rozhran\xed. B\u011bhem f\xe1ze "tex" u\u017e obsah ve webov\xe9m rozhran\xed editovat nelze. N\xe1vrhy na \xfapravy se pak p\xed\u0161\xed do korekturov\xe1tka a zan\xe1\u0161ej\xed do gitu. Z n\u011bj se pak generuje verze pro web.', max_length=32, verbose_name='F\xe1ze vytv\xe1\u0159en\xed obsahu'), + ), + ] diff --git a/seminar/migrations/0043_uprava_faze.py b/seminar/migrations/0043_uprava_faze.py new file mode 100644 index 00000000..29e06e01 --- /dev/null +++ b/seminar/migrations/0043_uprava_faze.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0042_cislo_faze'), + ] + + operations = [ + migrations.AlterField( + model_name='cislo', + name='faze', + field=models.CharField(default='admin', help_text='B\u011bhem f\xe1ze "admin" se obsah \u010d\xedsla vytv\xe1\u0159\xed (a p\u0159\xedpadn\u011b komentuje) ve webov\xe9m rozhran\xed. B\u011bhem f\xe1ze "tex" u\u017e obsah ve webov\xe9m rozhran\xed editovat nelze. N\xe1vrhy na \xfapravy se pak p\xed\u0161\xed do korekturov\xe1tka a zan\xe1\u0161ej\xed do gitu. Z n\u011bj se pak generuje verze pro web.', max_length=32, verbose_name='F\xe1ze vytv\xe1\u0159en\xed obsahu', choices=[('admin', 'Zad\xe1v\xe1n\xed \xfaloh do webu'), ('tex', '\xdapravy \xfaloh v TeXov\xe9m repozit\xe1\u0159i')]), + ), + ] diff --git a/seminar/migrations/0044_uprava_faze.py b/seminar/migrations/0044_uprava_faze.py new file mode 100644 index 00000000..0d683d6c --- /dev/null +++ b/seminar/migrations/0044_uprava_faze.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0043_uprava_faze'), + ] + + operations = [ + migrations.AlterField( + model_name='cislo', + name='faze', + field=models.CharField(default='admin', help_text='B\u011bhem f\xe1ze "\xdapravy na webu" se obsah \u010d\xedsla vytv\xe1\u0159\xed (a p\u0159\xedpadn\u011b komentuje) ve webov\xe9m rozhran\xed. B\u011bhem f\xe1ze "\xdapravy na webu" u\u017e obsah ve webov\xe9m rozhran\xed editovat nelze a n\xe1vrhy na \xfapravy se p\xed\u0161\xed do korekturov\xe1tka a zan\xe1\u0161ej\xed do gitu. Z n\u011bj se pak generuje verze pro web.', max_length=32, verbose_name='F\xe1ze vytv\xe1\u0159en\xed obsahu', choices=[('admin', '\xdapravy na webu'), ('tex', '\xdapravy v TeXu')]), + ), + ] diff --git a/seminar/migrations/0045_cislo_pridani_faze_nahrano.py b/seminar/migrations/0045_cislo_pridani_faze_nahrano.py new file mode 100644 index 00000000..06ca8201 --- /dev/null +++ b/seminar/migrations/0045_cislo_pridani_faze_nahrano.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0044_uprava_faze'), + ] + + operations = [ + migrations.AlterField( + model_name='cislo', + name='faze', + field=models.CharField(default='admin', help_text='B\u011bhem f\xe1ze "\xdapravy na webu" se obsah \u010d\xedsla vytv\xe1\u0159\xed (a p\u0159\xedpadn\u011b komentuje) ve webov\xe9m rozhran\xed. B\u011bhem f\xe1ze "\xdapravy v TeXu" u\u017e obsah ve webov\xe9m rozhran\xed editovat nelze a n\xe1vrhy na \xfapravy se p\xed\u0161\xed do korekturov\xe1tka a zan\xe1\u0161ej\xed do gitu. Z n\u011bj se pak vygeneruje verze pro web a \u010d\xedslo se p\u0159epne do f\xe1ze "Nahr\xe1no na web", co\u017e jen znamen\xe1, \u017ee u\u017e nejde automaticky st\xe1hnout obsah pro zalo\u017een\xed \u010d\xedsla v TeXu.', max_length=32, verbose_name='F\xe1ze vytv\xe1\u0159en\xed obsahu', choices=[('admin', '\xdapravy na webu'), ('tex', '\xdapravy v TeXu'), ('tex', 'Nahr\xe1no na web')]), + ), + ] diff --git a/seminar/migrations/0046_merge.py b/seminar/migrations/0046_merge.py new file mode 100644 index 00000000..19352440 --- /dev/null +++ b/seminar/migrations/0046_merge.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0042_auto_20161005_0847'), + ('seminar', '0045_cislo_pridani_faze_nahrano'), + ] + + operations = [ + ] diff --git a/seminar/migrations/0047_auto_20170120_2118.py b/seminar/migrations/0047_auto_20170120_2118.py new file mode 100644 index 00000000..1876fe25 --- /dev/null +++ b/seminar/migrations/0047_auto_20170120_2118.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0046_merge'), + ] + + operations = [ + migrations.AlterField( + model_name='cislo', + name='faze', + field=models.CharField(default='admin', help_text='B\u011bhem f\xe1ze "\xdapravy na webu" se obsah \u010d\xedsla vytv\xe1\u0159\xed (a p\u0159\xedpadn\u011b komentuje) ve webov\xe9m rozhran\xed. B\u011bhem f\xe1ze "\xdapravy v TeXu" u\u017e obsah ve webov\xe9m rozhran\xed editovat nelze a n\xe1vrhy na \xfapravy se p\xed\u0161\xed do korekturov\xe1tka a zan\xe1\u0161ej\xed do gitu. Z n\u011bj se pak vygeneruje verze pro web a \u010d\xedslo se p\u0159epne do f\xe1ze "Nahr\xe1no na web", co\u017e jen znamen\xe1, \u017ee u\u017e nejde automaticky st\xe1hnout obsah pro zalo\u017een\xed \u010d\xedsla v TeXu.', max_length=32, verbose_name='F\xe1ze vytv\xe1\u0159en\xed obsahu', choices=[('admin', '\xdapravy na webu'), ('tex', '\xdapravy v TeXu'), ('nahrano', 'Nahr\xe1no na web')]), + ), + ] diff --git a/seminar/migrations/0048_add_cislo_datum_deadline_soustredeni.py b/seminar/migrations/0048_add_cislo_datum_deadline_soustredeni.py new file mode 100644 index 00000000..134a00a8 --- /dev/null +++ b/seminar/migrations/0048_add_cislo_datum_deadline_soustredeni.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0047_auto_20170120_2118'), + ] + + operations = [ + migrations.AddField( + model_name='cislo', + name='datum_deadline_soustredeni', + field=models.DateField(help_text='Datum pro p\u0159\xedjem \u0159e\u0161en\xed pro \xfa\u010dast na soust\u0159ed\u011bn\xed', null=True, verbose_name='datum deadline soust\u0159ed\u011bn\xed', blank=True), + ), + ] diff --git a/seminar/migrations/0049_auto_20190430_2354.py b/seminar/migrations/0049_auto_20190430_2354.py new file mode 100644 index 00000000..de2b1b0d --- /dev/null +++ b/seminar/migrations/0049_auto_20190430_2354.py @@ -0,0 +1,508 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-04-30 21:54 +from __future__ import unicode_literals + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone +import django_countries.fields +import imagekit.models.fields +import taggit.managers + + +class Migration(migrations.Migration): + atomic = False + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('seminar', '0048_add_cislo_datum_deadline_soustredeni'), + ] + + operations = [ + migrations.CreateModel( + name='Clanek', + fields=[ + ('problem_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.Problem')), + ], + options={ + 'verbose_name': 'Článek', + 'verbose_name_plural': 'Články', + 'db_table': 'seminar_clanky', + }, + bases=('seminar.problem',), + ), + migrations.CreateModel( + name='Hodnoceni', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('body', models.DecimalField(decimal_places=1, max_digits=8, verbose_name='body')), + ], + options={ + 'verbose_name': 'Hodnocení', + 'verbose_name_plural': 'Hodnocení', + 'db_table': 'seminar_hodnoceni', + }, + ), + migrations.CreateModel( + name='Obrazek', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('na_web', models.ImageField(blank=True, null=True, upload_to='obrazky/%Y/%m/%d/', verbose_name='obrázek na web')), + ('do_cisla_barevny', models.FileField(blank=True, help_text='Barevná verze obrázku do čísla', null=True, upload_to='obrazky/%Y/%m/%d/', verbose_name='barevný obrázek do čísla')), + ('do_cisla_cernobily', models.FileField(blank=True, help_text='Černobílá verze obrázku do čísla', null=True, upload_to='obrazky/%Y/%m/%d/', verbose_name='černobílý obrázek do čísla')), + ], + options={ + 'verbose_name': 'obrázek', + 'verbose_name_plural': 'obrázky', + 'db_table': 'seminar_obrazky', + }, + ), + 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(max_length=256, 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')), + ('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.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='uživatel')), + ], + options={ + 'verbose_name': 'Osoba', + 'verbose_name_plural': 'Osoby', + 'db_table': 'seminar_osoby', + 'ordering': ['prijmeni', 'jmeno'], + }, + ), + 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')), + ('osoba', models.ForeignKey(help_text='Které osobě či na jakou adresu se mají zasílat čísla', on_delete=django.db.models.deletion.CASCADE, to='seminar.Osoba', verbose_name='komu')), + ], + options={ + 'verbose_name': 'příjemce', + 'verbose_name_plural': 'příjemce', + 'db_table': 'seminar_prijemce', + }, + ), + migrations.CreateModel( + name='Reseni_Resitele', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ], + options={ + 'verbose_name': 'Řešení řešitelů', + 'verbose_name_plural': 'Řešení řešitelů', + 'db_table': 'seminar_reseni_resitele', + 'ordering': ['reseni', 'resitele'], + }, + ), + migrations.CreateModel( + name='Tema', + fields=[ + ('problem_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.Problem')), + ('tema_typ', models.CharField(choices=[('tema', 'Téma'), ('serial', 'Seriál')], default='tema', max_length=16, verbose_name='Typ tématu')), + ], + options={ + 'verbose_name': 'Téma', + 'verbose_name_plural': 'Témata', + 'db_table': 'seminar_temata', + }, + bases=('seminar.problem',), + ), + migrations.CreateModel( + name='Text', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('na_web', models.TextField(blank=True, help_text='Text ke zveřejnění na webu', verbose_name='text na web')), + ('do_cisla', models.TextField(blank=True, help_text='Text ke zveřejnění v čísle', verbose_name='text do čísla')), + ], + options={ + 'verbose_name': 'text', + 'verbose_name_plural': 'texty', + 'db_table': 'seminar_texty', + }, + ), + migrations.CreateModel( + name='Uloha', + fields=[ + ('problem_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.Problem')), + ('max_body', models.DecimalField(blank=True, decimal_places=1, max_digits=8, null=True, verbose_name='maximum bodů')), + ], + options={ + 'verbose_name': 'Úloha', + 'verbose_name_plural': 'Úlohy', + 'db_table': 'seminar_ulohy', + }, + bases=('seminar.problem',), + ), + migrations.AlterModelOptions( + name='novinky', + options={'ordering': ['-datum'], 'verbose_name': 'Novinka', 'verbose_name_plural': 'Novinky'}, + ), + migrations.AlterModelOptions( + name='prilohareseni', + options={'ordering': ['reseni', 'vytvoreno'], 'verbose_name': 'Příloha řešení', 'verbose_name_plural': 'Přílohy řešení'}, + ), + migrations.AlterModelOptions( + name='reseni', + options={'ordering': ['-cas_doruceni'], 'verbose_name': 'Řešení', 'verbose_name_plural': 'Řešení'}, + ), + migrations.AlterModelOptions( + name='resitel', + options={'ordering': ['osoba'], 'verbose_name': 'Řešitel', 'verbose_name_plural': 'Řešitelé'}, + ), + migrations.RenameField( + model_name='konfera', + old_name='org_poznamka', + new_name='poznamka', + ), + migrations.RenameField( + model_name='pohadka', + old_name='timestamp', + new_name='vytvoreno', + ), + migrations.RenameField( + model_name='reseni', + old_name='timestamp', + new_name='cas_doruceni', + ), + migrations.RenameField( + model_name='prilohareseni', + old_name='timestamp', + new_name='vytvoreno', + ), + migrations.RenameField( + model_name='problem', + old_name='text_org', + new_name='poznamka', + ), + migrations.RenameField( + model_name='problem', + old_name='timestamp', + new_name='vytvoreno', + ), + migrations.RenameField( + model_name='problem', + old_name='cislo_zadani', + new_name='cislo_zadani_old', + ), + migrations.RenameField( + model_name='problem', + old_name='cislo_reseni', + new_name='cislo_reseni_old', + ), + migrations.AddField( + model_name='konfera', + name='anotace', + field=models.TextField(blank=True, help_text='Popis, o čem bude konfera.', verbose_name='anotace'), + ), + migrations.AddField( + model_name='konfera', + name='reseni', + field=models.ForeignKey(blank=True, help_text='Účastnický přípěvek o konfeře', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='konfery', to='seminar.Reseni', verbose_name='článek ke konfeře'), + ), + migrations.AddField( + model_name='organizator', + name='organizuje_do', + field=models.DateTimeField(blank=True, null=True, verbose_name='Organizuje do'), + ), + migrations.AddField( + model_name='organizator', + name='organizuje_od', + field=models.DateTimeField(null=True,blank=True, verbose_name='Organizuje od'), + ), + migrations.AddField( + model_name='organizator', + name='skola', + field=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'), + ), + migrations.AddField( + model_name='organizator', + name='vytvoreno', + field=models.DateTimeField(blank=True, default=django.utils.timezone.now, editable=False, verbose_name='Vytvořeno'), + ), + migrations.AddField( + model_name='problem', + name='garant', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='garant_problemu_problem', to='seminar.Organizator', verbose_name='garant zadaného problému'), + ), + migrations.AddField( + model_name='problem', + name='nadproblem', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='nadproblem_problem', to='seminar.Problem', verbose_name='nadřazený problém'), + ), + migrations.AddField( + model_name='problem', + name='opravovatele', + field=models.ManyToManyField(blank=True, related_name='opravovatele_problem', to='seminar.Organizator', verbose_name='opravovatelé'), + ), + migrations.AddField( + model_name='reseni', + name='zverejneno', + field=models.BooleanField(default=False, help_text='Udává, zda je řešení zveřejněno', verbose_name='řešení zveřejněno'), + ), + migrations.AlterField( + model_name='cislo', + name='verejna_vysledkovka', + field=models.BooleanField(default=False, help_text='Je-li false u veřejného čísla,\t\t\t\t není výsledkovka zatím veřejná.', verbose_name='zveřejněna výsledkovka'), + ), + migrations.AlterField( + model_name='cislo', + name='verejne_db', + field=models.BooleanField(db_column='verejne', default=False, verbose_name='číslo zveřejněno'), + ), + migrations.AlterField( + model_name='konfera', + name='typ_prezentace', + field=models.CharField(choices=[('veletrh', 'Veletrh (postery)'), ('prezentace', 'Prezentace (přednáška)')], default='veletrh', max_length=16, verbose_name='typ prezentace'), + ), + migrations.RenameField( + model_name='novinky', + old_name='autor', + new_name='autor_old' + ), + migrations.AddField( + model_name='novinky', + name='autor', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Organizator', verbose_name='Autor novinky', null=True), + ), + migrations.AlterField( + model_name='novinky', + name='obrazek', + field=models.ImageField(blank=True, null=True, upload_to='image_novinky/%Y/%m/%d/', verbose_name='Obrázek'), + ), + migrations.AlterField( + model_name='novinky', + name='text', + field=models.TextField(blank=True, null=True, verbose_name='Text novinky'), + ), + migrations.AlterField( + model_name='novinky', + name='zverejneno', + field=models.BooleanField(default=False, verbose_name='Zveřejněno'), + ), + migrations.AlterField( + model_name='organizator', + name='strucny_popis_organizatora', + field=models.TextField(blank=True, null=True, verbose_name='Stručný popis organizátora'), + ), + migrations.AlterField( + model_name='organizator', + name='studuje', + field=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.'), + ), + migrations.RenameField( + model_name='pohadka', + old_name='autor', + new_name='autor_old' + ), + migrations.AddField( + model_name='pohadka', + name='autor', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='seminar.Organizator', verbose_name='Autor pohádky'), + ), + migrations.RenameField( + model_name='pohadka', + old_name='uloha', + new_name='uloha_old' + ), + migrations.AddField( + model_name='pohadka', + name='uloha', + field=models.ForeignKey(null=True,on_delete=django.db.models.deletion.CASCADE, related_name='pohadky', to='seminar.Uloha', verbose_name='Úloha'), + ), + migrations.RenameField( + model_name='problem', + old_name='autor', + new_name='autor_old', + ), + migrations.AddField( + model_name='problem', + name='autor', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='autor_problemu_problem', to='seminar.Organizator', verbose_name='autor problému'), + ), + migrations.AlterField( + model_name='problem', + name='kod', + field=models.CharField(blank=True, default='', help_text='Číslo/kód úlohy v čísle nebo kód tématu/článku/seriálu v ročníku', max_length=32, verbose_name='lokální kód'), + ), + migrations.AlterField( + model_name='problem', + name='stav', + field=models.CharField(choices=[('navrh', 'Návrh'), ('zadany', 'Zadaný'), ('vyreseny', 'Vyřešený'), ('smazany', 'Smazaný')], default='navrh', max_length=32, verbose_name='stav problému'), + ), + migrations.AlterField( + model_name='problem', + name='zamereni', + field=taggit.managers.TaggableManager(blank=True, help_text='Zaměření M/F/I/O problému, příp. další tagy', through='taggit.TaggedItem', to='taggit.Tag', verbose_name='zaměření'), + ), + migrations.AlterField( + model_name='reseni', + name='forma', + field=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í'), + ), + migrations.RenameField( + model_name='reseni', + old_name='problem', + new_name='problem_old', + ), + migrations.AlterField( + model_name='resitel', + name='zasilat', + field=models.CharField(choices=[('domu', 'Domů'), ('do_skoly', 'Do školy'), ('nikam', 'Nikam')], default='domu', max_length=32, verbose_name='kam zasílat'), + ), + migrations.AlterField( + model_name='rocnik', + name='exportovat', + field=models.BooleanField(db_column='exportovat', default=False, help_text='Exportuje se jen podle tohoto flagu (ne veřejnosti), a to jen čísla s veřejnou výsledkovkou', verbose_name='export do AESOPa'), + ), + migrations.AlterField( + model_name='skola', + name='aesop_id', + field=models.CharField(blank=True, default='', help_text='Aesopi ID typu "izo:..." nebo "aesop:..."', max_length=32, verbose_name='Aesop ID'), + ), + migrations.AlterField( + model_name='skola', + name='kratky_nazev', + field=models.CharField(blank=True, help_text='Zkrácený název pro zobrazení ve výsledkovce', max_length=256, verbose_name='zkrácený název'), + ), + migrations.AlterField( + model_name='skola', + name='stat', + field=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'), + ), + migrations.AlterField( + model_name='soustredeni', + name='exportovat', + field=models.BooleanField(db_column='exportovat', default=False, help_text='Exportuje se jen podle tohoto flagu (ne veřejnosti)', verbose_name='export do AESOPa'), + ), + migrations.AlterField( + model_name='soustredeni', + name='misto', + field=models.CharField(blank=True, default='', help_text='Místo (název obce, volitelně též objektu', max_length=256, verbose_name='místo soustředění'), + ), + migrations.AlterField( + model_name='soustredeni', + name='text', + field=models.TextField(blank=True, default='', verbose_name='text k soustředění (HTML)'), + ), + migrations.AlterField( + model_name='soustredeni', + name='typ', + field=models.CharField(choices=[('jarni', 'Jarní soustředění'), ('podzimni', 'Podzimní soustředění'), ('vikend', 'Víkendový sraz')], default='podzimni', max_length=16, verbose_name='typ akce'), + ), + migrations.AlterField( + model_name='soustredeni', + name='verejne_db', + field=models.BooleanField(db_column='verejne', default=False, verbose_name='soustředění zveřejněno'), + ), + migrations.AlterModelTable( + name='problem', + table='seminar_problemy', + ), + migrations.AddField( + model_name='uloha', + name='cislo_deadline', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='deadlinove_ulohy', to='seminar.Cislo', verbose_name='číslo deadlinu'), + ), + migrations.AddField( + model_name='uloha', + name='cislo_reseni', + field=models.ForeignKey(blank=True, help_text='Číslo s řešením úlohy, jen pro úlohy', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='resene_ulohy', to='seminar.Cislo', verbose_name='číslo řešení'), + ), + migrations.AddField( + model_name='uloha', + name='cislo_zadani', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='zadane_ulohy', to='seminar.Cislo', verbose_name='číslo zadání'), + ), + migrations.AddField( + model_name='tema', + name='rocnik', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='seminar.Rocnik', verbose_name='ročník'), + ), + migrations.AddField( + model_name='reseni_resitele', + name='reseni', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Reseni', verbose_name='řešení'), + ), + migrations.AddField( + model_name='reseni_resitele', + name='resitele', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Resitel', verbose_name='řešitel'), + ), + migrations.AddField( + model_name='obrazek', + name='text', + field=models.ForeignKey(help_text='text, ve kterém se obrázek vyskytuje', on_delete=django.db.models.deletion.CASCADE, to='seminar.Text', verbose_name='text'), + ), + migrations.AddField( + model_name='hodnoceni', + name='cislo_body', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='hodnoceni', to='seminar.Cislo', verbose_name='číslo pro body'), + ), + migrations.AddField( + model_name='hodnoceni', + name='problem', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Problem', verbose_name='problém'), + ), + migrations.AddField( + model_name='hodnoceni', + name='reseni', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Reseni', verbose_name='řešení'), + ), + migrations.AddField( + model_name='clanek', + name='cislo', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='seminar.Cislo', verbose_name='číslo'), + ), + migrations.AddField( + model_name='organizator', + name='osoba', + field=models.ForeignKey(help_text='osobní údaje organizátora', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='org', to='seminar.Osoba', verbose_name='osoba'), + ), + migrations.AddField( + model_name='reseni', + name='resitele', + field=models.ManyToManyField(help_text='Seznam autorů řešení', through='seminar.Reseni_Resitele', to='seminar.Resitel', verbose_name='autoři řešení'), + ), + migrations.AddField( + model_name='reseni', + name='text_cely', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='reseni_cely_set', to='seminar.Text', verbose_name='Plná verze textu řešení'), + ), + migrations.AddField( + model_name='reseni', + name='text_zkraceny', + field=models.ManyToManyField(help_text='Seznam úryvků z řešení', related_name='reseni_zkraceny_set', to='seminar.Text', verbose_name='zkrácené verze řešení'), + ), + migrations.AddField( + model_name='resitel', + name='osoba', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='seminar.Osoba', verbose_name='osoba'), + ), + migrations.AddField( + model_name='skola', + name='kontaktni_osoba', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='seminar.Osoba', verbose_name='Kontaktní osoba'), + ), + migrations.AddField( + model_name='reseni', + name='problem', + field=models.ManyToManyField(help_text='Problém', through='seminar.Hodnoceni', to='seminar.Problem', verbose_name='problém'), + ), + ] diff --git a/seminar/migrations/0050_auto_20190510_2228.py b/seminar/migrations/0050_auto_20190510_2228.py new file mode 100644 index 00000000..c6ed9f66 --- /dev/null +++ b/seminar/migrations/0050_auto_20190510_2228.py @@ -0,0 +1,191 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-10 20:28 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0049_auto_20190430_2354'), + ] + + operations = [ + migrations.AlterField( + model_name='konfera', + name='reseni', + field=models.OneToOneField(blank=True, help_text='Účastnický přípěvek o konfeře', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='konfery', to='seminar.Reseni', verbose_name='článek ke konfeře'), + ), + migrations.AlterField( + model_name='organizator', + name='osoba', + field=models.OneToOneField(help_text='osobní údaje organizátora', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='org', to='seminar.Osoba', verbose_name='osoba'), + ), + migrations.AlterField( + model_name='reseni', + name='text_cely', + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='reseni_cely_set', to='seminar.Text', verbose_name='Plná verze textu řešení'), + ), + migrations.AlterField( + model_name='resitel', + name='osoba', + field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.CASCADE, to='seminar.Osoba', verbose_name='osoba'), + ), + migrations.CreateModel( + name='TreeNode', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ], + options={ + 'verbose_name': 'TreeNode', + 'verbose_name_plural': 'TreeNody', + 'db_table': 'seminar_nodes_treenode', + }, + ), + migrations.CreateModel( + name='CisloNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('cislo', models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, to='seminar.Cislo', verbose_name='číslo')), + ], + options={ + 'verbose_name': 'Číslo (Node)', + 'verbose_name_plural': 'Čísla (Node)', + 'db_table': 'seminar_nodes_cislo', + }, + bases=('seminar.treenode',), + ), + migrations.CreateModel( + name='ClanekNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('clanek', models.OneToOneField(null=True, on_delete=django.db.models.deletion.PROTECT, to='seminar.Clanek', verbose_name='článek')), + ], + options={ + 'verbose_name': 'Článek (Node)', + 'verbose_name_plural': 'Články (Node)', + 'db_table': 'seminar_nodes_clanek', + }, + bases=('seminar.treenode',), + ), + migrations.CreateModel( + name='KonferaNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('konfera', models.OneToOneField(null=True, on_delete=django.db.models.deletion.PROTECT, to='seminar.Konfera', verbose_name='konfera')), + ], + options={ + 'verbose_name': 'Konfera (Node)', + 'verbose_name_plural': 'Konfery (Node)', + 'db_table': 'seminar_nodes_konfera', + }, + bases=('seminar.treenode',), + ), + migrations.CreateModel( + name='MezicisloNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ], + options={ + 'verbose_name': 'Mezičíslo (Node)', + 'verbose_name_plural': 'Mezičísla (Node)', + 'db_table': 'seminar_nodes_mezicislo', + }, + bases=('seminar.treenode',), + ), + migrations.CreateModel( + name='RocnikNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('rocnik', models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, to='seminar.Rocnik', verbose_name='ročník')), + ], + options={ + 'verbose_name': 'Ročník (Node)', + 'verbose_name_plural': 'Ročníky (Node)', + 'db_table': 'seminar_nodes_rocnik', + }, + bases=('seminar.treenode',), + ), + migrations.CreateModel( + name='TemaVCisleNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('tema', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Tema', verbose_name='téma v čísle')), + ], + options={ + 'verbose_name': 'Téma v čísle (Node)', + 'verbose_name_plural': 'Témata v čísle (Node)', + 'db_table': 'seminar_nodes_temavcisle', + }, + bases=('seminar.treenode',), + ), + migrations.CreateModel( + name='TextNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('text', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Text', verbose_name='text')), + ], + options={ + 'verbose_name': 'Text (Node)', + 'verbose_name_plural': 'Text (Node)', + 'db_table': 'seminar_nodes_obsah', + }, + bases=('seminar.treenode',), + ), + migrations.CreateModel( + name='UlohaVzorakNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('uloha', models.OneToOneField(null=True, on_delete=django.db.models.deletion.PROTECT, to='seminar.Uloha', verbose_name='úloha')), + ], + options={ + 'verbose_name': 'Vzorák úlohy (Node)', + 'verbose_name_plural': 'Vzoráky úloh (Node)', + 'db_table': 'seminar_nodes_uloha_vzorak', + }, + bases=('seminar.treenode',), + ), + migrations.CreateModel( + name='UlohaZadaniNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('uloha', models.OneToOneField(null=True, on_delete=django.db.models.deletion.PROTECT, to='seminar.Uloha', verbose_name='úloha')), + ], + options={ + 'verbose_name': 'Zadání úlohy (Node)', + 'verbose_name_plural': 'Zadání úloh (Node)', + 'db_table': 'seminar_nodes_uloha_zadani', + }, + bases=('seminar.treenode',), + ), + migrations.CreateModel( + name='PohadkaNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('pohadka', models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, to='seminar.Pohadka', verbose_name='pohádka')), + ], + options={ + 'verbose_name': 'Pohádka (Node)', + 'verbose_name_plural': 'Pohádky (Node)', + 'db_table': 'seminar_nodes_pohadka', + }, + bases=('seminar.treenode',), + ), + migrations.AddField( + model_name='treenode', + name='first_child', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='seminar.TreeNode', verbose_name='první potomek'), + ), + migrations.AddField( + model_name='treenode', + name='root', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='potomci_set', to='seminar.TreeNode', verbose_name='kořen stromu'), + ), + migrations.AddField( + model_name='treenode', + name='succ', + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='prev', to='seminar.TreeNode', verbose_name='další element na stejné úrovni'), + ), + ] diff --git a/seminar/migrations/0051_resitel_to_osoba.py b/seminar/migrations/0051_resitel_to_osoba.py new file mode 100644 index 00000000..17237bd0 --- /dev/null +++ b/seminar/migrations/0051_resitel_to_osoba.py @@ -0,0 +1,89 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-10 20:44 +from __future__ import unicode_literals + +from django.db import migrations + +def resitel_to_osoba(apps,schema_editor): + Resitel = apps.get_model('seminar','Resitel') + Osoba = apps.get_model('seminar','Osoba') + for r in Resitel.objects.all(): + o = Osoba() + o.datum_narozeni = r.datum_narozeni + o.datum_registrace = r.datum_prihlaseni + o.datum_souhlasu_udaje = r.datum_souhlasu_udaje + o.datum_souhlasu_zasilani = r.datum_souhlasu_zasilani + o.email = r.email + o.jmeno = r.jmeno + o.mesto = r.mesto + o.pohlavi_muz = r.pohlavi_muz + o.prijmeni = r.prijmeni + o.psc = r.psc + o.stat = r.stat + o.telefon = r.telefon + o.ulice = r.ulice + o.user = r.user + if o.user: + u = o.user + if u.first_name: + if not o.jmeno: + o.jmeno = u.first_name + u.first_name = 'Použij osobu!' + elif o.jmeno == u.first_name: + u.first_name = 'Použij osobu!' + else: + raise ValueError('jmeno a first_name rozdílné: "{}" vs. "{}"'.format(o.jmeno, u.first_name)) + if u.last_name: + if not o.prijmeni: + o.prijmeni = u.last_name + u.last_name = 'Použij osobu!' + elif o.prijmeni == u.last_name: + u.last_name = 'Použij osobu!' + else: + raise ValueError('prijmeni a last_name rozdílné: "{}" vs. "{}"'.format(o.prijmeni, u.last_name)) + if u.email: + if not o.email: + o.email = u.email + u.email = 'Použij osobu!' + elif o.email == u.email: + u.email = 'Použij osobu!' + else: + raise ValueError('o.email a u.email rozdílné: "{}" vs. "{}"'.format(o.email, u.email)) + u.save() + + + o.save() + r.osoba = o + r.save() + +def osoba_to_resitel(apps, schema_editor): + Resitel = apps.get_model('seminar','Resitel') + Osoba = apps.get_model('seminar','Osoba') + for r in Resitel.objects.all(): + o = r.osoba + r.datum_narozeni = o.datum_narozeni + r.datum_prihlaseni = o.datum_registrace + r.datum_souhlasu_udaje = o.datum_souhlasu_udaje + r.datum_souhlasu_zasilani = o.datum_souhlasu_zasilani + r.email = o.email + r.jmeno = o.jmeno + r.mesto = o.mesto + r.pohlavi_muz = o.pohlavi_muz + r.prijmeni = o.prijmeni + r.psc = o.psc + r.stat = o.stat + r.telefon = o.telefon + r.ulice = o.ulice + r.user = o.user + r.save() + o.delete() + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0050_auto_20190510_2228'), + ] + + operations = [ + migrations.RunPython(resitel_to_osoba, osoba_to_resitel), + ] diff --git a/seminar/migrations/0052_user_to_organizator.py b/seminar/migrations/0052_user_to_organizator.py new file mode 100644 index 00000000..d52e29ca --- /dev/null +++ b/seminar/migrations/0052_user_to_organizator.py @@ -0,0 +1,82 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.15 on 2019-05-16 20:59 +from __future__ import unicode_literals + +from django.db import migrations + +def spoj_k_organizatorum_osoby(apps, scema_editor): + Organizator = apps.get_model('seminar', 'Organizator') + Resitel = apps.get_model('seminar', 'Resitel') + Osoba = apps.get_model('seminar', 'Osoba') + for org in Organizator.objects.all(): + + # Spárování organizátora s osobou + user = org.user + resitele = Resitel.objects.filter(user=user) + if resitele.count() != 0: + osoba = resitele.first().osoba + else: + osoba = Osoba(user=user) + + # Přesun informací z usera do osoby + # pro řešitele již v minule migraci + osoba.jmeno = user.first_name + osoba.prijmeni = user.last_name + osoba.email = user.email + user.jmeno = "Použij osobu!" + user.prijmeni = "Použij osobu!" + user.email = "Použij osobu!" + user.save() + + # Přesun informací z organizátora do jeho osoby + osoba.prezdivka = org.prezdivka if org.prezdivka is not None else '' + osoba.foto = org.foto + + # Všechno uložit + osoba.save() + org.osoba = osoba + org.save() + +def fix_problem(apps, schema_editor): + Problem = apps.get_model('seminar', 'Problem') + Organizator = apps.get_model('seminar', 'Organizator') + for pr in Problem.objects.all(): + if pr.autor_old is not None: + pr.autor = Organizator.objects.filter(osoba__user=pr.autor_old).first() + else: + pr.autor = None + if pr.opravovatel is not None: + pr.opravovatele.add(Organizator.objects.filter(osoba__user=pr.opravovatel).first()) + pr.save() + +def fix_pohadka(apps, schema_editor): + Pohadka = apps.get_model('seminar', 'Pohadka') + Organizator = apps.get_model('seminar', 'Organizator') + for poh in Pohadka.objects.all(): + if poh.autor_old is not None: + poh.autor = Organizator.objects.filter(osoba__user=poh.autor_old).first() + else: + poh.autor = None + poh.save() + +def fix_novinka(apps, schema_editor): + Novinky = apps.get_model('seminar', 'Novinky') + Organizator = apps.get_model('seminar', 'Organizator') + for nov in Novinky.objects.all(): + nov.autor = Organizator.objects.filter(osoba__user=nov.autor_old).first() + nov.save() + + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0051_resitel_to_osoba'), + ] + + operations = [ + migrations.RunPython(spoj_k_organizatorum_osoby), + migrations.RunPython(fix_problem), + migrations.RunPython(fix_pohadka), + migrations.RunPython(fix_novinka), + ] diff --git a/seminar/migrations/0053_organizator_organizuje_od_do.py b/seminar/migrations/0053_organizator_organizuje_od_do.py new file mode 100644 index 00000000..b94e8032 --- /dev/null +++ b/seminar/migrations/0053_organizator_organizuje_od_do.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-16 21:26 +from __future__ import unicode_literals + +import datetime as dt +from django.db import migrations + +def rok_to_datetime(apps,schema_editor): + Organizator = apps.get_model('seminar','Organizator') + for o in Organizator.objects.all(): + rok = o.organizuje_od_roku + if rok: + o.organizuje_od = dt.datetime(rok,1,1) + rok = o.organizuje_do_roku + if rok: + o.organizuje_do = dt.datetime(rok,12,31) + o.save() + +def datetime_to_rok(apps,schema_editor): + Organizator = apps.get_model('seminar','Organizator') + for o in Organizator.objects.all(): + o.organizuje_od_roku = o.organizuje_od.year + o.organizuje_do_roku = o.organizuje_do.year + o.save() + + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0052_user_to_organizator'), + ] + + operations = [ + migrations.RunPython(rok_to_datetime, datetime_to_rok), + ] diff --git a/seminar/migrations/0055_smazat_nemigrovane_zastarale_veci.py b/seminar/migrations/0055_smazat_nemigrovane_zastarale_veci.py new file mode 100644 index 00000000..1b6f95f4 --- /dev/null +++ b/seminar/migrations/0055_smazat_nemigrovane_zastarale_veci.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-23 20:16 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0053_organizator_organizuje_od_do'), + ] + + operations = [ + migrations.RemoveField( + model_name='prispevek', + name='problem', + ), + migrations.RemoveField( + model_name='prispevek', + name='reseni', + ), + migrations.DeleteModel( + name='ProblemNavrh', + ), + migrations.DeleteModel( + name='ProblemZadany', + ), + migrations.RemoveField( + model_name='cislo', + name='faze', + ), + migrations.RemoveField( + model_name='konfera', + name='popis', + ), + migrations.RemoveField( + model_name='konfera', + name='prispevek', + ), + migrations.RemoveField( + model_name='problem', + name='import_dakos_id', + ), + migrations.RemoveField( + model_name='resitel', + name='import_mamoper_id', + ), + migrations.RemoveField( + model_name='skola', + name='import_dakos_id', + ), + migrations.DeleteModel( + name='Prispevek', + ), + ] diff --git a/seminar/migrations/0056_vrcholy_pro_rocniky_a_cisla.py b/seminar/migrations/0056_vrcholy_pro_rocniky_a_cisla.py new file mode 100644 index 00000000..024400a4 --- /dev/null +++ b/seminar/migrations/0056_vrcholy_pro_rocniky_a_cisla.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-23 21:54 +from __future__ import unicode_literals + +from django.db import migrations + +def generuj_RocnikNody_a_CisloNody(apps,schema_editor): + Rocnik = apps.get_model('seminar', 'Rocnik') + RocnikNode = apps.get_model('seminar', 'RocnikNode') + Cislo = apps.get_model('seminar', 'Cislo') + CisloNode = apps.get_model('seminar', 'CisloNode') + + last_rn = None # last_* slouží k navázání následníků + for r in Rocnik.objects.all(): + rn = RocnikNode.objects.create(rocnik=r) + rn.save() + rn.root = rn + rn.save() + if last_rn: + last_rn.succ = rn + last_rn.save() + last_rn = rn + + last_cn = None + for c in Cislo.objects.filter(rocnik=r): + cn = CisloNode.objects.create(cislo=c, root=rn) + cn.save() + if last_cn: # Jsme něčí následník + last_cn.succ = cn + last_cn.save() + else: # Jsme první v řadě, takže se musíme přidat jako first_child RočníkNodu + rn.first_child = cn + rn.save() + last_cn = cn + + + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0055_smazat_nemigrovane_zastarale_veci'), + ] + + operations = [ + migrations.RunPython(generuj_RocnikNody_a_CisloNody), + ] diff --git a/seminar/migrations/0057_reseni_to_reseni_hodnoceni.py b/seminar/migrations/0057_reseni_to_reseni_hodnoceni.py new file mode 100644 index 00000000..b3f0405b --- /dev/null +++ b/seminar/migrations/0057_reseni_to_reseni_hodnoceni.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-28 21:46 +from __future__ import unicode_literals + +from django.db import migrations + +def reseni_to_Reseni(apps, schema_editor): + Reseni = apps.get_model('seminar','Reseni') + Reseni_Resitele = apps.get_model('seminar','Reseni_Resitele') + Hodnoceni = apps.get_model('seminar','Hodnoceni') + + for r in Reseni.objects.all(): + rr = Reseni_Resitele.objects.create(resitele = r.resitel, reseni=r) + if r.body == None: + print("!!!!!!!!!!!!!!!") + print(r.id,r) + print("!!!!!!!!!!!!!!!") + else: + h = Hodnoceni.objects.create( + body=r.body, + cislo_body = r.cislo_body, + problem = r.problem_old, + reseni = r) + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0056_vrcholy_pro_rocniky_a_cisla'), + ] + + operations = [ + migrations.RunPython(reseni_to_Reseni) + ] diff --git a/seminar/migrations/0058_problem_to_uloha_tema_clanek.py b/seminar/migrations/0058_problem_to_uloha_tema_clanek.py new file mode 100644 index 00000000..333f5453 --- /dev/null +++ b/seminar/migrations/0058_problem_to_uloha_tema_clanek.py @@ -0,0 +1,161 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-17 17:44 +from __future__ import unicode_literals + +from django.db import migrations + +from django.db.models import Q + +def poskladej_strom(apps, rodic, *texty): + Text = apps.get_model('seminar', 'Text') + TextNode = apps.get_model('seminar', 'TextNode') + if not rodic: + raise ValueError("Rodič musí být definovaný") + + uz_ma_deti = False + tn = None + for txt in texty: + if not txt: + continue + # Přidej do stromu: + textobj = Text.objects.create(na_web = txt) + textobj.save() + textnode = TextNode.objects.create(text = textobj) + textnode.save() + if not uz_ma_deti: + rodic.first_child = textnode + rodic.save() + tn = rodic.first_child + uz_ma_deti = True + else: + tn.succ = textnode + tn.save() + tn = tn.succ + +def uloha_to_Uloha(apps,schema_editor): + Problem = apps.get_model('seminar', 'Problem') + Uloha = apps.get_model('seminar', 'Uloha') + Text = apps.get_model('seminar', 'Text') + UlohaZadaniNode = apps.get_model('seminar', 'UlohaZadaniNode') + UlohaVzorakNode = apps.get_model('seminar', 'UlohaVzorakNode') + TextNode = apps.get_model('seminar', 'TextNode') + + ulohy = Problem.objects.filter(typ = 'uloha') + for uold in ulohy: + unew = Uloha.objects.create( + problem_ptr = uold, + # Zakomentované fieldy by se už měly nacházet v příslušném problému + #nazev = uold.nazev, + #stav = uold.stav, + #zamereni = uold.zamereni, + #poznamka = uold.poznamka, + #autor = uold.autor, + #kod = uold.kod, + cislo_zadani = uold.cislo_zadani_old, + cislo_reseni = uold.cislo_reseni_old, + max_body = uold.body, + #vytvoreno = uold.vytvoreno, + ) +# unew.opravovatele.add(*uold.opravovatele.all()) + unew.save() + + # Nody: + zadani_node = UlohaZadaniNode.objects.create(uloha = unew) + poskladej_strom(apps, zadani_node, uold.text_zadani) + zadani_node.save() + vzorak_node = UlohaVzorakNode.objects.create(uloha = unew) + poskladej_strom(apps, vzorak_node, uold.text_reseni) + vzorak_node.save() + +def konfery_rucne(apps, schema_editor): + # Tohle dělat nebudu, máme aktuálně celou jednu. Ale "Errors should never pass silently" + Problem = apps.get_model('seminar', 'Problem') + pocet_konfer = Problem.objects.filter(typ = 'konfera').count() + if pocet_konfer > 0: + raise NotImplementedError("Zkonvertuj {} konfer na objekt Konfera ručně, prosím".format(pocet_konfer)) + +def clanek_to_Clanek(apps,schema_editor): + Problem = apps.get_model('seminar', 'Problem') + Clanek = apps.get_model('seminar', 'Clanek') + ClanekNode = apps.get_model('seminar', 'ClanekNode') + Text = apps.get_model('seminar', 'Text') + TextNode = apps.get_model('seminar', 'TextNode') + + clanky = Problem.objects.filter(Q(typ='org-clanek') | Q(typ='res-clanek')) + for cl in clanky: + # Vybereme vhodné číslo pro článek z čísla zadání a čísla řešení: + if cl.cislo_zadani_old is None: + cislo = cl.cislo_reseni_old + elif cl.cislo_reseni_old is None: + cislo = cl.cislo_zadani_old + elif cl.cislo_reseni_old == cl.cislo_zadani_old: + cislo = cl.cislo_zadani_old + else: + raise ValueError("Různá čísla zadání a řešení u článku! (Článek: {})".format(cl.nazev)) + + clnew = Clanek.objects.create( + problem_ptr = cl, + # Problém by nemělo být potřeba upravovat + cislo = cislo, + # Body ignorujeme, protože už jsou v hodnocení + ) + clnew.save() + + # Aktuálně nemáme v modelu informaci o tom, jestli je to org-článek + # nebo řešitelský článek. Aby se neztratila informace, poznamenám to do + # poznámky. + cl.poznamka += "\nTyp:\t{}".format(cl.typ) + cl.save() + + # Vyrobíme nody: + clnode = ClanekNode(clanek = clnew) + poskladej_strom(apps, clnode, cl.text_zadani, cl.text_reseni) + clnode.save() + +def tema_to_Tema(apps, schema_editor): + Problem = apps.get_model('seminar', 'Problem') + Tema = apps.get_model('seminar', 'Tema') + TemaVCisleNode = apps.get_model('seminar', 'TemaVCisleNode') + Text = apps.get_model('seminar', 'Text') + TextNode = apps.get_model('seminar', 'TextNode') + + temata = Problem.objects.filter(Q(typ = 'tema') | Q(typ='serial')) + for t in temata: + # Vymyslíme správně ročník: + if t.cislo_zadani_old is None and t.cislo_reseni_old is None: + rocnik = None + elif t.cislo_zadani_old is None: + rocnik = t.cislo_reseni_old.rocnik + elif t.cislo_reseni_old is None: + rocnik = t.cislo_zadani_old.rocnik + elif t.cislo_reseni_old.rocnik == t.cislo_zadani_old.rocnik: + rocnik = t.cislo_zadani_old.rocnik + else: + raise ValueError("Nelze mít téma přes více ročníků! (Téma: {}".format(t.nazev)) + + tnew = Tema.objects.create( + problem_ptr = t, + tema_typ = t.typ, + rocnik = rocnik, + ) + tnew.save() + + # Nody: + tnode = TemaVCisleNode(tema = tnew) + poskladej_strom(apps, tnode, t.text_zadani, t.text_reseni) + tnode.save() + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0057_reseni_to_reseni_hodnoceni'), + ] + + operations = [ + # ashes to Ashes, dust to Dust.... + migrations.RunPython(uloha_to_Uloha), + migrations.RunPython(tema_to_Tema), + migrations.RunPython(clanek_to_Clanek), + migrations.RunPython(konfery_rucne), + ] diff --git a/seminar/migrations/0059_vytvorit_pohadkanode.py b/seminar/migrations/0059_vytvorit_pohadkanode.py new file mode 100644 index 00000000..7ff7c655 --- /dev/null +++ b/seminar/migrations/0059_vytvorit_pohadkanode.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-29 03:26 +from __future__ import unicode_literals + +from django.db import migrations + +def vytvor_pohadkanode(apps, schema_editor): + Pohadka = apps.get_model('seminar', 'Pohadka') + PohadkaNode = apps.get_model('seminar', 'PohadkaNode') + Text = apps.get_model('seminar', 'Text') + TextNode = apps.get_model('seminar', 'TextNode') + + for p in Pohadka.objects.all(): + t = Text.objects.create(na_web = p.text) + t.save() + tn = TextNode.objects.create(text = t) + tn.save() + pn = PohadkaNode.objects.create(pohadka = p, first_child = tn) + pn.save() + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0058_problem_to_uloha_tema_clanek'), + ] + + operations = [ + migrations.RunPython(vytvor_pohadkanode), + ] diff --git a/seminar/migrations/0060_spoj_stromy.py b/seminar/migrations/0060_spoj_stromy.py new file mode 100644 index 00000000..a94caf48 --- /dev/null +++ b/seminar/migrations/0060_spoj_stromy.py @@ -0,0 +1,112 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-29 03:26 +from __future__ import unicode_literals + +from django.db import migrations + +from django.db.models import Q + +def pridej_potomka(rodic, potomek): + # Daný vrchol bude posledním potomkem rodiče + uz_ma_deti = False + posledni = None + + # Přidávaný potomek by neměl mít následovníka -- přidáváme potomka, ne podles. + if potomek.succ: + raise ValueError("Potomek má následovníka, to je velmi podezřelé!") + + # Najdeme aktuálně posledního potomka: + if rodic.first_child: + uz_ma_deti = True + posledni = rodic.first_child + while posledni.succ: + posledni = posledni.succ + + # Nastavíme kořen: + potomek.root = rodic.root + potomek.save() + + # Připojíme vrchol: + if uz_ma_deti: + posledni.succ = potomek + posledni.save() + else: + rodic.first_child = potomek + rodic.save() + +def pokacej_les(apps, schema_editor): + # Teď je potřeba všechny TreeNody příslušející k zadaným problémům připojit + # do hlavního stromu + # Tohle je jednoduchá verze: nejdřív témátka a seriály, pak úložky a pohádky, + # pak články a konfery, pak vzoráky, všechno setříděné podle kódu (FIXME?) + + # Kopírování je častým zdrojem chyb! + Cislo = apps.get_model('seminar', 'Cislo') + Tema = apps.get_model('seminar', 'Tema') + Konfera = apps.get_model('seminar', 'Konfera') + Clanek = apps.get_model('seminar', 'Clanek') + Uloha = apps.get_model('seminar', 'Uloha') + Problem = apps.get_model('seminar', 'Problem') + Pohadka = apps.get_model('seminar', 'Pohadka') + + for c in Cislo.objects.all().reverse(): + cnode = c.cislonode + + # Témata a seriály: + relevantni_temata = Tema.objects.filter(Q(cislo_zadani_old = c) | Q(cislo_reseni_old = c)).order_by('kod') + # Téma dáme do prvního čísla, kde se vyskytne + for t in relevantni_temata: + tnode = t.temavcislenode + if t.cislo_zadani_old and t.cislo_reseni_old: + assert(t.cislo_zadani_old <= t.cislo_reseni_old) + if t.cislo_reseni_old == c: + # Už by mělo být přidané do čísla zadání + continue + else: + # Patří sem (buď je to jediné číslo, nebo je to číslo zadání) + pridej_potomka(cnode, tnode) + + # Úložky (zadání) a pohádky + for u in Uloha.objects.filter(cislo_zadani = c).order_by('kod'): + unode = u.ulohazadaninode + pohadky_pred = Pohadka.objects.filter(uloha_old = u.problem_ptr, pred = True) + pohadky_po = Pohadka.objects.filter(uloha_old = u.problem_ptr, pred = False) + for p in pohadky_pred: + pnode = p.pohadkanode + pridej_potomka(cnode, pnode) + pridej_potomka(cnode, unode) + for p in pohadky_po: + pnode = p.pohadkanode + pridej_potomka(cnode, pnode) + + # Pohádky, které nejsou u úlohy jsou špatně: + if Pohadka.objects.exclude(uloha_old__typ='uloha').count(): + raise ValueError("Existuje pohádka, která není u úlohy") + + # Články + for cl in Clanek.objects.filter(cislo = c).order_by('kod'): + clnode = cl.claneknode + pridej_potomka(cnode, clnode) + + # Konfery + for k in Konfera.objects.all(): + knode = k.konferanode + if k.reseni and knode.root is None: + # Takováhle konfera nejspíš neexistuje + raise NotImplementedError("Konfery neumím zapojit do stromu") + + # Vzoráky + for u in Uloha.objects.filter(cislo_reseni = c).order_by('kod'): + unode = u.ulohavzoraknode + pridej_potomka(cnode, unode) + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0059_vytvorit_pohadkanode'), + ] + + operations = [ + migrations.RunPython(pokacej_les), + ] diff --git a/seminar/migrations/0061_kill_frankenstein.py b/seminar/migrations/0061_kill_frankenstein.py new file mode 100644 index 00000000..0a367edf --- /dev/null +++ b/seminar/migrations/0061_kill_frankenstein.py @@ -0,0 +1,153 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-29 03:29 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0060_spoj_stromy'), + ] + + operations = [ + migrations.RemoveField( + model_name='novinky', + name='autor_old', + ), + migrations.RemoveField( + model_name='organizator', + name='foto', + ), + migrations.RemoveField( + model_name='organizator', + name='organizuje_do_roku', + ), + migrations.RemoveField( + model_name='organizator', + name='organizuje_od_roku', + ), + migrations.RemoveField( + model_name='organizator', + name='prezdivka', + ), + migrations.RemoveField( + model_name='organizator', + name='user', + ), + migrations.RemoveField( + model_name='pohadka', + name='autor_old', + ), + migrations.RemoveField( + model_name='pohadka', + name='uloha_old', + ), + migrations.RemoveField( + model_name='problem', + name='autor_old', + ), + migrations.RemoveField( + model_name='problem', + name='body', + ), + migrations.RemoveField( + model_name='problem', + name='cislo_reseni_old', + ), + migrations.RemoveField( + model_name='problem', + name='cislo_zadani_old', + ), + migrations.RemoveField( + model_name='problem', + name='opravovatel', + ), + migrations.RemoveField( + model_name='problem', + name='text_reseni', + ), + migrations.RemoveField( + model_name='problem', + name='text_zadani', + ), + migrations.RemoveField( + model_name='problem', + name='typ', + ), + migrations.RemoveField( + model_name='reseni', + name='body', + ), + migrations.RemoveField( + model_name='reseni', + name='cislo_body', + ), + migrations.RemoveField( + model_name='reseni', + name='problem_old', + ), + migrations.RemoveField( + model_name='reseni', + name='resitel', + ), + migrations.RemoveField( + model_name='resitel', + name='datum_narozeni', + ), + migrations.RemoveField( + model_name='resitel', + name='datum_prihlaseni', + ), + migrations.RemoveField( + model_name='resitel', + name='datum_souhlasu_udaje', + ), + migrations.RemoveField( + model_name='resitel', + name='datum_souhlasu_zasilani', + ), + migrations.RemoveField( + model_name='resitel', + name='email', + ), + migrations.RemoveField( + model_name='resitel', + name='jmeno', + ), + migrations.RemoveField( + model_name='resitel', + name='mesto', + ), + migrations.RemoveField( + model_name='resitel', + name='pohlavi_muz', + ), + migrations.RemoveField( + model_name='resitel', + name='prijmeni', + ), + migrations.RemoveField( + model_name='resitel', + name='psc', + ), + migrations.RemoveField( + model_name='resitel', + name='stat', + ), + migrations.RemoveField( + model_name='resitel', + name='telefon', + ), + migrations.RemoveField( + model_name='resitel', + name='ulice', + ), + migrations.RemoveField( + model_name='resitel', + name='user', + ), + ] diff --git a/seminar/migrations/0062_redukce_modelu_pohadky.py b/seminar/migrations/0062_redukce_modelu_pohadky.py new file mode 100644 index 00000000..b4e5f11e --- /dev/null +++ b/seminar/migrations/0062_redukce_modelu_pohadky.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-30 01:16 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0061_kill_frankenstein'), + ] + + operations = [ + migrations.AlterModelOptions( + name='pohadka', + options={'ordering': ['vytvoreno'], 'verbose_name': 'Pohádka', 'verbose_name_plural': 'Pohádky'}, + ), + migrations.RemoveField( + model_name='pohadka', + name='pred', + ), + migrations.RemoveField( + model_name='pohadka', + name='text', + ), + migrations.RemoveField( + model_name='pohadka', + name='uloha', + ), + ] diff --git a/seminar/migrations/0063_procisteni_migraci.py b/seminar/migrations/0063_procisteni_migraci.py new file mode 100644 index 00000000..3dce57ad --- /dev/null +++ b/seminar/migrations/0063_procisteni_migraci.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-30 01:32 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0062_redukce_modelu_pohadky'), + ] + + operations = [ + migrations.AlterField( + model_name='cislo', + name='verejna_vysledkovka', + # Změnil se help_text -- byly v něm tabulátory kvůli zlomu v modelech + field=models.BooleanField(default=False, help_text='Je-li false u veřejného čísla, není výsledkovka zatím veřejná.', verbose_name='zveřejněna výsledkovka'), + ), + migrations.AlterField( + model_name='prijemce', + name='osoba', + # Bylo: ForeignKey + field=models.OneToOneField(help_text='Které osobě či na jakou adresu se mají zasílat čísla', on_delete=django.db.models.deletion.CASCADE, to='seminar.Osoba', verbose_name='komu'), + ), + migrations.AlterField( + model_name='reseni', + name='cas_doruceni', + # Bylo: editable=False + field=models.DateTimeField(blank=True, default=django.utils.timezone.now, verbose_name='čas_doručení'), + ), + ] diff --git a/seminar/migrations/0064_auto_20190610_2358.py b/seminar/migrations/0064_auto_20190610_2358.py new file mode 100644 index 00000000..344b132c --- /dev/null +++ b/seminar/migrations/0064_auto_20190610_2358.py @@ -0,0 +1,162 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.21 on 2019-06-10 21:58 +from __future__ import unicode_literals + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0063_procisteni_migraci'), + ] + + operations = [ + migrations.AlterField( + model_name='cislo', + name='rocnik', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='cisla', to='seminar.Rocnik', verbose_name='ročník'), + ), + migrations.AlterField( + model_name='clanek', + name='cislo', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='seminar.Cislo', verbose_name='číslo'), + ), + migrations.AlterField( + model_name='hodnoceni', + name='cislo_body', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='hodnoceni', to='seminar.Cislo', verbose_name='číslo pro body'), + ), + migrations.AlterField( + model_name='hodnoceni', + name='problem', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Problem', verbose_name='problém'), + ), + migrations.AlterField( + model_name='konfery_ucastnici', + name='konfera', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Konfera', verbose_name='konfera'), + ), + migrations.AlterField( + model_name='konfery_ucastnici', + name='resitel', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Resitel', verbose_name='řešitel'), + ), + migrations.AlterField( + model_name='nastaveni', + name='aktualni_cislo', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Cislo', verbose_name='poslední vydané číslo'), + ), + migrations.AlterField( + model_name='nastaveni', + name='aktualni_rocnik', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Rocnik', verbose_name='aktuální ročník'), + ), + migrations.AlterField( + model_name='novinky', + name='autor', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='seminar.Organizator', verbose_name='Autor novinky'), + ), + migrations.AlterField( + model_name='organizator', + name='osoba', + field=models.OneToOneField(help_text='osobní údaje organizátora', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='org', to='seminar.Osoba', verbose_name='osoba'), + ), + migrations.AlterField( + model_name='osoba', + name='user', + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, to=settings.AUTH_USER_MODEL, verbose_name='uživatel'), + ), + migrations.AlterField( + model_name='pohadka', + name='autor', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='seminar.Organizator', verbose_name='Autor pohádky'), + ), + migrations.AlterField( + model_name='problem', + name='autor', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='autor_problemu_problem', to='seminar.Organizator', verbose_name='autor problému'), + ), + migrations.AlterField( + model_name='problem', + name='garant', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='garant_problemu_problem', to='seminar.Organizator', verbose_name='garant zadaného problému'), + ), + migrations.AlterField( + model_name='problem', + name='nadproblem', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='nadproblem_problem', to='seminar.Problem', verbose_name='nadřazený problém'), + ), + migrations.AlterField( + model_name='reseni', + name='text_cely', + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='reseni_cely_set', to='seminar.Text', verbose_name='Plná verze textu řešení'), + ), + migrations.AlterField( + model_name='reseni_resitele', + name='resitele', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Resitel', verbose_name='řešitel'), + ), + migrations.AlterField( + model_name='resitel', + name='osoba', + field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.SET_NULL, to='seminar.Osoba', verbose_name='osoba'), + ), + migrations.AlterField( + model_name='resitel', + name='skola', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='seminar.Skola', verbose_name='škola'), + ), + migrations.AlterField( + model_name='skola', + name='kontaktni_osoba', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='seminar.Osoba', verbose_name='Kontaktní osoba'), + ), + migrations.AlterField( + model_name='soustredeni', + name='rocnik', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='soustredeni', to='seminar.Rocnik', verbose_name='ročník'), + ), + migrations.AlterField( + model_name='soustredeni_organizatori', + name='organizator', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Organizator', verbose_name='organizátor'), + ), + migrations.AlterField( + model_name='soustredeni_organizatori', + name='soustredeni', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Soustredeni', verbose_name='soustředění'), + ), + migrations.AlterField( + model_name='soustredeni_ucastnici', + name='resitel', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Resitel', verbose_name='řešitel'), + ), + migrations.AlterField( + model_name='soustredeni_ucastnici', + name='soustredeni', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Soustredeni', verbose_name='soustředění'), + ), + migrations.AlterField( + model_name='tema', + name='rocnik', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='seminar.Rocnik', verbose_name='ročník'), + ), + migrations.AlterField( + model_name='uloha', + name='cislo_deadline', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='deadlinove_ulohy', to='seminar.Cislo', verbose_name='číslo deadlinu'), + ), + migrations.AlterField( + model_name='uloha', + name='cislo_reseni', + field=models.ForeignKey(blank=True, help_text='Číslo s řešením úlohy, jen pro úlohy', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='resene_ulohy', to='seminar.Cislo', verbose_name='číslo řešení'), + ), + migrations.AlterField( + model_name='uloha', + name='cislo_zadani', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='zadane_ulohy', to='seminar.Cislo', verbose_name='číslo zadání'), + ), + ] diff --git a/seminar/migrations/0065_treenode_polymorphic_ctype.py b/seminar/migrations/0065_treenode_polymorphic_ctype.py new file mode 100644 index 00000000..71eef262 --- /dev/null +++ b/seminar/migrations/0065_treenode_polymorphic_ctype.py @@ -0,0 +1,31 @@ +# Generated by Django 2.2.4 on 2019-08-13 19:36 + +from django.db import migrations, models +import django.db.models.deletion + +def vyrob_treenodum_ctypes(apps, schema_editor): + # Kód zkopírovaný z dokumentace: https://django-polymorphic.readthedocs.io/en/stable/migrating.html + # XXX: Nevím, jestli se tohle náhodou nemělo spustit na všech childech (jen/i) + TreeNode = apps.get_model('seminar', 'TreeNode') + ContentType = apps.get_model('contenttypes', 'ContentType') + + new_ct = ContentType.objects.get_for_model(TreeNode) + TreeNode.objects.filter(polymorphic_ctype__isnull=True).update(polymorphic_ctype=new_ct) + + + +class Migration(migrations.Migration): + + dependencies = [ + ('contenttypes', '0002_remove_content_type_name'), + ('seminar', '0064_auto_20190610_2358'), + ] + + operations = [ + migrations.AddField( + model_name='treenode', + name='polymorphic_ctype', + field=models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_seminar.treenode_set+', to='contenttypes.ContentType'), + ), + migrations.RunPython(vyrob_treenodum_ctypes, migrations.RunPython.noop), + ] diff --git a/seminar/migrations/0066_problem_polymorphic_ctype.py b/seminar/migrations/0066_problem_polymorphic_ctype.py new file mode 100644 index 00000000..f956217e --- /dev/null +++ b/seminar/migrations/0066_problem_polymorphic_ctype.py @@ -0,0 +1,29 @@ +# Generated by Django 2.2.4 on 2019-08-13 19:45 + +from django.db import migrations, models +import django.db.models.deletion + +def vyrob_problemum_ctypes(apps, schema_editor): + # Kód zkopírovaný z dokumentace: https://django-polymorphic.readthedocs.io/en/stable/migrating.html + # XXX: Nevím, jestli se tohle náhodou nemělo spustit na všech childech (jen/i) + Problem = apps.get_model('seminar', 'Problem') + ContentType = apps.get_model('contenttypes', 'ContentType') + + new_ct = ContentType.objects.get_for_model(Problem) + Problem.objects.filter(polymorphic_ctype__isnull=True).update(polymorphic_ctype=new_ct) + +class Migration(migrations.Migration): + + dependencies = [ + ('contenttypes', '0002_remove_content_type_name'), + ('seminar', '0065_treenode_polymorphic_ctype'), + ] + + operations = [ + migrations.AddField( + model_name='problem', + name='polymorphic_ctype', + field=models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_seminar.problem_set+', to='contenttypes.ContentType'), + ), + migrations.RunPython(vyrob_problemum_ctypes, migrations.RunPython.noop), + ] diff --git a/seminar/migrations/0067_auto_20190814_0805.py b/seminar/migrations/0067_auto_20190814_0805.py new file mode 100644 index 00000000..8a72a659 --- /dev/null +++ b/seminar/migrations/0067_auto_20190814_0805.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2.4 on 2019-08-14 06:05 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0066_problem_polymorphic_ctype'), + ] + + operations = [ + migrations.AlterField( + model_name='konfera', + name='nazev', + field=models.CharField(help_text='Název konfery', max_length=100, verbose_name='název konfery'), + ), + ] From 418eb7c17a42dc3509cd27cbc11ddb434a0fa35d Mon Sep 17 00:00:00 2001 From: Pavel 'LEdoian' Turinsky Date: Thu, 7 Nov 2019 22:19:23 +0100 Subject: [PATCH 45/92] =?UTF-8?q?Migrace:=20Nefunguje=20vol=C3=A1n=C3=AD?= =?UTF-8?q?=20metod?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Revert souboru seminar/migrations/0002_treenode_nazev.py --- seminar/migrations/0002_treenode_nazev.py | 104 ++++++++++++++++++---- 1 file changed, 87 insertions(+), 17 deletions(-) diff --git a/seminar/migrations/0002_treenode_nazev.py b/seminar/migrations/0002_treenode_nazev.py index 896ca744..1219c339 100644 --- a/seminar/migrations/0002_treenode_nazev.py +++ b/seminar/migrations/0002_treenode_nazev.py @@ -2,24 +2,94 @@ from django.db import migrations, models +# Migrace nejspíš neumí volat metody modelů: +# https://stackoverflow.com/questions/28777338/django-migrations-runpython-not-able-to-call-model-methods#37685925 + +def fix_RocnikNode_names(apps,schema_editor): + Objects = apps.get_model('seminar', 'RocnikNode') + for obj in Objects.objects.all(): + obj.nazev = str(obj.rocnik)+" (RocnikNode)" + obj.save() + +def fix_CisloNode_names(apps,schema_editor): + Objects = apps.get_model('seminar', 'CisloNode') + for obj in Objects.objects.all(): + obj.nazev = str(obj.cislo)+" (CisloNode)" + obj.save() + +def fix_MezicisloNode_names(apps,schema_editor): + Objects = apps.get_model('seminar', 'MezicisloNode') + for obj in Objects.objects.all(): + if obj.prev: + if (obj.prev.get_real_instance_class() != CisloNode and + obj.prev.get_real_instance_class() != MezicisloNode): + raise ValueError("Předchůdce není číslo!") + posledni = obj.prev.cislo + obj.nazev = "Mezičíslo po čísle"+str(posledni)+" (MezicisloNode)" + elif obj.root: + if obj.root.get_real_instance_class() != RocnikNode: + raise ValueError("Kořen stromu není ročník!") + rocnik = obj.root.rocnik + obj.nazev = "První mezičíslo ročníku "+" (MezicisloNode)" + else: + print("!!!!! Nějaké neidentifikované mezičíslo !!!!!") + obj.nazev = "Neidentifikovatelné mezičíslo! (MezicisloNode)" + obj.save() + +def fix_TemaVCisleNode_names(apps,schema_editor): + Objects = apps.get_model('seminar', 'TemaVCisleNode') + for obj in Objects.objects.all(): + obj.nazev = str(obj.tema)+" (TemaVCisleNode)" + obj.save() + +def fix_KonferaNode_names(apps,schema_editor): + Objects = apps.get_model('seminar', 'KonferaNode') + for obj in Objects.objects.all(): + obj.nazev = str(obj.konfera)+" (KonferaNode)" + obj.save() + +def fix_ClanekNode_names(apps,schema_editor): + Objects = apps.get_model('seminar', 'ClanekNode') + for obj in Objects.objects.all(): + obj.nazev = str(obj.clanek)+" (ClanekNode)" + obj.save() + +def fix_UlohaZadaniNode_names(apps,schema_editor): + Objects = apps.get_model('seminar', 'UlohaZadaniNode') + for obj in Objects.objects.all(): + obj.nazev = str(obj.uloha)+" (UlohaZadaniNode)" + obj.save() + +def fix_PohadkaNode_names(apps,schema_editor): + Objects = apps.get_model('seminar', 'PohadkaNode') + for obj in Objects.objects.all(): + obj.nazev = str(obj.pohadka)+" (PohadkaNode)" + obj.save() + +def fix_UlohaVzorakNode_names(apps,schema_editor): + Objects = apps.get_model('seminar', 'UlohaVzorakNode') + for obj in Objects.objects.all(): + obj.nazev = str(obj.uloha)+" (UlohaVzorakNode)" + obj.save() + +def fix_TextNode_names(apps,schema_editor): + Objects = apps.get_model('seminar', 'TextNode') + for obj in Objects.objects.all(): + obj.nazev = str(obj.text)+" (TextNode)" + obj.save() + def fix_all_names(apps,schema_editor): - for objtype in [ - "RocnikNode", - "CisloNode", - "MezicisloNode", - "TemaVCisleNode", - "KonferaNode", - "ClanekNode", - "UlohaZadaniNode", - "PohadkaNode", - "UlohaVzorakNode", - "TextNode", - ]: - Objects = apps.get_model('seminar', objtype) - for obj in Objects.objects.all(): - obj.aktualizuj_nazev() - # Better save than sorry - obj.save() + fix_RocnikNode_names(apps,schema_editor) + fix_CisloNode_names(apps,schema_editor) + fix_MezicisloNode_names(apps,schema_editor) + fix_TemaVCisleNode_names(apps,schema_editor) + fix_KonferaNode_names(apps,schema_editor) + fix_ClanekNode_names(apps,schema_editor) + fix_UlohaZadaniNode_names(apps,schema_editor) + fix_PohadkaNode_names(apps,schema_editor) + fix_UlohaVzorakNode_names(apps,schema_editor) + fix_TextNode_names(apps,schema_editor) + class Migration(migrations.Migration): From d407f27ed971e22962e4d9e5dcb5868a74912214 Mon Sep 17 00:00:00 2001 From: "Tomas \"Jethro\" Pokorny" Date: Fri, 8 Nov 2019 00:11:33 +0100 Subject: [PATCH 46/92] Logovani registracniho formulare. --- seminar/forms.py | 37 +++++++++++++++++--- seminar/views.py | 87 ++++++++++++++++++++++-------------------------- 2 files changed, 73 insertions(+), 51 deletions(-) diff --git a/seminar/forms.py b/seminar/forms.py index 830203a2..f05b18e2 100644 --- a/seminar/forms.py +++ b/seminar/forms.py @@ -1,9 +1,12 @@ from django import forms from dal import autocomplete +from django.core.exceptions import ObjectDoesNotExist +from django.contrib.auth.models import User -from .models import Skola, Resitel +from .models import Skola, Resitel, Osoba from datetime import date +import logging class LoginForm(forms.Form): username = forms.CharField(label='Přihlašovací jméno', @@ -71,8 +74,37 @@ class PrihlaskaForm(forms.Form): zasilat = forms.ChoiceField(label='Kam zasílat čísla a řešení',choices = Resitel.ZASILAT_CHOICES, required=True) gdpr = forms.BooleanField(label='Souhlasím se zpracováním osobních údajů', required=True) spam = forms.BooleanField(label='Souhlasím se zasíláním materiálů od MFF UK', required=False) + + def clean_username(self): + err_logger = logging.getLogger('seminar.prihlaska.problem') + username = self.cleaned_data.get('username') + try: + User.objects.get(username=username) + msg = "Username {} exists".format(username) + err_logger.info(msg) + raise forms.ValidationError('Přihlašovací jméno je již použito') + + except ObjectDoesNotExist: + pass + + def clean_email(self): + err_logger = logging.getLogger('seminar.prihlaska.problem') + email = self.cleaned_data.get('email') + try: + Osoba.objects.get(email=email) + msg = "Email {} exists".format(email) + err_logger.info(msg) + raise forms.ValidationError('Email je již použit') + + except ObjectDoesNotExist: + pass + + def clean(self): super().clean() + + err_logger = logging.getLogger('seminar.prihlaska.problem') + data = self.cleaned_data if data.get('password') != data.get('password_check'): self.add_error('password_check',forms.ValidationError('Hesla se neshodují')) @@ -87,6 +119,3 @@ class PrihlaskaForm(forms.Form): self.add_error('skola_nazev',forms.ValidationError('Je nutné vyplnit název školy')) elif data.get('skola_adresa')=='': self.add_error('skola_adresa',forms.ValidationError('Je nutné vyplnit adresu školy')) -from seminar.models import Resitel - - diff --git a/seminar/views.py b/seminar/views.py index 1b540197..a320307e 100644 --- a/seminar/views.py +++ b/seminar/views.py @@ -10,6 +10,7 @@ from django.http import Http404,HttpResponseBadRequest,HttpResponseRedirect from django.db.models import Q from django.views.decorators.csrf import ensure_csrf_cookie from django.contrib.auth import authenticate, login, get_user_model, logout +from django.contrib.auth.models import User from django.contrib.auth.mixins import LoginRequiredMixin from django.db import transaction from dal import autocomplete @@ -1025,83 +1026,75 @@ def logoutView(request): return render(request, 'seminar/login.html', {'form': form}) +def prihlaska_log_gdpr_safe(logger, gdpr_logger, msg, form_data): + msg = "{}, form_hash:{}".format(msg,hash(form_data)) + logger.warn(msg) + gdpr_logger.warn(msg+", form:{}".format(form_data)) + + def prihlaskaView(request): - logger = logging.getLogger('seminar.prihlaska') + generic_logger = logging.getLogger('seminar.prihlaska') + err_logger = logging.getLogger('seminar.prihlaska.problem') + form_logger = logging.getLogger('seminar.prihlaska.form') if request.method == 'POST': form = PrihlaskaForm(request.POST) # TODO vyresit, co se bude v jakych situacich zobrazovat if form.is_valid(): - print("Form valid") - try: - # mame jiz email v databazi? - o = Osoba.objects.get(email=form.cleaned_data['email']) - print("Email existuje: {}".format(form.cleaned_data)) - # TODO seřvat a nepustit dál - return HttpResponseRedirect('/thanks/') - except ObjectDoesNotExist: - pass - - User = get_user_model() - try: - u = User.objects.get(username=form.cleaned_data['username']) - print("Username existuje: {}".format(form.cleaned_data)) - # TODO seřvat a nepustit dál - return HttpResponseRedirect('/thanks/') - - except ObjectDoesNotExist: - pass + generic_logger.info("Form valid") + fcd = form.cleaned_data + form_hash = hash(fcd) + form_logger.info(fcd,form_hash=form_hash) with transaction.atomic(): u = User.objects.create_user( - username=form.cleaned_data['username'], - password=form.cleaned_data['password'], - email = form.cleaned_data['email']) + username=fcd['username'], + password=fcd['password'], + email = fcd['email']) u.save() o = Osoba( - jmeno = form.cleaned_data['jmeno'], - prijmeni = form.cleaned_data['prijmeni'], - pohlavi_muz = form.cleaned_data['pohlavi_muz'], - email = form.cleaned_data['email'], - telefon = form.cleaned_data.get('telefon',''), - datum_narozeni = form.cleaned_data.get('datum_narozeni',None), + jmeno = fcd['jmeno'], + prijmeni = fcd['prijmeni'], + pohlavi_muz = fcd['pohlavi_muz'], + email = fcd['email'], + telefon = fcd.get('telefon',''), + datum_narozeni = fcd.get('datum_narozeni',None), datum_souhlasu_udaje = date.today(), datum_registrace = date.today(), - ulice = form.cleaned_data.get('ulice',''), - mesto = form.cleaned_data.get('mesto',''), - psc = form.cleaned_data.get('psc',''), - poznamka = str(form.cleaned_data) + ulice = fcd.get('ulice',''), + mesto = fcd.get('mesto',''), + psc = fcd.get('psc',''), + poznamka = str(fcd) ) - if form.cleaned_data.get('spam',False): + if fcd.get('spam',False): o.datum_souhlasu_zasilani = date.today() - if form.cleaned_data.get('stat','') in ('CZ','SK'): - o.stat = form.cleaned_data['stat'] + if fcd.get('stat','') in ('CZ','SK'): + o.stat = fcd['stat'] else: - pass - #TODO jak budeme resit jine staty? + # Unknown country - log it + msg = "Unknown country {}".format(fcd['stat_text']) + err_logger.warn(msg,form_hash=form_hash) o.save() o.user = u o.save() r = Resitel( - rok_maturity = form.cleaned_data['rok_maturity'], - zasilat = form.cleaned_data['zasilat'] + rok_maturity = fcd['rok_maturity'], + zasilat = fcd['zasilat'] ) r.save() r.osoba = o - if form.cleaned_data.get('skola'): - r.skola = form.cleaned_data['skola'] + if fcd.get('skola'): + r.skola = fcd['skola'] else: - pass - #TODO doplnit skolu, kdyz neni v seznamu + # Unknown school - log it + msg = "Unknown school {}, {}".format(fcd['skola_nazev'],fcd['skola_adresa']) + err_logger.warn(msg,form_hash=form_hash) r.save() - # TODO logovat jednotlive validni formulare do souboru - print(form.cleaned_data) - logger.info(form.cleaned_data) return HttpResponseRedirect('/thanks/') # if a GET (or any other method) we'll create a blank form From 8ff93a0c5c5bc5ac2b7adc141d716ebfc81fbae4 Mon Sep 17 00:00:00 2001 From: Pavel 'LEdoian' Turinsky Date: Fri, 8 Nov 2019 00:31:19 +0100 Subject: [PATCH 47/92] =?UTF-8?q?Save=20hook,=20kter=C3=BD=20aktualizuje?= =?UTF-8?q?=20n=C3=A1zvy=20*Nod=C5=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/models.py | 55 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 45 insertions(+), 10 deletions(-) diff --git a/seminar/models.py b/seminar/models.py index 9eefdec4..055ab07b 100644 --- a/seminar/models.py +++ b/seminar/models.py @@ -384,6 +384,10 @@ class Rocnik(SeminarModelBase): cache.set(name, c, 300) return c + def save(self): + super().save() + # *Node.save() aktualizuje název *Nodu. + self.rocniknode.save() def cislo_pdf_filename(self, filename): rocnik = str(self.rocnik.rocnik) @@ -477,6 +481,11 @@ class Cislo(SeminarModelBase): return None return c + def save(self): + super().save() + # *Node.save() aktualizuje název *Nodu. + self.cislonode.save() + @reversion.register(ignore_duplicates=True) class Organizator(SeminarModelBase): # zmena dedicnosti z models.Model na SeminarModelBase, potencialni vznik bugu @@ -707,6 +716,12 @@ class Tema(Problem): return "t{}".format(self.kod) return '' + def save(self): + super().save() + # *Node.save() aktualizuje název *Nodu. + for tvcn in self_temavcislenode_set: + tvcn.save() + class Clanek(Problem): class Meta: db_table = 'seminar_clanky' @@ -727,6 +742,11 @@ class Clanek(Problem): return "c{}".format(self.kod) return '' + def save(self): + super().save() + # *Node.save() aktualizuje název *Nodu. + self.claneknode.save() + class Text(SeminarModelBase): class Meta: db_table = 'seminar_texty' @@ -744,6 +764,12 @@ class Text(SeminarModelBase): # obrázky mají návaznost opačným směrem (vazba z druhé strany) + def save(self): + super().save() + # *Node.save() aktualizuje název *Nodu. + for tn in self.textnode_set: + tn.save() + class Uloha(Problem): @@ -778,6 +804,12 @@ class Uloha(Problem): return name return '' + def save(self): + super().save() + # *Node.save() aktualizuje název *Nodu. + self.ulohazadaninode.save() + self.ulohavzoraknode.save() + @reversion.register(ignore_duplicates=True) class Reseni(SeminarModelBase): @@ -959,6 +991,10 @@ class Pohadka(SeminarModelBase): uryvek = self.text if len(self.text) < 50 else self.text[:(50-3)]+"..." return uryvek + def save(self): + super().save() + # *Node.save() aktualizuje název *Nodu. + self.pohadkanode.save() @reversion.register(ignore_duplicates=True) class Soustredeni_Ucastnici(SeminarModelBase): @@ -1069,6 +1105,11 @@ class Konfera(models.Model): def __str__(self): return "{}: ({})".format(self.nazev, self.soustredeni) + def save(self): + super().save() + # *Node.save() aktualizuje název *Nodu. + self.konferanode.save() + # Vazebna tabulka. Mozna se generuje automaticky. @reversion.register(ignore_duplicates=True) @@ -1182,6 +1223,10 @@ class TreeNode(PolymorphicModel): else: #TODO: logování return "Nepojmenovaný Treenode" + + def save(self): + self.aktualizuj_nazev() + super().save() class RocnikNode(TreeNode): class Meta: @@ -1194,7 +1239,6 @@ class RocnikNode(TreeNode): def aktualizuj_nazev(self): self.nazev = "RocnikNode: "+str(self.rocnik) - self.save() class CisloNode(TreeNode): class Meta: @@ -1207,7 +1251,6 @@ class CisloNode(TreeNode): def aktualizuj_nazev(self): self.nazev = "CisloNode: "+str(self.cislo) - self.save() class MezicisloNode(TreeNode): class Meta: @@ -1230,7 +1273,6 @@ class MezicisloNode(TreeNode): else: print("!!!!! Nějaké neidentifikované mezičíslo !!!!!") self.nazev = "MezicisloNode: Neidentifikovatelné mezičíslo!" - self.save() class TemaVCisleNode(TreeNode): """ Obsahuje příspěvky k tématu v daném čísle """ @@ -1244,7 +1286,6 @@ class TemaVCisleNode(TreeNode): def aktualizuj_nazev(self): self.nazev = "TemaVCisleNode: "+str(self.tema) - self.save() class KonferaNode(TreeNode): class Meta: @@ -1259,7 +1300,6 @@ class KonferaNode(TreeNode): def aktualizuj_nazev(self): self.nazev = "KonferaNode: "+str(self.konfera) - self.save() class ClanekNode(TreeNode): class Meta: @@ -1274,7 +1314,6 @@ class ClanekNode(TreeNode): def aktualizuj_nazev(self): self.nazev = "ClanekNode: "+str(self.clanek) - self.save() class UlohaZadaniNode(TreeNode): class Meta: @@ -1289,7 +1328,6 @@ class UlohaZadaniNode(TreeNode): def aktualizuj_nazev(self): self.nazev = "UlohaZadaniNode: "+str(self.uloha) - self.save() class PohadkaNode(TreeNode): class Meta: @@ -1303,7 +1341,6 @@ class PohadkaNode(TreeNode): def aktualizuj_nazev(self): self.nazev = "PohadkaNode: "+str(self.pohadka) - self.save() class UlohaVzorakNode(TreeNode): class Meta: @@ -1318,7 +1355,6 @@ class UlohaVzorakNode(TreeNode): def aktualizuj_nazev(self): self.nazev = "UlohaVzorakNode: "+str(self.uloha) - self.save() class TextNode(TreeNode): class Meta: @@ -1331,7 +1367,6 @@ class TextNode(TreeNode): def aktualizuj_nazev(self): self.nazev = "TextNode: "+str(self.text) - self.save() ## FIXME: Logiku přesunout do views. #class VysledkyBase(SeminarModelBase): From 6cb4512083ba63cdfe9791e79a075794e87f06ba Mon Sep 17 00:00:00 2001 From: Anet Date: Wed, 13 Nov 2019 20:50:51 +0100 Subject: [PATCH 48/92] =?UTF-8?q?README.md:=20p=C5=99idan=C3=A9=20info=20o?= =?UTF-8?q?=20tom,=20jak=20se=20st=C3=A1hnou=20aktu=C3=A1ln=C3=AD=20flatpa?= =?UTF-8?q?ges?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index fd67c511..b4f168d3 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,8 @@ Make commands * `make schema` - generates graph of seminar and all schemas as PDF. Supercool! +* `make sync_prod_flatpages` - downloads current flat/static pages from production version + ./manage.py commands -------------------- From 4f8e98096e6b20d56fcbf55271bcee382d75b08f Mon Sep 17 00:00:00 2001 From: "Tomas \"Jethro\" Pokorny" Date: Wed, 13 Nov 2019 22:14:49 +0100 Subject: [PATCH 49/92] Prihlaska | logovani do souboru + bugfixy --- mamweb/settings_common.py | 22 +++++++++++++++++++--- mamweb/settings_prod.py | 2 ++ mamweb/settings_test.py | 2 ++ seminar/forms.py | 2 ++ seminar/views.py | 20 +++++--------------- 5 files changed, 30 insertions(+), 18 deletions(-) diff --git a/mamweb/settings_common.py b/mamweb/settings_common.py index 7bdd6abf..62cd7fe7 100644 --- a/mamweb/settings_common.py +++ b/mamweb/settings_common.py @@ -218,10 +218,14 @@ LOGGING = { 'handlers': ['console'], 'level': 'DEBUG', }, - 'seminar.prihlaska':{ + 'seminar.prihlaska.form':{ 'handlers': ['console','registration_logfile'], 'level': 'INFO' }, + 'seminar.prihlaska.problem':{ + 'handlers': ['console','mail_registration','registration_error_log'], + 'level': 'INFO' + }, # Catch-all logger '': { @@ -244,12 +248,24 @@ LOGGING = { 'class': 'django.utils.log.AdminEmailHandler', 'formatter': 'verbose', }, + 'mail_registraion': { + 'level': 'WARN', + 'class': 'django.utils.log.AdminEmailHandler', + 'formatter': 'verbose', + }, 'registration_logfile':{ 'level': 'INFO', 'class': 'logging.FileHandler', - 'filename': 'registration.log', + # filename declared in specific configuration files 'formatter': 'verbose', - } + }, + 'registration_error_log':{ + 'level': 'INFO', + 'class': 'logging.FileHandler', + # filename declared in specific configuration files + 'formatter': 'verbose', + }, + }, } diff --git a/mamweb/settings_prod.py b/mamweb/settings_prod.py index 918fd4b2..1c223842 100644 --- a/mamweb/settings_prod.py +++ b/mamweb/settings_prod.py @@ -61,6 +61,8 @@ CSRF_COOKIE_SECURE = True LOGGING['loggers']['']['handlers'] = ['console', 'mail_admins'] LOGGING['loggers']['django']['handlers'] = ['console', 'mail_admins'] +LOGGING['handlers']['registration_logfile']['filename'] = '/home/mam-web/logs/prod/registration.log' +LOGGING['handlers']['registration_error_log']['filename'] = '/home/mam-web/logs/prod/registration_errors.log' # E-MAIL NOTIFICATIONS diff --git a/mamweb/settings_test.py b/mamweb/settings_test.py index 9f971f45..2d85f2f5 100644 --- a/mamweb/settings_test.py +++ b/mamweb/settings_test.py @@ -65,3 +65,5 @@ CSRF_COOKIE_SECURE = True LOGGING['loggers']['']['handlers'] = ['console', 'mail_admins'] LOGGING['loggers']['django']['handlers'] = ['console', 'mail_admins'] +LOGGING['handlers']['registration_logfile']['filename'] = '/home/mam-web/logs/test/registration.log' +LOGGING['handlers']['registration_error_log']['filename'] = '/home/mam-web/logs/test/registration_errors.log' diff --git a/seminar/forms.py b/seminar/forms.py index f05b18e2..42d3c2d7 100644 --- a/seminar/forms.py +++ b/seminar/forms.py @@ -86,6 +86,7 @@ class PrihlaskaForm(forms.Form): except ObjectDoesNotExist: pass + return username def clean_email(self): err_logger = logging.getLogger('seminar.prihlaska.problem') @@ -98,6 +99,7 @@ class PrihlaskaForm(forms.Form): except ObjectDoesNotExist: pass + return email def clean(self): diff --git a/seminar/views.py b/seminar/views.py index a320307e..2d442eb9 100644 --- a/seminar/views.py +++ b/seminar/views.py @@ -1026,24 +1026,16 @@ def logoutView(request): return render(request, 'seminar/login.html', {'form': form}) -def prihlaska_log_gdpr_safe(logger, gdpr_logger, msg, form_data): - msg = "{}, form_hash:{}".format(msg,hash(form_data)) - logger.warn(msg) - gdpr_logger.warn(msg+", form:{}".format(form_data)) - - def prihlaskaView(request): - generic_logger = logging.getLogger('seminar.prihlaska') err_logger = logging.getLogger('seminar.prihlaska.problem') form_logger = logging.getLogger('seminar.prihlaska.form') if request.method == 'POST': form = PrihlaskaForm(request.POST) - # TODO vyresit, co se bude v jakych situacich zobrazovat if form.is_valid(): - generic_logger.info("Form valid") fcd = form.cleaned_data - form_hash = hash(fcd) - form_logger.info(fcd,form_hash=form_hash) + form_hash = hash(frozenset(fcd.items())) + fcd["hash"] = form_hash + form_logger.info(fcd) with transaction.atomic(): u = User.objects.create_user( @@ -1072,8 +1064,7 @@ def prihlaskaView(request): o.stat = fcd['stat'] else: # Unknown country - log it - msg = "Unknown country {}".format(fcd['stat_text']) - err_logger.warn(msg,form_hash=form_hash) + err_logger.warn("Unknown country {}. Form hash:{}".format(fcd['stat_text'],form_hash)) o.save() o.user = u @@ -1090,8 +1081,7 @@ def prihlaskaView(request): r.skola = fcd['skola'] else: # Unknown school - log it - msg = "Unknown school {}, {}".format(fcd['skola_nazev'],fcd['skola_adresa']) - err_logger.warn(msg,form_hash=form_hash) + err_logger.warn("Unknown school {}, {}. Form hash:{}".format(fcd['skola_nazev'],fcd['skola_adresa'],form_hash)) r.save() From bc3b6fdf49d3ce595fb6d8156e4fdb9e78389737 Mon Sep 17 00:00:00 2001 From: Anet Date: Wed, 13 Nov 2019 23:08:00 +0100 Subject: [PATCH 50/92] =?UTF-8?q?README.md:=20update=20pokyn=C5=AF=20k=20z?= =?UTF-8?q?a=C4=8D=C3=A1tku=20v=C3=BDvoje?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index b4f168d3..dc05017a 100644 --- a/README.md +++ b/README.md @@ -13,12 +13,12 @@ Use git :-) Quickstart ---------- +Run the following commands: + make install_venv + . env/bin/activate + make install_web -Install the following packages in Debian/Ubuntu: `libpq-dev python-dev python-setuptools python2.7 libjpeg-dev libpng12-dev`. Then run: - - make - ./manage.py testdata - make run +After finishing development, run "deactivate". Make commands ------------- From d3f045137fb18a1ca5bd84a18851ac9a69330c5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Domes?= Date: Wed, 13 Nov 2019 22:00:08 +0100 Subject: [PATCH 51/92] =?UTF-8?q?Zm=C4=9Bna=20obr=C3=A1zku=20li=C5=A1?= =?UTF-8?q?=C3=A1ka=20na=20ob=C3=A1lk=C3=A1ch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/static/seminar/lisak.eps | 1603 ------------------- seminar/static/seminar/lisak.pdf | Bin 0 -> 1959 bytes seminar/templates/seminar/archiv/obalky.tex | 3 +- seminar/views.py | 4 +- 4 files changed, 4 insertions(+), 1606 deletions(-) delete mode 100644 seminar/static/seminar/lisak.eps create mode 100644 seminar/static/seminar/lisak.pdf diff --git a/seminar/static/seminar/lisak.eps b/seminar/static/seminar/lisak.eps deleted file mode 100644 index 3a136212..00000000 --- a/seminar/static/seminar/lisak.eps +++ /dev/null @@ -1,1603 +0,0 @@ -%%BeginDocument: ./Eps/lisak.eps -%!PS-Adobe-3.0 EPSF-3.0 -%%BoundingBox: -191 -97 769 946 -%%Creator: CorelDRAW 8 -%%Title: L:\Prace\MaM\Obrazky\Lisak.eps -%%CreationDate: Tue May 11 17:28:49 1999 -%%For: Halef -%%DocumentProcessColors: Black -%%DocumentSuppliedResources: (atend) -%%EndComments -%%BeginProlog -/AutoFlatness false def -/AutoSteps 0 def -/CMYKMarks true def -/UseLevel 1 def -%Color profile: PROFILES.CCM - Obecn profil tiskrny CMYK - d. -%%BeginResource: procset wCorel8Dict 8.0 0 -/wCorel8Dict 300 dict def wCorel8Dict begin -% Copyright (c)1992-97 Corel Corporation -% All rights reserved. v8.0 r0.7 -/bd{bind def}bind def/ld{load def}bd/xd{exch def}bd/_ null def/rp{{pop}repeat} -bd/@cp/closepath ld/@gs/gsave ld/@gr/grestore ld/@np/newpath ld/Tl/translate ld -/$sv 0 def/@sv{/$sv save def}bd/@rs{$sv restore}bd/spg/showpage ld/showpage{} -bd currentscreen/@dsp xd/$dsp/@dsp def/$dsa xd/$dsf xd/$sdf false def/$SDF -false def/$Scra 0 def/SetScr/setscreen ld/setscreen{pop pop pop}bd/@ss{2 index -0 eq{$dsf 3 1 roll 4 -1 roll pop}if exch $Scra add exch load SetScr}bd -/SepMode_5 where{pop}{/SepMode_5 0 def}ifelse/CurrentInkName_5 where{pop} -{/CurrentInkName_5(Composite)def}ifelse/$ink_5 where{pop}{/$ink_5 -1 def} -ifelse/$c 0 def/$m 0 def/$y 0 def/$k 0 def/$t 1 def/$n _ def/$o 0 def/$fil 0 -def/$C 0 def/$M 0 def/$Y 0 def/$K 0 def/$T 1 def/$N _ def/$O 0 def/$PF false -def/s1c 0 def/s1m 0 def/s1y 0 def/s1k 0 def/s1t 0 def/s1n _ def/$bkg false def -/SK 0 def/SM 0 def/SY 0 def/SC 0 def/$op false def matrix currentmatrix/$ctm xd -/$ptm matrix def/$ttm matrix def/$stm matrix def/$ffpnt true def -/CorelDrawReencodeVect[16#0/grave 16#5/breve 16#6/dotaccent 16#8/ring -16#A/hungarumlaut 16#B/ogonek 16#C/caron 16#D/dotlessi 16#27/quotesingle -16#60/grave 16#7C/bar -16#82/quotesinglbase/florin/quotedblbase/ellipsis/dagger/daggerdbl -16#88/circumflex/perthousand/Scaron/guilsinglleft/OE -16#91/quoteleft/quoteright/quotedblleft/quotedblright/bullet/endash/emdash -16#98/tilde/trademark/scaron/guilsinglright/oe 16#9F/Ydieresis -16#A1/exclamdown/cent/sterling/currency/yen/brokenbar/section -16#a8/dieresis/copyright/ordfeminine/guillemotleft/logicalnot/minus/registered/macron -16#b0/degree/plusminus/twosuperior/threesuperior/acute/mu/paragraph/periodcentered -16#b8/cedilla/onesuperior/ordmasculine/guillemotright/onequarter/onehalf/threequarters/questiondown -16#c0/Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE/Ccedilla -16#c8/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex/Idieresis -16#d0/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis/multiply -16#d8/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls -16#e0/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla -16#e8/egrave/eacute/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis -16#f0/eth/ntilde/ograve/oacute/ocircumflex/otilde/odieresis/divide -16#f8/oslash/ugrave/uacute/ucircumflex/udieresis/yacute/thorn/ydieresis]def -/L2?/languagelevel where{pop languagelevel 2 ge}{false}ifelse def -/@BeginSysCorelDict{systemdict/Corel30Dict known{systemdict/Corel30Dict get -exec}if systemdict/CorelLexDict known{1 systemdict/CorelLexDict get exec}if}bd -/@EndSysCorelDict{systemdict/Corel30Dict known{end}if/EndCorelLexDict where -{pop EndCorelLexDict}if}bd AutoFlatness{/@ifl{dup currentflat exch sub 10 gt{ -([Error: PathTooComplex; OffendingCommand: AnyPaintingOperator]\n)print flush -@np exit}{currentflat 2 add setflat}ifelse}bd/@fill/fill ld/fill{currentflat{ -{@fill}stopped{@ifl}{exit}ifelse}bind loop setflat}bd/@eofill/eofill ld/eofill -{currentflat{{@eofill}stopped{@ifl}{exit}ifelse}bind loop setflat}bd/@clip -/clip ld/clip{currentflat{{@clip}stopped{@ifl}{exit}ifelse}bind loop setflat} -bd/@eoclip/eoclip ld/eoclip{currentflat{{@eoclip}stopped{@ifl}{exit}ifelse} -bind loop setflat}bd/@stroke/stroke ld/stroke{currentflat{{@stroke}stopped -{@ifl}{exit}ifelse}bind loop setflat}bd}if L2?{/@ssa{true setstrokeadjust}bd}{ -/@ssa{}bd}ifelse/d/setdash ld/j/setlinejoin ld/J/setlinecap ld/M/setmiterlimit -ld/w/setlinewidth ld/O{/$o xd}bd/R{/$O xd}bd/W/eoclip ld/c/curveto ld/C/c ld/l -/lineto ld/L/l ld/rl/rlineto ld/m/moveto ld/n/newpath ld/N/newpath ld/P{11 rp} -bd/u{}bd/U{}bd/A{pop}bd/q/@gs ld/Q/@gr ld/&{}bd/@j{@sv @np}bd/@J{@rs}bd/g{1 -exch sub/$k xd/$c 0 def/$m 0 def/$y 0 def/$t 1 def/$n _ def/$fil 0 def}bd/G{1 -sub neg/$K xd _ 1 0 0 0/$C xd/$M xd/$Y xd/$T xd/$N xd}bd/k{1 index type -/stringtype eq{/$t xd/$n xd}{/$t 0 def/$n _ def}ifelse/$k xd/$y xd/$m xd/$c xd -/$fil 0 def}bd/K{1 index type/stringtype eq{/$T xd/$N xd}{/$T 0 def/$N _ def} -ifelse/$K xd/$Y xd/$M xd/$C xd}bd/x/k ld/X/K ld/sf{1 index type/stringtype eq{ -/s1t xd/s1n xd}{/s1t 0 def/s1n _ def}ifelse/s1k xd/s1y xd/s1m xd/s1c xd}bd/i{ -dup 0 ne{setflat}{pop}ifelse}bd/v{4 -2 roll 2 copy 6 -2 roll c}bd/V/v ld/y{2 -copy c}bd/Y/y ld/@w{matrix rotate/$ptm xd matrix scale $ptm dup concatmatrix -/$ptm xd 1 eq{$ptm exch dup concatmatrix/$ptm xd}if 1 w}bd/@g{1 eq dup/$sdf xd -{/$scp xd/$sca xd/$scf xd}if}bd/@G{1 eq dup/$SDF xd{/$SCP xd/$SCA xd/$SCF xd} -if}bd/@D{2 index 0 eq{$dsf 3 1 roll 4 -1 roll pop}if 3 copy exch $Scra add exch -load SetScr/$dsp xd/$dsa xd/$dsf xd}bd/$ngx{$SDF{$SCF SepMode_5 0 eq{$SCA} -{$dsa}ifelse $SCP @ss}if}bd/p{/$pm xd 7 rp/$pyf xd/$pxf xd/$pn xd/$fil 1 def} -bd/@MN{2 copy le{pop}{exch pop}ifelse}bd/@MX{2 copy ge{pop}{exch pop}ifelse}bd -/InRange{3 -1 roll @MN @MX}bd/@sqr{dup 0 rl dup 0 exch rl neg 0 rl @cp}bd -/currentscale{1 0 dtransform matrix defaultmatrix idtransform dup mul exch dup -mul add sqrt 0 1 dtransform matrix defaultmatrix idtransform dup mul exch dup -mul add sqrt}bd/@unscale{}bd/wDstChck{2 1 roll dup 3 -1 roll eq{1 add}if}bd -/@dot{dup mul exch dup mul add 1 exch sub}bd/@lin{exch pop abs 1 exch sub}bd -/cmyk2rgb{3{dup 5 -1 roll add 1 exch sub dup 0 lt{pop 0}if exch}repeat pop}bd -/rgb2cmyk{3{1 exch sub 3 1 roll}repeat 3 copy @MN @MN 3{dup 5 -1 roll sub neg -exch}repeat}bd/rgb2g{2 index .299 mul 2 index .587 mul add 1 index .114 mul add -4 1 roll pop pop pop}bd/WaldoColor_5 where{pop}{/SetRgb/setrgbcolor ld/GetRgb -/currentrgbcolor ld/SetGry/setgray ld/GetGry/currentgray ld/SetRgb2 systemdict -/setrgbcolor get def/GetRgb2 systemdict/currentrgbcolor get def/SetHsb -systemdict/sethsbcolor get def/GetHsb systemdict/currenthsbcolor get def -/rgb2hsb{SetRgb2 GetHsb}bd/hsb2rgb{3 -1 roll dup floor sub 3 1 roll SetHsb -GetRgb2}bd/setcmykcolor where{pop/SetCmyk_5/setcmykcolor ld}{/SetCmyk_5{ -cmyk2rgb SetRgb}bd}ifelse/currentcmykcolor where{pop/GetCmyk/currentcmykcolor -ld}{/GetCmyk{GetRgb rgb2cmyk}bd}ifelse/setoverprint where{pop}{/setoverprint{ -/$op xd}bd}ifelse/currentoverprint where{pop}{/currentoverprint{$op}bd}ifelse -/@tc_5{5 -1 roll dup 1 ge{pop}{4{dup 6 -1 roll mul exch}repeat pop}ifelse}bd -/@trp{exch pop 5 1 roll @tc_5}bd/setprocesscolor_5{SepMode_5 0 eq{SetCmyk_5}{0 -4 $ink_5 sub index exch pop 5 1 roll pop pop pop pop SepsColor true eq{$ink_5 3 -gt{1 sub neg SetGry}{0 0 0 4 $ink_5 roll SetCmyk_5}ifelse}{1 sub neg SetGry} -ifelse}ifelse}bd/findcmykcustomcolor where{pop}{/findcmykcustomcolor{5 array -astore}bd}ifelse/setcustomcolor where{pop}{/setcustomcolor{exch aload pop -SepMode_5 0 eq{pop @tc_5 setprocesscolor_5}{CurrentInkName_5 eq{4 index}{0} -ifelse 6 1 roll 5 rp 1 sub neg SetGry}ifelse}bd}ifelse/@scc_5{dup type -/booleantype eq{setoverprint}{1 eq setoverprint}ifelse dup _ eq{pop -setprocesscolor_5 pop}{findcmykcustomcolor exch setcustomcolor}ifelse SepMode_5 -0 eq{true}{GetGry 1 eq currentoverprint and not}ifelse}bd/colorimage where{pop -/ColorImage{colorimage}def}{/ColorImage{/ncolors xd pop/dataaq xd{dataaq -ncolors dup 3 eq{/$dat xd 0 1 $dat length 3 div 1 sub{dup 3 mul $dat 1 index -get 255 div $dat 2 index 1 add get 255 div $dat 3 index 2 add get 255 div rgb2g -255 mul cvi exch pop $dat 3 1 roll put}for $dat 0 $dat length 3 idiv -getinterval pop}{4 eq{/$dat xd 0 1 $dat length 4 div 1 sub{dup 4 mul $dat 1 -index get 255 div $dat 2 index 1 add get 255 div $dat 3 index 2 add get 255 div -$dat 4 index 3 add get 255 div cmyk2rgb rgb2g 255 mul cvi exch pop $dat 3 1 -roll put}for $dat 0 $dat length ncolors idiv getinterval}if}ifelse}image}bd -}ifelse/setcmykcolor{1 5 1 roll _ currentoverprint @scc_5/$ffpnt xd}bd -/currentcmykcolor{0 0 0 0}bd/setrgbcolor{rgb2cmyk setcmykcolor}bd -/currentrgbcolor{currentcmykcolor cmyk2rgb}bd/sethsbcolor{hsb2rgb setrgbcolor} -bd/currenthsbcolor{currentrgbcolor rgb2hsb}bd/setgray{dup dup setrgbcolor}bd -/currentgray{currentrgbcolor rgb2g}bd/InsideDCS false def/IMAGE systemdict -/image get def/image{InsideDCS{IMAGE}{/EPSDict where{pop SepMode_5 0 eq{IMAGE} -{dup type/dicttype eq{dup/ImageType get 1 ne{IMAGE}{dup dup/BitsPerComponent -get 8 eq exch/BitsPerComponent get 1 eq or currentcolorspace 0 get/DeviceGray -eq and{CurrentInkName_5(Black)eq{IMAGE}{dup/DataSource get/TCC xd/Height get -abs{TCC pop}repeat}ifelse}{IMAGE}ifelse}ifelse}{2 index 1 ne{CurrentInkName_5 -(Black)eq{IMAGE}{/TCC xd pop pop exch pop abs{TCC pop}repeat}ifelse}{IMAGE} -ifelse}ifelse}ifelse}{IMAGE}ifelse}ifelse}bd}ifelse/WaldoColor_5 true def/@sft -{$tllx $pxf add dup $tllx gt{$pwid sub}if/$tx xd $tury $pyf sub dup $tury lt -{$phei add}if/$ty xd}bd/@stb{pathbbox/$ury xd/$urx xd/$lly xd/$llx xd}bd/@ep{{ -cvx exec}forall}bd/@tp{@sv/$in true def 2 copy dup $lly le{/$in false def}if -$phei sub $ury ge{/$in false def}if dup $urx ge{/$in false def}if $pwid add -$llx le{/$in false def}if $in{@np 2 copy m $pwid 0 rl 0 $phei neg rl $pwid neg -0 rl 0 $phei rl clip @np $pn cvlit load aload pop 7 -1 roll 5 index sub 7 -1 -roll 3 index sub Tl matrix currentmatrix/$ctm xd @ep pop pop pop pop}{pop pop -}ifelse @rs}bd/@th{@sft 0 1 $tly 1 sub{dup $psx mul $tx add{dup $llx gt{$pwid -sub}{exit}ifelse}loop exch $phei mul $ty exch sub 0 1 $tlx 1 sub{$pwid mul 3 -copy 3 -1 roll add exch @tp pop}for pop pop}for}bd/@tv{@sft 0 1 $tlx 1 sub{dup -$pwid mul $tx add exch $psy mul $ty exch sub{dup $ury lt{$phei add}{exit} -ifelse}loop 0 1 $tly 1 sub{$phei mul 3 copy sub @tp pop}for pop pop}for}bd/$fm -0 def/wfill{1 $fm eq{fill}{eofill}ifelse}bd/wclip{1 $fm eq{clip}{eoclip}ifelse -}bd/@pf{@gs $ctm setmatrix $pm concat @stb wclip @sv Bburx Bbury $pm itransform -/$tury xd/$turx xd Bbllx Bblly $pm itransform/$tlly xd/$tllx xd newpath $tllx -$tlly m $tllx $tury l $turx $tury l $turx $tlly l $tllx $tlly m @cp pathbbox -@rs/$tury xd/$turx xd/$tlly xd/$tllx xd/$wid $turx $tllx sub def/$hei $tury -$tlly sub def @gs $vectpat{1 0 0 0 0 _ $o @scc_5{wfill}if}{$t $c $m $y $k $n $o -@scc_5{SepMode_5 0 eq $pfrg or{$tllx $tlly Tl $wid $hei scale <00> 8 1 false[8 -0 0 1 0 0]{}imagemask}{/$bkg true def}ifelse}if}ifelse @gr $wid 0 gt $hei 0 gt -and{$pn cvlit load aload pop/$pd xd 3 -1 roll sub/$phei xd exch sub/$pwid xd -$wid $pwid div ceiling 1 add/$tlx xd $hei $phei div ceiling 1 add/$tly xd $psx -0 eq{@tv}{@th}ifelse}if @gr @np/$bkg false def}bd/@Pf{@sv SepMode_5 0 eq $Psc 0 -ne or $ink_5 3 eq or{0 J 0 j[]0 d $t $c $m $y $k $n $o @scc_5 pop $ctm -setmatrix 72 1000 div dup matrix scale dup concat dup Bburx exch Bbury exch -itransform ceiling cvi/Bbury xd ceiling cvi/Bburx xd Bbllx exch Bblly exch -itransform floor cvi/Bblly xd floor cvi/Bbllx xd $Prm aload pop $Psn load exec -}{1 SetGry wfill}ifelse @rs @np}bd/F{matrix currentmatrix $sdf{$scf $sca $scp -@ss}if $fil 1 eq{@pf}{$fil 2 eq{@ff}{$fil 3 eq{@Pf}{$t $c $m $y $k $n $o @scc_5 -{wfill}{@np}ifelse}ifelse}ifelse}ifelse $sdf{$dsf $dsa $dsp @ss}if setmatrix} -bd/f{@cp F}bd/S{matrix currentmatrix $ctm setmatrix $SDF{$SCF $SCA $SCP @ss}if -$T $C $M $Y $K $N $O @scc_5{matrix currentmatrix $ptm concat stroke setmatrix} -{@np}ifelse $SDF{$dsf $dsa $dsp @ss}if setmatrix}bd/s{@cp S}bd/B{@gs F @gr S} -bd/b{@cp B}bd/_E{5 array astore exch cvlit xd}bd/@cc{currentfile $dat -readhexstring pop}bd/@sm{/$ctm $ctm currentmatrix def}bd/@E{/Bbury xd/Bburx xd -/Bblly xd/Bbllx xd}bd/@c{@cp}bd/@p{/$fil 1 def 1 eq dup/$vectpat xd{/$pfrg true -def}{@gs $t $c $m $y $k $n $o @scc_5/$pfrg xd @gr}ifelse/$pm xd/$psy xd/$psx xd -/$pyf xd/$pxf xd/$pn xd}bd/@P{/$fil 3 def/$Psn xd/$Psc xd array astore/$Prm xd -}bd/@ii{concat 3 index 3 index m 3 index 1 index l 2 copy l 1 index 3 index l 3 -index 3 index l clip pop pop pop pop}bd/tcc{@cc}def/@i{@sm @gs @ii 6 index 1 ne -{/$frg true def pop pop}{1 eq{s1t s1c s1m s1y s1k s1n $O @scc_5/$frg xd}{/$frg -false def}ifelse 1 eq{@gs $ctm setmatrix F @gr}if}ifelse @np/$ury xd/$urx xd -/$lly xd/$llx xd/$bts xd/$hei xd/$wid xd/$dat $wid $bts mul 8 div ceiling cvi -string def $bkg $frg or{$SDF{$SCF $SCA $SCP @ss}if $llx $lly Tl $urx $llx sub -$ury $lly sub scale $bkg{$t $c $m $y $k $n $o @scc_5 pop}if $wid $hei abs $bts -1 eq{$bkg}{$bts}ifelse[$wid 0 0 $hei neg 0 $hei 0 gt{$hei}{0}ifelse]/tcc load -$bts 1 eq{imagemask}{image}ifelse $SDF{$dsf $dsa $dsp @ss}if}{$hei abs{tcc pop} -repeat}ifelse @gr $ctm setmatrix}bd/@I{@sm @gs @ii @np/$ury xd/$urx xd/$lly xd -/$llx xd/$ncl xd/$bts xd/$hei xd/$wid xd/$dat $wid $bts mul $ncl mul 8 div -ceiling cvi string def $ngx $llx $lly Tl $urx $llx sub $ury $lly sub scale $wid -$hei abs $bts[$wid 0 0 $hei neg 0 $hei 0 gt{$hei}{0}ifelse]/@cc load false $ncl -ColorImage $SDF{$dsf $dsa $dsp @ss}if @gr $ctm setmatrix}bd/COMP 0 def -/MaskedImage false def L2?{/@I_2{@sm @gs @ii @np/$ury xd/$urx xd/$lly xd/$llx -xd/$ncl xd/$bts xd/$hei xd/$wid xd/$dat $wid $bts mul $ncl mul 8 div ceiling -cvi string def $ngx $ncl 1 eq{/DeviceGray}{$ncl 3 eq{/DeviceRGB}{/DeviceCMYK} -ifelse}ifelse setcolorspace $llx $lly Tl $urx $llx sub $ury $lly sub scale 8 -dict begin/ImageType 1 def/Width $wid def/Height $hei abs def/BitsPerComponent -$bts def/Decode $ncl 1 eq{[0 1]}{$ncl 3 eq{[0 1 0 1 0 1]}{[0 1 0 1 0 1 0 1]} -ifelse}ifelse def/ImageMatrix[$wid 0 0 $hei neg 0 $hei 0 gt{$hei}{0}ifelse]def -/DataSource currentfile/ASCII85Decode filter COMP 1 eq{/DCTDecode filter}{COMP -2 eq{/RunLengthDecode filter}if}ifelse def currentdict end image $SDF{$dsf $dsa -$dsp @ss}if @gr $ctm setmatrix}bd}{/@I_2{}bd}ifelse/@I_3{@sm @gs @ii @np/$ury -xd/$urx xd/$lly xd/$llx xd/$ncl xd/$bts xd/$hei xd/$wid xd/$dat $wid $bts mul -$ncl mul 8 div ceiling cvi string def $ngx $ncl 1 eq{/DeviceGray}{$ncl 3 eq -{/DeviceRGB}{/DeviceCMYK}ifelse}ifelse setcolorspace $llx $lly Tl $urx $llx sub -$ury $lly sub scale/ImageDataDict 8 dict def ImageDataDict begin/ImageType 1 -def/Width $wid def/Height $hei abs def/BitsPerComponent $bts def/Decode $ncl 1 -eq{[0 1]}{$ncl 3 eq{[0 1 0 1 0 1]}{[0 1 0 1 0 1 0 1]}ifelse}ifelse def -/ImageMatrix[$wid 0 0 $hei neg 0 $hei 0 gt{$hei}{0}ifelse]def/DataSource -currentfile/ASCII85Decode filter COMP 1 eq{/DCTDecode filter}{COMP 2 eq{ -/RunLengthDecode filter}if}ifelse def end/MaskedImageDict 7 dict def -MaskedImageDict begin/ImageType 3 def/InterleaveType 3 def/MaskDict -ImageMaskDict def/DataDict ImageDataDict def end MaskedImageDict image $SDF -{$dsf $dsa $dsp @ss}if @gr $ctm setmatrix}bd/@SetMask{/$mbts xd/$mhei xd/$mwid -xd/ImageMaskDict 8 dict def ImageMaskDict begin/ImageType 1 def/Width $mwid def -/Height $mhei abs def/BitsPerComponent $mbts def/DataSource maskstream def -/ImageMatrix[$mwid 0 0 $mhei neg 0 $mhei 0 gt{$mhei}{0}ifelse]def/Decode[1 0] -def end}bd/@B{@gs S @gr F}bd/@b{@cp @B}bd/@sep{CurrentInkName_5(Composite)eq -{/$ink_5 -1 def}{CurrentInkName_5(Cyan)eq{/$ink_5 0 def}{CurrentInkName_5 -(Magenta)eq{/$ink_5 1 def}{CurrentInkName_5(Yellow)eq{/$ink_5 2 def}{ -CurrentInkName_5(Black)eq{/$ink_5 3 def}{/$ink_5 4 def}ifelse}ifelse}ifelse} -ifelse}ifelse}bd/@whi{@gs -72000 dup m -72000 72000 l 72000 dup l 72000 -72000 -l @cp 1 SetGry fill @gr}bd/@neg{[{1 exch sub}/exec cvx currenttransfer/exec -cvx]cvx settransfer @whi}bd/deflevel 0 def/@sax{/deflevel deflevel 1 add def} -bd/@eax{/deflevel deflevel dup 0 gt{1 sub}if def deflevel 0 gt{/eax load}{eax} -ifelse}bd/eax{{exec}forall}bd/@rax{deflevel 0 eq{@rs @sv}if}bd/@daq{dup type -/arraytype eq{{}forall}if}bd/@BMP{/@cc xd UseLevel 3 eq MaskedImage true eq and -{7 -2 roll pop pop @I_3}{12 index 1 gt UseLevel 2 eq UseLevel 3 eq or and{7 -2 -roll pop pop @I_2}{11 index 1 eq{12 -1 roll pop @i}{7 -2 roll pop pop @I} -ifelse}ifelse}ifelse}bd systemdict/pdfmark known not{/pdfmark/cleartomark ld} -if -end -%%EndResource -%%EndProlog -%%BeginSetup -wCorel8Dict begin -@BeginSysCorelDict -2.6131 setmiterlimit -1.00 setflat -/$fst 128 def -%%EndSetup - -%%Page: 1 1 -%LogicalPage: 1 -%%BeginPageSetup -@sv -@sm -@sv -%%EndPageSetup -@rax %Note: Object -482.82180 -96.51912 768.51780 183.48888 @E - 1 O 0 @g -0.00 0.00 0.00 1.00 k -/$fm 0 def -614.79780 -96.51912 m -610.54980 -96.23112 606.30180 -96.01512 602.05380 -95.79912 C -594.49380 -90.75912 581.53380 -79.52712 580.23780 -71.31912 C -573.54180 -72.90312 569.86980 -76.71912 564.46980 -80.75112 C -552.15780 -82.69512 539.12580 -86.94312 527.60580 -86.36712 C -523.57380 -78.30312 530.26980 -71.10312 536.96580 -68.29512 C -538.76580 -62.10312 543.30180 -61.16712 548.62980 -57.71112 C -548.05380 -50.00712 537.32580 -44.82312 535.88580 -36.61512 C -535.38180 -36.61512 534.87780 -36.61512 534.37380 -36.61512 C -532.50180 -26.82312 531.70980 -26.10312 531.34980 -23.79912 C -533.65380 -22.64712 533.65380 -22.64712 534.37380 -20.77512 C -547.33380 -17.96712 552.58980 -17.03112 564.82980 -26.10312 C -565.04580 -28.04712 576.56580 -35.39112 580.23780 -35.89512 C -582.54180 -11.48712 580.59780 7.59288 565.98180 27.10488 C -565.18980 27.24888 564.39780 27.39288 563.67780 27.46488 C -562.23780 18.17688 557.84580 10.32888 552.01380 2.55288 C -540.92580 -2.05512 538.54980 13.64088 536.60580 19.90488 C -535.81380 19.90488 535.09380 19.90488 534.37380 19.90488 C -529.40580 9.89688 520.69380 -0.83112 508.81380 -0.83112 C -494.26980 8.88888 501.90180 18.60888 506.94180 32.00088 C -510.03780 38.04888 513.13380 44.09688 516.30180 50.07288 C -502.62180 47.69688 487.28580 43.37688 482.82180 60.58488 C -482.82180 75.92088 495.99780 80.81688 508.81380 83.62488 C -509.17380 86.21688 509.17380 86.21688 507.66180 90.03288 C -511.62180 108.96888 509.53380 106.66488 525.73380 108.82488 C -525.80580 109.83288 525.94980 110.84088 526.09380 111.84888 C -531.06180 111.56088 536.31780 105.94488 538.11780 100.54488 C -543.08580 102.27288 544.45380 108.17688 546.75780 112.64088 C -552.80580 120.12888 556.18980 122.79288 556.90980 124.66488 C -559.21380 123.58488 559.21380 123.58488 561.80580 123.94488 C -562.16580 125.09688 562.52580 126.24888 562.95780 127.32888 C -566.34180 126.68088 572.67780 117.10488 574.54980 113.36088 C -574.54980 105.87288 573.68580 99.60888 571.95780 91.54488 C -577.50180 91.83288 580.09380 94.92888 587.00580 94.92888 C -589.95780 92.91288 592.98180 90.89688 596.00580 88.88088 C -606.15780 73.32888 587.65380 57.34488 575.70180 48.20088 C -568.93380 45.17688 568.93380 45.17688 565.54980 42.51288 C -565.40580 41.28888 565.26180 40.06488 565.18980 38.76888 C -565.69380 38.76888 566.19780 38.76888 566.70180 38.76888 C -575.12580 25.16088 585.85380 9.10488 587.72580 -7.95912 C -592.83780 -6.08712 598.74180 27.75288 600.90180 34.23288 C -603.99780 38.76888 605.72580 44.45688 606.87780 49.28088 C -618.97380 73.40088 624.94980 83.19288 625.30980 85.49688 C -605.86980 84.77688 614.79780 105.15288 618.18180 116.38488 C -622.42980 122.72088 625.74180 126.39288 631.35780 131.14488 C -631.21380 151.08888 626.38980 166.28088 648.63780 171.39288 C -648.34980 172.40088 648.13380 173.40888 647.91780 174.41688 C -658.42980 174.05688 660.15780 170.45688 661.45380 158.57688 C -667.93380 160.16088 680.46180 184.42488 687.01380 177.87288 C -688.74180 178.37688 690.46980 178.88088 692.26980 179.38488 C -692.62980 181.25688 692.62980 181.25688 691.47780 183.48888 C -700.90980 182.98488 702.42180 175.13688 702.42180 166.13688 C -697.09380 155.62488 697.09380 155.62488 696.73380 153.32088 C -709.47780 152.88888 712.14180 142.30488 712.14180 129.99288 C -706.95780 120.63288 695.50980 108.96888 684.70980 106.95288 C -681.90180 104.57688 680.74980 103.35288 677.22180 102.84888 C -677.72580 90.24888 664.33380 71.67288 652.38180 67.06488 C -639.49380 70.16088 648.34980 87.36888 644.17380 94.92888 C -643.38180 95.07288 642.58980 95.21688 641.86980 95.28888 C -641.14980 93.41688 637.76580 90.75288 625.66980 72.68088 C -611.91780 47.40888 601.26180 22.64088 597.51780 -6.44712 C -612.63780 -1.04712 612.49380 24.29688 632.07780 22.92888 C -632.07780 22.42488 632.07780 21.92088 632.07780 21.41688 C -632.58180 21.41688 633.08580 21.41688 633.58980 21.41688 C -635.10180 12.99288 632.29380 6.72888 629.84580 -1.98312 C -638.62980 3.99288 643.23780 15.36888 654.68580 18.03288 C -660.01380 23.64888 665.41380 25.95288 672.32580 29.69688 C -673.26180 48.12888 680.02980 58.78488 697.09380 66.63288 C -695.43780 84.92088 694.28580 92.19288 710.26980 103.20888 C -714.08580 103.20888 714.80580 102.48888 721.21380 102.84888 C -721.71780 103.85688 722.22180 104.86488 722.72580 105.87288 C -723.58980 106.01688 724.45380 106.16088 725.31780 106.23288 C -729.06180 102.48888 731.94180 99.75288 732.87780 93.05688 C -740.29380 95.21688 745.04580 103.20888 753.90180 103.20888 C -754.69380 102.48888 754.69380 102.48888 757.64580 102.48888 C -762.03780 106.88088 763.98180 104.50488 768.51780 100.54488 C -767.65380 91.25688 763.33380 83.84088 757.64580 76.06488 C -753.32580 75.05688 749.07780 67.13688 747.92580 62.88888 C -749.36580 62.67288 750.87780 62.38488 752.38980 62.09688 C -754.47780 57.05688 758.79780 53.60088 758.79780 46.25688 C -751.30980 29.62488 738.06180 20.26488 720.06180 20.26488 C -715.45380 15.00888 703.64580 1.47288 695.65380 6.36888 C -691.11780 13.13688 694.57380 20.84088 695.29380 27.46488 C -675.78180 25.01688 656.34180 16.16088 642.66180 2.19288 C -640.35780 -1.55112 638.48580 -2.70312 638.12580 -5.00712 C -643.38180 -5.36712 643.38180 -5.36712 645.25380 -6.44712 C -645.25380 -20.84712 643.74180 -31.14312 637.76580 -44.89512 C -636.25380 -46.40712 636.25380 -46.40712 635.89380 -48.71112 C -648.99780 -49.07112 665.12580 -49.79112 678.73380 -51.73512 C -678.73380 -52.23912 678.73380 -52.74312 678.73380 -53.24712 C -663.39780 -63.61512 643.09380 -80.31912 623.86980 -81.11112 C -625.81380 -93.99912 627.97380 -95.00712 614.79780 -96.51912 C -@c -F - -@rax %Note: Object -587.00580 -92.77512 618.15345 -70.52712 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -613.28580 -92.77512 m -609.68580 -86.58312 600.61380 -91.40712 596.79780 -82.62312 C -596.29380 -82.62312 595.78980 -82.62312 595.28580 -82.62312 C -591.61380 -77.36712 589.16580 -75.85512 587.00580 -70.52712 C -594.49380 -70.88712 598.88580 -71.03112 603.92580 -78.08712 C -609.54180 -80.75112 609.54180 -80.75112 617.10180 -82.62312 C -618.39780 -87.15912 619.69380 -92.77512 613.28580 -92.77512 C -@c -F - -@rax %Note: Object -534.37380 -79.95912 573.46980 -64.09020 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -535.88580 -79.95912 m -535.38180 -79.81512 534.87780 -79.67112 534.37380 -79.59912 C -539.77380 -60.80712 558.34980 -63.54312 573.46980 -65.27112 C -567.13380 -78.01512 550.14180 -74.19912 539.62980 -78.44712 C -538.11780 -79.95912 538.11780 -79.95912 535.88580 -79.95912 C -@c -F - -@rax %Note: Object -612.20580 -75.42312 656.91780 -55.75946 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -620.05380 -75.42312 m -616.88580 -74.63112 612.63780 -68.79912 612.20580 -66.06312 C -630.34980 -54.75912 634.95780 -54.03912 656.91780 -57.71112 C -651.44580 -68.15112 631.64580 -75.42312 620.05380 -75.42312 C -@c -F - -@rax %Note: Object --104.09528 -70.16712 339.97380 514.40088 @E - 1 O 0 @g -0.00 0.00 0.00 1.00 k -/$fm 0 def -226.14180 -70.16712 m -220.81380 -64.83912 220.23780 -58.86312 212.60580 -56.99112 C -211.66980 -58.21512 210.80580 -59.43912 209.94180 -60.73512 C -201.08580 -61.02312 198.63780 -59.36712 198.63780 -50.94312 C -196.04580 -47.41512 195.90180 -47.19912 197.55780 -44.17512 C -195.54180 -44.17512 193.52580 -44.17512 191.50980 -44.17512 C -185.82180 -54.83112 185.96580 -59.22312 174.22980 -61.09512 C -169.18980 -57.71112 169.62180 -56.55912 168.61380 -51.73512 C -167.67780 -51.59112 166.81380 -51.44712 165.94980 -51.30312 C -153.34980 -67.43112 148.02180 -71.17512 140.38980 -51.73512 C -133.62180 -54.32712 133.62180 -54.32712 127.64580 -58.07112 C -116.48580 -58.07112 114.75780 -54.18312 114.10980 -44.89512 C -106.04580 -45.47112 99.63780 -55.19112 92.29380 -59.58312 C -89.26980 -59.58312 86.24580 -59.58312 83.29380 -59.58312 C -78.46980 -54.75912 78.32580 -52.81512 78.75780 -47.19912 C -72.06180 -48.49512 70.47780 -55.11912 62.19780 -55.11912 C -57.66180 -49.35912 58.38180 -47.05512 57.73380 -40.43112 C -53.91780 -41.51112 53.91780 -41.51112 47.94180 -44.53512 C -24.54180 -44.53512 29.36580 -27.11112 40.45380 -14.36712 C -48.66180 -9.83112 47.79780 -10.62312 56.94180 -10.62312 C -77.24580 9.68088 33.90180 36.53688 22.38180 45.17688 C -2.36580 55.18488 -17.72220 68.07288 -33.99420 82.11288 C --37.66620 83.91288 -45.44220 89.60088 -47.53020 90.03288 C --47.53020 90.53688 -47.53020 91.04088 -47.53020 91.54488 C --60.56220 102.63288 -68.84220 110.04888 -77.98620 122.43288 C --79.49820 126.96888 -82.52220 130.71288 -91.52220 146.55288 C --107.50620 182.40888 -113.69820 219.12888 -77.62620 243.46488 C --59.26620 249.65688 -50.26620 247.64088 -30.25020 244.90488 C --29.31420 243.96888 -8.21820 236.12088 -4.69020 235.47288 C --4.47420 234.89688 -4.25820 234.24888 -3.97020 233.60088 C -4.23780 232.23288 8.19780 227.40888 16.33380 224.96088 C -16.33380 224.45688 16.33380 223.95288 16.33380 223.44888 C -19.06980 221.93688 21.80580 220.42488 24.61380 218.91288 C -24.61380 218.40888 24.61380 217.90488 24.61380 217.40088 C -34.26180 213.44088 44.84580 189.68088 49.45380 178.95288 C -57.08580 182.84088 50.60580 193.78488 52.04580 201.56088 C -52.04580 207.82488 50.82180 221.00088 54.27780 226.47288 C -51.61380 269.67288 66.66180 315.53688 81.34980 355.35288 C -84.37380 359.09688 84.37380 359.09688 93.37380 377.96088 C -109.71780 400.35288 123.39780 430.23288 135.49380 454.85688 C -141.97380 473.57688 150.68580 493.88088 154.28580 512.88888 C -155.43780 514.04088 155.43780 514.04088 159.97380 514.40088 C -154.71780 483.22488 139.81380 451.47288 126.13380 422.81688 C -125.62980 422.74488 125.12580 422.60088 124.62180 422.45688 C -120.37380 404.38488 103.74180 389.55288 97.90980 371.91288 C -95.10180 366.44088 92.36580 360.89688 89.62980 355.35288 C -85.74180 353.91288 78.18180 327.84888 76.88580 320.64888 C -67.23780 302.07288 65.14980 271.11288 61.04580 249.80088 C -61.04580 236.98488 58.81380 218.91288 58.09380 200.84088 C -60.32580 164.62488 60.32580 164.62488 60.32580 155.62488 C -58.74180 153.96888 56.79780 151.88088 54.70980 151.44888 C -51.18180 157.92888 51.54180 163.25688 47.50980 168.44088 C -36.99780 191.04888 34.04580 195.51288 32.53380 199.32888 C -8.77380 229.06488 -34.28220 244.61688 -70.85820 238.92888 C --76.76220 236.55288 -83.81820 233.74488 -86.26620 227.19288 C --102.17820 211.28088 -97.06620 190.32888 -93.82620 169.95288 C --88.28220 156.12888 -74.09820 119.55288 -59.55420 113.36088 C --56.60220 108.10488 -39.97020 91.18488 -32.48220 90.03288 C --32.48220 89.52888 -32.48220 89.02488 -32.48220 88.52088 C --29.38620 86.79288 -26.29020 84.99288 -23.12220 83.19288 C --23.05020 82.76088 -22.90620 82.25688 -22.76220 81.75288 C --12.17820 77.00088 -1.16220 63.75288 10.35780 61.01688 C -12.51780 58.85688 23.53380 52.52088 27.63780 51.58488 C -30.73380 43.16088 45.27780 42.15288 49.45380 32.72088 C -57.15780 29.98488 64.71780 19.11288 67.81380 10.83288 C -67.81380 2.33688 69.61380 -5.36712 63.70980 -12.85512 C -51.18180 -16.23912 38.50980 -18.90312 38.50980 -34.38312 C -40.02180 -35.89512 40.02180 -35.89512 40.45380 -37.40712 C -44.70180 -36.75912 48.94980 -36.11112 53.19780 -35.46312 C -55.71780 -31.14312 61.33380 -27.83112 66.37380 -28.33512 C -66.37380 -34.31112 64.93380 -40.14312 65.22180 -47.19912 C -77.38980 -43.45512 72.70980 -30.92712 84.80580 -29.84712 C -85.23780 -36.90312 83.86980 -43.88712 85.52580 -51.73512 C -98.26980 -50.72712 104.67780 -40.64712 115.62180 -34.74312 C -119.43780 -25.23912 121.30980 -18.18312 132.90180 -16.31112 C -132.90180 -17.03112 132.90180 -17.75112 132.90180 -18.54312 C -145.64580 -14.65512 139.59780 -8.46312 143.77380 0.32088 C -143.77380 10.11288 143.77380 19.90488 143.77380 29.69688 C -140.89380 49.49688 138.66180 68.86488 134.77380 87.72888 C -134.77380 126.68088 107.70180 164.26488 107.70180 203.07288 C -106.18980 206.88888 103.16580 233.24088 102.44580 233.96088 C -96.32580 258.51288 101.07780 285.94488 102.44580 310.13688 C -103.16580 313.16088 104.67780 314.67288 105.10980 319.20888 C -106.69380 318.99288 108.27780 318.70488 109.93380 318.41688 C -107.70180 289.76088 107.70180 289.76088 106.90980 289.04088 C -106.90980 256.85688 110.65380 226.04088 114.46980 193.28088 C -117.99780 181.11288 123.18180 165.92088 124.98180 152.60088 C -132.97380 144.60888 141.75780 91.54488 143.77380 80.96088 C -145.28580 64.40088 146.79780 59.07288 150.54180 24.44088 C -150.25380 12.63288 150.03780 0.82488 149.82180 -10.98312 C -142.69380 -25.31112 131.67780 -18.75912 123.46980 -31.35912 C -122.31780 -36.47112 119.14980 -44.46312 122.38980 -49.79112 C -132.46980 -55.04712 136.21380 -39.35112 146.43780 -38.48712 C -146.94180 -45.25512 146.07780 -50.58312 150.18180 -56.55912 C -153.20580 -56.55912 153.20580 -56.55912 158.02980 -54.75912 C -161.05380 -47.91912 167.10180 -38.12712 169.76580 -32.43912 C -171.49380 -32.58312 173.22180 -32.72712 175.02180 -32.87112 C -175.38180 -47.19912 175.38180 -47.19912 176.53380 -52.09512 C -185.67780 -52.09512 184.38180 -46.40712 187.40580 -38.91912 C -188.91780 -21.71112 190.71780 -3.85512 184.38180 12.34488 C -183.22980 23.36088 182.43780 30.12888 184.02180 40.28088 C -183.51780 40.28088 183.01380 40.28088 182.50980 40.28088 C -182.07780 54.39288 183.30180 68.14488 184.38180 81.75288 C -180.13380 90.10488 179.41380 99.39288 177.97380 107.74488 C -177.46980 107.88888 176.96580 108.03288 176.53380 108.10488 C -175.38180 114.87288 176.10180 115.66488 175.02180 124.66488 C -165.66180 122.50488 166.02180 122.57688 163.35780 131.50488 C -163.35780 140.50488 164.07780 141.29688 164.79780 148.06488 C -164.07780 148.78488 164.79780 167.64888 164.07780 193.28088 C -163.06980 201.63288 162.06180 209.91288 161.05380 218.19288 C -155.72580 218.62488 156.51780 215.52888 151.33380 219.70488 C -145.57380 239.93688 152.98980 260.88888 153.92580 280.76088 C -151.69380 280.40088 149.46180 278.09688 147.94980 278.09688 C -138.22980 287.81688 162.34980 335.91288 163.71780 344.84088 C -157.59780 344.26488 152.19780 327.63288 146.79780 332.74488 C -146.79780 337.28088 148.30980 340.30488 149.02980 344.04888 C -154.21380 353.62488 179.55780 393.36888 177.97380 404.02488 C -177.18180 404.02488 176.46180 404.02488 175.74180 404.02488 C -172.50180 400.13688 170.77380 397.18488 165.94980 397.18488 C -161.48580 401.64888 168.97380 410.14488 171.56580 414.17688 C -179.26980 431.45688 190.14180 449.60088 194.17380 467.67288 C -198.34980 473.50488 197.91780 485.24088 205.04580 486.53688 C -205.90980 467.38488 189.92580 438.80088 181.35780 421.66488 C -178.83780 419.14488 179.19780 419.72088 178.76580 415.68888 C -181.71780 416.33688 184.74180 416.98488 187.76580 417.56088 C -188.48580 417.05688 189.20580 416.55288 189.99780 416.04888 C -191.29380 396.46488 165.15780 373.42488 160.69380 352.32888 C -165.30180 354.99288 168.03780 359.52888 173.50980 359.52888 C -175.02180 358.01688 175.02180 358.01688 175.38180 356.14488 C -166.45380 336.92088 159.68580 321.44088 155.43780 300.34488 C -160.90980 303.08088 156.58980 308.91288 165.58980 307.83288 C -165.58980 305.60088 165.58980 303.36888 165.58980 301.06488 C -159.75780 280.61688 156.73380 260.09688 156.22980 238.49688 C -158.60580 239.36088 158.53380 240.94488 159.18180 243.03288 C -161.41380 243.03288 163.64580 243.03288 165.94980 243.03288 C -167.53380 211.42488 170.62980 179.60088 171.99780 147.27288 C -172.57380 147.56088 173.22180 147.84888 173.86980 148.06488 C -175.38180 156.34488 175.38180 156.34488 177.97380 163.11288 C -179.70180 163.11288 181.50180 163.11288 183.30180 163.11288 C -183.44580 155.55288 183.22980 150.65688 181.35780 142.80888 C -182.14980 125.45688 182.86980 124.66488 182.50980 114.87288 C -183.01380 114.87288 183.51780 114.87288 184.02180 114.87288 C -183.58980 104.00088 184.02180 99.75288 188.55780 89.24088 C -194.53380 90.68088 208.35780 129.05688 211.45380 136.76088 C -212.17380 144.03288 211.81380 152.16888 219.73380 145.76088 C -220.30980 140.50488 220.95780 135.24888 221.60580 129.99288 C -222.46980 130.28088 223.33380 130.49688 224.19780 130.71288 C -227.22180 138.27288 230.24580 143.52888 236.22180 160.08888 C -240.54180 168.58488 241.83780 180.75288 248.31780 187.23288 C -248.17380 189.75288 248.02980 192.27288 247.95780 194.79288 C -251.70180 195.15288 251.70180 195.15288 254.72580 194.07288 C -257.02980 188.81688 259.40580 183.56088 261.78180 178.23288 C -262.42980 178.16088 263.07780 178.01688 263.72580 177.87288 C -270.13380 197.96088 269.34180 223.44888 269.34180 243.82488 C -270.85380 247.56888 270.85380 252.10488 272.00580 253.97688 C -279.99780 252.46488 282.73380 238.78488 284.74980 231.00888 C -286.62180 231.72888 286.62180 231.72888 287.41380 233.24088 C -288.34980 262.04088 284.53380 290.98488 285.90180 319.20888 C -287.41380 320.64888 287.41380 320.64888 289.28580 321.08088 C -292.52580 318.48888 296.05380 311.43288 300.51780 310.49688 C -301.95780 318.27288 294.10980 335.98488 291.87780 343.32888 C -288.85380 349.44888 278.77380 368.96088 282.08580 374.21688 C -287.12580 374.57688 290.29380 369.39288 294.90180 370.40088 C -292.66980 377.96088 292.66980 377.96088 289.64580 384.72888 C -280.64580 397.54488 267.10980 413.38488 266.74980 414.89688 C -246.51780 429.87288 232.18980 452.55288 221.24580 473.72088 C -218.22180 477.03288 215.19780 480.27288 212.17380 483.51288 C -210.66180 488.76888 210.66180 488.76888 209.22180 490.28088 C -211.09380 510.51288 215.34180 492.22488 219.73380 488.76888 C -221.10180 480.63288 230.31780 470.04888 233.98980 460.90488 C -249.03780 440.52888 249.03780 440.52888 258.03780 430.73688 C -260.98980 429.65688 276.03780 412.37688 276.46980 410.36088 C -276.97380 410.36088 277.47780 410.36088 277.98180 410.36088 C -277.98180 409.85688 277.98180 409.35288 277.98180 408.84888 C -278.48580 408.84888 278.98980 408.84888 279.49380 408.84888 C -279.56580 408.12888 279.70980 407.40888 279.85380 406.61688 C -290.94180 394.23288 299.29380 382.49688 303.54180 365.14488 C -304.04580 365.14488 304.54980 365.14488 305.05380 365.14488 C -307.21380 360.82488 305.41380 356.50488 300.51780 356.50488 C -297.78180 360.10488 295.26180 362.26488 291.51780 362.91288 C -295.04580 340.80888 308.43780 322.30488 308.43780 297.32088 C -307.93380 296.60088 307.42980 295.88088 306.92580 295.08888 C -306.06180 295.01688 305.19780 294.87288 304.33380 294.72888 C -300.15780 298.83288 297.13380 307.11288 292.30980 307.83288 C -291.87780 298.04088 294.18180 258.08088 294.18180 236.98488 C -293.82180 231.08088 295.76580 212.72088 287.77380 210.99288 C -285.10980 215.16888 285.10980 215.16888 283.23780 220.42488 C -283.81380 220.71288 284.46180 220.92888 285.10980 221.14488 C -284.96580 221.79288 284.82180 222.44088 284.74980 223.08888 C -279.20580 225.39288 278.91780 232.88088 277.98180 237.77688 C -277.18980 237.77688 276.46980 237.77688 275.74980 237.77688 C -274.95780 215.02488 274.38180 188.52888 268.54980 165.41688 C -265.88580 162.60888 265.59780 162.39288 262.21380 162.39288 C -261.78180 165.92088 261.42180 169.44888 261.06180 172.90488 C -255.37380 175.56888 255.80580 176.93688 253.93380 181.61688 C -252.92580 181.76088 251.91780 181.90488 250.90980 181.97688 C -241.54980 157.85688 233.91780 137.69688 230.24580 111.84888 C -224.41380 90.17688 215.55780 70.01688 207.70980 48.56088 C -204.68580 32.00088 204.68580 32.00088 198.63780 6.36888 C -198.34980 -8.96712 198.06180 -23.22312 199.42980 -38.91912 C -202.45380 -46.40712 202.45380 -46.40712 203.53380 -51.30312 C -204.75780 -51.30312 206.05380 -51.30312 207.34980 -51.30312 C -210.44580 -47.48712 209.86980 -46.40712 209.58180 -41.94312 C -212.67780 -39.99912 212.38980 -39.99912 216.70980 -40.43112 C -220.02180 -46.98312 220.45380 -54.18312 225.34980 -61.88712 C -226.42980 -61.74312 227.58180 -61.59912 228.73380 -61.52712 C -231.54180 -54.68712 230.46180 -45.90312 230.60580 -38.91912 C -239.53380 -41.51112 238.95780 -53.60712 247.16580 -53.60712 C -255.94980 -42.66312 244.14180 -32.29512 236.22180 -26.10312 C -229.30980 -11.55912 231.68580 13.49688 240.75780 25.16088 C -253.06980 55.32888 270.13380 81.17688 285.90180 108.82488 C -309.94980 168.44088 309.94980 168.44088 314.41380 181.97688 C -323.34180 215.45688 327.30180 248.64888 330.97380 282.27288 C -335.36580 286.23288 330.39780 325.25688 334.35780 332.38488 C -343.35780 332.38488 338.10180 314.16888 339.97380 306.39288 C -337.02180 261.89688 337.02180 261.89688 334.71780 245.26488 C -329.67780 231.72888 328.23780 216.46488 326.50980 201.56088 C -318.51780 172.68888 307.14180 144.53688 296.41380 116.38488 C -281.36580 88.52088 278.34180 84.70488 269.70180 67.78488 C -269.19780 67.71288 268.69380 67.56888 268.18980 67.42488 C -253.06980 37.47288 235.93380 15.65688 240.75780 -18.54312 C -245.22180 -24.23112 254.14980 -28.83912 256.16580 -37.40712 C -257.89380 -37.26312 259.62180 -37.11912 261.42180 -36.97512 C -264.94980 -41.15112 275.67780 -57.85512 284.38980 -56.19912 C -284.24580 -52.88712 284.10180 -49.64712 284.02980 -46.40712 C -289.57380 -47.41512 293.53380 -48.35112 294.54180 -55.47912 C -295.04580 -55.47912 295.54980 -55.47912 296.05380 -55.47912 C -293.74980 -61.59912 290.86980 -64.04712 285.54180 -68.65512 C -274.09380 -65.34312 266.67780 -52.81512 254.72580 -52.81512 C -250.18980 -60.66312 250.33380 -63.03912 241.18980 -60.73512 C -241.18980 -60.23112 241.18980 -59.72712 241.18980 -59.22312 C -239.67780 -58.71912 238.16580 -58.21512 236.65380 -57.71112 C -234.27780 -63.32712 233.34180 -70.16712 226.14180 -70.16712 C -@c -F - -@rax %Note: Object -298.07433 -67.14312 601.62180 853.66488 @E - 1 O 0 @g -0.00 0.00 0.00 1.00 k -/$fm 0 def -303.54180 -67.14312 m -302.02980 -66.63912 300.51780 -66.13512 299.07780 -65.63112 C -297.92580 -63.03912 297.92580 -63.03912 298.28580 -58.86312 C -300.01380 -58.86312 301.74180 -58.86312 303.54180 -58.86312 C -307.50180 -54.90312 306.70980 -44.53512 306.20580 -39.63912 C -311.10180 -39.27912 311.10180 -39.27912 314.05380 -40.43112 C -320.82180 -51.30312 322.69380 -52.45512 323.84580 -55.11912 C -327.30180 -54.97512 330.82980 -54.83112 334.35780 -54.75912 C -334.35780 -53.75112 334.35780 -52.74312 334.35780 -51.73512 C -334.86180 -51.73512 335.36580 -51.73512 335.86980 -51.73512 C -337.02180 -47.19912 337.02180 -47.19912 337.02180 -44.17512 C -327.80580 -25.67112 327.44580 -15.66312 330.25380 3.34488 C -332.34180 8.96088 337.16580 16.08888 338.17380 21.41688 C -338.74980 21.70488 339.32580 21.92088 339.97380 22.13688 C -346.38180 37.68888 373.66980 51.36888 389.29380 57.20088 C -406.57380 69.87288 430.47780 82.11288 444.51780 98.31288 C -454.38180 105.65688 464.31780 113.14488 470.43780 123.94488 C -483.39780 133.95288 486.99780 162.24888 488.86980 178.23288 C -482.38980 195.80088 481.30980 201.92088 463.66980 206.52888 C -442.64580 206.52888 442.64580 206.52888 441.92580 205.73688 C -427.74180 200.55288 413.19780 196.66488 399.80580 190.68888 C -390.22980 183.20088 380.72580 175.64088 371.22180 168.08088 C -364.52580 159.51288 354.22980 131.28888 347.89380 130.35288 C -345.30180 132.94488 346.23780 134.60088 346.02180 137.48088 C -354.87780 167.43288 364.52580 198.24888 369.34980 228.70488 C -381.44580 270.10488 388.86180 308.91288 390.37380 351.60888 C -388.86180 373.42488 388.86180 373.42488 384.39780 409.64088 C -383.60580 411.15288 382.88580 417.92088 381.37380 420.94488 C -380.58180 425.48088 379.86180 426.20088 373.81380 456.36888 C -370.86180 464.64888 364.81380 475.95288 358.83780 489.56088 C -357.03780 501.72888 349.69380 514.11288 345.66180 524.98488 C -344.65380 524.98488 343.64580 524.98488 342.63780 524.98488 C -342.27780 528.00888 340.76580 529.52088 339.25380 533.26488 C -338.60580 536.79288 337.95780 540.32088 337.38180 543.84888 C -336.87780 543.84888 336.37380 543.84888 335.86980 543.84888 C -332.77380 559.97688 327.80580 575.81688 324.99780 591.29688 C -321.32580 630.10488 322.76580 667.40088 323.48580 705.92088 C -327.94980 740.55288 327.94980 740.55288 329.46180 744.36888 C -331.33380 745.16088 333.20580 745.88088 335.14980 746.60088 C -336.44580 742.85688 334.28580 731.98488 332.48580 728.52888 C -328.95780 684.89688 327.44580 639.46488 331.76580 595.11288 C -335.36580 576.75288 339.75780 557.74488 345.66180 539.31288 C -346.23780 539.09688 346.88580 538.80888 347.53380 538.52088 C -349.40580 530.09688 353.86980 523.11288 357.32580 514.40088 C -358.18980 514.18488 359.05380 513.96888 359.91780 513.68088 C -365.89380 545.43288 375.18180 574.88088 382.88580 605.62488 C -401.53380 651.27288 424.42980 692.74488 448.26180 736.01688 C -458.12580 763.37688 472.38180 786.70488 476.84580 815.93688 C -476.84580 828.60888 479.58180 841.92888 482.46180 853.66488 C -484.47780 853.66488 486.49380 853.66488 488.50980 853.66488 C -488.43780 834.94488 486.13380 815.36088 490.38180 796.35288 C -493.26180 789.72888 496.14180 783.10488 499.02180 776.40888 C -507.44580 777.41688 514.14180 809.96088 526.09380 807.29688 C -527.24580 805.42488 527.24580 805.42488 528.68580 798.58488 C -528.25380 776.55288 526.81380 759.12888 533.65380 737.52888 C -534.58980 737.67288 535.59780 737.81688 536.60580 737.96088 C -542.22180 746.60088 542.22180 746.60088 552.80580 766.18488 C -555.39780 767.33688 555.39780 767.33688 558.42180 767.33688 C -560.29380 765.46488 560.43780 756.53688 558.78180 753.36888 C -560.14980 737.67288 562.88580 723.27288 565.98180 707.43288 C -566.41380 707.43288 566.91780 707.43288 567.42180 707.43288 C -567.78180 704.40888 568.57380 703.61688 572.31780 692.31288 C -577.57380 664.44888 579.08580 660.63288 582.10980 642.56088 C -585.13380 631.25688 588.08580 615.41688 589.59780 611.67288 C -596.79780 564.80088 599.96580 516.05688 601.62180 467.67288 C -598.74180 428.57688 594.06180 394.52088 585.85380 356.14488 C -581.31780 341.81688 579.87780 340.30488 573.82980 321.44088 C -555.82980 286.30488 540.78180 254.48088 516.66180 222.65688 C -508.52580 217.97688 501.32580 198.68088 493.04580 196.30488 C -492.61380 194.28888 492.25380 192.27288 491.89380 190.25688 C -492.90180 188.02488 493.90980 185.79288 494.91780 183.48888 C -496.28580 148.49688 481.45380 117.60888 452.43780 96.44088 C -426.80580 70.80888 395.05380 55.11288 364.81380 36.46488 C -364.45380 35.88888 364.09380 35.24088 363.73380 34.59288 C -342.70980 24.87288 336.66180 4.78488 335.50980 -17.03112 C -341.55780 -32.94312 352.06980 -51.66312 333.63780 -64.11912 C -322.83780 -64.11912 320.60580 -52.88712 314.05380 -51.73512 C -313.26180 -57.99912 312.10980 -67.14312 303.54180 -67.14312 C -@c -F - -@rax %Note: Object -541.14180 -56.55912 585.85380 -26.96088 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -570.44580 -56.55912 m -563.46180 -53.24712 556.11780 -54.68712 552.44580 -47.91912 C -551.94180 -47.91912 551.43780 -47.91912 550.93380 -47.91912 C -547.26180 -39.20712 540.42180 -37.55112 541.14180 -27.18312 C -559.35780 -25.95912 558.78180 -29.70312 574.18980 -40.43112 C -577.35780 -44.96712 579.73380 -50.07912 585.49380 -52.81512 C -585.56580 -53.46312 585.70980 -54.11112 585.85380 -54.75912 C -583.26180 -55.11912 580.23780 -53.60712 574.18980 -53.96712 C -573.90180 -54.83112 573.68580 -55.69512 573.46980 -56.55912 C -572.46180 -56.55912 571.45380 -56.55912 570.44580 -56.55912 C -@c -F - -@rax %Note: Object -598.30980 -56.55912 637.40580 -21.56712 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -602.77380 -56.55912 m -601.26180 -56.41512 599.74980 -56.27112 598.30980 -56.19912 C -599.82180 -48.35112 607.95780 -48.63912 614.07780 -44.53512 C -618.90180 -36.90312 629.98980 -23.79912 637.40580 -21.56712 C -635.82180 -34.02312 633.87780 -42.37512 624.58980 -50.58312 C -612.56580 -53.60712 605.79780 -56.55912 602.77380 -56.55912 C -@c -F - -@rax %Note: Object --189.56041 -47.56365 -38.17020 169.95288 @E - 1 O 0 @g -0.00 0.00 0.00 1.00 k -/$fm 0 def --111.46620 -47.55912 m --128.09820 -39.13512 -147.17820 -16.16712 -147.17820 2.55288 C --140.19420 11.33688 -142.42620 15.65688 -129.46620 11.98488 C --126.51420 9.96888 -106.42620 -5.72712 -103.90620 -5.72712 C --103.90620 -6.44712 -103.90620 -7.16712 -103.90620 -7.95912 C --98.93820 -11.48712 -95.91420 -15.59112 -91.88220 -21.13512 C --91.01820 -20.99112 -90.15420 -20.84712 -89.29020 -20.77512 C --90.73020 17.67288 -95.98620 41.64888 -120.10620 71.88888 C --120.75420 72.17688 -121.40220 72.46488 -121.97820 72.68088 C --121.97820 73.18488 -121.97820 73.68888 -121.97820 74.19288 C --122.98620 74.19288 -123.99420 74.19288 -125.00220 74.19288 C --128.31420 62.02488 -131.12220 48.20088 -146.02620 48.20088 C --155.53020 54.17688 -156.82620 67.49688 -155.02620 77.21688 C --164.09820 76.35288 -177.56220 44.96088 -189.29820 60.58488 C --190.30620 82.25688 -189.44220 95.07288 -172.37820 109.97688 C --172.30620 110.91288 -172.16220 111.77688 -172.01820 112.64088 C --188.43420 129.48888 -190.16220 134.16888 -186.63420 157.13688 C --185.91420 157.49688 -185.19420 157.85688 -184.40220 158.21688 C --179.79420 172.11288 -168.70620 168.87288 -158.05020 163.54488 C --157.33020 161.60088 -150.92220 156.34488 -150.56220 154.83288 C --149.55420 154.97688 -148.54620 155.12088 -147.53820 155.26488 C --142.85820 161.88888 -136.01820 162.17688 -133.28220 169.95288 C --112.76220 169.01688 -117.44220 150.00888 -120.89820 135.24888 C --120.75420 133.73688 -120.61020 132.22488 -120.46620 130.71288 C --87.05820 139.13688 -95.77020 106.80888 -106.57020 87.72888 C --110.53020 84.27288 -112.69020 83.26488 -117.44220 81.75288 C --115.42620 71.88888 -107.36220 66.48888 -102.39420 56.84088 C --92.89020 53.31288 -84.17820 2.62488 -82.52220 -6.44712 C --81.65820 -6.51912 -80.79420 -6.66312 -79.85820 -6.80712 C --69.99420 3.05688 -64.23420 16.66488 -52.06620 24.80088 C --42.34620 34.52088 -41.98620 32.50488 -38.17020 19.90488 C --38.17020 -14.36712 -48.53820 -36.83112 -85.11420 -42.30312 C --95.12220 -47.91912 -100.81020 -47.55912 -111.46620 -47.55912 C -@c -F - -@rax %Note: Object -588.87780 -47.55912 627.61380 15.36888 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -590.74980 -47.55912 m -590.10180 -47.12712 589.45380 -46.76712 588.87780 -46.40712 C -588.87780 -37.62312 595.42980 -24.01512 599.38980 -17.03112 C -599.53380 -16.81512 619.54980 13.92888 627.61380 15.36888 C -626.38980 4.42488 602.70180 -47.55912 590.74980 -47.55912 C -@c -F - -@rax %Note: Object --139.86539 -40.79112 -93.03420 6.00888 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def --106.21020 -40.79112 m --121.61820 -36.83112 -128.67420 -23.43912 -137.38620 -11.77512 C --138.68220 -4.14312 -143.29020 0.39288 -135.51420 6.00888 C --126.94620 6.00888 -99.94620 -15.08712 -98.65020 -24.59112 C --93.82620 -27.83112 -94.40220 -31.28712 -93.03420 -37.40712 C --94.18620 -38.48712 -99.44220 -39.99912 -106.21020 -40.79112 C -@c -F - -@rax %Note: Object --81.37020 -33.23112 -44.62016 20.62488 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def --77.62620 -33.23112 m --78.92220 -32.72712 -80.14620 -32.22312 -81.37020 -31.71912 C --83.60220 -18.25512 -57.89820 18.39288 -45.29820 20.62488 C --41.84220 -1.04712 -51.41820 -33.23112 -77.62620 -33.23112 C -@c -F - -@rax %Note: Object -629.12580 -17.39112 637.40580 -7.95912 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -630.63780 -17.39112 m -629.48580 -16.31112 629.48580 -16.31112 629.12580 -14.00712 C -632.94180 -12.56712 632.79780 -8.75112 637.40580 -7.95912 C -635.38980 -11.99112 633.80580 -14.22312 630.63780 -17.39112 C -@c -F - -@rax %Note: Object -506.97326 6.00888 539.26980 55.32888 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -509.53380 6.00888 m -498.73380 12.70488 521.55780 53.60088 533.65380 55.32888 C -534.73380 50.79288 536.31780 48.56088 539.26980 44.02488 C -537.68580 32.57688 522.99780 6.00888 509.53380 6.00888 C -@c -F - -@rax %Note: Object -543.60794 8.96088 557.79506 45.17688 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -547.18980 8.96088 m -543.80580 18.10488 540.78180 38.04888 547.90980 45.17688 C -549.49380 45.03288 551.14980 44.88888 552.80580 44.74488 C -552.87780 44.31288 553.02180 43.80888 553.16580 43.30488 C -554.17380 43.08888 555.18180 42.80088 556.18980 42.51288 C -560.22180 31.20888 556.26180 18.68088 549.42180 8.96088 C -548.62980 8.96088 547.90980 8.96088 547.18980 8.96088 C -@c -F - -@rax %Note: Object -188.91780 12.34488 223.83780 123.15288 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -191.50980 12.34488 m -189.42180 32.00088 188.91780 50.28888 188.91780 69.65688 C -193.81380 75.56088 193.81380 77.28888 194.89380 84.70488 C -201.37380 96.80088 206.41380 110.98488 212.96580 122.43288 C -213.82980 122.72088 214.69380 122.93688 215.62980 123.15288 C -216.42180 121.06488 216.49380 121.35288 219.37380 120.12888 C -218.22180 117.89688 218.22180 117.89688 218.22180 113.36088 C -220.09380 111.48888 220.38180 110.76888 223.83780 110.33688 C -214.26180 85.35288 203.24580 59.36088 198.63780 32.72088 C -195.39780 29.48088 195.68580 21.27288 195.68580 16.16088 C -195.03780 15.94488 194.38980 15.65688 193.81380 15.36888 C -193.52580 14.50488 193.23780 13.64088 193.02180 12.77688 C -192.51780 12.63288 192.01380 12.48888 191.50980 12.34488 C -@c -F - -@rax %Note: Object -699.67219 12.77688 716.67780 40.64088 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -700.54980 12.77688 m -697.38180 15.72888 703.35780 27.96888 704.65380 32.00088 C -708.39780 36.17688 709.83780 39.92088 715.59780 40.64088 C -715.95780 35.52888 716.31780 30.34488 716.67780 25.16088 C -711.78180 20.55288 706.95780 14.14488 700.54980 12.77688 C -@c -F - -@rax %Note: Object -724.59780 27.82488 753.30454 57.27969 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -728.34180 27.82488 m -727.04580 28.25688 725.82180 28.61688 724.59780 28.97688 C -727.18980 37.97688 727.98180 38.76888 728.34180 41.79288 C -727.69380 42.08088 727.04580 42.29688 726.46980 42.51288 C -726.46980 43.30488 726.46980 44.02488 726.46980 44.74488 C -736.69380 52.23288 737.55780 60.94488 753.18180 55.76088 C -755.55780 42.58488 740.72580 27.82488 728.34180 27.82488 C -@c -F - -@rax %Note: Object -678.83386 34.59288 711.42180 59.81074 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -680.24580 34.59288 m -674.98980 39.84888 685.14180 50.14488 687.73380 54.24888 C -699.68580 60.94488 699.03780 62.02488 711.42180 55.32888 C -711.42180 42.51288 689.67780 34.59288 680.24580 34.59288 C -@c -F - -@rax %Note: Object -719.07591 48.20088 727.83128 59.07288 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -719.34180 48.20088 m -718.90980 53.81688 718.90980 53.81688 720.06180 59.07288 C -727.62180 58.71288 730.28580 58.92888 725.31780 51.22488 C -720.85380 48.20088 720.85380 48.20088 719.34180 48.20088 C -@c -F - -@rax %Note: Object -557.36759 50.79288 593.94898 88.52088 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -558.42180 50.79288 m -555.54180 56.62488 559.35780 65.84088 560.29380 71.16888 C -570.22980 81.10488 576.06180 89.38488 591.54180 88.52088 C -601.98180 73.76088 578.36580 56.62488 565.98180 51.22488 C -563.46180 51.08088 560.94180 50.93688 558.42180 50.79288 C -@c -F - -@rax %Note: Object -540.92665 51.58488 551.95087 69.33402 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -541.86180 51.58488 m -540.78180 56.84088 540.78180 56.84088 541.14180 59.50488 C -541.71780 59.86488 542.36580 60.22488 543.01380 60.58488 C -543.22980 62.88888 543.44580 65.19288 543.73380 67.42488 C -555.61380 76.28088 554.38980 52.73688 541.86180 51.58488 C -@c -F - -@rax %Note: Object -488.86980 54.24888 525.73380 75.31569 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -496.78980 54.24888 m -492.75780 56.12088 490.81380 56.98488 488.86980 59.86488 C -488.86980 72.96888 502.11780 78.15288 513.34980 73.83288 C -517.16580 68.93688 519.25380 65.33688 525.73380 62.88888 C -524.94180 58.71288 501.68580 54.24888 496.78980 54.24888 C -@c -F - -@rax %Note: Object --148.92803 55.76088 -131.77020 92.92195 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def --145.30620 55.76088 m --145.81020 55.90488 -146.31420 56.04888 -146.81820 56.12088 C --150.41820 68.28888 -149.05020 78.72888 -145.66620 90.03288 C --141.63420 92.55288 -138.03420 95.72088 -137.02620 88.52088 C --136.52220 88.52088 -136.01820 88.52088 -135.51420 88.52088 C --130.25820 81.03288 -129.53820 60.58488 -139.25820 55.76088 C --141.27420 55.76088 -143.29020 55.76088 -145.30620 55.76088 C -@c -F - -@rax %Note: Object --184.04220 63.24888 -154.66620 105.08088 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def --182.89020 63.24888 m --183.32220 63.89688 -183.68220 64.54488 -184.04220 65.12088 C --184.04220 83.04888 -181.16220 106.30488 -158.48220 105.08088 C --157.69020 100.54488 -156.17820 98.31288 -154.66620 90.03288 C --160.06620 82.11288 -173.89020 63.24888 -182.89020 63.24888 C -@c -F - -@rax %Note: Object -726.10980 64.04088 761.46180 97.16088 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -731.36580 64.04088 m -729.85380 65.55288 729.85380 65.55288 726.10980 66.63288 C -734.53380 86.00088 738.70980 95.00088 761.46180 97.16088 C -762.39780 85.92888 740.36580 64.04088 731.36580 64.04088 C -@c -F - -@rax %Note: Object -701.93367 66.63288 726.32353 97.52088 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -714.80580 66.63288 m -714.80580 67.13688 714.80580 67.64088 714.80580 68.14488 C -711.99780 68.07288 709.26180 67.92888 706.52580 67.78488 C -694.86180 84.92088 706.81380 98.45688 724.95780 97.52088 C -728.12580 89.81688 725.74980 83.26488 719.70180 77.21688 C -718.98180 73.68888 718.62180 68.28888 714.80580 66.63288 C -@c -F - -@rax %Note: Object -514.93266 70.01688 535.14000 103.06035 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -533.65380 70.01688 m -516.73380 80.31288 510.75780 83.19288 517.81380 102.05688 C -521.55780 103.20888 521.55780 103.20888 530.19780 102.84888 C -536.10180 92.40888 535.38180 82.97688 534.73380 70.37688 C -534.37380 70.30488 534.01380 70.16088 533.65380 70.01688 C -@c -F - -@rax %Note: Object -651.61899 74.55288 671.53380 110.33688 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -654.68580 74.55288 m -653.67780 74.69688 652.66980 74.84088 651.66180 74.91288 C -651.51780 89.88888 651.30180 97.80888 658.42980 110.33688 C -659.65380 110.33688 660.87780 110.33688 662.17380 110.33688 C -662.46180 105.51288 666.63780 104.36088 671.53380 102.05688 C -670.45380 89.31288 664.69380 84.77688 656.19780 74.55288 C -655.69380 74.55288 655.18980 74.55288 654.68580 74.55288 C -@c -F - -@rax %Note: Object -544.45153 76.85688 568.13386 119.04888 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -550.14180 76.85688 m -549.63780 77.36088 549.13380 77.86488 548.62980 78.36888 C -547.33380 78.22488 546.10980 78.08088 544.88580 77.93688 C -543.08580 96.22488 546.10980 107.31288 561.44580 119.04888 C -562.45380 119.04888 563.46180 119.04888 564.46980 119.04888 C -574.54980 108.96888 561.87780 76.85688 550.14180 76.85688 C -@c -F - -@rax %Note: Object --133.33408 89.67288 -102.20400 126.60888 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def --119.74620 89.67288 m --134.07420 91.25688 -135.15420 102.99288 -131.77020 115.30488 C --122.12220 122.14488 -117.80220 126.60888 -105.41820 126.60888 C --97.57020 116.16888 -105.56220 101.26488 -110.31420 90.75288 C --113.69820 89.67288 -113.69820 89.67288 -119.74620 89.67288 C -@c -F - -@rax %Note: Object -580.23780 90.75288 584.77380 93.05688 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -580.23780 90.75288 m -580.23780 91.54488 580.23780 92.33688 580.23780 93.05688 C -581.74980 92.98488 583.26180 92.84088 584.77380 92.69688 C -583.26180 92.04888 581.74980 91.40088 580.23780 90.75288 C -@c -F - -@rax %Note: Object -619.22239 92.69688 651.30180 125.09688 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -620.84580 92.69688 m -614.72580 102.56088 626.24580 119.33688 633.58980 125.09688 C -638.84580 125.09688 639.63780 124.30488 650.94180 123.94488 C -650.50980 117.17688 651.30180 115.66488 651.30180 113.36088 C -642.87780 105.65688 632.00580 94.06488 620.84580 92.69688 C -@c -F - -@rax %Note: Object --152.07420 97.95288 -138.89820 120.81515 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def --148.25820 97.95288 m --149.05020 98.31288 -149.84220 98.67288 -150.56220 99.03288 C --150.56220 99.53688 -150.56220 100.04088 -150.56220 100.54488 C --151.06620 100.54488 -151.57020 100.54488 -152.07420 100.54488 C --152.00220 106.01688 -150.41820 129.41688 -138.89820 117.89688 C --138.89820 111.84888 -139.97820 97.95288 -148.25820 97.95288 C -@c -F - -@rax %Note: Object -668.58180 110.76888 708.03780 145.07943 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -672.68580 110.76888 m -671.31780 111.63288 669.94980 112.49688 668.58180 113.36088 C -668.58180 118.54488 672.10980 120.41688 675.34980 123.94488 C -678.15780 136.40088 691.04580 146.55288 704.29380 145.04088 C -705.08580 142.66488 704.86980 142.16088 708.03780 140.50488 C -704.50980 120.41688 691.98180 113.93688 672.68580 110.76888 C -@c -F - -@rax %Note: Object --183.02854 116.81688 -152.93820 161.29474 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def --167.12220 116.81688 m --180.44220 127.32888 -186.49020 138.92088 -181.01820 154.83288 C --174.03420 163.47288 -170.21820 162.17688 -160.35420 158.57688 C --160.35420 158.14488 -160.35420 157.64088 -160.35420 157.13688 C --148.83420 149.00088 -153.73020 135.89688 -155.45820 123.15288 C --159.77820 119.69688 -161.72220 116.81688 -167.12220 116.81688 C -@c -F - -@rax %Note: Object -659.14980 119.04888 668.26687 128.48088 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -659.14980 119.04888 m -658.64580 125.24088 662.82180 127.54488 668.22180 128.48088 C -668.43780 124.23288 667.93380 123.72888 665.55780 119.40888 C -663.39780 119.33688 661.23780 119.19288 659.14980 119.04888 C -@c -F - -@rax %Note: Object --144.71291 122.79288 -122.98989 162.75288 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def --134.72220 122.79288 m --138.10620 125.60088 -140.62620 127.25688 -144.51420 126.17688 C --144.15420 144.39288 -147.97020 150.65688 -134.00220 162.75288 C --114.05820 162.75288 -126.08220 134.38488 -130.97820 123.58488 C --132.49020 122.79288 -132.49020 122.79288 -134.72220 122.79288 C -@c -F - -@rax %Note: Object -665.14394 133.73688 696.37380 175.20888 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -665.91780 133.73688 m -665.48580 143.16888 662.89380 150.65688 670.09380 157.85688 C -671.31780 163.11288 683.91780 172.11288 688.52580 174.84888 C -690.97380 174.99288 693.49380 175.13688 696.01380 175.20888 C -696.08580 172.47288 696.22980 169.73688 696.37380 166.92888 C -692.62980 159.36888 674.98980 135.96888 665.91780 133.73688 C -@c -F - -@rax %Note: Object -636.69175 135.60888 655.88287 167.28888 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -638.84580 135.60888 m -634.02180 140.43288 638.41380 156.77688 640.35780 162.39288 C -644.96580 164.04888 645.25380 167.28888 652.38180 167.28888 C -656.91780 162.75288 657.06180 142.59288 652.74180 135.96888 C -648.06180 135.89688 643.45380 135.75288 638.84580 135.60888 C -@c -F - -@rax %Note: Object -694.14180 147.70488 699.03780 151.80888 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -694.50180 147.70488 m -694.35780 148.85688 694.21380 150.00888 694.14180 151.08888 C -695.22180 151.37688 696.37380 151.59288 697.52580 151.80888 C -697.52580 151.30488 697.52580 150.80088 697.52580 150.29688 C -698.02980 150.29688 698.53380 150.29688 699.03780 150.29688 C -698.74980 149.72088 698.46180 149.07288 698.24580 148.42488 C -696.94980 148.20888 695.72580 147.99288 694.50180 147.70488 C -@c -F - -@rax %Note: Object -363.73380 173.69688 594.13380 799.37688 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -363.73380 173.69688 m -364.81380 180.46488 370.86180 203.07288 376.83780 231.00888 C -377.62980 231.72888 380.58180 242.31288 381.37380 243.03288 C -388.42980 277.59288 394.98180 310.78488 397.93380 345.56088 C -397.93380 357.65688 397.14180 359.09688 397.14180 367.44888 C -391.16580 413.38488 391.16580 413.38488 390.37380 414.17688 C -387.27780 428.14488 383.38980 442.18488 381.73380 455.64888 C -381.22980 455.64888 380.72580 455.64888 380.22180 455.64888 C -379.06980 462.41688 376.11780 469.18488 372.73380 482.79288 C -372.22980 482.79288 371.72580 482.79288 371.22180 482.79288 C -369.78180 488.33688 368.41380 493.88088 367.04580 499.35288 C -365.74980 522.24888 371.22180 547.44888 378.70980 568.32888 C -379.28580 568.25688 379.93380 568.11288 380.58180 567.96888 C -382.52580 555.94488 384.25380 532.25688 398.29380 526.85688 C -416.29380 526.85688 428.74980 537.72888 443.36580 547.95288 C -444.37380 548.09688 445.38180 548.24088 446.38980 548.31288 C -446.74980 547.59288 447.10980 546.87288 447.54180 546.08088 C -448.18980 527.43288 444.30180 464.28888 473.46180 464.28888 C -484.40580 472.35288 489.80580 482.21688 499.02180 491.43288 C -499.88580 491.36088 500.74980 491.21688 501.68580 491.07288 C -501.68580 479.26488 501.68580 467.45688 501.68580 455.64888 C -503.62980 446.21688 505.14180 430.52088 514.78980 424.32888 C -533.72580 424.32888 535.09380 444.48888 550.14180 446.57688 C -552.80580 426.20088 552.80580 426.20088 553.52580 412.66488 C -558.06180 400.20888 568.28580 389.19288 582.10980 399.84888 C -582.10980 405.60888 575.12580 403.44888 571.23780 403.59288 C -570.80580 404.38488 570.44580 405.17688 570.08580 405.89688 C -567.70980 406.18488 565.33380 406.40088 562.95780 406.61688 C -558.42180 421.08888 558.13380 435.20088 556.54980 449.60088 C -553.88580 452.98488 552.44580 453.34488 552.44580 454.85688 C -541.35780 452.62488 536.46180 446.28888 529.47780 438.29688 C -525.51780 435.27288 521.77380 431.16888 517.09380 431.16888 C -501.97380 449.96088 511.54980 482.93688 506.58180 504.60888 C -489.51780 503.96088 486.27780 471.84888 466.69380 471.84888 C -457.62180 480.92088 455.89380 512.24088 455.02980 523.47288 C -455.02980 533.26488 455.24580 549.03288 451.64580 557.38488 C -450.13380 557.52888 448.62180 557.67288 447.18180 557.74488 C -433.71780 551.33688 410.60580 528.22488 396.78180 535.13688 C -386.98980 553.20888 386.62980 568.25688 386.62980 588.27288 C -398.36580 638.45688 425.07780 681.44088 449.77380 726.22488 C -452.00580 732.27288 455.02980 736.80888 467.05380 762.44088 C -471.44580 774.75288 475.83780 787.06488 480.22980 799.37688 C -480.94980 799.37688 481.66980 799.37688 482.46180 799.37688 C -491.10180 775.97688 491.10180 775.97688 495.63780 766.18488 C -496.78980 765.10488 496.78980 765.10488 500.17380 765.46488 C -506.50980 775.54488 514.35780 784.90488 519.32580 795.63288 C -520.33380 795.63288 521.34180 795.63288 522.34980 795.63288 C -522.27780 785.91288 517.59780 728.88888 536.60580 728.88888 C -539.62980 731.91288 539.62980 731.91288 549.42180 748.47288 C -550.28580 748.40088 551.14980 748.25688 552.01380 748.11288 C -552.80580 746.60088 552.80580 746.60088 554.24580 728.52888 C -562.09380 698.00088 570.66180 668.62488 576.06180 636.51288 C -588.37380 596.69688 589.59780 550.11288 594.13380 508.35288 C -593.34180 506.12088 593.34180 506.12088 594.13380 462.41688 C -589.16580 405.24888 584.19780 356.21688 557.26980 304.88088 C -549.56580 283.92888 537.10980 267.87288 527.24580 247.56888 C -526.30980 247.06488 525.44580 246.56088 524.58180 246.05688 C -523.93380 236.48088 501.54180 217.68888 494.55780 206.52888 C -493.54980 206.16888 492.54180 205.80888 491.53380 205.37688 C -491.24580 204.29688 490.95780 203.14488 490.74180 201.99288 C -489.22980 201.20088 489.22980 201.20088 485.48580 201.56088 C -473.38980 217.90488 461.94180 215.45688 443.36580 214.01688 C -434.29380 211.42488 427.88580 209.69688 420.10980 205.01688 C -396.27780 205.01688 384.46980 179.60088 363.73380 173.69688 C -@c -F - -@rax %Note: Object --27.22620 483.15288 195.36180 602.63660 @E - 1 O 0 @g -0.00 0.00 0.00 1.00 k -/$fm 0 def -41.17380 483.15288 m -28.42980 484.80888 15.75780 488.33688 5.46180 494.81688 C -5.17380 497.26488 -3.32220 500.57688 -5.41020 502.01688 C --8.14620 507.20088 -12.17820 508.56888 -13.69020 512.88888 C --14.69820 513.32088 -15.70620 513.68088 -16.71420 514.04088 C --18.51420 521.31288 -28.16220 522.68088 -27.22620 533.62488 C --24.27420 535.92888 -24.27420 535.92888 -22.76220 535.92888 C --19.09020 532.25688 -16.64220 520.80888 -9.94620 518.93688 C --7.42620 513.68088 5.60580 506.04888 6.61380 502.37688 C -11.86980 499.71288 11.86980 499.71288 22.38180 496.32888 C -22.38180 495.82488 22.38180 495.32088 22.38180 494.81688 C -42.68580 491.43288 42.68580 491.43288 49.45380 491.43288 C -50.96580 492.22488 69.75780 494.45688 93.80580 498.99288 C -97.04580 501.29688 100.28580 503.52888 103.59780 505.76088 C -113.24580 507.41688 132.90180 522.96888 137.79780 530.24088 C -149.24580 539.38488 155.79780 556.44888 160.33380 569.48088 C -160.18980 575.24088 160.04580 581.00088 159.97380 586.76088 C -160.54980 587.04888 161.19780 587.33688 161.84580 587.55288 C -161.91780 588.56088 162.06180 589.56888 162.20580 590.57688 C -161.41380 590.57688 160.69380 590.57688 159.97380 590.57688 C -158.31780 595.32888 157.09380 597.41688 158.02980 601.88088 C -159.18180 602.02488 160.33380 602.16888 161.48580 602.24088 C -171.63780 596.26488 182.58180 604.47288 194.53380 602.24088 C -195.61380 599.57688 195.54180 598.56888 194.89380 595.11288 C -185.24580 594.03288 175.38180 593.67288 166.74180 590.57688 C -167.17380 560.98488 161.62980 547.16088 141.54180 523.47288 C -141.39780 522.75288 141.25380 521.96088 141.18180 521.16888 C -157.23780 523.47288 169.69380 532.11288 180.99780 543.48888 C -183.01380 543.63288 185.02980 543.77688 187.04580 543.84888 C -187.04580 543.34488 187.04580 542.84088 187.04580 542.33688 C -187.54980 542.33688 188.05380 542.33688 188.55780 542.33688 C -186.97380 530.81688 155.58180 517.78488 146.43780 513.32088 C -143.98980 513.46488 141.61380 513.60888 139.23780 513.68088 C -138.87780 515.48088 138.51780 517.20888 138.15780 518.93688 C -130.59780 516.70488 129.37380 509.86488 121.59780 507.27288 C -98.70180 490.35288 68.89380 483.15288 41.17380 483.15288 C -@c -F - -@rax %Note: Object --72.73020 540.46488 248.32205 910.38784 @E - 1 O 0 @g -0.00 0.00 0.00 1.00 k -/$fm 0 def --45.29820 540.46488 m --47.60220 540.96888 -49.83420 541.47288 -52.06620 541.97688 C --66.61020 549.10488 -69.77820 554.50488 -72.73020 569.48088 C --69.85020 596.98488 -42.77820 613.40088 -26.14620 585.24888 C --25.06620 582.00888 -23.91420 578.76888 -22.76220 575.45688 C --8.65020 576.46488 6.90180 589.35288 18.63780 596.98488 C -30.87780 608.64888 58.81380 634.71288 58.81380 653.14488 C -56.50980 655.95288 54.27780 658.68888 52.04580 661.42488 C -50.24580 677.76888 50.96580 688.49688 54.27780 703.61688 C -57.01380 707.72088 57.94980 708.87288 56.22180 712.68888 C -55.71780 712.68888 55.21380 712.68888 54.70980 712.68888 C -53.34180 720.75288 49.66980 727.52088 55.42980 733.42488 C -56.94180 733.06488 58.45380 732.70488 59.96580 732.27288 C -61.62180 739.47288 62.12580 740.26488 67.81380 744.36888 C -66.66180 752.07288 62.62980 751.85688 58.45380 756.03288 C -54.78180 761.14488 53.12580 763.73688 48.66180 766.61688 C -33.32580 785.33688 13.45380 808.37688 5.46180 830.26488 C -3.94980 838.54488 3.15780 850.64088 0.20580 866.48088 C -1.28580 881.31288 6.03780 894.99288 7.69380 908.67288 C -11.29380 912.27288 14.38980 909.39288 18.63780 907.59288 C -29.94180 905.79288 40.16580 903.63288 51.68580 900.03288 C -52.69380 897.00888 74.43780 889.37688 79.54980 888.29688 C -79.54980 887.79288 79.54980 887.28888 79.54980 886.78488 C -80.26980 886.78488 80.98980 886.78488 81.78180 886.78488 C -81.78180 886.28088 81.78180 885.77688 81.78180 885.27288 C -84.66180 884.19288 90.70980 879.08088 90.06180 874.40088 C -84.01380 875.40888 84.08580 878.79288 80.26980 881.16888 C -68.74980 882.60888 58.74180 890.02488 47.94180 892.83288 C -47.94180 893.33688 47.94180 893.84088 47.94180 894.34488 C -36.27780 897.15288 25.04580 900.46488 13.74180 899.60088 C -12.22980 894.34488 11.43780 893.62488 11.07780 891.32088 C -17.70180 889.08888 31.38180 881.74488 33.68580 873.96888 C -34.54980 873.75288 35.41380 873.53688 36.27780 873.24888 C -36.34980 871.95288 43.47780 862.30488 46.06980 861.15288 C -46.14180 860.43288 46.28580 859.71288 46.42980 858.92088 C -47.00580 858.70488 47.65380 858.48888 48.30180 858.20088 C -62.19780 838.76088 69.10980 816.51288 78.03780 793.76088 C -78.54180 793.61688 79.04580 793.47288 79.54980 793.32888 C -83.00580 809.38488 85.45380 817.01688 93.37380 831.05688 C -100.93380 840.05688 100.93380 840.05688 101.29380 841.56888 C -87.39780 840.92088 80.62980 835.59288 80.62980 850.64088 C -92.65380 864.96888 92.65380 864.96888 98.70180 870.94488 C -113.60580 881.96088 125.12580 885.63288 143.41380 889.08888 C -143.41380 889.88088 143.41380 890.60088 143.41380 891.32088 C -142.62180 891.32088 141.90180 891.32088 141.18180 891.32088 C -141.18180 891.82488 141.18180 892.32888 141.18180 892.83288 C -140.53380 893.12088 139.88580 893.40888 139.23780 893.62488 C -139.45380 894.92088 139.74180 896.14488 140.02980 897.36888 C -166.59780 907.08888 193.88580 913.92888 222.39780 905.28888 C -229.09380 899.24088 229.09380 899.24088 230.60580 898.88088 C -231.82980 895.92888 231.68580 894.34488 235.14180 892.47288 C -235.50180 890.60088 235.86180 888.72888 236.22180 886.78488 C -236.86980 886.56888 237.51780 886.35288 238.16580 886.06488 C -238.02180 884.55288 237.87780 883.04088 237.73380 881.52888 C -247.59780 848.48088 253.78980 819.03288 241.54980 784.25688 C -234.56580 771.51288 237.44580 776.26488 226.86180 777.48888 C -225.56580 769.06488 213.10980 758.26488 206.55780 753.00888 C -193.38180 753.00888 195.25380 765.24888 194.53380 774.46488 C -182.36580 773.60088 175.66980 746.67288 159.97380 743.21688 C -157.95780 744.72888 155.94180 746.24088 153.92580 747.75288 C -152.70180 757.76088 153.99780 764.96088 155.43780 774.46488 C -142.26180 769.78488 132.03780 733.78488 115.62180 744.72888 C -108.13380 761.00088 114.46980 783.39288 119.36580 799.37688 C -105.97380 797.21688 99.27780 777.84888 83.29380 776.76888 C -82.93380 773.52888 82.42980 770.43288 78.03780 769.64088 C -75.08580 772.44888 76.09380 773.38488 72.78180 774.46488 C -73.14180 769.20888 78.32580 766.25688 79.90980 760.13688 C -79.40580 759.41688 78.90180 758.69688 78.39780 757.90488 C -76.95780 757.68888 75.58980 757.47288 74.22180 757.18488 C -74.43780 754.95288 74.72580 752.64888 75.01380 750.34488 C -76.23780 750.12888 77.46180 749.91288 78.75780 749.62488 C -80.12580 745.95288 84.22980 748.25688 83.29380 742.49688 C -81.78180 741.70488 81.78180 741.70488 69.75780 742.85688 C -69.82980 741.34488 69.97380 739.83288 70.11780 738.32088 C -65.07780 733.28088 68.24580 727.37688 69.75780 720.96888 C -74.94180 720.53688 79.47780 721.90488 85.52580 720.60888 C -88.62180 733.92888 91.42980 749.84088 92.29380 763.16088 C -92.79780 763.16088 93.30180 763.16088 93.80580 763.16088 C -93.80580 760.71288 93.80580 758.19288 93.80580 755.67288 C -94.52580 755.31288 95.24580 754.95288 96.03780 754.52088 C -96.10980 748.40088 96.25380 742.20888 96.39780 736.01688 C -90.85380 716.64888 92.72580 698.21688 88.90980 677.98488 C -86.24580 671.28888 76.81380 653.28888 69.75780 651.63288 C -67.16580 642.99288 66.51780 646.52088 61.47780 641.48088 C -51.46980 613.97688 24.75780 593.45688 1.35780 577.40088 C --6.13020 573.58488 -12.89820 567.75288 -21.25020 567.17688 C --24.85020 552.56088 -28.52220 540.46488 -45.29820 540.46488 C -@c -F - -@rax %Note: Object --53.21820 559.25688 -38.27197 582.29688 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def --46.01820 559.25688 m --49.83420 562.28088 -49.83420 562.28088 -51.27420 562.64088 C --51.27420 563.64888 -51.27420 564.65688 -51.27420 565.66488 C --51.92220 565.95288 -52.57020 566.24088 -53.21820 566.45688 C --53.21820 576.96888 -53.21820 576.96888 -52.06620 579.63288 C --50.19420 580.78488 -50.19420 580.78488 -49.83420 582.29688 C --36.73020 581.86488 -35.14620 568.97688 -43.06620 559.25688 C --44.07420 559.25688 -45.08220 559.25688 -46.01820 559.25688 C -@c -F - -@rax %Note: Object -147.81487 656.52888 195.99846 740.98488 @E - 1 O 0 @g -0.00 0.00 0.00 1.00 k -/$fm 0 def -156.94980 656.52888 m -150.18180 661.06488 150.18180 661.06488 149.02980 662.93688 C -147.08580 679.35288 146.14980 700.08888 156.58980 713.40888 C -156.66180 714.92088 156.80580 716.43288 156.94980 717.94488 C -160.26180 718.59288 161.91780 718.80888 164.43780 721.32888 C -179.77380 725.14488 180.20580 727.73688 187.76580 740.98488 C -189.34980 740.84088 191.00580 740.69688 192.66180 740.55288 C -192.66180 732.27288 182.86980 724.28088 184.02180 719.09688 C -184.52580 719.09688 185.02980 719.09688 185.53380 719.09688 C -188.12580 722.55288 191.07780 726.72888 195.32580 727.37688 C -198.42180 721.97688 190.50180 712.47288 185.89380 708.87288 C -185.89380 699.36888 184.45380 671.50488 172.71780 668.19288 C -171.42180 662.86488 161.98980 657.75288 156.94980 656.52888 C -@c -F - -@rax %Note: Object -56.77965 660.27288 85.64995 708.51288 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -61.47780 660.27288 m -52.33380 671.64888 56.79780 704.91288 71.98980 708.51288 C -85.16580 708.51288 86.10180 707.14488 85.52580 692.74488 C -85.02180 692.74488 84.51780 692.74488 84.01380 692.74488 C -80.70180 697.71288 78.25380 697.13688 73.50180 698.72088 C -55.71780 692.38488 60.54180 675.96888 62.98980 661.06488 C -62.48580 660.84888 61.98180 660.56088 61.47780 660.27288 C -@c -F - -@rax %Note: Object -153.92580 682.52088 180.26476 710.53682 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -153.92580 682.52088 m -155.79780 698.57688 159.03780 718.66488 178.76580 707.43288 C -179.55780 702.89688 181.50180 699.36888 179.12580 694.61688 C -175.02180 700.44888 173.65380 700.23288 167.46180 700.23288 C -163.86180 696.27288 157.30980 684.03288 153.92580 682.52088 C -@c -F - -@rax %Note: Object -86.24580 748.83288 242.26980 902.10132 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -120.08580 748.83288 m -114.46980 772.44888 126.13380 790.95288 129.51780 812.19288 C -122.10180 819.60888 98.62980 786.20088 86.24580 785.04888 C -86.60580 791.60088 86.96580 798.15288 87.39780 804.63288 C -95.67780 826.16088 102.30180 835.16088 120.87780 847.97688 C -122.24580 850.20888 123.61380 851.72088 123.10980 854.02488 C -120.08580 854.81688 120.08580 854.81688 115.62180 854.02488 C -106.40580 849.41688 96.82980 847.32888 87.03780 846.82488 C -92.65380 870.44088 128.00580 880.59288 148.66980 883.40088 C -157.66980 883.68888 166.66980 883.97688 175.74180 884.19288 C -177.97380 886.42488 178.69380 886.92888 179.12580 889.80888 C -175.52580 893.40888 159.32580 892.68888 153.20580 893.62488 C -153.20580 894.41688 153.20580 895.13688 153.20580 895.85688 C -175.88580 901.47288 197.26980 905.21688 220.88580 898.52088 C -227.22180 892.83288 227.22180 892.83288 230.96580 887.57688 C -230.96580 878.28888 233.98980 863.02488 238.88580 854.02488 C -239.38980 853.95288 239.89380 853.80888 240.39780 853.66488 C -238.88580 843.72888 241.83780 828.96888 242.26980 817.44888 C -241.54980 809.16888 241.54980 809.16888 235.86180 785.40888 C -234.85380 785.33688 233.84580 785.19288 232.90980 785.04888 C -232.47780 791.81688 232.62180 791.96088 227.65380 793.32888 C -224.12580 784.40088 213.90180 759.27288 202.09380 760.92888 C -201.80580 770.72088 201.51780 780.51288 201.30180 790.30488 C -199.50180 790.30488 197.77380 790.30488 196.04580 790.30488 C -190.57380 781.66488 169.62180 752.14488 159.97380 751.13688 C -159.46980 764.45688 161.77380 774.24888 165.58980 786.56088 C -165.44580 789.00888 165.30180 791.38488 165.22980 793.76088 C -149.89380 793.76088 138.58980 751.42488 120.08580 748.83288 C -@c -F - -@rax %Note: Object -252.06180 759.77688 393.39780 945.96888 @E - 1 O 0 @g -0.00 0.00 0.00 1.00 k -/$fm 0 def -332.12580 759.77688 m -331.33380 759.92088 330.61380 760.06488 329.89380 760.13688 C -329.60580 762.65688 329.31780 765.17688 329.10180 767.69688 C -333.42180 768.34488 338.02980 768.27288 338.89380 773.74488 C -350.91780 778.85688 365.10180 789.36888 373.81380 799.37688 C -395.05380 838.90488 384.97380 892.04088 376.47780 933.51288 C -369.42180 930.99288 368.70180 928.83288 367.04580 922.20888 C -344.43780 914.79288 332.77380 895.06488 319.74180 876.27288 C -308.58180 858.20088 288.92580 830.12088 292.30980 806.93688 C -303.61380 812.55288 310.09380 821.84088 320.10180 829.90488 C -322.33380 830.04888 324.56580 830.19288 326.86980 830.26488 C -326.50980 823.06488 319.45380 813.56088 315.92580 806.93688 C -315.27780 802.18488 314.62980 797.43288 314.05380 792.60888 C -322.40580 793.04088 323.26980 798.29688 334.35780 795.63288 C -336.73380 790.52088 337.30980 778.20888 333.99780 772.95288 C -333.13380 772.88088 332.26980 772.73688 331.40580 772.59288 C -328.23780 775.76088 329.89380 785.55288 329.89380 789.58488 C -327.37380 789.22488 324.85380 788.86488 322.33380 788.43288 C -300.15780 777.12888 307.21380 792.75288 310.30980 809.88888 C -301.52580 809.31288 299.22180 798.22488 289.28580 798.22488 C -280.71780 811.32888 286.90980 824.07288 291.15780 837.82488 C -303.18180 861.15288 303.18180 861.15288 315.20580 880.80888 C -320.24580 887.14488 330.18180 898.37688 332.91780 905.64888 C -307.64580 899.67288 288.27780 875.33688 265.23780 864.17688 C -262.64580 859.13688 259.54980 855.53688 253.93380 855.53688 C -251.70180 857.76888 252.27780 858.70488 252.06180 861.15288 C -257.24580 863.52888 258.46980 864.75288 261.78180 869.50488 C -288.27780 887.79288 315.70980 905.07288 344.14980 920.40888 C -355.52580 927.89688 369.56580 934.80888 377.98980 945.96888 C -385.83780 945.96888 383.31780 942.00888 383.60580 933.51288 C -386.05380 923.21688 390.44580 908.24088 389.29380 897.36888 C -389.79780 897.36888 390.30180 897.36888 390.80580 897.36888 C -392.60580 872.45688 393.39780 870.94488 393.39780 855.89688 C -390.44580 849.92088 390.73380 829.47288 390.37380 825.00888 C -384.75780 798.51288 374.89380 788.43288 351.27780 772.95288 C -347.60580 766.25688 339.68580 759.77688 332.12580 759.77688 C -@c -F - -@rax %Note: Object -6.60359 765.82488 72.78180 884.91288 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -62.19780 765.82488 m -57.30180 769.56888 50.67780 774.96888 47.94180 779.79288 C -47.43780 779.79288 46.93380 779.79288 46.42980 779.79288 C -34.33380 794.33688 21.66180 812.19288 13.74180 828.03288 C -9.63780 842.14488 2.36580 872.38488 9.56580 884.91288 C -18.56580 883.32888 33.54180 869.57688 37.42980 860.43288 C -37.93380 860.43288 38.43780 860.43288 38.94180 860.43288 C -44.19780 852.51288 44.19780 852.51288 46.06980 851.36088 C -53.05380 838.90488 74.94180 795.41688 72.78180 785.40888 C -70.47780 785.40888 68.96580 786.20088 64.50180 786.20088 C -63.34980 785.04888 63.34980 785.04888 62.98980 781.30488 C -63.56580 781.08888 64.21380 780.80088 64.86180 780.51288 C -64.86180 779.00088 64.06980 778.28088 63.70980 772.95288 C -66.51780 771.65688 67.23780 771.00888 66.73380 767.33688 C -64.50180 765.82488 64.50180 765.82488 62.19780 765.82488 C -@c -F - -%%PageTrailer -@rs -@rs -%%Trailer -@EndSysCorelDict -end -%%DocumentSuppliedResources: procset wCorel8Dict -%%EOF - -%%EndDocument - diff --git a/seminar/static/seminar/lisak.pdf b/seminar/static/seminar/lisak.pdf new file mode 100644 index 0000000000000000000000000000000000000000..f90b2784a721c629ab2b509433196981ab8cec94 GIT binary patch literal 1959 zcmb7FYfuwc7_A~AD`HjD3btGyNKy*fO|l_Eh?N8w1_~IIY6W$ZED#J?+}%I`Tc?8) z@PV`?^+DBQDZUWIp|n*TQ3M=2;-j@#r&I-}*eVWHr^U)pdv8b}MgR0pW;c88-TR&I zeBV7Akfe?dCPGLopz&edASMMkV6<77LIFhav?+tn1SEts7yv*NZ7}jQ3-3mXr`5EM z(bJexiE%tjQ`wkhFIh@>wq)*Glu#sXGD2nS+Z8X}XDizOr=WRegu zDJNwh&Hk#2G4b$S4xsuB7bAvc%sDRXhXdMCXF|!421}W^928iW?}TFk&zfoHlM1d< z)42v6t%-?5pd(!k%`s+HM{@v4r*TOWWsW3u=@Iz|t(Wx(5_g!MLqilslx)`Wc9EhP zHrtLwx@v($kUG*I&Krn}E846+ku)EZmPBP9S}Cx+ z-`Bdo;quaO_b}gmcUyP$mz7^?cog#Gthf_Tr>TzUKCmhJj>io4)_haed@Zmut0vFD z7dDQIXs>T;O5Ij!n|HG>E%w}^e#Nt%n#z9nVtUckP>pPQiuFNb?Dvxsf41gs_33O{|^sRi@=g#l7v5+-m)DyK@8{!LRSkoCZEFd z30}T)q!Q!R`ejA!)>1#IJd;f)8r%ZUGzFKaeRs^75LxcMj#_KwU#Ti+CfBX%lTTT& z{?tLWdmuF}Xi50}p1jWe`zV!r2Zqg(KFsdEx%_nfxT5(JOOK@tsdMvwd{koF5r~zi zhY7WX{aIVIJtrT8x~;7$_nF&q;CQS=rBy}>tC=*-TJK`=>@}m%n>+5-HzizV?5aFV z1%@g_`uc|Ro^MDaCjAku?vO9NmE9h+HSk*3EApe|}p?zv9hc(0<8uPOFDoR@qtb%X7GK}oM{bI-G!+V%wpXWod+|JbMedPP}F za@QVfYsBv6drDi&i{66z+~F-UoOGUh)Re;q!rsRJ(_2RU13829V2%0*XWul=py!}Z zAdAtAn1UJEiOb1c?6N@;%jnHIXx9QAWndXVgb-v1fdfG%&*y}Rpus^jgQapZ4LUA_ zVKan6dmt4wbKbz1)W{qK>M$`*EG7s-A||9_TpolIfjBO7i3ztH%UVV8l#$7>Z-*R^ zb9mlprWTe?$8hM+7(Oz9j3lA;r2_|s;sN_CFgYVP(Y)6k@IO72G$MfHf-gw crgR3N+Sy%}<0+Q63q;6BDHaeAl^Biv3#gunCIA2c literal 0 HcmV?d00001 diff --git a/seminar/templates/seminar/archiv/obalky.tex b/seminar/templates/seminar/archiv/obalky.tex index ea20f63d..5f2d8e07 100644 --- a/seminar/templates/seminar/archiv/obalky.tex +++ b/seminar/templates/seminar/archiv/obalky.tex @@ -86,7 +86,8 @@ % Tohle makro vysází samotnou obálku \def\obalka#1#2#3#4#5#6#7{ % Horní a pravý okraj je zároveň okraj stránky, resetujeme odsazení -\includegraphics[height=2.55cm]{lisak.eps}\hskip 1 em\vbox{% +\includegraphics[height=2.55cm]{lisak.pdf} +\vbox{% \adresaMaM} \vskip 7.3 cm % Od oka \hskip\toskip% diff --git a/seminar/views.py b/seminar/views.py index 3dc29596..0e0c25a2 100644 --- a/seminar/views.py +++ b/seminar/views.py @@ -625,9 +625,9 @@ def obalkyView(request,resitele): tex = render(request,'seminar/archiv/obalky.tex', {'resitele': resitele}).content tempdir = tempfile.mkdtemp() - with open(tempdir+"/obalky.tex","wb") as texfile: + with open(tempdir+"/obalky.tex","w") as texfile: texfile.write(tex) - shutil.copy(os.path.join(settings.STATIC_ROOT, 'seminar/lisak.eps'),tempdir) + shutil.copy(os.path.join(settings.STATIC_ROOT, 'seminar/lisak.pdf'),tempdir) subprocess.call(["pdflatex","obalky.tex"],cwd = tempdir) with open(tempdir+"/obalky.pdf","rb") as pdffile: From dbc7cc2e57026d406ebfbd0633df52edd71f92d2 Mon Sep 17 00:00:00 2001 From: Pavel 'LEdoian' Turinsky Date: Thu, 14 Nov 2019 04:00:27 +0100 Subject: [PATCH 52/92] =?UTF-8?q?Oprava=20rozbit=C3=A9ho=20override=20save?= =?UTF-8?q?(),=20kter=C3=A9mu=20chyb=C4=9Bly=20*args=20a=20**kwargs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/models.py | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/seminar/models.py b/seminar/models.py index 85b2a9e8..0b33ddcc 100644 --- a/seminar/models.py +++ b/seminar/models.py @@ -384,8 +384,8 @@ class Rocnik(SeminarModelBase): cache.set(name, c, 300) return c - def save(self): - super().save() + def save(self, *args, **kwargs): + super().save(*args, **kwargs) # *Node.save() aktualizuje název *Nodu. self.rocniknode.save() @@ -481,8 +481,8 @@ class Cislo(SeminarModelBase): return None return c - def save(self): - super().save() + def save(self, *args, **kwargs): + super().save(*args, **kwargs) # *Node.save() aktualizuje název *Nodu. self.cislonode.save() @@ -716,8 +716,8 @@ class Tema(Problem): return "t{}".format(self.kod) return '' - def save(self): - super().save() + def save(self, *args, **kwargs): + super().save(*args, **kwargs) # *Node.save() aktualizuje název *Nodu. for tvcn in self_temavcislenode_set: tvcn.save() @@ -742,8 +742,8 @@ class Clanek(Problem): return "c{}".format(self.kod) return '' - def save(self): - super().save() + def save(self, *args, **kwargs): + super().save(*args, **kwargs) # *Node.save() aktualizuje název *Nodu. self.claneknode.save() @@ -764,8 +764,8 @@ class Text(SeminarModelBase): # obrázky mají návaznost opačným směrem (vazba z druhé strany) - def save(self): - super().save() + def save(self, *args, **kwargs): + super().save(*args, **kwargs) # *Node.save() aktualizuje název *Nodu. for tn in self.textnode_set: tn.save() @@ -804,8 +804,8 @@ class Uloha(Problem): return name return '' - def save(self): - super().save() + def save(self, *args, **kwargs): + super().save(*args, **kwargs) # *Node.save() aktualizuje název *Nodu. self.ulohazadaninode.save() self.ulohavzoraknode.save() @@ -991,8 +991,8 @@ class Pohadka(SeminarModelBase): uryvek = self.text if len(self.text) < 50 else self.text[:(50-3)]+"..." return uryvek - def save(self): - super().save() + def save(self, *args, **kwargs): + super().save(*args, **kwargs) # *Node.save() aktualizuje název *Nodu. self.pohadkanode.save() @@ -1105,8 +1105,8 @@ class Konfera(models.Model): def __str__(self): return "{}: ({})".format(self.nazev, self.soustredeni) - def save(self): - super().save() + def save(self, *args, **kwargs): + super().save(*args, **kwargs) # *Node.save() aktualizuje název *Nodu. self.konferanode.save() @@ -1224,9 +1224,9 @@ class TreeNode(PolymorphicModel): #TODO: logování return "Nepojmenovaný Treenode" - def save(self): + def save(self, *args, **kwargs): self.aktualizuj_nazev() - super().save() + super().save(*args, **kwargs) class RocnikNode(TreeNode): class Meta: From ea532c681a26d7638f34cc51c19ac75edbf856d9 Mon Sep 17 00:00:00 2001 From: Pavel 'LEdoian' Turinsky Date: Wed, 20 Nov 2019 20:45:32 +0100 Subject: [PATCH 53/92] =?UTF-8?q?Test:=20catchov=C3=A1n=C3=AD=20neexistuj?= =?UTF-8?q?=C3=ADc=C3=ADch=20vazeb?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/models.py | 42 +++++++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/seminar/models.py b/seminar/models.py index 0b33ddcc..fb49644d 100644 --- a/seminar/models.py +++ b/seminar/models.py @@ -387,7 +387,11 @@ class Rocnik(SeminarModelBase): def save(self, *args, **kwargs): super().save(*args, **kwargs) # *Node.save() aktualizuje název *Nodu. - self.rocniknode.save() + try: + self.rocniknode.save() + except RelatedObjectDoesNotExist: + # Neexistující *Node nemá smysl aktualizovat. + pass def cislo_pdf_filename(self, filename): rocnik = str(self.rocnik.rocnik) @@ -484,7 +488,11 @@ class Cislo(SeminarModelBase): def save(self, *args, **kwargs): super().save(*args, **kwargs) # *Node.save() aktualizuje název *Nodu. - self.cislonode.save() + try: + self.cislonode.save() + except RelatedObjectDoesNotExist: + # Neexistující *Node nemá smysl aktualizovat. + pass @reversion.register(ignore_duplicates=True) class Organizator(SeminarModelBase): @@ -745,7 +753,11 @@ class Clanek(Problem): def save(self, *args, **kwargs): super().save(*args, **kwargs) # *Node.save() aktualizuje název *Nodu. - self.claneknode.save() + try: + self.claneknode.save() + except RelatedObjectDoesNotExist: + # Neexistující *Node nemá smysl aktualizovat. + pass class Text(SeminarModelBase): class Meta: @@ -807,8 +819,16 @@ class Uloha(Problem): def save(self, *args, **kwargs): super().save(*args, **kwargs) # *Node.save() aktualizuje název *Nodu. - self.ulohazadaninode.save() - self.ulohavzoraknode.save() + try: + self.ulohazadaninode.save() + except RelatedObjectDoesNotExist: + # Neexistující *Node nemá smysl aktualizovat. + pass + try: + self.ulohavzoraknode.save() + except RelatedObjectDoesNotExist: + # Neexistující *Node nemá smysl aktualizovat. + pass @reversion.register(ignore_duplicates=True) @@ -994,7 +1014,11 @@ class Pohadka(SeminarModelBase): def save(self, *args, **kwargs): super().save(*args, **kwargs) # *Node.save() aktualizuje název *Nodu. - self.pohadkanode.save() + try: + self.pohadkanode.save() + except RelatedObjectDoesNotExist: + # Neexistující *Node nemá smysl aktualizovat. + pass @reversion.register(ignore_duplicates=True) class Soustredeni_Ucastnici(SeminarModelBase): @@ -1108,7 +1132,11 @@ class Konfera(models.Model): def save(self, *args, **kwargs): super().save(*args, **kwargs) # *Node.save() aktualizuje název *Nodu. - self.konferanode.save() + try: + self.konferanode.save() + except RelatedObjectDoesNotExist: + # Neexistující *Node nemá smysl aktualizovat. + pass # Vazebna tabulka. Mozna se generuje automaticky. From 112782699b6d2ebf0da91e534e0f800a9f6fe8ff Mon Sep 17 00:00:00 2001 From: Pavel 'LEdoian' Turinsky Date: Wed, 20 Nov 2019 20:51:17 +0100 Subject: [PATCH 54/92] =?UTF-8?q?Fix:=20ta=20v=C3=BDjimka=20se=20jmenuje?= =?UTF-8?q?=20jinak.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/models.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/seminar/models.py b/seminar/models.py index fb49644d..332a5baa 100644 --- a/seminar/models.py +++ b/seminar/models.py @@ -389,7 +389,7 @@ class Rocnik(SeminarModelBase): # *Node.save() aktualizuje název *Nodu. try: self.rocniknode.save() - except RelatedObjectDoesNotExist: + except ObjectDoesNotExist: # Neexistující *Node nemá smysl aktualizovat. pass @@ -490,7 +490,7 @@ class Cislo(SeminarModelBase): # *Node.save() aktualizuje název *Nodu. try: self.cislonode.save() - except RelatedObjectDoesNotExist: + except ObjectDoesNotExist: # Neexistující *Node nemá smysl aktualizovat. pass @@ -755,7 +755,7 @@ class Clanek(Problem): # *Node.save() aktualizuje název *Nodu. try: self.claneknode.save() - except RelatedObjectDoesNotExist: + except ObjectDoesNotExist: # Neexistující *Node nemá smysl aktualizovat. pass @@ -821,12 +821,12 @@ class Uloha(Problem): # *Node.save() aktualizuje název *Nodu. try: self.ulohazadaninode.save() - except RelatedObjectDoesNotExist: + except ObjectDoesNotExist: # Neexistující *Node nemá smysl aktualizovat. pass try: self.ulohavzoraknode.save() - except RelatedObjectDoesNotExist: + except ObjectDoesNotExist: # Neexistující *Node nemá smysl aktualizovat. pass @@ -1016,7 +1016,7 @@ class Pohadka(SeminarModelBase): # *Node.save() aktualizuje název *Nodu. try: self.pohadkanode.save() - except RelatedObjectDoesNotExist: + except ObjectDoesNotExist: # Neexistující *Node nemá smysl aktualizovat. pass @@ -1134,7 +1134,7 @@ class Konfera(models.Model): # *Node.save() aktualizuje název *Nodu. try: self.konferanode.save() - except RelatedObjectDoesNotExist: + except ObjectDoesNotExist: # Neexistující *Node nemá smysl aktualizovat. pass From 1d65f5ee8e0fff787059ec1877dd9653ecb2fd52 Mon Sep 17 00:00:00 2001 From: Pavel 'LEdoian' Turinsky Date: Wed, 20 Nov 2019 21:17:15 +0100 Subject: [PATCH 55/92] =?UTF-8?q?P=C5=99ejmenov=C3=A1no=20Cislo.cislo=20na?= =?UTF-8?q?=20.poradi?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/migrations/0069_auto_20191120_2115.py | 28 +++++++++++++++++++ seminar/models.py | 2 +- seminar/testutils.py | 2 +- 3 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 seminar/migrations/0069_auto_20191120_2115.py diff --git a/seminar/migrations/0069_auto_20191120_2115.py b/seminar/migrations/0069_auto_20191120_2115.py new file mode 100644 index 00000000..04c6d1dc --- /dev/null +++ b/seminar/migrations/0069_auto_20191120_2115.py @@ -0,0 +1,28 @@ +# Generated by Django 2.2.7 on 2019-11-20 20:15 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0068_treenode_nazev'), + ] + + operations = [ + migrations.AlterModelOptions( + name='cislo', + options={'ordering': ['-rocnik__rocnik', '-poradi'], 'verbose_name': 'Číslo', 'verbose_name_plural': 'Čísla'}, + ), + migrations.RenameField( + model_name='cislo', + old_name='cislo', + new_name='poradi', + ), + migrations.AlterField( + model_name='problem', + name='nadproblem', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='podproblem', to='seminar.Problem', verbose_name='nadřazený problém'), + ), + ] diff --git a/seminar/models.py b/seminar/models.py index 332a5baa..327e7424 100644 --- a/seminar/models.py +++ b/seminar/models.py @@ -480,7 +480,7 @@ class Cislo(SeminarModelBase): def get(cls, rocnik, cislo): try: r = Rocnik.objects.get(rocnik=rocnik) - c = r.cisla.get(cislo=cislo) + c = r.cisla.get(poradi=cislo) except ObjectDoesNotExist: return None return c diff --git a/seminar/testutils.py b/seminar/testutils.py index 83a5ae4b..1e853d72 100644 --- a/seminar/testutils.py +++ b/seminar/testutils.py @@ -333,7 +333,7 @@ def gen_cisla(rnd, rocniky): cislo = Cislo.objects.create( rocnik = rocnik, - cislo = str(ci), + poradi = str(ci), datum_vydani=vydano, datum_deadline=deadline, verejne_db=True From d83ac0eb237bd4cd00871f1c464cd15786e60e34 Mon Sep 17 00:00:00 2001 From: Pavel 'LEdoian' Turinsky Date: Wed, 20 Nov 2019 21:24:51 +0100 Subject: [PATCH 56/92] =?UTF-8?q?Opraven=20chyb=C4=9Bj=C3=ADc=C3=AD=20.all?= =?UTF-8?q?=20na=20*node=5Fset=20v=20nov=C3=BDch=20metod=C3=A1ch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/models.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/seminar/models.py b/seminar/models.py index 327e7424..ff074ff7 100644 --- a/seminar/models.py +++ b/seminar/models.py @@ -727,7 +727,7 @@ class Tema(Problem): def save(self, *args, **kwargs): super().save(*args, **kwargs) # *Node.save() aktualizuje název *Nodu. - for tvcn in self_temavcislenode_set: + for tvcn in self_temavcislenode_set.all(): tvcn.save() class Clanek(Problem): @@ -779,7 +779,7 @@ class Text(SeminarModelBase): def save(self, *args, **kwargs): super().save(*args, **kwargs) # *Node.save() aktualizuje název *Nodu. - for tn in self.textnode_set: + for tn in self.textnode_set.all(): tn.save() From b97e90332c1215abac5e584ae7280789ee351ea1 Mon Sep 17 00:00:00 2001 From: Pavel 'LEdoian' Turinsky Date: Wed, 20 Nov 2019 21:26:33 +0100 Subject: [PATCH 57/92] Typo --- seminar/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/seminar/models.py b/seminar/models.py index ff074ff7..122f7c70 100644 --- a/seminar/models.py +++ b/seminar/models.py @@ -727,7 +727,7 @@ class Tema(Problem): def save(self, *args, **kwargs): super().save(*args, **kwargs) # *Node.save() aktualizuje název *Nodu. - for tvcn in self_temavcislenode_set.all(): + for tvcn in self.temavcislenode_set.all(): tvcn.save() class Clanek(Problem): From 2a85c1c9873dbbb9c17c684a7dcdcaad807a1f71 Mon Sep 17 00:00:00 2001 From: Anet Date: Wed, 20 Nov 2019 23:56:51 +0100 Subject: [PATCH 58/92] =?UTF-8?q?views.py=20|=20p=C5=99eps=C3=A1na=20funkc?= =?UTF-8?q?e=20po=C4=8D=C3=ADtaj=C3=ADc=C3=AD=20po=C5=99ad=C3=AD=20ve=20v?= =?UTF-8?q?=C3=BDsledkovce=20podle=20bod=C5=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/views.py | 105 ++++++++++++++++++++++++++++------------------- 1 file changed, 62 insertions(+), 43 deletions(-) diff --git a/seminar/views.py b/seminar/views.py index 3dc29596..fbf8c46e 100644 --- a/seminar/views.py +++ b/seminar/views.py @@ -260,25 +260,35 @@ class ArchivView(generic.ListView): ### Výsledky -def sloupec_s_poradim(vysledky): - # počet řešitelů ve výsledkovce nad aktuálním - lepsich_resitelu = 0 - - poradi_l = [] - # projdeme skupiny řešitelů se stejným počtem bodů - for skupina in (list(x) for _, x in groupby(vysledky, lambda x: x.body)): - - # připravíme si obsahy buněk ve sloupci pořadí pro skupinu - if len(skupina) == 1: - poradi_l += ["{}.".format(lepsich_resitelu + 1)] - # je-li účastníků se stejným počtem bodů víc, - # pořadí (rozsah X.-Y.) je jen u prvního +# ze seznamu všech bodů vytvoří seznam s pořadími (včetně 3.-5. a pak 2 volná místa atp.) +def sloupec_s_poradim(seznam_s_body): + aktualni_poradi = 1 + sloupec_s_poradim = [] + + # seskupíme seznam všech bodů podle hodnot + for index in range(0, len(seznam_s_body)): + # pokud je pořadí větší než číslo řádku, tak jsme vypsali větší rozsah a chceme + # vypsat už jen prázdné místo, než dojdeme na správný řádek + if (index+1) < aktualni_poradi: + sloupec_s_poradim.append("") + continue + velikost_skupiny = 0 + # zjistíme počet po sobě jdoucích stejných hodnot + while seznam_s_body[index] == seznam_s_body[index + velikost_skupiny]: + velikost_skupiny = velikost_skupiny + 1 + # na konci musíme ošetřit přetečení seznamu + if (index + velikost_skupiny) > len(seznam_s_body) - 1: + break + # pokud je velikost skupiny 1, vypíšu pořadí + if velikost_skupiny == 1: + sloupec_s_poradim.append("{}.".format(aktualni_poradi)) + # pokud je skupina větší, vypíšu rozsah else: - poradi_l += ["{}.–{}.".format(lepsich_resitelu + 1, lepsich_resitelu + len(skupina))] + [""] * (len(skupina)-1) - lepsich_resitelu += len(skupina) - #pomlcka je opravdu pomlcka v unicode!!dulezite pro vysledkovku v TeXu - - return poradi_l + sloupec_s_poradim.append("{}.–{}.".format(aktualni_poradi, + aktualni_poradi+velikost_skupiny-1)) + # zvětšíme aktuální pořadí o tolik, kolik pozic bylo přeskočeno + aktualni_poradi = aktualni_poradi + velikost_skupiny + return sloupec_s_poradim # spočítá součet bodů získaných daným řešitelem za zadaný problém a všechny jeho podproblémy def __soucet_resitele_problemu(problem, resitel, cislo, soucet): @@ -323,6 +333,7 @@ def hlavni_problemy_cisla(cislo): # zunikátnění hlavni_problemy_set = set(hlavni_problemy) hlavni_problemy = list(hlavni_problemy_set) + hlavni_problemy.sort(key=lambda k: k.kod_v_rocniku) # setřídit podle t1, t2, c3, ... return hlavni_problemy @@ -331,7 +342,7 @@ def hlavni_problemy_cisla(cislo): def body_resitele_v_cisle(resitel, cislo): hlavni_problemy = hlavni_problemy_cisla(cislo) for h in hlavni_problemy: - body_resitele = body_resitele + body_resitele_problemu_v_cisle(resitel, cislo) + body_resitele = body_resitele + body_resitele_problemu_v_cisle(h, resitel, cislo) # TODO: je rozdíl mezi odevzdanou úlohou za 0 a tím, když řešitel nic neodevzdal # řešit přes kontrolu velikosti množiny řešení daného problému do daného čísla? # Tady to ale nevadí, tady se počítá součet za číslo. @@ -456,19 +467,16 @@ class ProblemView(generic.DetailView): class VysledkyResitele(object): """Pro daného řešitele ukládá počet bodů za jednotlivé úlohy a celkový - počet bodů za konkrétní číslo.""" + počet bodů za konkrétní ročník do daného čísla a za dané číslo.""" - def __init__(self, resitel): + def __init__(self, resitel, cislo, rocnik): resitel_jmeno = resitel.osoba.jmeno resitel_prijmeni = resitel.osoba.prijmeni - body = {} - body_rocnik = 0 - - def body_za_cislo(self): - return sum(body.values()) - - def body_za_rocnik(self): - return body_rocnik + self.cislo = cislo + body_cislo = body_resitele_v_cisle(resitel, cislo) + body = [] + self.rocnik = rocnik + body_rocnik = body_resitele_v_rocniku(resitel, rocnik, cislo) class CisloView(generic.DetailView): model = Cislo @@ -504,17 +512,18 @@ class CisloView(generic.DetailView): #.filter(hodnoceni_set__rocnik__eq=cislo_rocnik) radky_vysledkovky = [] for ar in aktivni_resitele: - # získáme výsledky řešitele - součty přes jednotlivé hlavní problémy - vr = VysledkyResitele(ar) - # ukládání součtu bodů za všechny hlavní problémy => součet bodů za číslo - vr.body_cislo = body_resitele_v_cisle(ar, cislo) - # výpočet bodů za ročník do daného čísla (aby fungovalo i pro starší čísla) - vr.body_rocnik = body_resitele_v_rocniku(ar, cislo.rocnik, cislo) + # získáme výsledky řešitele - součty přes číslo a ročník + vr = VysledkyResitele(ar, cislo, cislo.rocnik) + for hp in hlavni_problemy: + ar.body.append(body_resitele_problemu_v_cisle(hp, resitel, cislo)) radky_vysledkovky.append(vr) - ## TODO: seřadit řešitele podle bodů v daném ročníku - ## řazení viz fce výše - pochopit a případně přepsat - + ## TODO: + ## vytvořit každému řešiteli objekt nesoucí jeho data + ## setřídit tyto objekty podle bodů + ## vygenerovat sloupec s pořadím pomocí stejně zvané funkce + ## předat to do kontextu + # XXX # problemy = sorted(set(r.problem for r in reseni), key=lambda x:(poradi_typu[x.typ], x.kod_v_rocniku())) # #setridi problemy podle typu a poradi zadani @@ -1013,16 +1022,24 @@ def logoutView(request): return render(request, 'seminar/login.html', {'form': form}) +def prihlaska_log_gdpr_safe(logger, gdpr_logger, msg, form_data): + msg = "{}, form_hash:{}".format(msg,hash(form_data)) + logger.warn(msg) + gdpr_logger.warn(msg+", form:{}".format(form_data)) + + def prihlaskaView(request): + generic_logger = logging.getLogger('seminar.prihlaska') err_logger = logging.getLogger('seminar.prihlaska.problem') form_logger = logging.getLogger('seminar.prihlaska.form') if request.method == 'POST': form = PrihlaskaForm(request.POST) + # TODO vyresit, co se bude v jakych situacich zobrazovat if form.is_valid(): + generic_logger.info("Form valid") fcd = form.cleaned_data - form_hash = hash(frozenset(fcd.items())) - fcd["hash"] = form_hash - form_logger.info(fcd) + form_hash = hash(fcd) + form_logger.info(fcd,form_hash=form_hash) with transaction.atomic(): u = User.objects.create_user( @@ -1051,7 +1068,8 @@ def prihlaskaView(request): o.stat = fcd['stat'] else: # Unknown country - log it - err_logger.warn("Unknown country {}. Form hash:{}".format(fcd['stat_text'],form_hash)) + msg = "Unknown country {}".format(fcd['stat_text']) + err_logger.warn(msg,form_hash=form_hash) o.save() o.user = u @@ -1068,7 +1086,8 @@ def prihlaskaView(request): r.skola = fcd['skola'] else: # Unknown school - log it - err_logger.warn("Unknown school {}, {}. Form hash:{}".format(fcd['skola_nazev'],fcd['skola_adresa'],form_hash)) + msg = "Unknown school {}, {}".format(fcd['skola_nazev'],fcd['skola_adresa']) + err_logger.warn(msg,form_hash=form_hash) r.save() From e4f0b95b70dc2c56508935254c50f4b743036891 Mon Sep 17 00:00:00 2001 From: Anet Date: Wed, 20 Nov 2019 23:58:36 +0100 Subject: [PATCH 59/92] =?UTF-8?q?views.py=20|=20p=C5=99idan=C3=A9=20d?= =?UTF-8?q?=C5=AFle=C5=BEit=C3=A9=20upozorn=C4=9Bn=C3=AD=20k=20funci=20slo?= =?UTF-8?q?upec=5Fs=5Fporadim?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/seminar/views.py b/seminar/views.py index fbf8c46e..252521d7 100644 --- a/seminar/views.py +++ b/seminar/views.py @@ -260,7 +260,7 @@ class ArchivView(generic.ListView): ### Výsledky -# ze seznamu všech bodů vytvoří seznam s pořadími (včetně 3.-5. a pak 2 volná místa atp.) +# ze setřízeného(!) seznamu všech bodů vytvoří seznam s pořadími (včetně 3.-5. a pak 2 volná místa atp.) def sloupec_s_poradim(seznam_s_body): aktualni_poradi = 1 sloupec_s_poradim = [] From cedf5e753b108e596116263047c63a5998623e99 Mon Sep 17 00:00:00 2001 From: "Martin Z. (Zimamazim)" Date: Thu, 21 Nov 2019 00:01:03 +0100 Subject: [PATCH 60/92] =?UTF-8?q?Model=20|=20Tema=20|=20P=C5=99id=C3=A1n?= =?UTF-8?q?=20abstrakt=20a=20obr=C3=A1zek?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/migrations/0070_auto_20191120_2357.py | 23 +++++++++++++++++++ seminar/models.py | 3 +++ 2 files changed, 26 insertions(+) create mode 100644 seminar/migrations/0070_auto_20191120_2357.py diff --git a/seminar/migrations/0070_auto_20191120_2357.py b/seminar/migrations/0070_auto_20191120_2357.py new file mode 100644 index 00000000..3bd5466f --- /dev/null +++ b/seminar/migrations/0070_auto_20191120_2357.py @@ -0,0 +1,23 @@ +# Generated by Django 2.2.7 on 2019-11-20 22:57 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0069_auto_20191120_2115'), + ] + + operations = [ + migrations.AddField( + model_name='tema', + name='abstrakt', + field=models.TextField(blank=True, verbose_name='Abstrakt na rozcestník'), + ), + migrations.AddField( + model_name='tema', + name='obrazek', + field=models.ImageField(null=True, upload_to='', verbose_name='Obrázek na rozcestník'), + ), + ] diff --git a/seminar/models.py b/seminar/models.py index 122f7c70..39e3c9ce 100644 --- a/seminar/models.py +++ b/seminar/models.py @@ -717,6 +717,9 @@ class Tema(Problem): rocnik = models.ForeignKey(Rocnik, verbose_name='ročník',blank=True, null=True, on_delete=models.PROTECT) + abstrakt = models.TextField('Abstrakt na rozcestník', blank=True) + obrazek = models.ImageField('Obrázek na rozcestník', null=True) + def kod_v_rocniku(self): if self.stav == 'zadany': if self.nadproblem: From 9d8e1722e55ddb24fcce6c92f9a6543b8900b2de Mon Sep 17 00:00:00 2001 From: "Martin Z. (Zimamazim)" Date: Thu, 21 Nov 2019 00:33:02 +0100 Subject: [PATCH 61/92] =?UTF-8?q?Magick=C3=A1=20v=C4=9Bc=20a=C5=A5=20nepad?= =?UTF-8?q?aj=C3=AD=20migrace=20na=20star=C3=A9m=20SQLite?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/migrations/0001_squashed_0067_auto_20190814_0805.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/seminar/migrations/0001_squashed_0067_auto_20190814_0805.py b/seminar/migrations/0001_squashed_0067_auto_20190814_0805.py index 287be0f1..05d5f265 100644 --- a/seminar/migrations/0001_squashed_0067_auto_20190814_0805.py +++ b/seminar/migrations/0001_squashed_0067_auto_20190814_0805.py @@ -510,7 +510,7 @@ def vyrob_problemum_ctypes(apps, schema_editor): class Migration(migrations.Migration): - + atomic = False replaces = [('seminar', '0001_initial'), ('seminar', '0002_add_body_views'), ('seminar', '0003_add_skola_zs_ss'), ('seminar', '0004_add_old_dakos_id'), ('seminar', '0005_alter_problem_autor'), ('seminar', '0006_problem_add_timestamp'), ('seminar', '0007_problem_zamereni'), ('seminar', '0008_reseni_forma'), ('seminar', '0009_rename_imported_IDs'), ('seminar', '0010_alter_rok_maturity'), ('seminar', '0011_alter_timestamp_def'), ('seminar', '0012_remove_soustredeni_ucastnici'), ('seminar', '0013_soustredeni_ucastnici_through_model'), ('seminar', '0014_uprava_poznamek'), ('seminar', '0015_soustredeni_text'), ('seminar', '0016_texty_problemu'), ('seminar', '0017_texty_problemu_minor'), ('seminar', '0018_problemnavrh_problemzadany'), ('seminar', '0019_rocnik_ciselne'), ('seminar', '0020_indexy_a_razeni'), ('seminar', '0021_cislo_verejna_vysledkovka'), ('seminar', '0022_decimal_body'), ('seminar', '0023_add_novinky'), ('seminar', '0024_add_organizator'), ('seminar', '0025_zmena_cesty_nahravani_obrazku'), ('seminar', '0026_soustredeni_typ'), ('seminar', '0027_export_flag_a_typ_akce'), ('seminar', '0028_add_body_celkem_views'), ('seminar', '0029_fix_body_celkem_views'), ('seminar', '0030_add_vysledky'), ('seminar', '0031_cislo_pdf'), ('seminar', '0032_cislo_pdf_blank_typos'), ('seminar', '0033_organizator_studuje_popisek'), ('seminar', '0034_reseni_forma_default_email'), ('seminar', '0035_django_imagekit'), ('seminar', '0036_add_org_to_soustredeni'), ('seminar', '0037_prispevek'), ('seminar', '0038_change_meta_prispevek'), ('seminar', '0039_pohadka'), ('seminar', '0040_pohadka_nepovinny_autor'), ('seminar', '0041_konfery'), ('seminar', '0042_cislo_faze'), ('seminar', '0043_uprava_faze'), ('seminar', '0044_uprava_faze'), ('seminar', '0045_cislo_pridani_faze_nahrano'), ('seminar', '0042_auto_20161005_0847'), ('seminar', '0046_merge'), ('seminar', '0047_auto_20170120_2118'), ('seminar', '0048_add_cislo_datum_deadline_soustredeni'), ('seminar', '0049_auto_20190430_2354'), ('seminar', '0050_auto_20190510_2228'), ('seminar', '0051_resitel_to_osoba'), ('seminar', '0052_user_to_organizator'), ('seminar', '0053_organizator_organizuje_od_do'), ('seminar', '0055_smazat_nemigrovane_zastarale_veci'), ('seminar', '0056_vrcholy_pro_rocniky_a_cisla'), ('seminar', '0057_reseni_to_reseni_hodnoceni'), ('seminar', '0058_problem_to_uloha_tema_clanek'), ('seminar', '0059_vytvorit_pohadkanode'), ('seminar', '0060_spoj_stromy'), ('seminar', '0061_kill_frankenstein'), ('seminar', '0062_redukce_modelu_pohadky'), ('seminar', '0063_procisteni_migraci'), ('seminar', '0064_auto_20190610_2358'), ('seminar', '0065_treenode_polymorphic_ctype'), ('seminar', '0066_problem_polymorphic_ctype'), ('seminar', '0067_auto_20190814_0805')] initial = True From cfa005267362aaf14cde257019381f55a1120da1 Mon Sep 17 00:00:00 2001 From: Pavel 'LEdoian' Turinsky Date: Thu, 21 Nov 2019 18:36:51 +0100 Subject: [PATCH 62/92] =?UTF-8?q?Nastavit=20ro=C4=8Dn=C3=ADk=20podle=20akt?= =?UTF-8?q?u=C3=A1ln=C3=ADho=20=C4=8D=C3=ADsla?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/models.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/seminar/models.py b/seminar/models.py index 122f7c70..f7ef945c 100644 --- a/seminar/models.py +++ b/seminar/models.py @@ -1481,12 +1481,15 @@ class Nastaveni(SingletonModel): db_table = 'seminar_nastaveni' verbose_name = 'Nastavení semináře' - aktualni_rocnik = models.ForeignKey(Rocnik, verbose_name='aktuální ročník', - null=False, on_delete=models.PROTECT) +# aktualni_rocnik = models.ForeignKey(Rocnik, verbose_name='aktuální ročník', +# null=False, on_delete=models.PROTECT) aktualni_cislo = models.ForeignKey(Cislo, verbose_name='poslední vydané číslo', null=False, on_delete=models.PROTECT) + def aktualni_rocnik(self): + return self.aktualni_cislo.rocnik + def __str__(self): return 'Nastavení semináře' From 8b9049add9a76ed1a780766cdc2d3e9b7f2f405e Mon Sep 17 00:00:00 2001 From: Pavel 'LEdoian' Turinsky Date: Thu, 21 Nov 2019 18:37:53 +0100 Subject: [PATCH 63/92] =?UTF-8?q?Testdata:=20nenastavovat=20ro=C4=8Dn?= =?UTF-8?q?=C3=ADk?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/testutils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/seminar/testutils.py b/seminar/testutils.py index 1e853d72..204c0ea6 100644 --- a/seminar/testutils.py +++ b/seminar/testutils.py @@ -600,5 +600,5 @@ def create_test_data(size = 6, rnd = None): # obecné nastavení semináře, musí být už přidané ročníky a čísla, jinak se nastaví divně - nastaveni = Nastaveni.objects.create(aktualni_rocnik = Rocnik.objects.last(), + nastaveni = Nastaveni.objects.create( aktualni_cislo = Cislo.objects.all()[1]) From b7497b37d906f06e9cb5a3a7849039f4a847e836 Mon Sep 17 00:00:00 2001 From: Pavel 'LEdoian' Turinsky Date: Thu, 21 Nov 2019 18:39:12 +0100 Subject: [PATCH 64/92] =?UTF-8?q?Migrace=20ru=C5=A1=C3=ADc=C3=AD=20akt.=20?= =?UTF-8?q?ro=C4=8Dn=C3=ADk=20z=20nastaven=C3=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../0070_remove_nastaveni_aktualni_rocnik.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 seminar/migrations/0070_remove_nastaveni_aktualni_rocnik.py diff --git a/seminar/migrations/0070_remove_nastaveni_aktualni_rocnik.py b/seminar/migrations/0070_remove_nastaveni_aktualni_rocnik.py new file mode 100644 index 00000000..6032c1ee --- /dev/null +++ b/seminar/migrations/0070_remove_nastaveni_aktualni_rocnik.py @@ -0,0 +1,17 @@ +# Generated by Django 2.2.7 on 2019-11-21 17:38 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0069_auto_20191120_2115'), + ] + + operations = [ + migrations.RemoveField( + model_name='nastaveni', + name='aktualni_rocnik', + ), + ] From 9e7f09334a25a16a831b567f3ccada6f8f3a29b3 Mon Sep 17 00:00:00 2001 From: KubaR Date: Wed, 27 Nov 2019 20:30:07 +0100 Subject: [PATCH 65/92] =?UTF-8?q?P=C5=99id=C3=A1n=C3=AD=20atomic=20=3D=20F?= =?UTF-8?q?lase?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/migrations/0001_squashed_0067_auto_20190814_0805.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/seminar/migrations/0001_squashed_0067_auto_20190814_0805.py b/seminar/migrations/0001_squashed_0067_auto_20190814_0805.py index 287be0f1..05d5f265 100644 --- a/seminar/migrations/0001_squashed_0067_auto_20190814_0805.py +++ b/seminar/migrations/0001_squashed_0067_auto_20190814_0805.py @@ -510,7 +510,7 @@ def vyrob_problemum_ctypes(apps, schema_editor): class Migration(migrations.Migration): - + atomic = False replaces = [('seminar', '0001_initial'), ('seminar', '0002_add_body_views'), ('seminar', '0003_add_skola_zs_ss'), ('seminar', '0004_add_old_dakos_id'), ('seminar', '0005_alter_problem_autor'), ('seminar', '0006_problem_add_timestamp'), ('seminar', '0007_problem_zamereni'), ('seminar', '0008_reseni_forma'), ('seminar', '0009_rename_imported_IDs'), ('seminar', '0010_alter_rok_maturity'), ('seminar', '0011_alter_timestamp_def'), ('seminar', '0012_remove_soustredeni_ucastnici'), ('seminar', '0013_soustredeni_ucastnici_through_model'), ('seminar', '0014_uprava_poznamek'), ('seminar', '0015_soustredeni_text'), ('seminar', '0016_texty_problemu'), ('seminar', '0017_texty_problemu_minor'), ('seminar', '0018_problemnavrh_problemzadany'), ('seminar', '0019_rocnik_ciselne'), ('seminar', '0020_indexy_a_razeni'), ('seminar', '0021_cislo_verejna_vysledkovka'), ('seminar', '0022_decimal_body'), ('seminar', '0023_add_novinky'), ('seminar', '0024_add_organizator'), ('seminar', '0025_zmena_cesty_nahravani_obrazku'), ('seminar', '0026_soustredeni_typ'), ('seminar', '0027_export_flag_a_typ_akce'), ('seminar', '0028_add_body_celkem_views'), ('seminar', '0029_fix_body_celkem_views'), ('seminar', '0030_add_vysledky'), ('seminar', '0031_cislo_pdf'), ('seminar', '0032_cislo_pdf_blank_typos'), ('seminar', '0033_organizator_studuje_popisek'), ('seminar', '0034_reseni_forma_default_email'), ('seminar', '0035_django_imagekit'), ('seminar', '0036_add_org_to_soustredeni'), ('seminar', '0037_prispevek'), ('seminar', '0038_change_meta_prispevek'), ('seminar', '0039_pohadka'), ('seminar', '0040_pohadka_nepovinny_autor'), ('seminar', '0041_konfery'), ('seminar', '0042_cislo_faze'), ('seminar', '0043_uprava_faze'), ('seminar', '0044_uprava_faze'), ('seminar', '0045_cislo_pridani_faze_nahrano'), ('seminar', '0042_auto_20161005_0847'), ('seminar', '0046_merge'), ('seminar', '0047_auto_20170120_2118'), ('seminar', '0048_add_cislo_datum_deadline_soustredeni'), ('seminar', '0049_auto_20190430_2354'), ('seminar', '0050_auto_20190510_2228'), ('seminar', '0051_resitel_to_osoba'), ('seminar', '0052_user_to_organizator'), ('seminar', '0053_organizator_organizuje_od_do'), ('seminar', '0055_smazat_nemigrovane_zastarale_veci'), ('seminar', '0056_vrcholy_pro_rocniky_a_cisla'), ('seminar', '0057_reseni_to_reseni_hodnoceni'), ('seminar', '0058_problem_to_uloha_tema_clanek'), ('seminar', '0059_vytvorit_pohadkanode'), ('seminar', '0060_spoj_stromy'), ('seminar', '0061_kill_frankenstein'), ('seminar', '0062_redukce_modelu_pohadky'), ('seminar', '0063_procisteni_migraci'), ('seminar', '0064_auto_20190610_2358'), ('seminar', '0065_treenode_polymorphic_ctype'), ('seminar', '0066_problem_polymorphic_ctype'), ('seminar', '0067_auto_20190814_0805')] initial = True From 61c1ebfc9b1f8951865e08906dfb9bfcafc6da8a Mon Sep 17 00:00:00 2001 From: Pavel 'LEdoian' Turinsky Date: Wed, 27 Nov 2019 20:34:27 +0100 Subject: [PATCH 66/92] =?UTF-8?q?Fix=20rozbit=C3=A9ho=20po=C5=99ad=C3=AD?= =?UTF-8?q?=20migrac=C3=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ualni_rocnik.py => 0071_remove_nastaveni_aktualni_rocnik.py} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename seminar/migrations/{0070_remove_nastaveni_aktualni_rocnik.py => 0071_remove_nastaveni_aktualni_rocnik.py} (85%) diff --git a/seminar/migrations/0070_remove_nastaveni_aktualni_rocnik.py b/seminar/migrations/0071_remove_nastaveni_aktualni_rocnik.py similarity index 85% rename from seminar/migrations/0070_remove_nastaveni_aktualni_rocnik.py rename to seminar/migrations/0071_remove_nastaveni_aktualni_rocnik.py index 6032c1ee..d20c1501 100644 --- a/seminar/migrations/0070_remove_nastaveni_aktualni_rocnik.py +++ b/seminar/migrations/0071_remove_nastaveni_aktualni_rocnik.py @@ -6,7 +6,7 @@ from django.db import migrations class Migration(migrations.Migration): dependencies = [ - ('seminar', '0069_auto_20191120_2115'), + ('seminar', '0070_auto_20191120_2357'), ] operations = [ From ad405c16f48019ce26e7ad7c8b05e846600c58f9 Mon Sep 17 00:00:00 2001 From: Anet Date: Wed, 27 Nov 2019 21:44:07 +0100 Subject: [PATCH 67/92] =?UTF-8?q?views=20|=20dops=C3=A1n=C3=AD=20view=20v?= =?UTF-8?q?=C3=BDsledkovky=20=C4=8D=C3=ADsla=20(zat=C3=ADm=20bez=20testov?= =?UTF-8?q?=C3=A1n=C3=AD)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/views.py | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/seminar/views.py b/seminar/views.py index f2906d90..35e2bb6b 100644 --- a/seminar/views.py +++ b/seminar/views.py @@ -477,6 +477,7 @@ class VysledkyResitele(object): body = [] self.rocnik = rocnik body_rocnik = body_resitele_v_rocniku(resitel, rocnik, cislo) + poradi = 0 class CisloView(generic.DetailView): model = Cislo @@ -515,15 +516,30 @@ class CisloView(generic.DetailView): # získáme výsledky řešitele - součty přes číslo a ročník vr = VysledkyResitele(ar, cislo, cislo.rocnik) for hp in hlavni_problemy: - ar.body.append(body_resitele_problemu_v_cisle(hp, resitel, cislo)) + vr.body.append(body_resitele_problemu_v_cisle(hp, resitel, cislo)) radky_vysledkovky.append(vr) ## TODO: - ## vytvořit každému řešiteli objekt nesoucí jeho data - ## setřídit tyto objekty podle bodů - ## vygenerovat sloupec s pořadím pomocí stejně zvané funkce - ## předat to do kontextu - # XXX + # setřídíme řádky výsledkovky/objekty VysledkyResitele podle bodů + radky_vysledkovky.sort(key=lambda vr: vr.body_rocnik, reverse=True) + + # generujeme sloupec s pořadím pomocí stejně zvané funkce + pocty_bodu = [rv.body_rocnik for rv in radky_vysledkovky] + sloupec_poradi = sloupec_s_poradim(pocty_bodu) + + # každému řádku výsledkovky přidáme jeho pořadí + i = 0 + for rv in radky_vysledkovky: + rv.poradi = sloupec_poradi[i] + i = i + 1 + + # vytahané informace předáváme do kontextu + context['radky_vysledkovky'] = radky_vysledkovky + context['problemy'] = hlavni_problemy +# context['v_cisle_zadane'] = TODO +# context['resene_problemy'] = resene_problemy + + return context # problemy = sorted(set(r.problem for r in reseni), key=lambda x:(poradi_typu[x.typ], x.kod_v_rocniku())) # #setridi problemy podle typu a poradi zadani @@ -562,7 +578,6 @@ class CisloView(generic.DetailView): # context['problemy'] = problemy # context['v_cisle_zadane'] = v_cisle_zadane # context['resene_problemy'] = resene_problemy - return context class ArchivTemataView(generic.ListView): model = Problem From 08eb89d790e353f47836970bf821b8d2aa428f94 Mon Sep 17 00:00:00 2001 From: KubaR Date: Wed, 27 Nov 2019 23:45:45 +0100 Subject: [PATCH 68/92] resitelEditView(view.py), EditForm(forms.py), template.edit.html --- seminar/forms.py | 103 ++++++++++++++++++++++++++++ seminar/templates/seminar/edit.html | 85 +++++++++++++++++++++++ seminar/views.py | 28 +++++++- 3 files changed, 213 insertions(+), 3 deletions(-) create mode 100644 seminar/templates/seminar/edit.html diff --git a/seminar/forms.py b/seminar/forms.py index 42d3c2d7..29e6607e 100644 --- a/seminar/forms.py +++ b/seminar/forms.py @@ -121,3 +121,106 @@ class PrihlaskaForm(forms.Form): self.add_error('skola_nazev',forms.ValidationError('Je nutné vyplnit název školy')) elif data.get('skola_adresa')=='': self.add_error('skola_adresa',forms.ValidationError('Je nutné vyplnit adresu školy')) + + + + +class EditForm(forms.Form): + username = forms.CharField(label='Přihlašovací jméno', + max_length=256, + required=True, + help_text='Tímto jménem se následně budeš přihlašovat pro odevzdání řešení a další činnosti v semináři') + password = forms.CharField( + label='Heslo', + max_length=256, + required=False, + widget=forms.PasswordInput()) + password_check = forms.CharField( + label='Ověření hesla', + max_length=256, + required=False, + widget=forms.PasswordInput()) + + jmeno = forms.CharField(label='Jméno', max_length=256, required=True) + prijmeni = forms.CharField(label='Příjmení', max_length=256, required=True) + pohlavi_muz = forms.ChoiceField(label='Pohlaví', + choices = ((True,'muž'),(False,'žena')), required=True) + email = forms.EmailField(label='E-mail',max_length=256, required=True) + telefon = forms.CharField(label='Telefon',max_length=256, required=False) + datum_narozeni = forms.DateField(label='Datum narození', required=False) + ulice = forms.CharField(label='Ulice', max_length=256, required=False) + mesto = forms.CharField(label='Město', max_length=256, required=False) + psc = forms.CharField(label='PSČ', max_length=32, required=False) + stat = forms.ChoiceField(label='Stát', + choices = (('CZ', 'Česká Republika'), + ('SK', 'Slovenská Republika'), + ('other', 'Jiné')), + required=False) + stat_text = forms.CharField(label='Stát', max_length=256, required=False) + + skola = forms.ModelChoiceField(label="Škola", + queryset=Skola.objects.all(), + widget=autocomplete.ModelSelect2( + url='autocomplete_skola', + attrs = {'data-placeholder--id': '-1', + 'data-placeholder--text' : '---', + 'data-allow-clear': 'true'}) + ,required=False) + + skola_nazev = forms.CharField(label='Název školy', max_length=256, required=False) + skola_adresa = forms.CharField(label='Adresa školy', max_length=256, required=False) + +# trida = forms.CharField(label='Třída',max_length=10, required=True) + + rok_maturity = forms.IntegerField( + label='Rok maturity', + min_value=date.today().year, + max_value=date.today().year+8, + required=True) + zasilat = forms.ChoiceField(label='Kam zasílat čísla a řešení',choices = Resitel.ZASILAT_CHOICES, required=True) + gdpr = forms.BooleanField(label='Souhlasím se zpracováním osobních údajů', required=True) + spam = forms.BooleanField(label='Souhlasím se zasíláním materiálů od MFF UK', required=False) +# def clean_username(self): +# err_logger = logging.getLogger('seminar.prihlaska.problem') +# username = self.cleaned_data.get('username') +# try: +# User.objects.get(username=username) +# msg = "Username {} exists".format(username) +# err_logger.info(msg) +# raise forms.ValidationError('Přihlašovací jméno je již použito') +# +# except ObjectDoesNotExist: +# pass +# return username +# +# def clean_email(self): +# err_logger = logging.getLogger('seminar.prihlaska.problem') +# email = self.cleaned_data.get('email') +# try: +# Osoba.objects.get(email=email) +# msg = "Email {} exists".format(email) +# err_logger.info(msg) +# raise forms.ValidationError('Email je již použit') +# +# except ObjectDoesNotExist: +# pass +# return email + #def clean(self): + # super().clean() + # + # err_logger = logging.getLogger('seminar.prihlaska.problem') + + # data = self.cleaned_data + # if data.get('password') != data.get('password_check'): + # self.add_error('password_check',forms.ValidationError('Hesla se neshodují')) + # if data.get('stat') != '' and data.get('stat_text') != '': + # self.add_error('stat',forms.ValidationError('Nelze mít vybraný stát z menu a zároven zapsaný textem')) + # if data.get('skola') and (data.get('skola_nazev') or data.get('skola_adresa')): + # self.add_error('skola',forms.ValidationError('Pokud je škola v seznamu, nevypisujte ji ručně, pokud není, zrušte výběr ze seznamu (křížek vpravo)')) + # if not data.get('skola'): + # if data.get('skola_nazev')=='' and data.get('skola_adresa')=='': + # self.add_error('skola',forms.ValidationError('Je nutné vyplnit školu')) + # elif data.get('skola_nazev')=='': + # self.add_error('skola_nazev',forms.ValidationError('Je nutné vyplnit název školy')) + # elif data.get('skola_adresa')=='': + # self.add_error('skola_adresa',forms.ValidationError('Je nutné vyplnit adresu školy')) diff --git a/seminar/templates/seminar/edit.html b/seminar/templates/seminar/edit.html new file mode 100644 index 00000000..cc039301 --- /dev/null +++ b/seminar/templates/seminar/edit.html @@ -0,0 +1,85 @@ +{% extends "seminar/zadani/base.html" %} +{% load staticfiles %} + +{% block script %} + + {{form.media}} + +{% endblock %} +{% block content %} +

    + {% block nadpis1a %}{% block nadpis1b %} + Změna osobních údajů + {% endblock %}{% endblock %} +

    + + {% csrf_token %} + {{form.non_field_errors}} +
      +
    • + Přihlašovací údaje +
    • + {% include "seminar/prihlaska_field.html" with field=form.username %} +
    • + {% include "seminar/prihlaska_field.html" with field=form.password %} +
    • + {% include "seminar/prihlaska_field.html" with field=form.password_check %} +
    • + Osobní údaje +
    • + {% include "seminar/prihlaska_field.html" with field=form.jmeno %} +
    • + {% include "seminar/prihlaska_field.html" with field=form.prijmeni %} +
    • + {% include "seminar/prihlaska_field.html" with field=form.pohlavi_muz%} +
    • + {% include "seminar/prihlaska_field.html" with field=form.email %} +
    • + {% include "seminar/prihlaska_field.html" with field=form.telefon %} +
    • + {% include "seminar/prihlaska_field.html" with field=form.datum_narozeni %} +
    • +
      + Bydliště +
    • + {% include "seminar/prihlaska_field.html" with field=form.ulice %} +
    • + {% include "seminar/prihlaska_field.html" with field=form.mesto %} +
    • + {% include "seminar/prihlaska_field.html" with field=form.psc %} +
    • + {% include "seminar/prihlaska_field.html" with field=form.stat %} +
    • +
    • + {% include "seminar/prihlaska_field.html" with field=form.stat_text %} +
    • +
      + {% include "seminar/prihlaska_field.html" with field=form.skola %} +
    • + +
    • +
    • + Vyplň prosím celý název a adresu školy.
      + {% include "seminar/prihlaska_field.html" with field=form.skola_nazev %} +
    • +
    • + {% include "seminar/prihlaska_field.html" with field=form.skola_adresa %} +
    • + {% include "seminar/prihlaska_field.html" with field=form.rok_maturity %} +
    • + {% include "seminar/prihlaska_field.html" with field=form.zasilat %} +
    • + {% include "seminar/gdpr.html" %} + {% include "seminar/prihlaska_field.html" with field=form.gdpr %} +
    • + {% include "seminar/prihlaska_field.html" with field=form.spam %} +
    • +
    + + + +{% endblock %} + diff --git a/seminar/views.py b/seminar/views.py index f2906d90..39ee76af 100644 --- a/seminar/views.py +++ b/seminar/views.py @@ -19,7 +19,7 @@ from .models import Problem, Cislo, Reseni, Nastaveni, Rocnik, Soustredeni, Orga #from .models import VysledkyZaCislo, VysledkyKCisluZaRocnik, VysledkyKCisluOdjakziva from . import utils from .unicodecsv import UnicodeWriter -from .forms import PrihlaskaForm, LoginForm +from .forms import PrihlaskaForm, LoginForm, EditForm from datetime import timedelta, date, datetime from django.utils import timezone @@ -989,8 +989,6 @@ class ResitelView(LoginRequiredMixin,generic.DetailView): return Resitel.objects.get(osoba__user=self.request.user) ## Formulare -def resitelEditView(request): - pass def resetPasswordView(request): pass @@ -1027,6 +1025,30 @@ def prihlaska_log_gdpr_safe(logger, gdpr_logger, msg, form_data): logger.warn(msg) gdpr_logger.warn(msg+", form:{}".format(form_data)) +from django.forms.models import model_to_dict +def resitelEditView(request): + ## Načtení objektu Osoba a Resitel, patrici k aktuálně přihlášenému uživately + u = request.user + osoba_edit = Osoba.objects.get(user=u) + resitel_edit = osoba_edit.resitel + user_edit = osoba_edit.user + ## Vytvoření slovníku, kterým předvyplním formulář + prefill_1=model_to_dict(osoba_edit) + prefill_2=model_to_dict(resitel_edit) + prefill_3=model_to_dict(user_edit) + prefill_1.update(prefill_2) + prefill_1.update(prefill_3) + form = EditForm(initial=prefill_1) + ## Změna údajů a jejich uložení + if request.method == 'POST': + form = EditForm(request.POST) + if form.is_valid(): + osoba_edit.prijmeni = 'NOVOTA' + osoba_edit.save() + return HttpResponseRedirect('/thanks/') + else: + ## Stránka před odeslaním formuláře = předvyplněný formulář + return render(request, 'seminar/edit.html', {'form': form}) def prihlaskaView(request): generic_logger = logging.getLogger('seminar.prihlaska') From 5f66fd0b03a7bf84ff488706dc5aca8fcd62ef5c Mon Sep 17 00:00:00 2001 From: KubaR Date: Wed, 4 Dec 2019 22:33:20 +0100 Subject: [PATCH 69/92] EditView, EditFrom, Edit.html uprava --- seminar/forms.py | 16 +------------ seminar/templates/seminar/edit.html | 7 ------ seminar/views.py | 35 ++++++++++++++++++++++++++--- 3 files changed, 33 insertions(+), 25 deletions(-) diff --git a/seminar/forms.py b/seminar/forms.py index 29e6607e..b28beeb9 100644 --- a/seminar/forms.py +++ b/seminar/forms.py @@ -123,23 +123,10 @@ class PrihlaskaForm(forms.Form): self.add_error('skola_adresa',forms.ValidationError('Je nutné vyplnit adresu školy')) - - class EditForm(forms.Form): username = forms.CharField(label='Přihlašovací jméno', max_length=256, - required=True, - help_text='Tímto jménem se následně budeš přihlašovat pro odevzdání řešení a další činnosti v semináři') - password = forms.CharField( - label='Heslo', - max_length=256, - required=False, - widget=forms.PasswordInput()) - password_check = forms.CharField( - label='Ověření hesla', - max_length=256, - required=False, - widget=forms.PasswordInput()) + required=True) jmeno = forms.CharField(label='Jméno', max_length=256, required=True) prijmeni = forms.CharField(label='Příjmení', max_length=256, required=True) @@ -178,7 +165,6 @@ class EditForm(forms.Form): max_value=date.today().year+8, required=True) zasilat = forms.ChoiceField(label='Kam zasílat čísla a řešení',choices = Resitel.ZASILAT_CHOICES, required=True) - gdpr = forms.BooleanField(label='Souhlasím se zpracováním osobních údajů', required=True) spam = forms.BooleanField(label='Souhlasím se zasíláním materiálů od MFF UK', required=False) # def clean_username(self): # err_logger = logging.getLogger('seminar.prihlaska.problem') diff --git a/seminar/templates/seminar/edit.html b/seminar/templates/seminar/edit.html index cc039301..3f3e0d99 100644 --- a/seminar/templates/seminar/edit.html +++ b/seminar/templates/seminar/edit.html @@ -20,10 +20,6 @@ Přihlašovací údaje
  • {% include "seminar/prihlaska_field.html" with field=form.username %} -
  • - {% include "seminar/prihlaska_field.html" with field=form.password %} -
  • - {% include "seminar/prihlaska_field.html" with field=form.password_check %}
  • Osobní údaje
  • @@ -68,9 +64,6 @@ {% include "seminar/prihlaska_field.html" with field=form.rok_maturity %}
  • {% include "seminar/prihlaska_field.html" with field=form.zasilat %} -
  • - {% include "seminar/gdpr.html" %} - {% include "seminar/prihlaska_field.html" with field=form.gdpr %}
  • {% include "seminar/prihlaska_field.html" with field=form.spam %}
  • diff --git a/seminar/views.py b/seminar/views.py index 39ee76af..27728f0c 100644 --- a/seminar/views.py +++ b/seminar/views.py @@ -1027,15 +1027,16 @@ def prihlaska_log_gdpr_safe(logger, gdpr_logger, msg, form_data): from django.forms.models import model_to_dict def resitelEditView(request): + err_logger = logging.getLogger('seminar.prihlaska.problem') ## Načtení objektu Osoba a Resitel, patrici k aktuálně přihlášenému uživately u = request.user osoba_edit = Osoba.objects.get(user=u) resitel_edit = osoba_edit.resitel user_edit = osoba_edit.user ## Vytvoření slovníku, kterým předvyplním formulář - prefill_1=model_to_dict(osoba_edit) + prefill_1=model_to_dict(user_edit) prefill_2=model_to_dict(resitel_edit) - prefill_3=model_to_dict(user_edit) + prefill_3=model_to_dict(osoba_edit) prefill_1.update(prefill_2) prefill_1.update(prefill_3) form = EditForm(initial=prefill_1) @@ -1043,7 +1044,35 @@ def resitelEditView(request): if request.method == 'POST': form = EditForm(request.POST) if form.is_valid(): - osoba_edit.prijmeni = 'NOVOTA' + ## Změny v osobě + fcd = form.cleaned_data + osoba_edit.jmeno = fcd['jmeno'] + osoba_edit.prijmeni = fcd['prijmeni'] + osoba_edit.pohlavi_muz = fcd['pohlavi_muz'] + osoba_edit.email = fcd['email'] + osoba_edit.telefon = fcd['telefon'] + osoba_edit.ulice = fcd['ulice'] + osoba_edit.mesto = fcd['mesto'] + osoba_edit.psc = fcd['psc'] + ## Změny v osobě s podmínkami + if fcd.get('spam',False): + osoba_edit.datum_souhlasu_zasilani = date.today() + if fcd.get('stat','') in ('CZ','SK'): + osoba_edit.stat = fcd['stat'] + else: + ## Neznámá země + msg = "Unknown country {}".format(fcd['stat_text']) + + ## Změny v řešiteli + resitel_edit.skola = fcd['skola'] + resitel_edit.rok_maturity = fcd['rok_maturity'] + resitel_edit.zasilat = fcd['zasilat'] + if fcd.get('skola'): + resitel_edit.skola = fcd['skola'] + else: + # Unknown school - log it + msg = "Unknown school {}, {}".format(fcd['skola_nazev'],fcd['skola_adresa']) + resitel_edit.save() osoba_edit.save() return HttpResponseRedirect('/thanks/') else: From 19fa7361504839d2c9bde0aff7b63a6fb74752c4 Mon Sep 17 00:00:00 2001 From: Pavel 'LEdoian' Turinsky Date: Wed, 4 Dec 2019 23:03:12 +0100 Subject: [PATCH 70/92] =?UTF-8?q?TeXov=C3=BD=20upload=20p=C5=99ejmenov?= =?UTF-8?q?=C3=A1n,=20aby=20se=20za=20chv=C3=ADli=20nekryl=20n=C3=A1zev=20?= =?UTF-8?q?s=20vestav=C4=9Bn=C3=BDm=20LoginView?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/urls.py | 2 +- seminar/views.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/seminar/urls.py b/seminar/urls.py index c37d1357..9d2c158a 100644 --- a/seminar/urls.py +++ b/seminar/urls.py @@ -92,7 +92,7 @@ urlpatterns = [ path('soustredeni//obalky.pdf', staff_member_required(views.soustredeniObalkyView), name='seminar_soustredeni_obalky'), - path('tex-upload/login/', views.LoginView, name='seminar_login'), + path('tex-upload/login/', views.TeXUploadLoginView, name='seminar_login'), path( 'tex-upload/', staff_member_required(views.texUploadView), diff --git a/seminar/views.py b/seminar/views.py index 39ee76af..bb580c08 100644 --- a/seminar/views.py +++ b/seminar/views.py @@ -782,7 +782,7 @@ def StavDatabazeView(request): @ensure_csrf_cookie -def LoginView(request): +def TeXUploadLoginView(request): """Pro přihlášení při nahrávání z texu""" q = request.POST # nastavení cookie csrftoken From 1ff1d050280f389ffbcaf8d26bcc63e6bbc85e3f Mon Sep 17 00:00:00 2001 From: "Martin Z. (Zimamazim)" Date: Thu, 5 Dec 2019 00:50:04 +0100 Subject: [PATCH 71/92] Rozcestnik tematek view --- seminar/migrations/0072_auto_20191204_2257.py | 23 +++++ seminar/models.py | 49 +++++++++-- .../templates/seminar/tematka/rozcestnik.html | 14 ++++ seminar/testutils.py | 3 +- seminar/urls.py | 3 + seminar/utils.py | 9 ++ seminar/views.py | 84 ++++++++++++++++++- 7 files changed, 177 insertions(+), 8 deletions(-) create mode 100644 seminar/migrations/0072_auto_20191204_2257.py create mode 100644 seminar/templates/seminar/tematka/rozcestnik.html diff --git a/seminar/migrations/0072_auto_20191204_2257.py b/seminar/migrations/0072_auto_20191204_2257.py new file mode 100644 index 00000000..f96b670a --- /dev/null +++ b/seminar/migrations/0072_auto_20191204_2257.py @@ -0,0 +1,23 @@ +# Generated by Django 2.2.7 on 2019-12-04 21:57 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0071_remove_nastaveni_aktualni_rocnik'), + ] + + operations = [ + migrations.AddField( + model_name='treenode', + name='srolovatelne', + field=models.BooleanField(blank=True, help_text='Bude na stránce témátka možnost tuto položku skrýt', null=True, verbose_name='Srolovatelné'), + ), + migrations.AddField( + model_name='treenode', + name='zajimave', + field=models.BooleanField(default=False, help_text='Zobrazí se daná věc na rozcestníku témátek', verbose_name='Zajímavé'), + ), + ] diff --git a/seminar/models.py b/seminar/models.py index 691c04af..414f96aa 100644 --- a/seminar/models.py +++ b/seminar/models.py @@ -21,7 +21,7 @@ from taggit.managers import TaggableManager from reversion import revisions as reversion -from seminar.utils import roman +from seminar.utils import roman, FirstTagParser # Pro získání úryvku z TextNode from unidecode import unidecode @@ -785,8 +785,11 @@ class Text(SeminarModelBase): for tn in self.textnode_set.all(): tn.save() - - + def __str__(self): + parser = FirstTagParser() + parser.feed(str(self.na_web)) + return parser.firstTag + class Uloha(Problem): class Meta: db_table = 'seminar_ulohy' @@ -1238,8 +1241,15 @@ class TreeNode(PolymorphicModel): on_delete=models.SET_NULL, verbose_name="další element na stejné úrovni") nazev = models.TextField("název tohoto node", - help_text = "Tento název se zobrazuje v nabídkách pro výběr vhodného TreeNode", - blank=False, null=True) + help_text = "Tento název se zobrazuje v nabídkách pro výběr vhodného TreeNode", + blank=False, + null=True) + zajimave = models.BooleanField(default = False, + verbose_name = "Zajímavé", + help_text = "Zobrazí se daná věc na rozcestníku témátek") + srolovatelne = models.BooleanField(null = True, blank = True, + verbose_name = "Srolovatelné", + help_text = "Bude na stránce témátka možnost tuto položku skrýt") def print_tree(self,indent=0): print("{}TreeNode({})".format(" "*indent,self.id)) @@ -1247,7 +1257,10 @@ class TreeNode(PolymorphicModel): self.first_child.print_tree(indent=indent+2) if self.succ: self.succ.print_tree(indent=indent) - + + def getOdkaz(self): + return self.first_child.getOdkaz() + def __str__(self): if self.nazev: return self.nazev @@ -1283,6 +1296,9 @@ class CisloNode(TreeNode): def aktualizuj_nazev(self): self.nazev = "CisloNode: "+str(self.cislo) + def getOdkaz(self): + return "Číslo " + str(self.cislo) + class MezicisloNode(TreeNode): class Meta: db_table = 'seminar_nodes_mezicislo' @@ -1304,6 +1320,8 @@ class MezicisloNode(TreeNode): else: print("!!!!! Nějaké neidentifikované mezičíslo !!!!!") self.nazev = "MezicisloNode: Neidentifikovatelné mezičíslo!" + def getOdkaz(self): + return "Obsah dostupný pouze na webu" class TemaVCisleNode(TreeNode): """ Obsahuje příspěvky k tématu v daném čísle """ @@ -1318,6 +1336,9 @@ class TemaVCisleNode(TreeNode): def aktualizuj_nazev(self): self.nazev = "TemaVCisleNode: "+str(self.tema) + def getOdkaz(self): + return str(self.tema) + class KonferaNode(TreeNode): class Meta: db_table = 'seminar_nodes_konfera' @@ -1346,6 +1367,10 @@ class ClanekNode(TreeNode): def aktualizuj_nazev(self): self.nazev = "ClanekNode: "+str(self.clanek) + def getOdkaz(self): + return str(self.clanek) + + class UlohaZadaniNode(TreeNode): class Meta: db_table = 'seminar_nodes_uloha_zadani' @@ -1360,6 +1385,10 @@ class UlohaZadaniNode(TreeNode): def aktualizuj_nazev(self): self.nazev = "UlohaZadaniNode: "+str(self.uloha) + def getOdkaz(self): + return str(self.uloha) + + class PohadkaNode(TreeNode): class Meta: db_table = 'seminar_nodes_pohadka' @@ -1387,6 +1416,10 @@ class UlohaVzorakNode(TreeNode): def aktualizuj_nazev(self): self.nazev = "UlohaVzorakNode: "+str(self.uloha) + def getOdkaz(self): + return str(self.uloha) + + class TextNode(TreeNode): class Meta: db_table = 'seminar_nodes_obsah' @@ -1399,6 +1432,10 @@ class TextNode(TreeNode): def aktualizuj_nazev(self): self.nazev = "TextNode: "+str(self.text) + def getOdkaz(self): + return str(self.text) + + ## FIXME: Logiku přesunout do views. #class VysledkyBase(SeminarModelBase): # diff --git a/seminar/templates/seminar/tematka/rozcestnik.html b/seminar/templates/seminar/tematka/rozcestnik.html new file mode 100644 index 00000000..2afb0e38 --- /dev/null +++ b/seminar/templates/seminar/tematka/rozcestnik.html @@ -0,0 +1,14 @@ +{% for tematko in tematka %} +

    TEMA

    +

    {{tematko.abstrakt}}

    +
      + {% for cislo in tematko.cisla %} +
    • {{cislo.0}}
    • +
        + {% for odkaz in cislo.1 %} +
      • {{odkaz}}
      • + {% endfor %} +
      + {% endfor %} +
    +{% endfor %} diff --git a/seminar/testutils.py b/seminar/testutils.py index 204c0ea6..f378e725 100644 --- a/seminar/testutils.py +++ b/seminar/testutils.py @@ -380,7 +380,8 @@ def gen_temata(rnd, rocniky, rocnik_cisla, organizatori): kod=str(n), # atributy třídy Téma tema_typ=rnd.choice(Tema.TEMA_CHOICES)[0], - rocnik=rocnik + rocnik=rocnik, + abstrakt = "Abstrakt tematka {}".format(n) ) konec_tematu = min(rnd.randint(ci, 7), len(cisla)) for i in range(ci, konec_tematu+1): diff --git a/seminar/urls.py b/seminar/urls.py index c37d1357..67b1f865 100644 --- a/seminar/urls.py +++ b/seminar/urls.py @@ -8,6 +8,9 @@ from django.contrib.auth import views as auth_views staff_member_required = user_passes_test(lambda u: u.is_staff) urlpatterns = [ + # TEMP DEV + path('dev_tematka/', views.TemataRozcestnikView), + # REDIRECTy path('jak-resit/', RedirectView.as_view(url='/co-je-MaM/jak-resit/')), diff --git a/seminar/utils.py b/seminar/utils.py index 75092384..d910a5b6 100644 --- a/seminar/utils.py +++ b/seminar/utils.py @@ -2,9 +2,18 @@ import datetime from django.contrib.auth.decorators import user_passes_test +from html.parser import HTMLParser staff_member_required = user_passes_test(lambda u: u.is_staff) +class FirstTagParser(HTMLParser): + def __init__(self, *args, **kwargs): + self.firstTag = None + super().__init__(*args, **kwargs) + def handle_data(self, data): + if self.firstTag == None: + self.firstTag = data + def histogram(seznam): d = {} for i in seznam: diff --git a/seminar/views.py b/seminar/views.py index f2906d90..0e5f9cd7 100644 --- a/seminar/views.py +++ b/seminar/views.py @@ -15,7 +15,8 @@ from django.contrib.auth.mixins import LoginRequiredMixin from django.db import transaction from dal import autocomplete -from .models import Problem, Cislo, Reseni, Nastaveni, Rocnik, Soustredeni, Organizator, Resitel, Novinky, Soustredeni_Ucastnici, Pohadka, Tema, Clanek, Osoba, Skola +import seminar.models as s +from .models import Problem, Cislo, Reseni, Nastaveni, Rocnik, Soustredeni, Organizator, Resitel, Novinky, Soustredeni_Ucastnici, Pohadka, Tema, Clanek, Osoba, Skola # Tohle je stare a chceme se toho zbavit. Pouzivejte s.ToCoChci #from .models import VysledkyZaCislo, VysledkyKCisluZaRocnik, VysledkyKCisluOdjakziva from . import utils from .unicodecsv import UnicodeWriter @@ -73,6 +74,87 @@ def ZadaniTemataView(request): } ) +#TODO na příště - implementovat DFS, které vrátí seznam objektů, jejich hloubku a objekt, který chci zobrazit, +#TODO na příště - rozmyslet, jak zobrazovat objekty - u každého Nodu se objekt, na který ukazuje jmenuje jinak, zavést metodu, která se u každé subclassy bude jmenovat stejně? __str__ +#TODO na příště - v jaké formě předávat templatu? Jak řešit rozbalovací tagy? +#TODO na příště - implementace vpisování rozbalovacích tagů, vytvořit si nový objekt, který bude mít stejnou metodu jako objekty, které mají node, která bude vracet vhodný tag a prostě ji přidat do seznamu? +def vytahniZLesaSeznam(tematko, koren, pouze_zajimave=False): + returnVal = [] + + stack = [] + stack.append((koren.first_child, 0, False)) #Tuple of node, depth and relevance + + while len(stack) > 0: + wn, wd, wr = stack.pop() + + if wn.succ != None: + stack.append((wn.succ, wd, wr)) + if isinstance(wn, s.TemaVCisleNode): + print("TEMA") + print(wn.tema.id) + print(tematko.id) + if wn.tema.id == tematko.id: + returnVal.append((posledni_cislo, 0)) + print("PRIDANO") + wr = True + wd = 1 + + if wn.srolovatelne: + tagOpen = s.Text(na_web = "Otevírací srolovací tag") + tagOpenNode = s.TextNode(text = tagOpen) + tagClose = s.Text(na_web = "Zavírací srolovací tag") + tagCloseNode = s.TextNode(text = tagClose) + stack.append((tagCloseNode, wd, True)) + + if wn.first_child != None: + stack.append((wn.first_child, wd + 1, wr)) + + if isinstance(wn, s.CisloNode): + posledni_cislo = wn + print(wn) + + if wr: + print("ZAJIMAVE") + if pouze_zajimave: + if not wn.zajimave: + continue + returnVal.append((wn, wd)) + return returnVal + + +def TemataRozcestnikView(request): + print("=============================================") + nastaveni = s.Nastaveni.objects.first() + tematka_objects = s.Tema.objects.filter(rocnik=nastaveni.aktualni_rocnik()) + tematka = [] #List tematka obsahuje pro kazde tematko object a list vsech TemaVCisleNodu - implementované pomocí slovníku + for tematko_object in tematka_objects: + print("AKTUALNI TEMATKO") + print(tematko_object.id) + odkazy = vytahniZLesaSeznam(tematko_object, nastaveni.aktualni_rocnik().rocniknode, pouze_zajimave = True) + print(odkazy) + cisla = [] + vcisle = [] + cislo = None + for odkaz in odkazy: + if odkaz[1] == 0: + if cislo != None: + cisla.append((cislo, vcisle)) + cislo = odkaz[0].getOdkaz() + vcisle = [] + else: + print(odkaz[0].getOdkaz()) + vcisle.append(odkaz[0].getOdkaz()) + if cislo != None: + cisla.append((cislo, vcisle)) + + print(cisla) + tematka.append({ + "abstrakt" : tematko_object.abstrakt, + "obrazek": tematko_object.obrazek, + "cisla" : cisla + }) + return render(request, 'seminar/tematka/rozcestnik.html', {"tematka": tematka}) + #def ZadaniAktualniVysledkovkaView(request): # nastaveni = get_object_or_404(Nastaveni) From 9a0d229f9ac7777d49e7ac0bde3b5f71ad571358 Mon Sep 17 00:00:00 2001 From: "Martin Z. (Zimamazim)" Date: Wed, 11 Dec 2019 23:35:27 +0100 Subject: [PATCH 72/92] Rozcestnik tematek - odkazy --- seminar/models.py | 43 +++++++++++++------ .../templates/seminar/tematka/rozcestnik.html | 6 +-- seminar/urls.py | 4 +- seminar/views.py | 12 ++++-- 4 files changed, 43 insertions(+), 22 deletions(-) diff --git a/seminar/models.py b/seminar/models.py index 414f96aa..60bc361e 100644 --- a/seminar/models.py +++ b/seminar/models.py @@ -23,7 +23,7 @@ from reversion import revisions as reversion from seminar.utils import roman, FirstTagParser # Pro získání úryvku z TextNode -from unidecode import unidecode +from unidecode import unidecode # Používám pro získání ID odkazu (ještě je to někde po někom zakomentované) from polymorphic.models import PolymorphicModel @@ -620,7 +620,7 @@ class Problem(SeminarModelBase,PolymorphicModel): id = models.AutoField(primary_key = True) # Název - nazev = models.CharField('název', max_length=256) + nazev = models.CharField('název', max_length=256) # Zveřejnitelný na stránky # Problém má podproblémy nadproblem = models.ForeignKey('self', verbose_name='nadřazený problém', @@ -1243,7 +1243,7 @@ class TreeNode(PolymorphicModel): nazev = models.TextField("název tohoto node", help_text = "Tento název se zobrazuje v nabídkách pro výběr vhodného TreeNode", blank=False, - null=True) + null=True) # Nezveřejnitelný název na stránky - pouze do adminu zajimave = models.BooleanField(default = False, verbose_name = "Zajímavé", help_text = "Zobrazí se daná věc na rozcestníku témátek") @@ -1258,9 +1258,26 @@ class TreeNode(PolymorphicModel): if self.succ: self.succ.print_tree(indent=indent) - def getOdkaz(self): - return self.first_child.getOdkaz() - + def getOdkazStr(self): # String na rozcestník + return self.first_child.getOdkazStr() + + def getOdkaz(self): # ID HTML tagu, na který se bude scrollovat #{{self.getOdkaz}} + # Jsem si vědom, že tu potenciálně vznikají kolize. + # Přijdou mi natolik nepravděpodobné, že je neřeším + # Chtěl jsem ale hezké odkazy + string = unidecode(self.getOdkazStr()) + returnVal = "" + i = 0 + while len(returnVal) < 16: # Max 15 znaků + if i == len(string): + break + if string[i] == " ": + returnVal += "-" + if string[i].isalnum(): + returnVal += string[i].lower() + i += 1 + return returnVal + def __str__(self): if self.nazev: return self.nazev @@ -1296,7 +1313,7 @@ class CisloNode(TreeNode): def aktualizuj_nazev(self): self.nazev = "CisloNode: "+str(self.cislo) - def getOdkaz(self): + def getOdkazStr(self): return "Číslo " + str(self.cislo) class MezicisloNode(TreeNode): @@ -1320,7 +1337,7 @@ class MezicisloNode(TreeNode): else: print("!!!!! Nějaké neidentifikované mezičíslo !!!!!") self.nazev = "MezicisloNode: Neidentifikovatelné mezičíslo!" - def getOdkaz(self): + def getOdkazStr(self): return "Obsah dostupný pouze na webu" class TemaVCisleNode(TreeNode): @@ -1336,7 +1353,7 @@ class TemaVCisleNode(TreeNode): def aktualizuj_nazev(self): self.nazev = "TemaVCisleNode: "+str(self.tema) - def getOdkaz(self): + def getOdkazStr(self): return str(self.tema) class KonferaNode(TreeNode): @@ -1367,7 +1384,7 @@ class ClanekNode(TreeNode): def aktualizuj_nazev(self): self.nazev = "ClanekNode: "+str(self.clanek) - def getOdkaz(self): + def getOdkazStr(self): return str(self.clanek) @@ -1385,7 +1402,7 @@ class UlohaZadaniNode(TreeNode): def aktualizuj_nazev(self): self.nazev = "UlohaZadaniNode: "+str(self.uloha) - def getOdkaz(self): + def getOdkazStr(self): return str(self.uloha) @@ -1416,7 +1433,7 @@ class UlohaVzorakNode(TreeNode): def aktualizuj_nazev(self): self.nazev = "UlohaVzorakNode: "+str(self.uloha) - def getOdkaz(self): + def getOdkazStr(self): return str(self.uloha) @@ -1432,7 +1449,7 @@ class TextNode(TreeNode): def aktualizuj_nazev(self): self.nazev = "TextNode: "+str(self.text) - def getOdkaz(self): + def getOdkazStr(self): return str(self.text) diff --git a/seminar/templates/seminar/tematka/rozcestnik.html b/seminar/templates/seminar/tematka/rozcestnik.html index 2afb0e38..abec82dd 100644 --- a/seminar/templates/seminar/tematka/rozcestnik.html +++ b/seminar/templates/seminar/tematka/rozcestnik.html @@ -1,12 +1,12 @@ {% for tematko in tematka %} -

    TEMA

    +

    {{tematko.nazev}}

    {{tematko.abstrakt}}

      {% for cislo in tematko.cisla %} -
    • {{cislo.0}}
    • +
    • {{cislo.0.0}} -> /{{tematko.kod}}/#{{cislo.0.1}}
      • {% for odkaz in cislo.1 %} -
      • {{odkaz}}
      • +
      • {{odkaz.0}} -> /{{tematko.kod}}/#{{odkaz.1}}
      • {% endfor %}
      {% endfor %} diff --git a/seminar/urls.py b/seminar/urls.py index 67b1f865..347b3821 100644 --- a/seminar/urls.py +++ b/seminar/urls.py @@ -8,8 +8,8 @@ from django.contrib.auth import views as auth_views staff_member_required = user_passes_test(lambda u: u.is_staff) urlpatterns = [ - # TEMP DEV - path('dev_tematka/', views.TemataRozcestnikView), + path('tematka/', views.TemataRozcestnikView), + path('tematko//', views.TematkoView), # REDIRECTy path('jak-resit/', RedirectView.as_view(url='/co-je-MaM/jak-resit/')), diff --git a/seminar/views.py b/seminar/views.py index 3b8408b2..9f743d5d 100644 --- a/seminar/views.py +++ b/seminar/views.py @@ -121,6 +121,8 @@ def vytahniZLesaSeznam(tematko, koren, pouze_zajimave=False): returnVal.append((wn, wd)) return returnVal +def TematkoView(request): + neco def TemataRozcestnikView(request): print("=============================================") @@ -130,25 +132,27 @@ def TemataRozcestnikView(request): for tematko_object in tematka_objects: print("AKTUALNI TEMATKO") print(tematko_object.id) - odkazy = vytahniZLesaSeznam(tematko_object, nastaveni.aktualni_rocnik().rocniknode, pouze_zajimave = True) + odkazy = vytahniZLesaSeznam(tematko_object, nastaveni.aktualni_rocnik().rocniknode, pouze_zajimave = True) #Odkazy jsou tuply (node, depth) v listu print(odkazy) - cisla = [] + cisla = [] # List tuplů (nazev cisla, list odkazů) vcisle = [] cislo = None for odkaz in odkazy: if odkaz[1] == 0: if cislo != None: cisla.append((cislo, vcisle)) - cislo = odkaz[0].getOdkaz() + cislo = (odkaz[0].getOdkazStr(), odkaz[0].getOdkaz()) vcisle = [] else: print(odkaz[0].getOdkaz()) - vcisle.append(odkaz[0].getOdkaz()) + vcisle.append((odkaz[0].getOdkazStr(), odkaz[0].getOdkaz())) if cislo != None: cisla.append((cislo, vcisle)) print(cisla) tematka.append({ + "kod" : tematko_object.kod, + "nazev" : tematko_object.nazev, "abstrakt" : tematko_object.abstrakt, "obrazek": tematko_object.obrazek, "cisla" : cisla From 5dda5f662838f212d4638b56b805240a0ee573a2 Mon Sep 17 00:00:00 2001 From: Pavel 'LEdoian' Turinsky Date: Fri, 13 Dec 2019 16:38:56 +0100 Subject: [PATCH 73/92] =?UTF-8?q?Built-in=20login=20formul=C3=A1=C5=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/templates/seminar/login.html | 11 +---------- seminar/urls.py | 2 +- seminar/views.py | 12 ++++++++++++ 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/seminar/templates/seminar/login.html b/seminar/templates/seminar/login.html index 88cd364f..eee1303c 100644 --- a/seminar/templates/seminar/login.html +++ b/seminar/templates/seminar/login.html @@ -8,19 +8,10 @@ Přihlášení {% endblock %}{% endblock %} -{% if login_error %} -{{login_error}} -{% endif %}
      {% csrf_token %} - {{form.non_field_errors}}
        -
      • - {% include "seminar/prihlaska_field.html" with field=form.username %} -
      • -
      • - {% include "seminar/prihlaska_field.html" with field=form.password %} -
      • + {{ form.as_ul }}
      diff --git a/seminar/urls.py b/seminar/urls.py index 9d2c158a..5f534020 100644 --- a/seminar/urls.py +++ b/seminar/urls.py @@ -99,7 +99,7 @@ urlpatterns = [ name='seminar_tex_upload' ), path('auth/prihlaska/',views.prihlaskaView, name='seminar_prihlaska'), - path('auth/login/', views.loginView, name='login'), + path('auth/login/', views.LoginView.as_view(), name='login'), path('auth/logout/', views.logoutView, name='logout'), path('auth/resitel/', views.ResitelView.as_view(), name='seminar_resitel'), path('autocomplete/skola/',views.SkolaAutocomplete.as_view(), name='autocomplete_skola'), diff --git a/seminar/views.py b/seminar/views.py index bb580c08..46571927 100644 --- a/seminar/views.py +++ b/seminar/views.py @@ -10,6 +10,7 @@ from django.http import Http404,HttpResponseBadRequest,HttpResponseRedirect from django.db.models import Q from django.views.decorators.csrf import ensure_csrf_cookie from django.contrib.auth import authenticate, login, get_user_model, logout +from django.contrib.auth import views as auth_views from django.contrib.auth.models import User from django.contrib.auth.mixins import LoginRequiredMixin from django.db import transaction @@ -1154,3 +1155,14 @@ class SkolaAutocomplete(autocomplete.Select2QuerySetView): # Q(user__last_name__isstartswith=query)) # # return qs + +# FIXME: Tohle asi vlastně vůbec nepatří do aplikace 'seminar' +class LoginView(auth_views.LoginView): + # Jen vezmeme vestavěný a dáme mu vhodný template a přesměrovací URL + template_name = 'seminar/login.html' + + # Přesměrovací URL má být v kontextu: + def get_context_data(self, **kwargs): + ctx = super().get_context_data(**kwargs) + ctx['next'] = reverse('titulni_strana') + return ctx From ca3daf769f0bf0960cd3cdb3e9d94cb166f32516 Mon Sep 17 00:00:00 2001 From: "Martin Z. (Zimamazim)" Date: Wed, 18 Dec 2019 22:50:17 +0100 Subject: [PATCH 74/92] =?UTF-8?q?Drobn=C3=A9=20=C3=BApravy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Dnes jsem se bavil s Jethrem, jak udělat toaleťák. Bude potřeba přepsat vytahniZLesaTematka, aby uměla otevírací a zavírací tagy pro každý podstrom. Poté uvidím, co použiju pro rozcestník. --- .../templates/seminar/tematka/rozcestnik.html | 4 ++-- .../templates/seminar/tematka/toaletak.html | 1 + seminar/urls.py | 4 ++-- seminar/views.py | 22 +++++++++++++------ 4 files changed, 20 insertions(+), 11 deletions(-) create mode 100644 seminar/templates/seminar/tematka/toaletak.html diff --git a/seminar/templates/seminar/tematka/rozcestnik.html b/seminar/templates/seminar/tematka/rozcestnik.html index abec82dd..b13d6075 100644 --- a/seminar/templates/seminar/tematka/rozcestnik.html +++ b/seminar/templates/seminar/tematka/rozcestnik.html @@ -3,10 +3,10 @@

      {{tematko.abstrakt}}

        {% for cislo in tematko.cisla %} -
      • {{cislo.0.0}} -> /{{tematko.kod}}/#{{cislo.0.1}}
      • +
      • {{cislo.0.0}}
        • {% for odkaz in cislo.1 %} -
        • {{odkaz.0}} -> /{{tematko.kod}}/#{{odkaz.1}}
        • +
        • {{odkaz.0}}
        • {% endfor %}
        {% endfor %} diff --git a/seminar/templates/seminar/tematka/toaletak.html b/seminar/templates/seminar/tematka/toaletak.html new file mode 100644 index 00000000..8b556c6c --- /dev/null +++ b/seminar/templates/seminar/tematka/toaletak.html @@ -0,0 +1 @@ +Stránká témátka diff --git a/seminar/urls.py b/seminar/urls.py index 213494f6..c09d32b0 100644 --- a/seminar/urls.py +++ b/seminar/urls.py @@ -8,8 +8,8 @@ from django.contrib.auth import views as auth_views staff_member_required = user_passes_test(lambda u: u.is_staff) urlpatterns = [ - path('tematka/', views.TemataRozcestnikView), - path('tematko//', views.TematkoView), + path('aktualni/temata/', views.TemataRozcestnikView), + path('/t/', views.TematkoView), # REDIRECTy path('jak-resit/', RedirectView.as_view(url='/co-je-MaM/jak-resit/')), diff --git a/seminar/views.py b/seminar/views.py index ccbb2d00..5838f48d 100644 --- a/seminar/views.py +++ b/seminar/views.py @@ -75,10 +75,7 @@ def ZadaniTemataView(request): } ) -#TODO na příště - implementovat DFS, které vrátí seznam objektů, jejich hloubku a objekt, který chci zobrazit, -#TODO na příště - rozmyslet, jak zobrazovat objekty - u každého Nodu se objekt, na který ukazuje jmenuje jinak, zavést metodu, která se u každé subclassy bude jmenovat stejně? __str__ -#TODO na příště - v jaké formě předávat templatu? Jak řešit rozbalovací tagy? -#TODO na příště - implementace vpisování rozbalovacích tagů, vytvořit si nový objekt, který bude mít stejnou metodu jako objekty, které mají node, která bude vracet vhodný tag a prostě ji přidat do seznamu? +# TODO Napsat tuto funkci znovu rekurzivně podle Jethrorad. Potom se podívat, jak lehce se dá modifikovat pro Rozcestník. Pokud lehce, rozšířit ji. Pokud složitě - použít tuhle def vytahniZLesaSeznam(tematko, koren, pouze_zajimave=False): returnVal = [] @@ -122,8 +119,19 @@ def vytahniZLesaSeznam(tematko, koren, pouze_zajimave=False): returnVal.append((wn, wd)) return returnVal -def TematkoView(request): - neco +def TematkoView(request, rocnik, tematko): + nastaveni = s.Nastaveni.objects.first() + rocnik_object = s.Rocnik.objects.filter(rocnik=rocnik) + tematko_object = s.Tema.objects.filter(rocnik=rocnik_object[0], kod=tematko) + seznam = vytahniZLesaSeznam(tematko_object[0], nastaveni.aktualni_rocnik().rocniknode) + for node, depth in seznam: + if node.isinstance(node, s.KonferaNode): + raise Exception("Not implemented yet") + if node.isinstance(node, s.PohadkaNode): # Mohu ignorovat, má pod sebou + pass + + return render(request, 'seminar/tematka/toaletak.html', {}) + def TemataRozcestnikView(request): print("=============================================") @@ -158,7 +166,7 @@ def TemataRozcestnikView(request): "obrazek": tematko_object.obrazek, "cisla" : cisla }) - return render(request, 'seminar/tematka/rozcestnik.html', {"tematka": tematka}) + return render(request, 'seminar/tematka/rozcestnik.html', {"tematka": tematka, "rocnik" : nastaveni.aktualni_rocnik().rocnik}) #def ZadaniAktualniVysledkovkaView(request): From 1f789f6ad0ef4646814505bc23666397009773c0 Mon Sep 17 00:00:00 2001 From: Pavel 'LEdoian' Turinsky Date: Thu, 19 Dec 2019 01:29:27 +0100 Subject: [PATCH 75/92] =?UTF-8?q?Models:=20ne=C3=BAsp=C4=9B=C5=A1n=C3=BD?= =?UTF-8?q?=20(zakomentovan=C3=BD)=20pokus=20o=20vlastn=C3=ADho=20Usera?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/models.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/seminar/models.py b/seminar/models.py index 60bc361e..bf68d015 100644 --- a/seminar/models.py +++ b/seminar/models.py @@ -1587,3 +1587,35 @@ class Novinky(models.Model): return '[' + str(self.datum) + '] ' + self.text[0:50] else: return '[' + str(self.datum) + '] ' + + + + +# FIXME: Tohle nepatří do aplikace 'seminar' +# Nefunkční alternativa vestavěného Usera, který má jméno a mail v přidružené Osobě +# from django.contrib.auth.models import User as Django_User +# +# class Uzivatel(Django_User): +# class Meta: +# proxy = True +# +# @property +# def first_name(self): +# osoby = Osoba.objects.filter(user=self) +# if len(osoby) == 0: +# return None +# return osoby.first().krestni_jmeno +# +# @property +# def last_name(self): +# osoby = Osoba.objects.filter(user=self) +# if len(osoby) == 0: +# return None +# return osoby.first().prijmeni +# +# @property +# def email(self): +# osoby = Osoba.objects.filter(user=self) +# if len(osoby) == 0: +# return None +# return osoby.first().email From 1004e785de9ff0641ac8e2c7cbc3b45cfff893b4 Mon Sep 17 00:00:00 2001 From: Pavel 'LEdoian' Turinsky Date: Thu, 19 Dec 2019 01:29:53 +0100 Subject: [PATCH 76/92] =?UTF-8?q?Models:=20Aktu=C3=A1ln=C3=AD=20ro=C4=8Dn?= =?UTF-8?q?=C3=ADk=20je=20property?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/models.py | 1 + 1 file changed, 1 insertion(+) diff --git a/seminar/models.py b/seminar/models.py index bf68d015..fefd72d3 100644 --- a/seminar/models.py +++ b/seminar/models.py @@ -1544,6 +1544,7 @@ class Nastaveni(SingletonModel): aktualni_cislo = models.ForeignKey(Cislo, verbose_name='poslední vydané číslo', null=False, on_delete=models.PROTECT) + @property def aktualni_rocnik(self): return self.aktualni_cislo.rocnik From 4f1828b7af2f40869cc3d78d3d66618d27108316 Mon Sep 17 00:00:00 2001 From: Pavel 'LEdoian' Turinsky Date: Thu, 19 Dec 2019 01:30:48 +0100 Subject: [PATCH 77/92] =?UTF-8?q?P=C5=99ihla=C5=A1ovac=C3=AD=20a=20odhla?= =?UTF-8?q?=C5=A1ovac=C3=AD=20a=20heslo-zapom=C3=ADnac=C3=AD=20views?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Templates většinou chybí. --- seminar/templates/seminar/login.html | 2 ++ seminar/templates/seminar/logout.html | 18 ++++++++++++++++ seminar/urls.py | 8 +++++-- seminar/views.py | 31 ++++++++++++++++++++++++++- 4 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 seminar/templates/seminar/logout.html diff --git a/seminar/templates/seminar/login.html b/seminar/templates/seminar/login.html index eee1303c..6319ecc0 100644 --- a/seminar/templates/seminar/login.html +++ b/seminar/templates/seminar/login.html @@ -13,6 +13,8 @@
          {{ form.as_ul }}
        + {# Django si posílá jméno další stránky jako obsah formuláře a výchozí hodnota (mi přišlo, že) nejde změnit... #} + diff --git a/seminar/templates/seminar/logout.html b/seminar/templates/seminar/logout.html new file mode 100644 index 00000000..ab41a8c8 --- /dev/null +++ b/seminar/templates/seminar/logout.html @@ -0,0 +1,18 @@ +{% extends "seminar/zadani/base.html" %} +{% load staticfiles %} + + +{% block content %} +

        + {% block nadpis1a %}{% block nadpis1b %} + Odhlášení + {% endblock %}{% endblock %} +

        + +Byl jsi úspěšně odhlášen +{# Tohle by se asi mělo udělat přes kontext (title), ale kašlu na to, stejně je to jen jednojazyčná stránka #} + +{# TODO: odkaz na znovupřihlášení? #} + +{% endblock %} + diff --git a/seminar/urls.py b/seminar/urls.py index 213494f6..3d3bd1d5 100644 --- a/seminar/urls.py +++ b/seminar/urls.py @@ -103,10 +103,14 @@ urlpatterns = [ ), path('auth/prihlaska/',views.prihlaskaView, name='seminar_prihlaska'), path('auth/login/', views.LoginView.as_view(), name='login'), - path('auth/logout/', views.logoutView, name='logout'), + path('auth/logout/', views.LogoutView.as_view(), name='logout'), path('auth/resitel/', views.ResitelView.as_view(), name='seminar_resitel'), path('autocomplete/skola/',views.SkolaAutocomplete.as_view(), name='autocomplete_skola'), - path('auth/reset_password', views.resetPasswordView, name='reset_password'), + path('auth/reset_password/', views.PasswordResetView.as_view(), name='reset_password'), + path('auth/change_password/', views.PasswordChangeView.as_view(), name='change_password'), + path('auth/reset_password_done/', views.PasswordResetDoneView.as_view(), name='reset_password_done'), + path('auth/reset_password_confirm/', views.PasswordResetConfirmView.as_view(), name='reset_password_confirm'), + path('auth/reset_password_complete/', views.PasswordResetCompleteView.as_view(), name='reset_password_complete'), path('auth/resitel_edit', views.resitelEditView, name='seminar_resitel_edit'), path('', views.TitulniStranaView.as_view(), name='titulni_strana'), diff --git a/seminar/views.py b/seminar/views.py index ccbb2d00..66a65bbc 100644 --- a/seminar/views.py +++ b/seminar/views.py @@ -2,7 +2,7 @@ from django.shortcuts import get_object_or_404, render from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden, JsonResponse -from django.urls import reverse +from django.urls import reverse,reverse_lazy from django.core.exceptions import PermissionDenied, ObjectDoesNotExist from django.views import generic from django.utils.translation import ugettext as _ @@ -1281,3 +1281,32 @@ class LoginView(auth_views.LoginView): ctx = super().get_context_data(**kwargs) ctx['next'] = reverse('titulni_strana') return ctx + +class LogoutView(auth_views.LogoutView): + # Jen vezmeme vestavěný a dáme mu vhodný template a přesměrovací URL + template_name = 'seminar/logout.html' + # Pavel: Vůbec nevím, proč to s _lazy funguje, ale bez toho to bylo rozbité. + next_page = reverse_lazy('titulni_strana') + +class PasswordResetView(auth_views.PasswordResetView): + #template_name = 'seminar/password_reset.html' + # TODO: vlastní email_template_name a subject_template_name a html_email_template_name + success_url = reverse_lazy('reset_password_done') + from_email = 'login@mam.mff.cuni.cz' + # TODO: přepsat User-a :-( + +class PasswordResetDoneView(auth_views.PasswordResetDoneView): + #template_name = 'seminar/password_reset_done.html' + pass + +class PasswordResetConfirmView(auth_views.PasswordResetConfirmView): + #template_name = 'seminar/password_confirm_done.html' + success_url = reverse_lazy('reset_password_complete') + +class PasswordResetCompleteView(auth_views.PasswordResetCompleteView): + #template_name = 'seminar/password_complete_done.html' + pass + +class PasswordChangeView(auth_views.PasswordChangeView): + #template_name = 'seminar/password_change.html' + success_url = reverse_lazy('titulni_strana') From f1b8a9b5adfcd7d2df28b72d1fe36bb88b2baff9 Mon Sep 17 00:00:00 2001 From: "Tomas \"Jethro\" Pokorny" Date: Wed, 8 Jan 2020 21:44:04 +0100 Subject: [PATCH 78/92] Models: str pro reseni podle noveho modelu. --- seminar/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/seminar/models.py b/seminar/models.py index fefd72d3..7a16bc96 100644 --- a/seminar/models.py +++ b/seminar/models.py @@ -888,7 +888,7 @@ class Reseni(SeminarModelBase): # Konfera def __str__(self): - return "{}: {}".format(self.resitel.osoba.plne_jmeno(), self.problem.nazev) + return "{}({}): {}({})".format(self.resitele.first(),len(self.resitele.all()), self.problem.first() ,len(self.problem.all())) # NOTE: Potenciální DB HOG (bez select_related) ## Pravdepodobne uz nebude potreba: From 65a76935a6a1c56182ed632002d79f7debf75197 Mon Sep 17 00:00:00 2001 From: "Tomas \"Jethro\" Pokorny" Date: Wed, 8 Jan 2020 21:44:50 +0100 Subject: [PATCH 79/92] Admin: django-reverse-admin ukazka a fail s m2m. --- requirements.txt | 1 + seminar/admin.py | 33 +++++++++++++++++++++++++++++---- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/requirements.txt b/requirements.txt index f2fd4306..22f8e43c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -27,6 +27,7 @@ django-crispy-forms django-imagekit django-polymorphic django-sitetree +django_reverse_admin # Comments akismet==1.0.1 diff --git a/seminar/admin.py b/seminar/admin.py index e524a19d..11944b56 100644 --- a/seminar/admin.py +++ b/seminar/admin.py @@ -1,6 +1,8 @@ from django.contrib import admin from polymorphic.admin import PolymorphicParentModelAdmin, PolymorphicChildModelAdmin, PolymorphicChildModelFilter +from reversion.admin import VersionAdmin +from django_reverse_admin import ReverseModelAdmin # Todo: reversion @@ -9,7 +11,6 @@ import seminar.models as m admin.site.register(m.Osoba) admin.site.register(m.Skola) admin.site.register(m.Prijemce) -admin.site.register(m.Resitel) admin.site.register(m.Rocnik) admin.site.register(m.Cislo) admin.site.register(m.Organizator) @@ -39,11 +40,35 @@ class UlohaAdmin(PolymorphicChildModelAdmin): base_model = m.Uloha show_in_index = True - +class TextAdminInline(admin.TabularInline): + model = m.Text + exclude = ['text_zkraceny_set','text_zkraceny'] admin.site.register(m.Text) -admin.site.register(m.Reseni) -admin.site.register(m.Hodnoceni) + +class ResitelInline(admin.TabularInline): + model = m.Resitel + extra = 1 +admin.site.register(m.Resitel) + +class PrilohaReseniInline(admin.TabularInline): + model = m.PrilohaReseni + extra = 1 admin.site.register(m.PrilohaReseni) + +class Reseni_ResiteleInline(admin.TabularInline): + model = m.Reseni_Resitele + +@admin.register(m.Reseni) +class ReseniAdmin(ReverseModelAdmin): + base_model = m.Reseni + inline_type = 'tabular' + inline_reverse = ['text_cely','resitele'] + exclude = ['text_zkraceny', 'text_zkraceny_set'] + inlines = [PrilohaReseniInline] +# FAIL in template +# inlines = [PrilohaReseniInline,Reseni_ResiteleInline] + +admin.site.register(m.Hodnoceni) admin.site.register(m.Pohadka) admin.site.register(m.Konfera) admin.site.register(m.Obrazek) From aa4b8da2abea0a5a11b16bb46f47317cbbd91d96 Mon Sep 17 00:00:00 2001 From: Anet Date: Thu, 9 Jan 2020 00:45:20 +0100 Subject: [PATCH 80/92] =?UTF-8?q?views=20|=20+-=20funk=C4=8Dn=C3=AD=20v?= =?UTF-8?q?=C3=BDsledkovka=20se=20sn=C3=AD=C5=BEen=C3=BDm=20po=C4=8Dtem=20?= =?UTF-8?q?dotaz=C5=AF=20do=20datab=C3=A1ze?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/models.py | 3 ++- seminar/views.py | 52 +++++++++++++++++++++++++++++------------------ 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/seminar/models.py b/seminar/models.py index 691c04af..d1bdd08c 100644 --- a/seminar/models.py +++ b/seminar/models.py @@ -913,7 +913,8 @@ class Hodnoceni(SeminarModelBase): reseni = models.ForeignKey(Reseni, verbose_name='řešení', on_delete=models.CASCADE) - problem = models.ForeignKey(Problem, verbose_name='problém', on_delete=models.PROTECT) + problem = models.ForeignKey(Problem, verbose_name='problém', + related_name='hodnoceni', on_delete=models.PROTECT) def __str__(self): return "{}, {}, {}".format(self.problem, self.reseni, self.body) diff --git a/seminar/views.py b/seminar/views.py index 35e2bb6b..ba11c9b4 100644 --- a/seminar/views.py +++ b/seminar/views.py @@ -269,7 +269,7 @@ def sloupec_s_poradim(seznam_s_body): for index in range(0, len(seznam_s_body)): # pokud je pořadí větší než číslo řádku, tak jsme vypsali větší rozsah a chceme # vypsat už jen prázdné místo, než dojdeme na správný řádek - if (index+1) < aktualni_poradi: + if (index + 1) < aktualni_poradi: sloupec_s_poradim.append("") continue velikost_skupiny = 0 @@ -292,18 +292,17 @@ def sloupec_s_poradim(seznam_s_body): # spočítá součet bodů získaných daným řešitelem za zadaný problém a všechny jeho podproblémy def __soucet_resitele_problemu(problem, resitel, cislo, soucet): - # FIXME: správně je nadproblem_(typ problemu), ale to by bylo potřeba nějak - # zjistit, jaký typ nodu to vlastně je a aplikovat to ve volání funkce - # sečteme body za daný problém přes všechna řešení daného problému # od daného řešitele - reseni_resitele = problem.hodnoceni_set.filter(reseni_resitele__contains=resitel, + reseni_resitele = problem.hodnoceni_set.filter(reseni__resitele=resitel, cislo_body=cislo) + # XXX chyba na řádku výše - řešení může mít více řešitelů, asi chceme contains + # nebo in for r in reseni_resitele: soucet += r.body # a přičteme k tomu hodnocení všech podproblémů - for p in problem.nadproblem_set: + for p in problem.podproblem.all(): # i přes jméno by to měla být množina jeho podproblémů soucet += __soucet_resitele_problemu(p, resitel, soucet) return soucet @@ -315,7 +314,7 @@ def body_resitele_problemu_v_cisle(problem, resitel, cislo): # vrátí list všech problémů s body v daném čísle, které již nemají nadproblém def hlavni_problemy_cisla(cislo): - hodnoceni = cislo.hodnoceni_set # hodnocení, která se vážou k danému číslu + hodnoceni = cislo.hodnoceni.select_related('problem', 'reseni').all() # hodnocení, která se vážou k danému číslu reseni = [h.reseni for h in hodnoceni] problemy = [h.problem for h in hodnoceni] @@ -333,14 +332,22 @@ def hlavni_problemy_cisla(cislo): # zunikátnění hlavni_problemy_set = set(hlavni_problemy) hlavni_problemy = list(hlavni_problemy_set) - hlavni_problemy.sort(key=lambda k: k.kod_v_rocniku) # setřídit podle t1, t2, c3, ... + hlavni_problemy.sort(key=lambda k: k.kod_v_rocniku()) # setřídit podle t1, t2, c3, ... return hlavni_problemy +def body_resitele_odjakziva(resitel): + body = 0 + resitelova_hodnoceni = Hodnoceni.objects.select_related('body').all().filter(reseni_resitele=resitel) + # TODO: v radku nahore chceme _in nebo _contains + for hodnoceni in resitelova_hodnoceni: + body = body + hodnoceni.body + return body # spočítá součet všech bodů řešitele za dané číslo def body_resitele_v_cisle(resitel, cislo): hlavni_problemy = hlavni_problemy_cisla(cislo) + body_resitele = 0 for h in hlavni_problemy: body_resitele = body_resitele + body_resitele_problemu_v_cisle(h, resitel, cislo) # TODO: je rozdíl mezi odevzdanou úlohou za 0 a tím, když řešitel nic neodevzdal @@ -352,7 +359,8 @@ def body_resitele_v_cisle(resitel, cislo): def body_resitele_v_rocniku(resitel, rocnik, do_cisla=None): # pokud do_cisla=None, tak do posledního čísla v ročníku # do_cisla je objekt Cislo - cisla = rocnik.cisla # funkce vrátí pole objektů Cislo už lexikograficky setřízené, viz models + cisla = rocnik.cisla.all() # funkce vrátí pole objektů + # Cislo už lexikograficky setřízené, viz models body = 0 for cislo in cisla: if cislo.poradi == do_cisla.poradi: break @@ -470,14 +478,14 @@ class VysledkyResitele(object): počet bodů za konkrétní ročník do daného čísla a za dané číslo.""" def __init__(self, resitel, cislo, rocnik): - resitel_jmeno = resitel.osoba.jmeno - resitel_prijmeni = resitel.osoba.prijmeni + self.resitel = resitel self.cislo = cislo - body_cislo = body_resitele_v_cisle(resitel, cislo) - body = [] + self.body_cislo = body_resitele_v_cisle(resitel, cislo) + self.body = [] self.rocnik = rocnik - body_rocnik = body_resitele_v_rocniku(resitel, rocnik, cislo) - poradi = 0 + self.body_rocnik = body_resitele_v_rocniku(resitel, rocnik, cislo) + self.body_celkem_odjakziva = resitel.vsechny_body() + self.poradi = 0 class CisloView(generic.DetailView): model = Cislo @@ -488,8 +496,8 @@ class CisloView(generic.DetailView): if queryset is None: queryset = self.get_queryset() rocnik_arg = self.kwargs.get('rocnik') - cislo_arg = self.kwargs.get('cislo') - queryset = queryset.filter(rocnik__rocnik=rocnik_arg, cislo=cislo_arg) + poradi_arg = self.kwargs.get('cislo') + queryset = queryset.filter(rocnik__rocnik=rocnik_arg, poradi=poradi_arg) try: obj = queryset.get() @@ -509,17 +517,18 @@ class CisloView(generic.DetailView): ## TODO možná chytřeji vybírat aktivní řešitele ## chceme letos něco poslal aktivni_resitele = Resitel.objects.filter( - rok_maturity__gte=context['rocnik'].druhy_rok()) + rok_maturity__gte=cislo.rocnik.druhy_rok()) + # TODO: zkusit hodnoceni__rocnik... #.filter(hodnoceni_set__rocnik__eq=cislo_rocnik) radky_vysledkovky = [] for ar in aktivni_resitele: # získáme výsledky řešitele - součty přes číslo a ročník vr = VysledkyResitele(ar, cislo, cislo.rocnik) for hp in hlavni_problemy: - vr.body.append(body_resitele_problemu_v_cisle(hp, resitel, cislo)) + vr.body.append( + body_resitele_problemu_v_cisle(hp, ar, cislo)) radky_vysledkovky.append(vr) - ## TODO: # setřídíme řádky výsledkovky/objekty VysledkyResitele podle bodů radky_vysledkovky.sort(key=lambda vr: vr.body_rocnik, reverse=True) @@ -534,10 +543,13 @@ class CisloView(generic.DetailView): i = i + 1 # vytahané informace předáváme do kontextu + context['cislo'] = cislo context['radky_vysledkovky'] = radky_vysledkovky context['problemy'] = hlavni_problemy # context['v_cisle_zadane'] = TODO # context['resene_problemy'] = resene_problemy + #XXX testovat + #XXX opravit to, že se nezobrazují body za jednotlivé úlohy return context From 83aa9a17587180de2f64a075e275da01308db26e Mon Sep 17 00:00:00 2001 From: Pavel 'LEdoian' Turinsky Date: Wed, 15 Jan 2020 22:33:15 +0100 Subject: [PATCH 81/92] =?UTF-8?q?Kop=C3=ADrujeme=20emaily=20z=20osoby=20do?= =?UTF-8?q?=20usera,=20aby=20jednodu=C5=A1e=20fungovalo=20resetov=C3=A1n?= =?UTF-8?q?=C3=AD=20hesla.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../0073_copy_osoba_email_to_user_email.py | 22 +++++++++++++++++++ seminar/models.py | 11 ++++++++++ seminar/views.py | 4 ++++ 3 files changed, 37 insertions(+) create mode 100644 seminar/migrations/0073_copy_osoba_email_to_user_email.py diff --git a/seminar/migrations/0073_copy_osoba_email_to_user_email.py b/seminar/migrations/0073_copy_osoba_email_to_user_email.py new file mode 100644 index 00000000..3b280209 --- /dev/null +++ b/seminar/migrations/0073_copy_osoba_email_to_user_email.py @@ -0,0 +1,22 @@ +# Generated by Django 2.2.9 on 2020-01-15 21:28 + +from django.db import migrations + +def copy_mails(apps, schema_editor): + Osoba = apps.get_model('seminar', 'Osoba') + + for o in Osoba.objects.all(): + if o.user is not None: + u = o.user + u.email = o.email + u.save() + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0072_auto_20191204_2257'), + ] + + operations = [ + migrations.RunPython(copy_mails, migrations.RunPython.noop) + ] diff --git a/seminar/models.py b/seminar/models.py index 7a16bc96..e65dcb67 100644 --- a/seminar/models.py +++ b/seminar/models.py @@ -130,6 +130,17 @@ class Osoba(SeminarModelBase): def __str__(self): return self.plne_jmeno() + # Overridujeme save Osoby, aby když si změní e-mail, aby se projevil i v + # Userovi (a tak se dal poslat mail s resetem hesla) + def save(self, *args, **kwargs): + if self.user is not None: + u = self.user + # U svatého tučňáka, prosím ať tohle funguje. + # (Takhle se kódit asi nemá...) + u.email = self.email + u.save() + super().save() + # # Mělo by být částečně vytaženo z Aesopa # viz https://ovvp.mff.cuni.cz/wiki/aesop/export-skol. diff --git a/seminar/views.py b/seminar/views.py index 065d6879..4a18739f 100644 --- a/seminar/views.py +++ b/seminar/views.py @@ -1296,6 +1296,7 @@ class LogoutView(auth_views.LogoutView): # Pavel: Vůbec nevím, proč to s _lazy funguje, ale bez toho to bylo rozbité. next_page = reverse_lazy('titulni_strana') +# "Chci resetovat heslo" class PasswordResetView(auth_views.PasswordResetView): #template_name = 'seminar/password_reset.html' # TODO: vlastní email_template_name a subject_template_name a html_email_template_name @@ -1303,14 +1304,17 @@ class PasswordResetView(auth_views.PasswordResetView): from_email = 'login@mam.mff.cuni.cz' # TODO: přepsat User-a :-( +# "Poslali jsme e-mail (pokud bylo kam))" class PasswordResetDoneView(auth_views.PasswordResetDoneView): #template_name = 'seminar/password_reset_done.html' pass +# "Vymysli si heslo" class PasswordResetConfirmView(auth_views.PasswordResetConfirmView): #template_name = 'seminar/password_confirm_done.html' success_url = reverse_lazy('reset_password_complete') +# "Heslo se asi změnilo." class PasswordResetCompleteView(auth_views.PasswordResetCompleteView): #template_name = 'seminar/password_complete_done.html' pass From a420a6bc98dc80307392998f7bc05e278c1b4b32 Mon Sep 17 00:00:00 2001 From: Pavel 'LEdoian' Turinsky Date: Wed, 15 Jan 2020 23:55:13 +0100 Subject: [PATCH 82/92] =?UTF-8?q?Zprovozn=C4=9Bn=20reset=20hesla?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mamweb/settings_local.py | 2 ++ seminar/urls.py | 2 +- seminar/views.py | 1 - 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/mamweb/settings_local.py b/mamweb/settings_local.py index 517772ee..5a2aa969 100644 --- a/mamweb/settings_local.py +++ b/mamweb/settings_local.py @@ -87,3 +87,5 @@ LOGGING = { # set to 'DEBUG' for EXTRA verbose output # LOGGING['handlers']['console']['level'] = 'INFO' + +EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' diff --git a/seminar/urls.py b/seminar/urls.py index d76e2e31..7ae2558c 100644 --- a/seminar/urls.py +++ b/seminar/urls.py @@ -109,7 +109,7 @@ urlpatterns = [ path('auth/reset_password/', views.PasswordResetView.as_view(), name='reset_password'), path('auth/change_password/', views.PasswordChangeView.as_view(), name='change_password'), path('auth/reset_password_done/', views.PasswordResetDoneView.as_view(), name='reset_password_done'), - path('auth/reset_password_confirm/', views.PasswordResetConfirmView.as_view(), name='reset_password_confirm'), + path('auth/reset_password_confirm///', views.PasswordResetConfirmView.as_view(), name='password_reset_confirm'), path('auth/reset_password_complete/', views.PasswordResetCompleteView.as_view(), name='reset_password_complete'), path('auth/resitel_edit', views.resitelEditView, name='seminar_resitel_edit'), path('', views.TitulniStranaView.as_view(), name='titulni_strana'), diff --git a/seminar/views.py b/seminar/views.py index 4a18739f..6f31a889 100644 --- a/seminar/views.py +++ b/seminar/views.py @@ -1302,7 +1302,6 @@ class PasswordResetView(auth_views.PasswordResetView): # TODO: vlastní email_template_name a subject_template_name a html_email_template_name success_url = reverse_lazy('reset_password_done') from_email = 'login@mam.mff.cuni.cz' - # TODO: přepsat User-a :-( # "Poslali jsme e-mail (pokud bylo kam))" class PasswordResetDoneView(auth_views.PasswordResetDoneView): From e86c090ab849faa0a64548a3dbd37168ab2dbb49 Mon Sep 17 00:00:00 2001 From: Pavel 'LEdoian' Turinsky Date: Thu, 16 Jan 2020 01:26:08 +0100 Subject: [PATCH 83/92] =?UTF-8?q?Admin:=20Akce=20na=20synchronizaci=20dupl?= =?UTF-8?q?icit=20informac=C3=AD=20v=20datab=C3=A1zi?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/admin.py | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/seminar/admin.py b/seminar/admin.py index 11944b56..6a9dd815 100644 --- a/seminar/admin.py +++ b/seminar/admin.py @@ -8,7 +8,6 @@ from django_reverse_admin import ReverseModelAdmin import seminar.models as m -admin.site.register(m.Osoba) admin.site.register(m.Skola) admin.site.register(m.Prijemce) admin.site.register(m.Rocnik) @@ -16,6 +15,19 @@ admin.site.register(m.Cislo) admin.site.register(m.Organizator) admin.site.register(m.Soustredeni) +@admin.register(m.Osoba) +class OsobaAdmin(admin.ModelAdmin): + actions = ['synchronizuj_maily'] + + def synchronizuj_maily(self, request, queryset): + for o in queryset: + if o.user is not None: + u = o.user + u.email = o.email + u.save() + self.message_user(request, "E-maily synchronizovány.") + synchronizuj_maily.short_description = "Synchronizuj vybraným osobám e-maily do uživatelů" + @admin.register(m.Problem) class ProblemAdmin(PolymorphicParentModelAdmin): base_model = m.Problem @@ -93,6 +105,17 @@ class TreeNodeAdmin(PolymorphicParentModelAdmin): m.TextNode, ] + actions = ['aktualizuj_nazvy'] + + # XXX: nejspíš je to totální DB HOG, nechcete to použít moc často. + def aktualizuj_nazvy(self, request, queryset): + newqs = queryset.get_real_instances() + for tn in newqs: + tn.aktualizuj_nazev() + tn.save() + self.message_user(request, "Názvy aktualizovány.") + aktualizuj_nazvy.short_description = "Aktualizuj vybraným TreeNodům názvy" + @admin.register(m.RocnikNode) class RocnikNodeAdmin(PolymorphicChildModelAdmin): base_model = m.RocnikNode From 33fe0452b34956ab84d4f30399cecff934435cc5 Mon Sep 17 00:00:00 2001 From: Pavel 'LEdoian' Turinsky Date: Thu, 16 Jan 2020 01:26:46 +0100 Subject: [PATCH 84/92] =?UTF-8?q?Models:=20sho=C4=8F=20web,=20pokud=20n?= =?UTF-8?q?=C4=9Bkdo=20aktualizuje=20n=C3=A1zev=20obecn=C3=A9mu=20TreeNode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/models.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/seminar/models.py b/seminar/models.py index e65dcb67..95441384 100644 --- a/seminar/models.py +++ b/seminar/models.py @@ -1300,6 +1300,9 @@ class TreeNode(PolymorphicModel): self.aktualizuj_nazev() super().save(*args, **kwargs) + def aktualizuj_nazev(self): + raise NotImplementedError("Pokus o aktualizaci názvu obecného TreeNode místo konkrétní instance") + class RocnikNode(TreeNode): class Meta: db_table = 'seminar_nodes_rocnik' From aaee03497d1718869b5b078f65b843091cc93a00 Mon Sep 17 00:00:00 2001 From: "Tomas \"Jethro\" Pokorny" Date: Wed, 29 Jan 2020 22:22:54 +0100 Subject: [PATCH 85/92] =?UTF-8?q?Views:=20Aktualizov=C3=A1n=20view=20a=20t?= =?UTF-8?q?emplate=20na=20ob=C3=A1lkov=C3=A1n=C3=AD.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/templates/seminar/org/obalkovani.html | 30 +++++++++++++ seminar/urls.py | 4 +- seminar/views.py | 43 ++++++++++++++++++- 3 files changed, 74 insertions(+), 3 deletions(-) create mode 100644 seminar/templates/seminar/org/obalkovani.html diff --git a/seminar/templates/seminar/org/obalkovani.html b/seminar/templates/seminar/org/obalkovani.html new file mode 100644 index 00000000..fa130bc7 --- /dev/null +++ b/seminar/templates/seminar/org/obalkovani.html @@ -0,0 +1,30 @@ +{% extends "base.html" %} + +{% block content %} +

        + {% block nadpis1a %}{% block nadpis1b %} + Obálkování {{ cislo }} + {% endblock %}{% endblock %} +

        +
          + {% for reseni in object_list %} + {% ifchanged reseni.resitele %} + {% if not forloop.first %} +
        + {% endif %} +

        {% for resitel in reseni.resitele.all %}{{resitel.osoba}},{% endfor %}

        +
          + {% endifchanged %} + +
        • Celkem {{reseni.hodnoceni__body__sum}} bodů z {{reseni.hodnoceni__count}} hodnocení +
            + {% for h in reseni.hodnoceni_set.all %} +
          • {{ h.problem }}: {{ h.body }}b
          • + {% endfor %} +
          +
        • + {% endfor %} +
        + + +{% endblock content %} diff --git a/seminar/urls.py b/seminar/urls.py index 7ae2558c..57e447f3 100644 --- a/seminar/urls.py +++ b/seminar/urls.py @@ -89,7 +89,7 @@ urlpatterns = [ path('stav', staff_member_required(views.StavDatabazeView), name='stav_databaze'), path('cislo/./obalkovani', - staff_member_required(views.obalkovaniView), name='seminar_cislo_resitel_obalkovani'), + staff_member_required(views.ObalkovaniView.as_view()), name='seminar_cislo_resitel_obalkovani'), path('cislo/./tex-download.json', staff_member_required(views.texDownloadView), name='seminar_tex_download'), path('soustredeni//obalky.pdf', @@ -101,6 +101,8 @@ urlpatterns = [ staff_member_required(views.texUploadView), name='seminar_tex_upload' ), + path('org/vloz_body//', + staff_member_required(views.VlozBodyView.as_view()),name='seminar_org_vlozbody'), path('auth/prihlaska/',views.prihlaskaView, name='seminar_prihlaska'), path('auth/login/', views.LoginView.as_view(), name='login'), path('auth/logout/', views.LogoutView.as_view(), name='logout'), diff --git a/seminar/views.py b/seminar/views.py index 6f31a889..b4c710a5 100644 --- a/seminar/views.py +++ b/seminar/views.py @@ -7,7 +7,7 @@ from django.core.exceptions import PermissionDenied, ObjectDoesNotExist from django.views import generic from django.utils.translation import ugettext as _ from django.http import Http404,HttpResponseBadRequest,HttpResponseRedirect -from django.db.models import Q +from django.db.models import Q, Sum, Count from django.views.decorators.csrf import ensure_csrf_cookie from django.contrib.auth import authenticate, login, get_user_model, logout from django.contrib.auth import views as auth_views @@ -45,6 +45,45 @@ def verejna_temata(rocnik): """ return Problem.objects.filter(typ=Problem.TYP_TEMA, cislo_zadani__rocnik=rocnik, cislo_zadani__verejne_db=True).order_by('kod') +def temata_v_rocniku(rocnik): + return Problem.objects.filter(typ=Problem.TYP_TEMA, rocnik=rocnik) + +def get_problemy_k_tematu(tema): + return Problemy.objects.filter(nadproblem = tema) + + +class VlozBodyView(generic.ListView): + template_name = 'seminar/org/vloz_body.html' + + def get_queryset(self): + self.tema = get_object_or_404(Problem,id=self.kwargs['tema']) + print(self.tema) + self.problemy = Problem.objects.filter(nadproblem = self.tema) + print(self.problemy) + self.reseni = Reseni.objects.filter(problem__in=self.problemy) + print(self.reseni) + return self.reseni + + +class ObalkovaniView(generic.ListView): + template_name = 'seminar/org/obalkovani.html' + + def get_queryset(self): + rocnik = get_object_or_404(Rocnik,rocnik=self.kwargs['rocnik']) + cislo = get_object_or_404(Cislo,rocnik=rocnik,poradi=self.kwargs['cislo']) + self.cislo = cislo + self.hodnoceni = s.Hodnoceni.objects.filter(cislo_body=cislo) + self.reseni = Reseni.objects.filter(hodnoceni__in = self.hodnoceni).annotate(Sum('hodnoceni__body')).annotate(Count('hodnoceni')).order_by('resitele__osoba') + return self.reseni + + def get_context_data(self, **kwargs): + context = super(ObalkovaniView, self).get_context_data(**kwargs) + print(self.cislo) + context['cislo'] = self.cislo + return context + + + def AktualniZadaniView(request): nastaveni = get_object_or_404(Nastaveni) @@ -740,7 +779,7 @@ def obalkyView(request,resitele): return response -def obalkovaniView(request, rocnik, cislo): +def oldObalkovaniView(request, rocnik, cislo): rocnik = Rocnik.objects.get(rocnik=rocnik) cislo = Cislo.objects.get(rocnik=rocnik, cislo=cislo) From a674d837ae6652ad255de5034e3ca3176e4cd87d Mon Sep 17 00:00:00 2001 From: "Tomas \"Jethro\" Pokorny" Date: Wed, 5 Feb 2020 23:30:41 +0100 Subject: [PATCH 86/92] forms | Pridan prototyp formulare na odevzdavani reseni. --- seminar/forms.py | 47 ++++++++++++++++++- .../templates/seminar/org/vloz_reseni.html | 17 +++++++ seminar/urls.py | 5 ++ seminar/views.py | 26 ++++++++++ 4 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 seminar/templates/seminar/org/vloz_reseni.html diff --git a/seminar/forms.py b/seminar/forms.py index b28beeb9..9ce38e68 100644 --- a/seminar/forms.py +++ b/seminar/forms.py @@ -3,7 +3,8 @@ from dal import autocomplete from django.core.exceptions import ObjectDoesNotExist from django.contrib.auth.models import User -from .models import Skola, Resitel, Osoba +from .models import Skola, Resitel, Osoba, Problem +import seminar.models as m from datetime import date import logging @@ -210,3 +211,47 @@ class EditForm(forms.Form): # self.add_error('skola_nazev',forms.ValidationError('Je nutné vyplnit název školy')) # elif data.get('skola_adresa')=='': # self.add_error('skola_adresa',forms.ValidationError('Je nutné vyplnit adresu školy')) + +class VlozReseniForm(forms.Form): + #FIXME jen podproblémy daného problému + problem = forms.ModelChoiceField(label='Problém',queryset=m.Problem.objects.all()) + # to_field_name + #problem = models.ManyToManyField(Problem, verbose_name='problém', help_text='Problém', + # through='Hodnoceni') + + # FIXME pridat vice resitelu + resitel = forms.ModelChoiceField(label="Řešitel", + queryset=Resitel.objects.all(), + widget=autocomplete.ModelSelect2( + url='autocomplete_resitel', + attrs = {'data-placeholder--id': '-1', + 'data-placeholder--text' : '---', + 'data-allow-clear': 'true'}) + ) + + + #resitele = models.ManyToManyField(Resitel, verbose_name='autoři řešení', + # help_text='Seznam autorů řešení', through='Reseni_Resitele') + + cas_doruceni = forms.DateField(label="Čas doručení") + + #cas_doruceni = models.DateTimeField('čas_doručení', default=timezone.now, blank=True) + + forma = forms.ChoiceField(label="Forma řešení",choices = m.Reseni.FORMA_CHOICES) + #forma = models.CharField('forma řešení', max_length=16, choices=FORMA_CHOICES, blank=False, + # default=FORMA_EMAIL) + + poznamka = forms.CharField(label='Neveřejná poznámka') + #poznamka = models.TextField('neveřejná poznámka', blank=True, + # help_text='Neveřejná poznámka k řešení (plain text)') + + #TODO body do cisla + #TODO prilohy + + def __init__(self, *args, **kwargs): + super(VlozReseniForm, self).__init__(*args, **kwargs) + #self.fields['favorite_color'] = forms.ChoiceField(choices=[(color.id, color.name) for color in Resitel.objects.all()]) + + + + diff --git a/seminar/templates/seminar/org/vloz_reseni.html b/seminar/templates/seminar/org/vloz_reseni.html new file mode 100644 index 00000000..4339e0e3 --- /dev/null +++ b/seminar/templates/seminar/org/vloz_reseni.html @@ -0,0 +1,17 @@ +{% extends "seminar/zadani/base.html" %} +{% load staticfiles %} +{% block script %} + + {{form.media}} + +{% endblock %} + +{% block content %} +

        + {% block nadpis1a %}{% block nadpis1b %} + Přihláška do semináře + {% endblock %}{% endblock %} +

        +{{form.as_p}} + +{% endblock %} diff --git a/seminar/urls.py b/seminar/urls.py index 57e447f3..84775838 100644 --- a/seminar/urls.py +++ b/seminar/urls.py @@ -108,12 +108,17 @@ urlpatterns = [ path('auth/logout/', views.LogoutView.as_view(), name='logout'), path('auth/resitel/', views.ResitelView.as_view(), name='seminar_resitel'), path('autocomplete/skola/',views.SkolaAutocomplete.as_view(), name='autocomplete_skola'), + path('autocomplete/resitel/',views.ResitelAutocomplete.as_view(), name='autocomplete_resitel'), path('auth/reset_password/', views.PasswordResetView.as_view(), name='reset_password'), path('auth/change_password/', views.PasswordChangeView.as_view(), name='change_password'), path('auth/reset_password_done/', views.PasswordResetDoneView.as_view(), name='reset_password_done'), path('auth/reset_password_confirm///', views.PasswordResetConfirmView.as_view(), name='password_reset_confirm'), path('auth/reset_password_complete/', views.PasswordResetCompleteView.as_view(), name='reset_password_complete'), path('auth/resitel_edit', views.resitelEditView, name='seminar_resitel_edit'), + + + path('temp/add_solution', views.AddSolutionView.as_view()), + path('', views.TitulniStranaView.as_view(), name='titulni_strana'), # Ceka na autocomplete v3 diff --git a/seminar/views.py b/seminar/views.py index b4c710a5..c43a0043 100644 --- a/seminar/views.py +++ b/seminar/views.py @@ -9,6 +9,7 @@ from django.utils.translation import ugettext as _ from django.http import Http404,HttpResponseBadRequest,HttpResponseRedirect from django.db.models import Q, Sum, Count from django.views.decorators.csrf import ensure_csrf_cookie +from django.views.generic.edit import FormView from django.contrib.auth import authenticate, login, get_user_model, logout from django.contrib.auth import views as auth_views from django.contrib.auth.models import User @@ -22,6 +23,7 @@ from .models import Problem, Cislo, Reseni, Nastaveni, Rocnik, Soustredeni, Orga from . import utils from .unicodecsv import UnicodeWriter from .forms import PrihlaskaForm, LoginForm, EditForm +import seminar.forms as f from datetime import timedelta, date, datetime from django.utils import timezone @@ -1123,6 +1125,11 @@ class ResitelView(LoginRequiredMixin,generic.DetailView): return Resitel.objects.get(osoba__user=self.request.user) ## Formulare +class AddSolutionView(LoginRequiredMixin, FormView): + template_name = 'seminar/org/vloz_reseni.html' + form_class = f.VlozReseniForm + success_url = '/' + def resetPasswordView(request): pass @@ -1297,6 +1304,25 @@ class SkolaAutocomplete(autocomplete.Select2QuerySetView): return qs +class LoginRequiredAjaxMixin(object): + def dispatch(self, request, *args, **kwargs): + #if request.is_ajax() and not request.user.is_authenticated: # Pokud to otevřu jako stránku, tak se omezení neuplatní, takže to asi nechceme + if not request.user.is_authenticated: + return JsonResponse(data={'results': [], 'pagination': {}}, status=401) + return super(LoginRequiredAjaxMixin, self).dispatch(request, *args, **kwargs) + +class ResitelAutocomplete(LoginRequiredAjaxMixin,autocomplete.Select2QuerySetView): + def get_queryset(self): + qs = Resitel.objects.all() + if self.q: + qs = qs.filter( + Q(osoba__jmeno__startswith=self.q)| + Q(osoba__prijmeni__startswith=self.q)| + Q(osoba__prezdivka__startswith=self.q) + ) + return qs + + # Ceka na autocomplete v3 # class OrganizatorAutocomplete(autocomplete.Select2QuerySetView): # def get_queryset(self): From e63253f848e00f29a62ecef9015db7c773a97a8f Mon Sep 17 00:00:00 2001 From: "Tomas \"Jethro\" Pokorny" Date: Wed, 5 Feb 2020 23:59:21 +0100 Subject: [PATCH 87/92] Forms | Prace na vkladani reseni. --- seminar/templates/seminar/org/vloz_reseni.html | 6 +++++- seminar/urls.py | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/seminar/templates/seminar/org/vloz_reseni.html b/seminar/templates/seminar/org/vloz_reseni.html index 4339e0e3..bfe4f6f6 100644 --- a/seminar/templates/seminar/org/vloz_reseni.html +++ b/seminar/templates/seminar/org/vloz_reseni.html @@ -9,9 +9,13 @@ {% block content %}

        {% block nadpis1a %}{% block nadpis1b %} - Přihláška do semináře + Vložit řešení {% endblock %}{% endblock %}

        +
        + {% csrf_token %} {{form.as_p}} + +
        {% endblock %} diff --git a/seminar/urls.py b/seminar/urls.py index 84775838..bc1c89a8 100644 --- a/seminar/urls.py +++ b/seminar/urls.py @@ -117,7 +117,7 @@ urlpatterns = [ path('auth/resitel_edit', views.resitelEditView, name='seminar_resitel_edit'), - path('temp/add_solution', views.AddSolutionView.as_view()), + path('temp/add_solution', views.AddSolutionView.as_view(),name='seminar_vloz_reseni'), path('', views.TitulniStranaView.as_view(), name='titulni_strana'), From 0e1eca9fcb3e917b548043b3258c731f5b8087ef Mon Sep 17 00:00:00 2001 From: Pavel 'LEdoian' Turinsky Date: Sat, 8 Feb 2020 03:45:53 +0100 Subject: [PATCH 88/92] =?UTF-8?q?TreeNode.print=5Ftree()=20vypisuje=20smys?= =?UTF-8?q?lupln=C3=BD=20n=C3=A1zev=20dan=C3=A9ho=20node.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/models.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/seminar/models.py b/seminar/models.py index 95441384..768b430a 100644 --- a/seminar/models.py +++ b/seminar/models.py @@ -1262,8 +1262,10 @@ class TreeNode(PolymorphicModel): verbose_name = "Srolovatelné", help_text = "Bude na stránce témátka možnost tuto položku skrýt") + # Slouží k debugování pro rychlé získání představy o podobě podstromu pod tímto TreeNode. def print_tree(self,indent=0): - print("{}TreeNode({})".format(" "*indent,self.id)) + # FIXME: Tady se spoléháme na to, že nedeklarovaný primární klíč se jmenuje by default 'id', což není úplně správně + print("{}{} (id: {})".format(" "*indent,self, self.id)) if self.first_child: self.first_child.print_tree(indent=indent+2) if self.succ: From 73c440b7fd3329cffc0eb008def8163b0bafae37 Mon Sep 17 00:00:00 2001 From: Anet Date: Tue, 11 Feb 2020 20:41:57 +0100 Subject: [PATCH 89/92] =?UTF-8?q?testutils:=20v=C3=ADce=20=C5=99e=C5=A1en?= =?UTF-8?q?=C3=AD=20m=C3=A1=20jen=20jednoho=20=C5=99e=C5=A1itele?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/testutils.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/seminar/testutils.py b/seminar/testutils.py index f378e725..6befbbf7 100644 --- a/seminar/testutils.py +++ b/seminar/testutils.py @@ -166,7 +166,7 @@ def gen_ulohy_do_cisla(rnd, organizatori, resitele, rocnik_cisla, rocniky, size) for rocnik in rocniky: k+=1 cisla = rocnik_cisla[k-1] - for ci in range(3, len(cisla)+1): + for ci in range(3, len(cisla)+1): # pro všechna čísla for pi in range(1, ((size + 1) // 2) + 1): poc_op = rnd.randint(1, 4) # počet opravovatelů @@ -206,7 +206,8 @@ def gen_ulohy_do_cisla(rnd, organizatori, resitele, rocnik_cisla, rocniky, size) uloha_zadani = UlohaZadaniNode.objects.create(uloha=p, first_child = zad) p.ulohazadaninode = uloha_zadani otec_syn(cisla[ci-2-1].cislonode, uloha_zadani) - + + # generování vzorového textu text_vzoraku = Text.objects.create( na_web = rnd.choice(reseni), do_cisla = rnd.choice(reseni) @@ -219,17 +220,18 @@ def gen_ulohy_do_cisla(rnd, organizatori, resitele, rocnik_cisla, rocniky, size) p.opravovatele.set(rnd.sample(organizatori,poc_op)) p.save() - # reseni ulohy + # generování řešení poc_reseni = rnd.randint(size // 2, size * 2) - #poc_resitel = rnd.randint(1, 3) <- k čemu je himbajs tahle proměnná? - # vybereme nahodny vzorek resitelu o delce poctu reseni - # (nebo skoro vsechny resitele, pokud jich je mene nez pocet reseni) + # generujeme náhodný počet řešení for ri in range(poc_reseni): - res_vyber = rnd.sample(resitele, rnd.randint(1, 5)) + if rnd.randint(1, 10) == 6: + # cca desetina řešení od více řešitelů + res_vyber = rnd.sample(resitele, rnd.randint(2, 5)) + else: + res_vyber = rnd.sample(resitele, 1) + res = Reseni.objects.create(forma=rnd.choice(Reseni.FORMA_CHOICES)[0]) # problem a resitele přiřadíme později, ManyToManyField # se nedá vyplnit v create() - res = Reseni.objects.create(forma=rnd.choice(Reseni.FORMA_CHOICES)[0]) - #res.save() <- asi smazat res.resitele.set(res_vyber) res.save() hod = Hodnoceni.objects.create( From 3b8ba5b0360013fbc16346bccb682a7810bed2aa Mon Sep 17 00:00:00 2001 From: Anet Date: Tue, 11 Feb 2020 21:17:17 +0100 Subject: [PATCH 90/92] =?UTF-8?q?testutils:=20snaha=20o=20to,=20aby=20v=20?= =?UTF-8?q?dan=C3=A9m=20=C4=8D=C3=ADsle=20bylo=20v=C3=ADce=20=C5=99e=C5=A1?= =?UTF-8?q?en=C3=AD=20od=20jednoho=20=C5=99e=C5=A1itele?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/testutils.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/seminar/testutils.py b/seminar/testutils.py index 6befbbf7..b81d09f8 100644 --- a/seminar/testutils.py +++ b/seminar/testutils.py @@ -167,6 +167,13 @@ def gen_ulohy_do_cisla(rnd, organizatori, resitele, rocnik_cisla, rocniky, size) k+=1 cisla = rocnik_cisla[k-1] for ci in range(3, len(cisla)+1): # pro všechna čísla + resitele_size = round(7/8 * 30 * size) # očekáváný celkový počet řešitelů + poc_res = rnd.randint(round(resitele_size/8), round(3*resitele_size/4)) + # dané číslo řeší něco mezi osminou a tříčtvrtinou všech řešitelů + # (náhodná hausnumera, možno změnit) + # účelem je, aby se řešení generovala z menší množiny řešitelů a tedy + # bylo více řešení od jednoho řešitele daného čísla + resitele_cisla = rnd.sample(resitele, poc_res) for pi in range(1, ((size + 1) // 2) + 1): poc_op = rnd.randint(1, 4) # počet opravovatelů @@ -226,9 +233,9 @@ def gen_ulohy_do_cisla(rnd, organizatori, resitele, rocnik_cisla, rocniky, size) for ri in range(poc_reseni): if rnd.randint(1, 10) == 6: # cca desetina řešení od více řešitelů - res_vyber = rnd.sample(resitele, rnd.randint(2, 5)) + res_vyber = rnd.sample(resitele_cisla, rnd.randint(2, 5)) else: - res_vyber = rnd.sample(resitele, 1) + res_vyber = rnd.sample(resitele_cisla, 1) res = Reseni.objects.create(forma=rnd.choice(Reseni.FORMA_CHOICES)[0]) # problem a resitele přiřadíme později, ManyToManyField # se nedá vyplnit v create() From 96b00025dbd97bc1d76097346de05bafa0e5c589 Mon Sep 17 00:00:00 2001 From: Pavel 'LEdoian' Turinsky Date: Tue, 11 Feb 2020 21:37:35 +0100 Subject: [PATCH 91/92] =?UTF-8?q?P=C5=99ejmenov=C3=A1n=20EditForm=20na=20P?= =?UTF-8?q?rofileEditForm?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/forms.py | 2 +- seminar/views.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/seminar/forms.py b/seminar/forms.py index 9ce38e68..8c50c2c5 100644 --- a/seminar/forms.py +++ b/seminar/forms.py @@ -124,7 +124,7 @@ class PrihlaskaForm(forms.Form): self.add_error('skola_adresa',forms.ValidationError('Je nutné vyplnit adresu školy')) -class EditForm(forms.Form): +class ProfileEditForm(forms.Form): username = forms.CharField(label='Přihlašovací jméno', max_length=256, required=True) diff --git a/seminar/views.py b/seminar/views.py index 0227a2c3..e174ab28 100644 --- a/seminar/views.py +++ b/seminar/views.py @@ -22,7 +22,7 @@ from .models import Problem, Cislo, Reseni, Nastaveni, Rocnik, Soustredeni, Orga #from .models import VysledkyZaCislo, VysledkyKCisluZaRocnik, VysledkyKCisluOdjakziva from . import utils from .unicodecsv import UnicodeWriter -from .forms import PrihlaskaForm, LoginForm, EditForm +from .forms import PrihlaskaForm, LoginForm, ProfileEditForm import seminar.forms as f from datetime import timedelta, date, datetime @@ -1207,10 +1207,10 @@ def resitelEditView(request): prefill_3=model_to_dict(osoba_edit) prefill_1.update(prefill_2) prefill_1.update(prefill_3) - form = EditForm(initial=prefill_1) + form = ProfileEditForm(initial=prefill_1) ## Změna údajů a jejich uložení if request.method == 'POST': - form = EditForm(request.POST) + form = ProfileEditForm(request.POST) if form.is_valid(): ## Změny v osobě fcd = form.cleaned_data From 8604ef7b4c04f982d8ea7e7f16d86ce6a6331c5c Mon Sep 17 00:00:00 2001 From: Pavel 'LEdoian' Turinsky Date: Tue, 11 Feb 2020 21:49:29 +0100 Subject: [PATCH 92/92] =?UTF-8?q?VlozReseniForm:=20nov=C4=9Bj=C5=A1=C3=AD?= =?UTF-8?q?=20super=20je=20super()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/forms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/seminar/forms.py b/seminar/forms.py index 8c50c2c5..6a0e7911 100644 --- a/seminar/forms.py +++ b/seminar/forms.py @@ -249,7 +249,7 @@ class VlozReseniForm(forms.Form): #TODO prilohy def __init__(self, *args, **kwargs): - super(VlozReseniForm, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) #self.fields['favorite_color'] = forms.ChoiceField(choices=[(color.id, color.name) for color in Resitel.objects.all()])