Browse Source

Merge remote-tracking branch 'origin/data_migrations' into treenode_editor

export_seznamu_prednasek
parent
commit
a7879dc799
  1. BIN
      galerie/static/galerie/prvky/dalsi.png
  2. 65
      galerie/static/galerie/prvky/dalsi.svg
  3. BIN
      galerie/static/galerie/prvky/nahoru.png
  4. BIN
      galerie/static/galerie/prvky/predchozi.png
  5. 65
      galerie/static/galerie/prvky/predchozi.svg
  6. 97
      mamweb/static/css/mamweb.css
  7. 19
      seminar/migrations/0082_auto_20200506_1951.py
  8. 19
      seminar/migrations/0083_auto_20200506_1952.py
  9. 10
      seminar/models.py
  10. 10
      seminar/static/seminar/prihlaska.js
  11. 14
      seminar/templates/seminar/archiv/temata.html
  12. 85
      seminar/templates/seminar/edit.html
  13. 7
      seminar/templates/seminar/login.html
  14. 118
      seminar/templates/seminar/prihlaska.html
  15. 25
      seminar/templates/seminar/prihlaska_field.html
  16. 241
      seminar/testutils.py
  17. 41
      seminar/treelib.py
  18. 5
      seminar/urls.py
  19. 14
      seminar/views/views_all.py

BIN
galerie/static/galerie/prvky/dalsi.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

65
galerie/static/galerie/prvky/dalsi.svg

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="25.135418mm"
height="42.333332mm"
viewBox="0 0 25.135418 42.333331"
version="1.1"
id="svg851"
sodipodi:docname="dalsi.svg"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1850"
inkscape:window-height="1136"
id="namedview7"
showgrid="true"
inkscape:zoom="23.600001"
inkscape:cx="18.587131"
inkscape:cy="74.924864"
inkscape:window-x="70"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="svg851">
<inkscape:grid
type="xygrid"
id="grid833" />
</sodipodi:namedview>
<defs
id="defs845" />
<metadata
id="metadata848">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
transform="matrix(-1.0282842,0,0,1,111.4545,-88.415317)">
<path
d="m 98.096584,101.64448 1.286528,1.32292 -5.660724,5.82083 h 13.379892 v 1.5875 H 93.722388 l 5.660724,5.82083 -1.286528,1.32292 -7.719171,-7.9375 z"
style="fill:#e84e10;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.23177969"
id="path44-3"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccccc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
galerie/static/galerie/prvky/nahoru.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

BIN
galerie/static/galerie/prvky/predchozi.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

65
galerie/static/galerie/prvky/predchozi.svg

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="25.135418mm"
height="42.333332mm"
viewBox="0 0 25.135418 42.333331"
version="1.1"
id="svg851"
sodipodi:docname="predchozi.svg"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1850"
inkscape:window-height="1136"
id="namedview7"
showgrid="true"
inkscape:zoom="4.1719301"
inkscape:cx="124.03002"
inkscape:cy="97.874031"
inkscape:window-x="70"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="svg851">
<inkscape:grid
type="xygrid"
id="grid833" />
</sodipodi:namedview>
<defs
id="defs845" />
<metadata
id="metadata848">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
transform="matrix(1.0282842,0,0,1,-86.319083,-88.415315)">
<path
d="m 98.096584,101.64448 1.286528,1.32292 -5.660724,5.82083 h 13.379892 v 1.5875 H 93.722388 l 5.660724,5.82083 -1.286528,1.32292 -7.719171,-7.9375 z"
style="fill:#e84e10;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.23177969"
id="path44-3"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccccc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

97
mamweb/static/css/mamweb.css

@ -712,19 +712,6 @@ div.cislo_odkazy ul {
padding: 0px; padding: 0px;
} }
/* archiv ročník
div.cisla-v-rocniku {
font-weight: bold;
color: #6f2509;
}
div.cislo-v-rocniku-blok {
display: inline-block;
width: 150px;
height: 220px;
text-align: center;
}*/
/* galerie */ /* galerie */
@ -745,7 +732,8 @@ div.cislo-v-rocniku-blok {
top: 0; top: 0;
} }
.predchozi_obrazek:hover{ .predchozi_obrazek:hover{
background-image: url("/static/galerie/prvky/predchozi.png"); background-image: url("/static/galerie/prvky/predchozi.svg");
filter: drop-shadow(0px 5px 5px rgba(0, 0, 0, 0.4));
background-position: left center; background-position: left center;
background-repeat: no-repeat; background-repeat: no-repeat;
} }
@ -758,7 +746,8 @@ div.cislo-v-rocniku-blok {
top: 0; top: 0;
} }
.dalsi_obrazek:hover{ .dalsi_obrazek:hover{
background-image: url("/static/galerie/prvky/dalsi.png"); background-image: url("/static/galerie/prvky/dalsi.svg");
filter: drop-shadow(0px 5px 5px rgba(0, 0, 0, 0.4));
background-position: right center; background-position: right center;
background-repeat: no-repeat; background-repeat: no-repeat;
} }
@ -788,31 +777,25 @@ div.cislo-v-rocniku-blok {
/* titulní obrázek hlavní galerie soustředění */ /* titulní obrázek hlavní galerie soustředění */
.titulni_obrazek { .titulni_obrazek {
border: 1px solid black;
} }
.galerie_nahledy{ .galerie_nahledy{
/*margin: 1em 0;*/ /*margin: 1em 0;*/
margin: 0 auto 30px auto; margin: auto;
padding: 10px;
text-align: center; text-align: center;
overflow: auto; overflow: auto;
} }
.galerie_nahledy img {
margin: 10px;
}
.galerie_nahledy div.navigace { .galerie_nahledy div.navigace {
display: inline-block; display: inline-block;
width: 150px;
} }
/*.galerie_nahledy img{*/ .galerie_nahled, .podgalerie_nahled { /* frame */
/*margin: 0 10px 0 10px;*/
/*}*/
/*.galerie_nahledy a{*/
/*height: 100%;*/
/*width: 100%;*/
/*}*/
.galerie_nahled { /* frame */
display: block; display: block;
position: relative; position: relative;
float: left; float: left;
@ -820,19 +803,19 @@ div.cislo-v-rocniku-blok {
height: 200px; height: 200px;
text-align: center; text-align: center;
border: solid; border: solid;
border-width: 2px; border-width: 1px;
border-radius: 5px; border-radius: 4px;
/*border-color: #ffa500;*/ border-color: #f9d59e;
border-color: #ffd546; background-color: #fffbf6;
/*background-color: #ffb52d;*/
background-color: white;
white-space: nowrap; white-space: nowrap;
margin: 10px 20px 10px 0px; margin: 10px;
font-weight: bold;
} }
.galerie_nahled:hover { .galerie_nahled:hover, .podgalerie_nahled:hover {
background-color: #ffd546; background-color: #f9d59e;
border-color: #ffa500; filter: drop-shadow(0px 5px 5px rgba(0, 0, 0, 0.4));
color: #6f2509;
} }
.vystredeno{ /* helper */ .vystredeno{ /* helper */
@ -845,12 +828,6 @@ div.cislo-v-rocniku-blok {
vertical-align: middle; vertical-align: middle;
max-height: 180px; max-height: 180px;
max-width: 180px; max-width: 180px;
/*border: 1px solid white;*/
}
.galerie_nahled img, .podgalerie_nahled img {
border-radius: 2px;
} }
.galerie_nahled div { .galerie_nahled div {
@ -860,30 +837,6 @@ div.cislo-v-rocniku-blok {
text-align: center; text-align: center;
} }
.podgalerie_nahled {
display: block;
position: relative;
float: left;
width: 200px;
height: 200px;
text-align: center;
border: solid;
border-width: 2px;
border-radius: 5px;
border-color: #ffa500;
/*border-color: #ffd546;*/
background-color: #ffd546;
/*background-color: white;*/
white-space: nowrap;
margin: 10px 20px 10px 0px;
font-weight: bold;
}
.podgalerie_nahled:hover {
background-color: #ffa500;
}
.podgalerie_nahled img { .podgalerie_nahled img {
margin-top: 20px; margin-top: 20px;
margin-bottom: 15px; margin-bottom: 15px;
@ -899,10 +852,10 @@ div.cislo-v-rocniku-blok {
/* plus a minus tlacitka */ /* plus a minus tlacitka */
.mam-org-only-galerie { .mam-org-only-galerie {
background: #fff0d7; background: #eee4ec;
padding: 10px; padding: 10px;
margin: 10px 10px 10px -20px; margin: 10px 10px 10px -20px;
border: orange 2px dashed; border: #333 2px dashed;
float: left; float: left;
} }
@ -910,8 +863,8 @@ div.cislo-v-rocniku-blok {
padding: 3px 5px; padding: 3px 5px;
margin: 5px; margin: 5px;
border-radius: 20px; border-radius: 20px;
background-color: lightblue; background-color: #6f2509;;
color: black; color: #fffbf6;
float: left; float: left;
} }

19
seminar/migrations/0082_auto_20200506_1951.py

@ -0,0 +1,19 @@
# Generated by Django 2.2.12 on 2020-05-06 17:51
from django.db import migrations, models
import seminar.models
class Migration(migrations.Migration):
dependencies = [
('seminar', '0081_auto_20200408_2221'),
]
operations = [
migrations.AlterField(
model_name='cislo',
name='titulka_nahled',
field=models.ImageField(blank=True, help_text='Obrázek titulní strany, generuje se automaticky', null=True, upload_to=seminar.models.cislo_png_filename, verbose_name='Obrázek titulní strany'),
),
]

19
seminar/migrations/0083_auto_20200506_1952.py

@ -0,0 +1,19 @@
# Generated by Django 2.2.12 on 2020-05-06 17:52
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('seminar', '0082_auto_20200506_1951'),
]
operations = [
migrations.AlterField(
model_name='treenode',
name='first_child',
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='father_of_first', to='seminar.TreeNode', verbose_name='první potomek'),
),
]

10
seminar/models.py

@ -14,6 +14,7 @@ from django.utils.text import slugify
from django.urls import reverse from django.urls import reverse
from django.core.cache import cache from django.core.cache import cache
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from django.contrib.contenttypes.models import ContentType
from django.utils.text import get_valid_filename from django.utils.text import get_valid_filename
from imagekit.models import ImageSpecField, ProcessedImageField from imagekit.models import ImageSpecField, ProcessedImageField
from imagekit.processors import ResizeToFit, Transpose from imagekit.processors import ResizeToFit, Transpose
@ -27,6 +28,7 @@ from reversion import revisions as reversion
from seminar.utils import roman, FirstTagParser # Pro získání úryvku z TextNode from seminar.utils import roman, FirstTagParser # Pro získání úryvku z TextNode
from unidecode import unidecode # Používám pro získání ID odkazu (ještě je to někde po někom zakomentované) from unidecode import unidecode # Používám pro získání ID odkazu (ještě je to někde po někom zakomentované)
from seminar.treelib import safe_pred
from polymorphic.models import PolymorphicModel from polymorphic.models import PolymorphicModel
@ -1246,7 +1248,7 @@ class TreeNode(PolymorphicModel):
blank = False, blank = False,
on_delete = models.SET_NULL, # Vrcholy s null kořenem jsou sirotci bez ročníku on_delete = models.SET_NULL, # Vrcholy s null kořenem jsou sirotci bez ročníku
verbose_name="kořen stromu") verbose_name="kořen stromu")
first_child = models.ForeignKey('TreeNode', first_child = models.OneToOneField('TreeNode',
related_name='father_of_first', related_name='father_of_first',
null = True, null = True,
blank = True, blank = True,
@ -1303,6 +1305,10 @@ class TreeNode(PolymorphicModel):
def aktualizuj_nazev(self): def aktualizuj_nazev(self):
raise NotImplementedError("Pokus o aktualizaci názvu obecného TreeNode místo konkrétní instance") raise NotImplementedError("Pokus o aktualizaci názvu obecného TreeNode místo konkrétní instance")
def get_admin_url(self):
content_type = ContentType.objects.get_for_model(self.__class__)
return reverse("admin:%s_%s_change" % (content_type.app_label, content_type.model), args=(self.id,))
class RocnikNode(TreeNode): class RocnikNode(TreeNode):
class Meta: class Meta:
db_table = 'seminar_nodes_rocnik' db_table = 'seminar_nodes_rocnik'
@ -1338,7 +1344,7 @@ class MezicisloNode(TreeNode):
# TODO: Využít TreeLib # TODO: Využít TreeLib
def aktualizuj_nazev(self): def aktualizuj_nazev(self):
if self.prev: if safe_pred(self) is not None:
if (self.prev.get_real_instance_class() != CisloNode and if (self.prev.get_real_instance_class() != CisloNode and
self.prev.get_real_instance_class() != MezicisloNode): self.prev.get_real_instance_class() != MezicisloNode):
raise ValueError("Předchůdce není číslo!") raise ValueError("Předchůdce není číslo!")

10
seminar/static/seminar/prihlaska.js

@ -3,7 +3,7 @@ function addrCountryChanged(){
var stat_text = document.getElementById('id_li_stat_text'); var stat_text = document.getElementById('id_li_stat_text');
var stat = stat_select[stat_select.selectedIndex].value; var stat = stat_select[stat_select.selectedIndex].value;
if (stat === "other"){ if (stat === "other"){
stat_text.style.display="block"; stat_text.style.display="revert";
} else { } else {
stat_text.style.display="none"; stat_text.style.display="none";
$('#id_stat_text').val(""); $('#id_stat_text').val("");
@ -12,18 +12,22 @@ function addrCountryChanged(){
function hideSchoolTextfields(){ function hideSchoolTextfields(){
var skola_nazev = document.getElementById('id_li_skola_nazev'); var skola_nazev = document.getElementById('id_li_skola_nazev');
var skola_adresa = document.getElementById('id_li_skola_adresa'); var skola_adresa = document.getElementById('id_li_skola_adresa');
var skola_vypln = document.getElementById('id_li_skola_vypln');
skola_nazev.style.display="none"; skola_nazev.style.display="none";
skola_adresa.style.display="none"; skola_adresa.style.display="none";
skola_vypln.style.display="none";
} }
function schoolNotInList(){ function schoolNotInList(){
var skola_nazev = document.getElementById('id_li_skola_nazev'); var skola_nazev = document.getElementById('id_li_skola_nazev');
var skola_adresa = document.getElementById('id_li_skola_adresa'); var skola_adresa = document.getElementById('id_li_skola_adresa');
var skola_vypln = document.getElementById('id_li_skola_vypln');
// FIXME nefunguje a nevim proc (TypeError: $(...).select2 is not a function) // FIXME nefunguje a nevim proc (TypeError: $(...).select2 is not a function)
//var skola_select = $('#id_skola').select2(); //var skola_select = $('#id_skola').select2();
//skola_select.val(null).trigger('change'); //skola_select.val(null).trigger('change');
skola_nazev.style.display="block"; skola_vypln.style.display="revert";
skola_adresa.style.display="block"; skola_nazev.style.display="revert";
skola_adresa.style.display="revert";
} }
document.addEventListener("DOMContentLoaded", function(){ document.addEventListener("DOMContentLoaded", function(){

14
seminar/templates/seminar/archiv/temata.html

@ -7,17 +7,13 @@
{% endblock %}{% endblock%} {% endblock %}{% endblock%}
</h1> </h1>
{% for tema in object_list %} {% for rocnik, temata in rocniky.items %}
{% with tema.cislo_zadani.rocnik.rocnik as rocnik %} <h2>Ročník {{ rocnik }}</h2>
{% ifchanged rocnik %}
{% if not forloop.first %}</ul>{% endif %}
<h2>{{ rocnik }}. ročník</h2>
<ul> <ul>
{% endifchanged %} {% for tema in temata %}
<li> <li><a href="{{ tema.verejne_utl }}"> {{ tema.kod_v_rocniku }}: {{ tema.nazev }} </a></li>
<a href="{{ tema.verejne_url }}">{{ tema.kod_v_rocniku }}: {{ tema.nazev }}</a>
{% endwith %}
{% endfor %} {% endfor %}
</ul> </ul>
{% endfor %}
{% endblock content %} {% endblock content %}

85
seminar/templates/seminar/edit.html

@ -15,59 +15,77 @@
<form action="{% url 'seminar_resitel_edit' %}" method="post"> <form action="{% url 'seminar_resitel_edit' %}" method="post">
{% csrf_token %} {% csrf_token %}
{{form.non_field_errors}} {{form.non_field_errors}}
<ul class="form">
<li> <hr>
<h4>
Přihlašovací údaje Přihlašovací údaje
</li><li> </h4>
<table class="form">
{% include "seminar/prihlaska_field.html" with field=form.username %} {% include "seminar/prihlaska_field.html" with field=form.username %}
</li><li> </table>
<hr>
<h4>
Osobní údaje Osobní údaje
</li><li> </h4>
<table class="form">
{% include "seminar/prihlaska_field.html" with field=form.jmeno %} {% include "seminar/prihlaska_field.html" with field=form.jmeno %}
</li><li>
{% include "seminar/prihlaska_field.html" with field=form.prijmeni %} {% include "seminar/prihlaska_field.html" with field=form.prijmeni %}
</li><li>
{% include "seminar/prihlaska_field.html" with field=form.pohlavi_muz%} {% include "seminar/prihlaska_field.html" with field=form.pohlavi_muz%}
</li><li>
{% include "seminar/prihlaska_field.html" with field=form.email %} {% include "seminar/prihlaska_field.html" with field=form.email %}
</li><li>
{% include "seminar/prihlaska_field.html" with field=form.telefon %} {% include "seminar/prihlaska_field.html" with field=form.telefon %}
</li><li>
{% include "seminar/prihlaska_field.html" with field=form.datum_narozeni %} {% include "seminar/prihlaska_field.html" with field=form.datum_narozeni %}
</li><li> </table>
<hr> <hr>
<h4>
Bydliště Bydliště
</li><li> </h4>
<table class="form">
{% include "seminar/prihlaska_field.html" with field=form.ulice %} {% include "seminar/prihlaska_field.html" with field=form.ulice %}
</li><li>
{% include "seminar/prihlaska_field.html" with field=form.mesto %} {% include "seminar/prihlaska_field.html" with field=form.mesto %}
</li><li>
{% include "seminar/prihlaska_field.html" with field=form.psc %} {% include "seminar/prihlaska_field.html" with field=form.psc %}
</li><li>
{% include "seminar/prihlaska_field.html" with field=form.stat %} {% include "seminar/prihlaska_field.html" with field=form.stat %}
</li> {% include "seminar/prihlaska_field.html" with field=form.stat_text id="id_li_stat_text"%}
<li id="id_li_stat_text"> </table>
{% include "seminar/prihlaska_field.html" with field=form.stat_text %}
</li><li>
<hr> <hr>
<h4>
Škola
</h4>
<table class="form">
{% include "seminar/prihlaska_field.html" with field=form.skola %} {% include "seminar/prihlaska_field.html" with field=form.skola %}
</li><li> <tr><td colspan="2" ><button id="id_skola_text_button" type="button">Škola není v seznamu</button></td></tr>
<button id="id_skola_text_button" type="button">Škola není v seznamu</button> <tr><td id="id_li_skola_vypln" colspan="2">Vyplň prosím celý název a adresu školy.</td></tr>
</li> {% include "seminar/prihlaska_field.html" with field=form.skola_nazev id="id_li_skola_nazev" %}
<li id="id_li_skola_nazev"> {% include "seminar/prihlaska_field.html" with field=form.skola_adresa id="id_li_skola_adresa" %}
Vyplň prosím celý název a adresu školy.<br>
{% include "seminar/prihlaska_field.html" with field=form.skola_nazev %}
</li>
<li id="id_li_skola_adresa">
{% include "seminar/prihlaska_field.html" with field=form.skola_adresa %}
</li><li>
{% include "seminar/prihlaska_field.html" with field=form.rok_maturity %} {% include "seminar/prihlaska_field.html" with field=form.rok_maturity %}
</li><li> </table>
<hr>
<h4>
Pošta
</h4>
<table class="form">
{% include "seminar/prihlaska_field.html" with field=form.zasilat %} {% include "seminar/prihlaska_field.html" with field=form.zasilat %}
</li><li> </table>
<hr>
<h4>
Zasílání propagačních materiálů
</h4>
<table class="form">
{% include "seminar/prihlaska_field.html" with field=form.spam %} {% include "seminar/prihlaska_field.html" with field=form.spam %}
</li> </table>
</ul>
<hr>
<input type="submit" value="Změnit"> <input type="submit" value="Změnit">
</form> </form>
<script> <script>
@ -75,4 +93,3 @@ $("#id_stat").on("change",addrCountryChanged);
$("#id_skola_text_button").on("click",schoolNotInList); $("#id_skola_text_button").on("click",schoolNotInList);
</script> </script>
{% endblock %} {% endblock %}

7
seminar/templates/seminar/login.html

@ -10,9 +10,9 @@
</h1> </h1>
<form action="{% url 'login' %}" method="post"> <form action="{% url 'login' %}" method="post">
{% csrf_token %} {% csrf_token %}
<ul class="form"> <table class="form">
{{ form.as_ul }} {{ form.as_table }}
</ul> </table>
{# 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... #} {# 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... #}
<input type="hidden" name='next' value="{{ next }}"> <input type="hidden" name='next' value="{{ next }}">
<input type="submit" value="Přihlásit"> <input type="submit" value="Přihlásit">
@ -23,4 +23,3 @@
{% endblock %} {% endblock %}

118
seminar/templates/seminar/prihlaska.html

@ -14,92 +14,93 @@
{% endblock %}{% endblock %} {% endblock %}{% endblock %}
</h1> </h1>
<form action="{% url 'seminar_prihlaska' %}" method="post"> <form action="{% url 'seminar_prihlaska' %}" method="post">
{% csrf_token %} {% csrf_token %}
{{form.non_field_errors}} {{form.non_field_errors}}
<ul class="form">
<li>
<hr>
<h4>
Přihlašovací údaje Přihlašovací údaje
</li> </h4>
<li> <table class="form">
{% include "seminar/prihlaska_field.html" with field=form.username %} {% include "seminar/prihlaska_field.html" with field=form.username %}
</li>
<li>
{% include "seminar/prihlaska_field.html" with field=form.password %} {% include "seminar/prihlaska_field.html" with field=form.password %}
</li>
<li>
{% include "seminar/prihlaska_field.html" with field=form.password_check %} {% include "seminar/prihlaska_field.html" with field=form.password_check %}
</li> </table>
<li>
<hr>
<h4>
Osobní údaje Osobní údaje
</li> </h4>
<li> <table class="form">
{% include "seminar/prihlaska_field.html" with field=form.jmeno %} {% include "seminar/prihlaska_field.html" with field=form.jmeno %}
</li>
<li>
{% include "seminar/prihlaska_field.html" with field=form.prijmeni %} {% include "seminar/prihlaska_field.html" with field=form.prijmeni %}
</li>
<li>
{% include "seminar/prihlaska_field.html" with field=form.pohlavi_muz%} {% include "seminar/prihlaska_field.html" with field=form.pohlavi_muz%}
</li>
<li>
{% include "seminar/prihlaska_field.html" with field=form.email %} {% include "seminar/prihlaska_field.html" with field=form.email %}
</li>
<li>
{% include "seminar/prihlaska_field.html" with field=form.telefon %} {% include "seminar/prihlaska_field.html" with field=form.telefon %}
</li>
<li>
{% include "seminar/prihlaska_field.html" with field=form.datum_narozeni %} {% include "seminar/prihlaska_field.html" with field=form.datum_narozeni %}
</li> </table>
<li>
<hr> <hr>
<h4>
Bydliště Bydliště
</li> </h4>
<li> <table class="form">
{% include "seminar/prihlaska_field.html" with field=form.ulice %} {% include "seminar/prihlaska_field.html" with field=form.ulice %}
</li>
<li>
{% include "seminar/prihlaska_field.html" with field=form.mesto %} {% include "seminar/prihlaska_field.html" with field=form.mesto %}
</li>
<li>
{% include "seminar/prihlaska_field.html" with field=form.psc %} {% include "seminar/prihlaska_field.html" with field=form.psc %}
</li>
<li>
{% include "seminar/prihlaska_field.html" with field=form.stat %} {% include "seminar/prihlaska_field.html" with field=form.stat %}
</li> {% include "seminar/prihlaska_field.html" with field=form.stat_text id="id_li_stat_text"%}
<li id="id_li_stat_text"> </table>
{% include "seminar/prihlaska_field.html" with field=form.stat_text %}
</li>
<li>
<hr> <hr>
<h4>
Škola
</h4>
<table class="form">
{% include "seminar/prihlaska_field.html" with field=form.skola %} {% include "seminar/prihlaska_field.html" with field=form.skola %}
</li> <tr><td colspan="2" ><button id="id_skola_text_button" type="button">Škola není v seznamu</button></td></tr>
<li> <tr><td id="id_li_skola_vypln" colspan="2">Vyplň prosím celý název a adresu školy.</td></tr>
<button id="id_skola_text_button" type="button">Škola není v seznamu</button> {% include "seminar/prihlaska_field.html" with field=form.skola_nazev id="id_li_skola_nazev" %}
</li> {% include "seminar/prihlaska_field.html" with field=form.skola_adresa id="id_li_skola_adresa" %}
<li id="id_li_skola_nazev">
Vyplň prosím celý název a adresu školy.<br>
{% include "seminar/prihlaska_field.html" with field=form.skola_nazev %}
</li>
<li id="id_li_skola_adresa">
{% include "seminar/prihlaska_field.html" with field=form.skola_adresa %}
</li>
<li>
{% include "seminar/prihlaska_field.html" with field=form.rok_maturity %} {% include "seminar/prihlaska_field.html" with field=form.rok_maturity %}
</li> </table>
<li>
<hr>
<h4>
Pošta
</h4>
<table class="form">
{% include "seminar/prihlaska_field.html" with field=form.zasilat %} {% include "seminar/prihlaska_field.html" with field=form.zasilat %}
</li> </table>
<li> <hr>
<h4>
GDPR
</h4>
{% include "seminar/gdpr.html" %} {% include "seminar/gdpr.html" %}
<table class="form">
{% include "seminar/prihlaska_field.html" with field=form.gdpr %} {% include "seminar/prihlaska_field.html" with field=form.gdpr %}
</li> </table>
<li>
<hr>
<h4>
Zasílání propagačních materiálů
</h4>
<table class="form">
{% include "seminar/prihlaska_field.html" with field=form.spam %} {% include "seminar/prihlaska_field.html" with field=form.spam %}
</li> </table>
</ul>
<hr>
<input type="submit" value="Odeslat"> <input type="submit" value="Odeslat">
</form> </form>
<script> <script>
@ -109,4 +110,3 @@ $("#id_skola_text_button").on("click",schoolNotInList);
{% endblock %} {% endblock %}

25
seminar/templates/seminar/prihlaska_field.html

@ -1,4 +1,23 @@
<label class="field-label{% if field.field.required %} field-required{% endif %}" for="{{ field.id_for_label }}">{{ field.label }}:</label>
<tr id="{{ id }}" >
<td>
<label class="field-label{% if field.field.required %} field-required{% endif %}" for="{{ field.id_for_label }}">
{{ field.label }}:
</label>
</td>
<td>
{{ field }} {{ field }}
{% if field.help_text %}<span class="field-helptext">{{ field.help_text|safe }}</span>{% endif %} </td>
{% if field.errors %}<span class="field-error">{{ field.errors }}</span>{% endif %} </tr>
{% if field.help_text %}
<tr>
<td colspan="2"><span class="field-helptext">{{ field.help_text|safe }}</span></td>
</tr>
{% endif %}
{% if field.errors %}
<tr>
<td colspan="2"><span class="field-error">{{ field.errors }}</span></td>
</tr>
{% endif %}

241
seminar/testutils.py

@ -10,9 +10,12 @@ import unidecode
import logging 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, TextNode, UlohaVzorakNode, RocnikNode, CisloNode, TemaVCisleNode, Text, Hodnoceni, UlohaZadaniNode, Novinky, TreeNode from seminar.models import Skola, Resitel, Rocnik, Cislo, Problem, Reseni, PrilohaReseni, Nastaveni, Soustredeni, Soustredeni_Ucastnici, Soustredeni_Organizatori, Osoba, Organizator, Prijemce, Tema, Uloha, Konfera, TextNode, UlohaVzorakNode, RocnikNode, CisloNode, TemaVCisleNode, Text, Hodnoceni, UlohaZadaniNode, Novinky, TreeNode
import seminar.models as m
from django.contrib.flatpages.models import FlatPage from django.contrib.flatpages.models import FlatPage
from django.contrib.sites.models import Site from django.contrib.sites.models import Site
from seminar.treelib import all_children, insert_last_child, all_children_of_type, create_node_after
User = django.contrib.auth.get_user_model() User = django.contrib.auth.get_user_model()
zlinska = None # tohle bude speciální škola, které později dodáme kontaktní osobu zlinska = None # tohle bude speciální škola, které později dodáme kontaktní osobu
@ -205,21 +208,16 @@ def gen_zadani_ulohy(rnd, cisla, organizatori, pocet_oboru, poradi_cisla, poradi
max_body = rnd.randint(1, 8) max_body = rnd.randint(1, 8)
) )
text_zadani = Text.objects.create( text = " ".join(
na_web = " ".join(
[rnd.choice(sloveso),
rnd.choice(koho),
rnd.choice(ceho),
rnd.choice(jmeno),
rnd.choice(kde)]
),
do_cisla = " ".join(
[rnd.choice(sloveso), [rnd.choice(sloveso),
rnd.choice(koho), rnd.choice(koho),
rnd.choice(ceho), rnd.choice(ceho),
rnd.choice(jmeno), rnd.choice(jmeno),
rnd.choice(kde)] rnd.choice(kde)]
) )
text_zadani = Text.objects.create(
na_web = text,
do_cisla = text,
) )
zad = TextNode.objects.create(text = text_zadani) zad = TextNode.objects.create(text = text_zadani)
uloha_zadani = UlohaZadaniNode.objects.create(uloha = p, first_child = zad) uloha_zadani = UlohaZadaniNode.objects.create(uloha = p, first_child = zad)
@ -228,7 +226,7 @@ def gen_zadani_ulohy(rnd, cisla, organizatori, pocet_oboru, poradi_cisla, poradi
return p return p
def gen_vzoroveho_reseni_ulohy(rnd, cisla, organizatori, uloha, pocet_opravovatelu, poradi_cisla): def gen_vzoroveho_reseni_ulohy(rnd, organizatori, uloha, pocet_opravovatelu):
reseni = ["to je přece jasné", "triviální", "omlouváme se," reseni = ["to je přece jasné", "triviální", "omlouváme se,"
"otevřený problém", "neřešitelné", "triviálně triviální", "otevřený problém", "neřešitelné", "triviálně triviální",
"použitím věty z prvního semestru na matfyzu", "použitím věty z prvního semestru na matfyzu",
@ -238,18 +236,18 @@ def gen_vzoroveho_reseni_ulohy(rnd, cisla, organizatori, uloha, pocet_opravovate
"tak jste fakt hloupí"] "tak jste fakt hloupí"]
# Generování vzorového řešení. # Generování vzorového řešení.
obsah = rnd.choice(reseni)
text_vzoraku = Text.objects.create( text_vzoraku = Text.objects.create(
na_web = rnd.choice(reseni), na_web = obsah,
do_cisla = rnd.choice(reseni) do_cisla = obsah
) )
vzorak = TextNode.objects.create(text = text_vzoraku) vzorak = TextNode.objects.create(text = text_vzoraku)
uloha_vzorak = UlohaVzorakNode.objects.create(uloha = uloha, first_child = vzorak) uloha_vzorak = UlohaVzorakNode.objects.create(uloha = uloha, first_child = vzorak)
uloha.ulohavzoraknode = uloha_vzorak uloha.ulohavzoraknode = uloha_vzorak
otec_syn(cisla[poradi_cisla-1].cislonode, uloha_vzorak)
uloha.opravovatele.set(rnd.sample(organizatori, pocet_opravovatelu)) uloha.opravovatele.set(rnd.sample(organizatori, pocet_opravovatelu))
uloha.save() uloha.save()
return return uloha_vzorak
def gen_reseni_ulohy(rnd, cisla, uloha, pocet_resitelu, poradi_cisla, resitele_cisla, resitele): def gen_reseni_ulohy(rnd, cisla, uloha, pocet_resitelu, poradi_cisla, resitele_cisla, resitele):
@ -307,7 +305,10 @@ def gen_ulohy_do_cisla(rnd, organizatori, resitele, rocnik_cisla, rocniky, size)
# přivěšení pod dané číslo # přivěšení pod dané číslo
p = gen_zadani_ulohy(rnd, cisla, organizatori, poc_oboru, ci, pi) p = gen_zadani_ulohy(rnd, cisla, organizatori, poc_oboru, ci, pi)
# Generování vzorového řešení # Generování vzorového řešení
gen_vzoroveho_reseni_ulohy(rnd, cisla, organizatori, p, poc_op, ci) uloha_vzorak = gen_vzoroveho_reseni_ulohy(rnd, organizatori,
p, poc_op)
insert_last_child(cisla[ci-1].cislonode, uloha_vzorak)
# Generování řešení a hodnocení k úloze # Generování řešení a hodnocení k úloze
gen_reseni_ulohy(rnd, cisla, p, poc_res, ci, gen_reseni_ulohy(rnd, cisla, p, poc_res, ci,
resitele_cisla, resitele) resitele_cisla, resitele)
@ -420,6 +421,85 @@ def gen_cisla(rnd, rocniky):
rocnik_cisla.append(cisla) rocnik_cisla.append(cisla)
return rocnik_cisla return rocnik_cisla
def add_first_child(node, child):
node.first_child = child
node.save()
return
def get_text():
odstavec = lorem.paragraph()
return Text.objects.create(na_web = odstavec, do_cisla = odstavec)
def gen_dlouhe_tema(rnd, organizatori, rocnik, nazev, obor, kod):
tema = Tema.objects.create(
nazev=nazev,
stav=Problem.STAV_ZADANY,
zamereni="M",
autor=rnd.choice(organizatori),
garant=rnd.choice(organizatori),
kod=str(kod),
tema_typ=rnd.choice(Tema.TEMA_CHOICES)[0],
rocnik=rocnik,
abstrakt = lorem.paragraph()
)
# Generování struktury k tématu
cisla = sorted(rocnik.cisla.all(), key=lambda cislo: cislo.poradi)
for cislo in cisla:
# Přidáme TemaVCisleNode do daného čísla
cislo_node = cislo.cislonode
tema_cislo_node = TemaVCisleNode.objects.create(tema = tema)
insert_last_child(cislo_node, tema_cislo_node)
# Přidávání obsahu do čísla
cast_node = m.CastNode.objects.create(nadpis = "Příspěvek k číslu {}".format(cislo.kod))
add_first_child(tema_cislo_node, cast_node)
text_node = TextNode.objects.create(text = get_text())
add_first_child(cast_node, text_node)
cast_node2 = m.CastNode.objects.create(nadpis = "První podproblém")
add_first_child(text_node, cast_node2)
text_node2 = TextNode.objects.create(text = get_text())
add_first_child(cast_node2, text_node2)
cast_node3 = m.CastNode.objects.create(nadpis = "Druhý podproblém")
add_first_child(text_node2, cast_node3)
text_node3 = TextNode.objects.create(text = get_text())
add_first_child(cast_node3, text_node3)
cast_node4 = m.CastNode.objects.create(nadpis = "Třetí podproblém")
add_first_child(text_node3, cast_node4)
text_node4 = TextNode.objects.create(text = get_text())
add_first_child(cast_node3, text_node4)
cast_node3a = m.CastNode.objects.create(nadpis = "Podproblém paralelní s "
"druhým podproblémem")
cast_node3.succ = cast_node3a
cast_node3.save()
text_node3a = TextNode.objects.create(text = get_text())
add_first_child(cast_node3a, text_node3a)
# Občas přidáme mezičíslo
if rnd.randint(1, 3) == 1:
create_node_after(cislo_node, m.MezicisloNode)
mezicislo_node = cislo_node.succ
cast_node_mezicislo = m.CastNode.objects.create(
nadpis = "Příspěvek k mezičíslu".format(cislo.kod))
add_first_child(mezicislo_node, cast_node_mezicislo)
odstavec = lorem.paragraph()
text_mezicislo = Text.objects.create(na_web = odstavec, do_cisla = odstavec)
text_node_mezicislo = TextNode.objects.create(text = text_mezicislo)
add_first_child(cast_node_mezicislo, text_node_mezicislo)
return tema
def gen_temata(rnd, rocniky, rocnik_cisla, organizatori): def gen_temata(rnd, rocniky, rocnik_cisla, organizatori):
logger.info('Generuji témata...') logger.info('Generuji témata...')
@ -474,11 +554,10 @@ def gen_temata(rnd, rocniky, rocnik_cisla, organizatori):
rocnik_temata.append(letosni_temata) rocnik_temata.append(letosni_temata)
return rocnik_temata return rocnik_temata
def gen_ulohy_tematu(rnd, organizatori, tema, kod, cislo, cislo_se_vzorakem):
""" Generování úlohy k danému tématu. """
def gen_ulohy_k_tematum(rnd, rocniky, rocnik_cisla, rocnik_temata, organizatori): # Proměnné pro náhodné generování názvů a zadání.
logger.info('Generuji úlohy k tématům...')
# ulohy resene v cisle
jaka = ["Šachová", "Černá", "Větrná", "Dlouhá", "Křehká", "Rychlá", jaka = ["Šachová", "Černá", "Větrná", "Dlouhá", "Křehká", "Rychlá",
"Zákeřná", "Fyzikální"] "Zákeřná", "Fyzikální"]
co = ["kostka", "smršť", "díra", "zrada", "toulka", "tyč", co = ["kostka", "smršť", "díra", "zrada", "toulka", "tyč",
@ -488,57 +567,9 @@ def gen_ulohy_k_tematum(rnd, rocniky, rocnik_cisla, rocnik_temata, organizatori)
ceho = ["všech", "správných", "konstatních", "zelených"] ceho = ["všech", "správných", "konstatních", "zelených"]
jmeno = ["řešení", "tahů", "čísel", "kalhot", "koulí", "hadů"] jmeno = ["řešení", "tahů", "čísel", "kalhot", "koulí", "hadů"]
kde = ["na zemi", "ve vesmíru", "ve vzduchu", "na šňůře", "v letadle"] kde = ["na zemi", "ve vesmíru", "ve vzduchu", "na šňůře", "v letadle"]
obor = ["M", "F", "I", "O", "B"] obory = ["M", "F", "I", "O", "B"]
reseni = ["to je přece jasné", "triviální", "omlouváme se,"
"otevřený problém", "neřešitelné", "triviálně triviální",
"použitím věty z prvního semestru na matfyzu",
"jednoduše pomocí látky z druhého semestru na matfyzu",
"netriviální aplikace diferenciálních rovnic", "zadání je vnitřně"
"sporné", "nepopsatelně jednoduché", "pokud jste na to nepřišli,"
"tak jste fakt hloupí"]
# Ke každému ročníku si vezmeme příslušná čísla a témata
for rocnik, cisla, temata in zip(rocniky, rocnik_cisla, rocnik_temata):
# Do každého čísla nagenerujeme ke každému témátku pár úložek
for cislo in cisla:
print("Generuji úložky do {}-tého čísla".format(cislo.poradi))
# Vzorák bude o dvě čísla dál
cislo_se_vzorakem = Cislo.objects.filter(
rocnik=rocnik,
poradi=str(int(cislo.poradi) + 2),
)
# Pokud není číslo pro vzorák, tak se dá do posledního čísla
# (i kdyby tam mělo být zadání i řešení...)
# Tohle sice umožňuje vygenerovat vzorák do čísla dávno po konci témátka,
# ale to nám pro jednoduchost nevadí.
if len(cislo_se_vzorakem) == 0:
cislo_se_vzorakem = cisla[-1]
else:
cislo_se_vzorakem = cislo_se_vzorakem.first()
# FIXME: Tenhle generátor dát asi někam jinam
def potomci(node):
if not isinstance(node, TreeNode):
raise ValueError("Typ {} nemá potomky", type(node))
current_child = node.first_child
while current_child is not None:
yield current_child
current_child = current_child.succ
for mozna_tema_node in potomci(cislo.cislonode):
if not isinstance(mozna_tema_node, TemaVCisleNode):
continue
tema_node = mozna_tema_node
tema = tema_node.tema
# Pokud už témátko skončilo, žádné úložky negenerujeme
# FIXME: Bylo by hezčí, kdyby se čísla předávala jako Cislo a ne
# jako int v té trojici (start, konec, tema)
if not temata[int(tema.kod)-1][1] >= int(cislo_se_vzorakem.poradi):
continue
# Generujeme 1 až 4 úložky k tomuto témátku do tohoto čísla uloha = Uloha.objects.create(
for kod in range(1, rnd.randint(1, 4)):
u = Uloha.objects.create(
nazev=": ".join([tema.nazev, nazev=": ".join([tema.nazev,
"úloha {}.".format(kod)]), "úloha {}.".format(kod)]),
nadproblem=tema, nadproblem=tema,
@ -553,9 +584,6 @@ def gen_ulohy_k_tematum(rnd, rocniky, rocnik_cisla, rocnik_temata, organizatori)
max_body = rnd.randint(1, 8) max_body = rnd.randint(1, 8)
) )
poc_opravovatelu = rnd.randint(1, 4)
u.opravovatele.set(rnd.sample(organizatori, poc_opravovatelu))
# Samotný obsah následně vzniklého Textu zadání # Samotný obsah následně vzniklého Textu zadání
obsah = " ".join( obsah = " ".join(
[rnd.choice(sloveso), [rnd.choice(sloveso),
@ -569,32 +597,63 @@ def gen_ulohy_k_tematum(rnd, rocniky, rocnik_cisla, rocnik_temata, organizatori)
do_cisla = obsah, do_cisla = obsah,
) )
zad = TextNode.objects.create(text = text_zadani) zad = TextNode.objects.create(text = text_zadani)
uloha_zadani = UlohaZadaniNode.objects.create(uloha=u, first_child = zad) uloha_zadani = UlohaZadaniNode.objects.create(uloha=uloha, first_child = zad)
u.ulohazadaninode = uloha_zadani uloha.ulohazadaninode = uloha_zadani
# FIXME: Tohle dává zadání vždy jako prvního potomka témátka, spec. se naskládají v opačném pořadí a nemůže mezi nimi vzniknout žádný (orgo-)text return uloha, uloha_zadani
otec_syn(tema_node, uloha_zadani)
# Text vzoráku stejně
obsah = rnd.choice(reseni) def gen_ulohy_k_tematum(rnd, rocniky, rocnik_cisla, rocnik_temata, organizatori):
text_vzoraku = Text.objects.create( logger.info('Generuji úlohy k tématům...')
na_web = obsah,
do_cisla = obsah, # Ke každému ročníku si vezmeme příslušná čísla a témata
for rocnik, cisla, temata in zip(rocniky, rocnik_cisla, rocnik_temata):
# Do každého čísla nagenerujeme ke každému témátku pár úložek
for cislo in cisla:
print("Generuji úložky do {}-tého čísla".format(cislo.poradi))
# Vzorák bude o dvě čísla dál
cislo_se_vzorakem = Cislo.objects.filter(
rocnik=rocnik,
poradi=str(int(cislo.poradi) + 2),
) )
vzorak = TextNode.objects.create(text = text_vzoraku) # Pokud není číslo pro vzorák, tak se dá do posledního čísla
uloha_vzorak = UlohaVzorakNode.objects.create(uloha=u, first_child = vzorak) # (i kdyby tam mělo být zadání i řešení...)
u.UlohaVzorakNode = uloha_vzorak # Tohle sice umožňuje vygenerovat vzorák do čísla dávno po konci témátka,
# ale to nám pro jednoduchost nevadí.
if len(cislo_se_vzorakem) == 0:
cislo_se_vzorakem = cisla[-1]
else:
cislo_se_vzorakem = cislo_se_vzorakem.first()
for tema_node in all_children_of_type(cislo.cislonode, TemaVCisleNode):
tema = tema_node.tema
# Pokud už témátko skončilo, žádné úložky negenerujeme
# FIXME: Bylo by hezčí, kdyby se čísla předávala jako Cislo a ne
# jako int v té trojici (start, konec, tema)
if not temata[int(tema.kod)-1][1] >= int(cislo_se_vzorakem.poradi):
continue
# Generujeme 1 až 4 úložky k tomuto témátku do tohoto čísla.
for kod in range(1, rnd.randint(1, 4)):
u, uz = gen_ulohy_tematu(rnd, organizatori, tema, kod,
cislo, cislo_se_vzorakem)
insert_last_child(tema_node, uz)
poc_op = rnd.randint(1, 4)
uvz = gen_vzoroveho_reseni_ulohy(rnd, organizatori,
u, poc_op)
# Najdeme správný TemaVCisleNode pro vložení vzoráku # Najdeme správný TemaVCisleNode pro vložení vzoráku
res_tema_node = None; res_tema_node = None;
for node in potomci(cislo_se_vzorakem.cislonode): for node in all_children(cislo_se_vzorakem.cislonode):
if isinstance(node, TemaVCisleNode) and node.tema == tema: if isinstance(node, TemaVCisleNode):
if node.tema == tema:
res_tema_node = node res_tema_node = node
if res_tema_node is None: if res_tema_node is None:
raise LookupError("Nenalezen Node pro vložení vzoráku") raise LookupError("Nenalezen Node pro vložení vzoráku")
# FIXME: Stejný problém jako výše: vzoráky se dají na začátek v opačném pořadí. insert_last_child(res_tema_node, uvz)
otec_syn(res_tema_node, uloha_vzorak)
u.save() u.save()
return return
@ -687,6 +746,10 @@ def create_test_data(size = 6, rnd = None):
# rocnik_temata je pole polí trojic (první číslo :int, poslední číslo :int, téma:Tema), přičemž každé vnitřní pole odpovídá ročníku a FIXME: je to takhle fuj a když to někdo vidí poprvé, tak je z toho smutný, protože vůbec neví, co se děje a co má čekat. # rocnik_temata je pole polí trojic (první číslo :int, poslední číslo :int, téma:Tema), přičemž každé vnitřní pole odpovídá ročníku a FIXME: je to takhle fuj a když to někdo vidí poprvé, tak je z toho smutný, protože vůbec neví, co se děje a co má čekat.
rocnik_temata = gen_temata(rnd, rocniky, rocnik_cisla, organizatori) rocnik_temata = gen_temata(rnd, rocniky, rocnik_cisla, organizatori)
rocnik = Rocnik.objects.filter(rocnik = 23).first()
dlouhe_tema = gen_dlouhe_tema(rnd, organizatori, rocnik, "Strašně dlouhé téma",
"MFI", 8)
# generování úloh k tématům ve všech číslech # generování úloh k tématům ve všech číslech
gen_ulohy_k_tematum(rnd, rocniky, rocnik_cisla, rocnik_temata, organizatori) gen_ulohy_k_tematum(rnd, rocniky, rocnik_cisla, rocnik_temata, organizatori)

41
seminar/treelib.py

@ -12,6 +12,13 @@ def print_tree(node,indent=0):
if node.succ: if node.succ:
print_tree(node.succ, indent=indent) print_tree(node.succ, indent=indent)
def is_orphan(node):
""" Zjišťuje, jestli už je daný Node někde pověšený či nikoli. """
if safe_father_of_first(node) is None and safe_pred(node) is None:
return True
else:
return False
# Django je trošku hloupé, takže node.prev nevrací None, ale hází django.core.exceptions.ObjectDoesNotExist # Django je trošku hloupé, takže node.prev nevrací None, ale hází django.core.exceptions.ObjectDoesNotExist
def safe_pred(node): def safe_pred(node):
try: try:
@ -43,6 +50,13 @@ def get_parent(node):
# ... a z prvního potomka umíme najít rodiče # ... a z prvního potomka umíme najít rodiče
return safe_father_of_first(node) return safe_father_of_first(node)
def get_last_child(node):
first = node.first_child
if first is None:
return None
else:
return last_brother(first)
# Obecný next: další Node v "the-right-order" pořadí (já, pak potomci, pak sousedé) # Obecný next: další Node v "the-right-order" pořadí (já, pak potomci, pak sousedé)
def general_next(node): def general_next(node):
# Máme potomka? # Máme potomka?
@ -100,12 +114,19 @@ def all_proper_brothers(node):
continue continue
yield br yield br
# Generátor potomků
def all_children(node): def all_children(node):
""" Generátor všech potomků zadaného Node. """
brothers = all_brothers(node.first_child) brothers = all_brothers(node.first_child)
for br in brothers: for br in brothers:
yield br yield br
def all_children_of_type(node, type):
""" Generuje všechny potomky daného Node a daného typu. """
brothers = all_brothers(node.first_child)
for br in brothers:
if isinstance(br, type):
yield br
# Generátor následníků v "the-right-order" # Generátor následníků v "the-right-order"
# Bez tohoto vrcholu # Bez tohoto vrcholu
def all_following(node): def all_following(node):
@ -173,6 +194,24 @@ def create_child(parent, type, **kwargs):
new_node.succ = orig_child new_node.succ = orig_child
new_node.save() new_node.save()
def insert_last_child(parent, node):
""" Zadaný Node přidá jako posledního potomka otce. """
last = get_last_child(parent)
if not is_orphan(node):
print(safe_pred(node))
print(safe_father_of_first(node))
if len(safe_father_of_first(node).get_real_instances()) == 0:
print("Related Manager je prázdný.")
print(type(safe_father_of_first(node).queryset_class))
raise TreeLibError("Snažíš se přidat do stromu Node, který už je zavěšený.")
if last is None:
parent.first_child = node
parent.save()
else:
last.succ = node
last.save()
def create_node_before(successor, type, **kwargs): def create_node_before(successor, type, **kwargs):
if safe_pred(successor) is not None: if safe_pred(successor) is not None:
# Easy: přidáme za předchůdce # Easy: přidáme za předchůdce

5
seminar/urls.py

@ -40,11 +40,6 @@ urlpatterns = [
views.SoustredeniListView.as_view(), views.SoustredeniListView.as_view(),
name='seminar_seznam_soustredeni' name='seminar_seznam_soustredeni'
), ),
path(
'soustredeni/probehlo/<int:soustredeni>/',
views.SoustredeniView.as_view(),
name='seminar_soustredeni'
),
path( path(
'soustredeni/<int:soustredeni>/seznam_ucastniku', 'soustredeni/<int:soustredeni>/seznam_ucastniku',
staff_member_required(views.SoustredeniUcastniciView.as_view()), staff_member_required(views.SoustredeniUcastniciView.as_view()),

14
seminar/views/views_all.py

@ -28,6 +28,7 @@ import seminar.forms as f
from datetime import timedelta, date, datetime from datetime import timedelta, date, datetime
from django.utils import timezone from django.utils import timezone
from itertools import groupby from itertools import groupby
from collections import OrderedDict
import tempfile import tempfile
import subprocess import subprocess
import shutil import shutil
@ -814,7 +815,14 @@ class CisloView(generic.DetailView):
class ArchivTemataView(generic.ListView): class ArchivTemataView(generic.ListView):
model = Problem model = Problem
template_name = 'seminar/archiv/temata.html' template_name = 'seminar/archiv/temata.html'
queryset = Tema.objects.filter(stav=Problem.STAV_ZADANY).select_related('cislo_zadani__rocnik').order_by('-cislo_zadani__rocnik__rocnik', 'kod') queryset = Tema.objects.filter(stav=Problem.STAV_ZADANY).select_related('rocnik').order_by('rocnik', 'kod')
def get_context_data(self, *args, **kwargs):
ctx = super().get_context_data(*args, **kwargs)
ctx['rocniky'] = OrderedDict()
for rocnik, temata in groupby(ctx['object_list'], lambda tema: tema.rocnik):
ctx['rocniky'][rocnik] = list(temata)
return ctx
### Generovani vysledkovky ### Generovani vysledkovky
@ -950,10 +958,6 @@ class SoustredeniListView(generic.ListView):
model = Soustredeni model = Soustredeni
template_name = 'seminar/soustredeni/seznam_soustredeni.html' template_name = 'seminar/soustredeni/seznam_soustredeni.html'
class SoustredeniView(generic.DetailView):
model = Soustredeni
template_name = 'seminar/archiv/soustredeni.html'
def soustredeniObalkyView(request,soustredeni): def soustredeniObalkyView(request,soustredeni):
soustredeni = get_object_or_404(Soustredeni,id = soustredeni) soustredeni = get_object_or_404(Soustredeni,id = soustredeni)
return obalkyView(request,soustredeni.ucastnici.all()) return obalkyView(request,soustredeni.ucastnici.all())

Loading…
Cancel
Save