Merge branch 'data_migrations' into treenode_editor
This commit is contained in:
commit
9ba5c65326
18 changed files with 631 additions and 494 deletions
BIN
Schema_new.dia
BIN
Schema_new.dia
Binary file not shown.
|
@ -14,8 +14,31 @@ div.container {
|
||||||
margin: auto;
|
margin: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.org-logged-in div.container {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
div.login-bar {
|
div.login-bar {
|
||||||
background: #6a0043;
|
background: #6a0043;
|
||||||
|
color: #f9d59e;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
position: fixed;
|
||||||
|
margin-top: -20px;
|
||||||
|
min-height: 20px;
|
||||||
|
z-index: 20;
|
||||||
|
|
||||||
|
padding-left: 5px;
|
||||||
|
padding-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.login-bar div {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.login-ref-admin {
|
||||||
|
display: inline;
|
||||||
|
color: #fffbf6;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* odkazy a nadpisy */
|
/* odkazy a nadpisy */
|
||||||
|
@ -28,7 +51,10 @@ a:focus, a:hover, a:active {
|
||||||
color: #e84e10;
|
color: #e84e10;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
a:focus a:hover
|
|
||||||
|
img {
|
||||||
|
filter: drop-shadow(0px 3px 3px rgba(0, 0, 0, 0.4));
|
||||||
|
}
|
||||||
|
|
||||||
h1 { /*todo: odlišit 1 a 2 */
|
h1 { /*todo: odlišit 1 a 2 */
|
||||||
font-size: 200%;
|
font-size: 200%;
|
||||||
|
@ -74,16 +100,16 @@ h6 {
|
||||||
|
|
||||||
|
|
||||||
.org-logged-in .mam-text-plugin {
|
.org-logged-in .mam-text-plugin {
|
||||||
border: dashed 1px #f77;
|
border: dashed 1px #6a0043;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
margin: -5px;
|
margin: -5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mam-org-only {
|
.mam-org-only {
|
||||||
background: #fff0d7;
|
background: #eee4ec;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
margin: 10px -10px;
|
margin: 10px -10px;
|
||||||
border: orange 2px dashed;
|
border: #6a0043 2px dashed;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mam-org-only .mam-org-only {
|
.mam-org-only .mam-org-only {
|
||||||
|
@ -123,6 +149,8 @@ h1 {
|
||||||
margin-top: 0px;
|
margin-top: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Comments */
|
/* Comments */
|
||||||
|
|
||||||
#id_comment {
|
#id_comment {
|
||||||
|
@ -191,7 +219,7 @@ vikendovka
|
||||||
#header.NOCsoustredeni { background-image: url("../images/header/vylet.jpg");}
|
#header.NOCsoustredeni { background-image: url("../images/header/vylet.jpg");}
|
||||||
#header.NOCzadani { background-image: url("../images/header/stiny.jpg");}
|
#header.NOCzadani { background-image: url("../images/header/stiny.jpg");}
|
||||||
#header.NOCclanky { background-image: url("../images/header/ohen.jpg");}
|
#header.NOCclanky { background-image: url("../images/header/ohen.jpg");}
|
||||||
#header.NOCarchiv { background-image: url("../images/header/vikendovka.jpg");}
|
#header.NOCarchiv { background-image: url("../images/header/stiny.jpg");}
|
||||||
|
|
||||||
|
|
||||||
#header img.logo {
|
#header img.logo {
|
||||||
|
@ -407,6 +435,10 @@ ul.submenu {
|
||||||
/* malý tablet, mobil */
|
/* malý tablet, mobil */
|
||||||
@media (max-width: 650px) {
|
@media (max-width: 650px) {
|
||||||
|
|
||||||
|
#hide-if-small.login-bar-flatpage {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
#title {
|
#title {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
@ -558,13 +590,21 @@ div.seznam_orgu {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.org_pole {
|
div.org_pole, div.rocnik_pole {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 30%;
|
width: 30%;
|
||||||
min-width: 300px;
|
min-width: 300px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div.cislo_pole {
|
||||||
|
display: inline-block;
|
||||||
|
width: 15%;
|
||||||
|
min-width: 165px;
|
||||||
|
text-align: center;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
div.seznam_orgu h3 {
|
div.seznam_orgu h3 {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
|
@ -576,16 +616,29 @@ div.org_email {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*otáčecí karty organizátorů*/
|
/*otáčecí karty (orgové, archiv) */
|
||||||
|
|
||||||
.flip-card {
|
.flip-card {
|
||||||
width: 200px;
|
|
||||||
height: 250px;
|
|
||||||
perspective: 1000px; /* Remove this if you don't want the 3D effect */
|
perspective: 1000px; /* Remove this if you don't want the 3D effect */
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#organizatori.flip-card {
|
||||||
|
width: 200px;
|
||||||
|
height: 250px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#archiv.flip-card {
|
||||||
|
width: 210px;
|
||||||
|
height: 298px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#archiv-rocnik.flip-card {
|
||||||
|
width: 144px;
|
||||||
|
height: 205px;
|
||||||
|
}
|
||||||
|
|
||||||
/* This container is needed to position the front and back side */
|
/* This container is needed to position the front and back side */
|
||||||
.flip-card-inner {
|
.flip-card-inner {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -614,35 +667,59 @@ div.org_email {
|
||||||
background-color: #bbb;
|
background-color: #bbb;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.foto_org img {
|
div.flip-card-foto img {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Style the back side */
|
/* Style the back side */
|
||||||
.flip-card-back {
|
.flip-card-back {
|
||||||
/*background-color: #e84e10;
|
|
||||||
color: #fffbf6;
|
|
||||||
background-color: #fdedd5;*/
|
|
||||||
background-color: #f9d59e;
|
background-color: #f9d59e;
|
||||||
color: black;/**/
|
color: black;
|
||||||
transform: rotateY(180deg);
|
transform: rotateY(180deg);
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
padding-top: 20px;
|
padding-top: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* graf na úvodní stránce */
|
/* karty archiv */
|
||||||
|
|
||||||
a span.popup {
|
div.popis_rocniku {
|
||||||
position: absolute;
|
text-align: left;
|
||||||
visibility: hidden;
|
font-weight: bold;
|
||||||
|
margin: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
a span.popup:hover {
|
|
||||||
visibility:visible;
|
div.popis_rocniku a, div.cislo_odkazy a {
|
||||||
top:37px; left:37px;
|
font-weight: bold;
|
||||||
|
color: black;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div.popis_rocniku a:hover,
|
||||||
|
div.cislo_odkazy a:hover {
|
||||||
|
color: #6f2509;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.cislo_odkazy ul {
|
||||||
|
margin: 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 */
|
||||||
|
|
||||||
/* velká fotka */
|
/* velká fotka */
|
||||||
|
|
|
@ -37,22 +37,22 @@
|
||||||
</head>
|
</head>
|
||||||
<body class='{% if user.is_staff %}org-logged-in{% endif %}'>
|
<body class='{% if user.is_staff %}org-logged-in{% endif %}'>
|
||||||
|
|
||||||
|
{% if user.is_staff %}
|
||||||
|
<div class="login-bar" >
|
||||||
|
{% if view.object %}
|
||||||
|
Objekt {{ view.object }}: {{ view.object }}
|
||||||
|
{% if view.object.admin_url %}<a class="login-ref-admin" href='{{ view.object.admin_url }}'>[admin]</a>{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% if flatpage %}
|
||||||
|
<div class="login-bar-flatpage" id="hide-if-small"> Stránka <tt>{{ flatpage.url }}</tt> ({{ flatpage.title }})</div>
|
||||||
|
<a class="login-ref-admin" href='{% url 'admin:flatpages_flatpage_change' flatpage.id %}'>[admin]</a>
|
||||||
|
{% endif %}
|
||||||
|
<a class="login-ref-admin" href='/admin'>[admin mainpage]</a>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
|
||||||
{% if user.is_staff %}
|
|
||||||
<div class="login-bar" >
|
|
||||||
{% if view.object %}
|
|
||||||
Objekt {{ view.object }}: {{ view.object }}
|
|
||||||
{% if view.object.admin_url %}<a href='{{ view.object.admin_url }}'>[admin]</a>{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
{% if flatpage %}
|
|
||||||
Stránka <tt>{{ flatpage.url }}</tt> ({{ flatpage.title }})
|
|
||||||
<a href='{% url 'admin:flatpages_flatpage_change' flatpage.id %}'>[admin]</a>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
|
|
||||||
<div class='row'>
|
<div class='row'>
|
||||||
<div class='col-md-12'>
|
<div class='col-md-12'>
|
||||||
<a href='/'>
|
<a href='/'>
|
||||||
|
|
|
@ -35,6 +35,7 @@ class ProblemAdmin(PolymorphicParentModelAdmin):
|
||||||
m.Tema,
|
m.Tema,
|
||||||
m.Clanek,
|
m.Clanek,
|
||||||
m.Uloha,
|
m.Uloha,
|
||||||
|
m.Konfera,
|
||||||
]
|
]
|
||||||
|
|
||||||
@admin.register(m.Tema)
|
@admin.register(m.Tema)
|
||||||
|
@ -52,6 +53,11 @@ class UlohaAdmin(PolymorphicChildModelAdmin):
|
||||||
base_model = m.Uloha
|
base_model = m.Uloha
|
||||||
show_in_index = True
|
show_in_index = True
|
||||||
|
|
||||||
|
@admin.register(m.Konfera)
|
||||||
|
class KonferaAdmin(PolymorphicChildModelAdmin):
|
||||||
|
base_model = m.Konfera
|
||||||
|
show_in_index = True
|
||||||
|
|
||||||
class TextAdminInline(admin.TabularInline):
|
class TextAdminInline(admin.TabularInline):
|
||||||
model = m.Text
|
model = m.Text
|
||||||
exclude = ['text_zkraceny_set','text_zkraceny']
|
exclude = ['text_zkraceny_set','text_zkraceny']
|
||||||
|
@ -82,7 +88,6 @@ class ReseniAdmin(ReverseModelAdmin):
|
||||||
|
|
||||||
admin.site.register(m.Hodnoceni)
|
admin.site.register(m.Hodnoceni)
|
||||||
admin.site.register(m.Pohadka)
|
admin.site.register(m.Pohadka)
|
||||||
admin.site.register(m.Konfera)
|
|
||||||
admin.site.register(m.Obrazek)
|
admin.site.register(m.Obrazek)
|
||||||
|
|
||||||
|
|
||||||
|
@ -97,8 +102,6 @@ class TreeNodeAdmin(PolymorphicParentModelAdmin):
|
||||||
m.CisloNode,
|
m.CisloNode,
|
||||||
m.MezicisloNode,
|
m.MezicisloNode,
|
||||||
m.TemaVCisleNode,
|
m.TemaVCisleNode,
|
||||||
m.KonferaNode,
|
|
||||||
m.ClanekNode,
|
|
||||||
m.UlohaZadaniNode,
|
m.UlohaZadaniNode,
|
||||||
m.PohadkaNode,
|
m.PohadkaNode,
|
||||||
m.UlohaVzorakNode,
|
m.UlohaVzorakNode,
|
||||||
|
@ -136,16 +139,6 @@ class TemaVCisleNodeAdmin(PolymorphicChildModelAdmin):
|
||||||
base_model = m.TemaVCisleNode
|
base_model = m.TemaVCisleNode
|
||||||
show_in_index = True
|
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)
|
@admin.register(m.UlohaZadaniNode)
|
||||||
class UlohaZadaniNodeAdmin(PolymorphicChildModelAdmin):
|
class UlohaZadaniNodeAdmin(PolymorphicChildModelAdmin):
|
||||||
base_model = m.UlohaZadaniNode
|
base_model = m.UlohaZadaniNode
|
||||||
|
|
121
seminar/migrations/0080_zruseni_claneknode_a_konferanode.py
Normal file
121
seminar/migrations/0080_zruseni_claneknode_a_konferanode.py
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
# Generated by Django 2.2.12 on 2020-04-01 20:54
|
||||||
|
# Fixed by Pavel, 2020-01-04 20:56 UTC
|
||||||
|
# This is quite possibly a bug in Django.
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
def vyrob_dummy_problemy(apps, schema_editor):
|
||||||
|
Problem = apps.get_model('seminar', 'Problem')
|
||||||
|
Konfera = apps.get_model('seminar', 'Konfera')
|
||||||
|
for k in Konfera.objects.all():
|
||||||
|
pr = Problem.objects.create(nazev=k.nazev,
|
||||||
|
garant=k.organizator)
|
||||||
|
pr.save()
|
||||||
|
k.problem_ptr = pr
|
||||||
|
k.save()
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('contenttypes', '0002_remove_content_type_name'),
|
||||||
|
('seminar', '0079_clanek_resitelsky'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.DeleteModel(
|
||||||
|
name='Konfery_Ucastnici',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='konfera',
|
||||||
|
name='ucastnici',
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='OrgTextNode',
|
||||||
|
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')),
|
||||||
|
('org_verejny', models.BooleanField(default=True, help_text='Pokud ano, bude org pod článkem podepsaný', verbose_name='Org je veřejný?')),
|
||||||
|
('organizator', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='seminar.Organizator', verbose_name='Organizátor')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'Organizátorský článek (Node)',
|
||||||
|
'verbose_name_plural': 'Organizátorské články (Node)',
|
||||||
|
'db_table': 'seminar_nodes_orgtextnode',
|
||||||
|
},
|
||||||
|
bases=('seminar.treenode',),
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='konfera',
|
||||||
|
name='id',
|
||||||
|
),
|
||||||
|
migrations.RenameModel(
|
||||||
|
old_name='OtisteneReseniNode',
|
||||||
|
new_name='ReseniNode',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='clanek',
|
||||||
|
name='cislo',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='clanek',
|
||||||
|
name='resitelsky',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='reseni',
|
||||||
|
name='text_zkraceny',
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='konfera',
|
||||||
|
name='problem_ptr',
|
||||||
|
field=models.OneToOneField(auto_created=True, null=False, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.Problem'),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='konfera',
|
||||||
|
name='nazev',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='konfera',
|
||||||
|
name='organizator',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='konfera',
|
||||||
|
name='poznamka',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='konfera',
|
||||||
|
name='reseni',
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='reseni',
|
||||||
|
name='text_cely',
|
||||||
|
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='reseni_cely_set', to='seminar.ReseniNode', verbose_name='Plná verze textu řešení'),
|
||||||
|
),
|
||||||
|
migrations.DeleteModel(
|
||||||
|
name='ClanekNode',
|
||||||
|
),
|
||||||
|
migrations.DeleteModel(
|
||||||
|
name='KonferaNode',
|
||||||
|
),
|
||||||
|
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='ucastnici',
|
||||||
|
field=models.ManyToManyField(help_text='Seznam účastníků konfery', through='seminar.Konfery_Ucastnici', to='seminar.Resitel', verbose_name='účastníci konfery'),
|
||||||
|
),
|
||||||
|
]
|
24
seminar/migrations/0081_auto_20200408_2221.py
Normal file
24
seminar/migrations/0081_auto_20200408_2221.py
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
# Generated by Django 2.2.9 on 2020-04-08 20:21
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import seminar.models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('seminar', '0080_zruseni_claneknode_a_konferanode'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='cislo',
|
||||||
|
name='titulka_nahled',
|
||||||
|
field=models.ImageField(blank=True, help_text='Obrázek titulní strany, generuje se automaticky', null=True, upload_to='', verbose_name='Obrázek titulní strany'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
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'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -728,6 +728,9 @@ class Problem(SeminarModelBase,PolymorphicModel):
|
||||||
return '<Není zadaný>'
|
return '<Není zadaný>'
|
||||||
|
|
||||||
def verejne(self):
|
def verejne(self):
|
||||||
|
# FIXME: Tohle se liší podle typu problému, má se udělat polymorfně.
|
||||||
|
# Zatím je tu jen dummy fail-safe default: nic není veřejné.
|
||||||
|
return False
|
||||||
return (self.cislo_zadani and self.cislo_zadani.verejne())
|
return (self.cislo_zadani and self.cislo_zadani.verejne())
|
||||||
verejne.boolean = True
|
verejne.boolean = True
|
||||||
|
|
||||||
|
@ -735,10 +738,7 @@ class Problem(SeminarModelBase,PolymorphicModel):
|
||||||
return reverse('seminar_problem', kwargs={'pk': self.id})
|
return reverse('seminar_problem', kwargs={'pk': self.id})
|
||||||
|
|
||||||
def admin_url(self):
|
def admin_url(self):
|
||||||
if self.stav == Problem.STAV_ZADANY:
|
return reverse('admin:seminar_problem_change', args=(self.id, ))
|
||||||
return reverse('admin:seminar_problemzadany_change', args=(self.id, ))
|
|
||||||
else:
|
|
||||||
return reverse('admin:seminar_problemnavrh_change', args=(self.id, ))
|
|
||||||
|
|
||||||
# FIXME - k úloze
|
# FIXME - k úloze
|
||||||
def body_v_zavorce(self):
|
def body_v_zavorce(self):
|
||||||
|
@ -792,14 +792,6 @@ class Clanek(Problem):
|
||||||
verbose_name = 'Článek'
|
verbose_name = 'Článek'
|
||||||
verbose_name_plural = 'Články'
|
verbose_name_plural = 'Články'
|
||||||
|
|
||||||
cislo = models.ForeignKey(Cislo, verbose_name='číslo', blank=True, null=True,
|
|
||||||
on_delete=models.PROTECT)
|
|
||||||
|
|
||||||
resitelsky = models.BooleanField('Jde o řešitelský článek?', default=True)
|
|
||||||
|
|
||||||
# má OneToOneField s:
|
|
||||||
# ClanekNode
|
|
||||||
|
|
||||||
def kod_v_rocniku(self):
|
def kod_v_rocniku(self):
|
||||||
if self.stav == 'zadany':
|
if self.stav == 'zadany':
|
||||||
# Nemělo by být potřeba
|
# Nemělo by být potřeba
|
||||||
|
@ -808,15 +800,6 @@ class Clanek(Problem):
|
||||||
return "c{}".format(self.kod)
|
return "c{}".format(self.kod)
|
||||||
return '<Není zadaný>'
|
return '<Není zadaný>'
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
|
||||||
super().save(*args, **kwargs)
|
|
||||||
# *Node.save() aktualizuje název *Nodu.
|
|
||||||
try:
|
|
||||||
self.claneknode.save()
|
|
||||||
except ObjectDoesNotExist:
|
|
||||||
# Neexistující *Node nemá smysl aktualizovat.
|
|
||||||
pass
|
|
||||||
|
|
||||||
class Text(SeminarModelBase):
|
class Text(SeminarModelBase):
|
||||||
class Meta:
|
class Meta:
|
||||||
db_table = 'seminar_texty'
|
db_table = 'seminar_texty'
|
||||||
|
@ -926,13 +909,10 @@ class Reseni(SeminarModelBase):
|
||||||
forma = models.CharField('forma řešení', max_length=16, choices=FORMA_CHOICES, blank=False,
|
forma = models.CharField('forma řešení', max_length=16, choices=FORMA_CHOICES, blank=False,
|
||||||
default=FORMA_EMAIL)
|
default=FORMA_EMAIL)
|
||||||
|
|
||||||
text_cely = models.OneToOneField(Text, verbose_name='Plná verze textu řešení',
|
text_cely = models.OneToOneField('ReseniNode', verbose_name='Plná verze textu řešení',
|
||||||
blank=True, null=True, related_name="reseni_cely_set",
|
blank=True, null=True, related_name="reseni_cely_set",
|
||||||
on_delete=models.SET_NULL)
|
on_delete=models.PROTECT)
|
||||||
|
|
||||||
text_zkraceny = models.ManyToManyField(Text, verbose_name='zkrácené verze řešení',
|
|
||||||
help_text='Seznam úryvků z řešení',related_name="reseni_zkraceny_set")
|
|
||||||
|
|
||||||
poznamka = models.TextField('neveřejná poznámka', blank=True,
|
poznamka = models.TextField('neveřejná poznámka', blank=True,
|
||||||
help_text='Neveřejná poznámka k řešení (plain text)')
|
help_text='Neveřejná poznámka k řešení (plain text)')
|
||||||
|
|
||||||
|
@ -1141,25 +1121,18 @@ class Soustredeni_Organizatori(SeminarModelBase):
|
||||||
|
|
||||||
|
|
||||||
@reversion.register(ignore_duplicates=True)
|
@reversion.register(ignore_duplicates=True)
|
||||||
class Konfera(models.Model):
|
class Konfera(Problem):
|
||||||
class Meta:
|
class Meta:
|
||||||
db_table = 'seminar_konfera'
|
db_table = 'seminar_konfera'
|
||||||
verbose_name = 'Konfera'
|
verbose_name = 'Konfera'
|
||||||
verbose_name_plural = 'Konfery'
|
verbose_name_plural = 'Konfery'
|
||||||
# Interní ID
|
|
||||||
id = models.AutoField(primary_key = True)
|
|
||||||
|
|
||||||
nazev = models.CharField('název konfery', max_length=100, help_text = 'Název konfery')
|
|
||||||
|
|
||||||
anotace = models.TextField('anotace', blank=True,
|
anotace = models.TextField('anotace', blank=True,
|
||||||
help_text='Popis, o čem bude konfera.')
|
help_text='Popis, o čem bude konfera.')
|
||||||
|
|
||||||
abstrakt = models.TextField('abstrakt', blank=True,
|
abstrakt = models.TextField('abstrakt', blank=True,
|
||||||
help_text='Abstrakt konfery tak, jak byl uveden ve sborníku')
|
help_text='Abstrakt konfery tak, jak byl uveden ve sborníku')
|
||||||
|
|
||||||
organizator = models.ForeignKey(Organizator, verbose_name='organizátor', related_name='konfery',
|
|
||||||
on_delete = models.SET_NULL, null=True)
|
|
||||||
|
|
||||||
# FIXME: Umíme omezit jen na účastníky daného soustřeďka?
|
# FIXME: Umíme omezit jen na účastníky daného soustřeďka?
|
||||||
ucastnici = models.ManyToManyField(Resitel, verbose_name='účastníci konfery',
|
ucastnici = models.ManyToManyField(Resitel, verbose_name='účastníci konfery',
|
||||||
help_text='Seznam účastníků konfery', through='Konfery_Ucastnici')
|
help_text='Seznam účastníků konfery', through='Konfery_Ucastnici')
|
||||||
|
@ -1167,13 +1140,6 @@ class Konfera(models.Model):
|
||||||
soustredeni = models.ForeignKey(Soustredeni, verbose_name='soustředění',
|
soustredeni = models.ForeignKey(Soustredeni, verbose_name='soustředění',
|
||||||
related_name='konfery', on_delete = models.SET_NULL, null=True)
|
related_name='konfery', on_delete = models.SET_NULL, null=True)
|
||||||
|
|
||||||
poznamka = models.TextField('neveřejná poznámka', blank=True,
|
|
||||||
help_text='Neveřejná poznámka ke konfeře(plain text)')
|
|
||||||
# Jedno reseni se vztahuje nejvyse k jedne konfere
|
|
||||||
reseni = models.OneToOneField(Reseni, verbose_name='článek ke konfeře', related_name='konfery',
|
|
||||||
help_text='Účastnický přípěvek o konfeře', on_delete = models.SET_NULL,
|
|
||||||
null=True, blank=True)
|
|
||||||
|
|
||||||
TYP_VELETRH = 'veletrh'
|
TYP_VELETRH = 'veletrh'
|
||||||
TYP_PREZENTACE = 'prezentace'
|
TYP_PREZENTACE = 'prezentace'
|
||||||
TYP_CHOICES = [
|
TYP_CHOICES = [
|
||||||
|
@ -1190,21 +1156,9 @@ class Konfera(models.Model):
|
||||||
help_text = 'Další materiály ke konfeře zabalené do jednoho souboru',
|
help_text = 'Další materiály ke konfeře zabalené do jednoho souboru',
|
||||||
upload_to = generate_filename_konfera, blank=True)
|
upload_to = generate_filename_konfera, blank=True)
|
||||||
|
|
||||||
# má OneToOneField s:
|
|
||||||
# KonferaNode
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "{}: ({})".format(self.nazev, self.soustredeni)
|
return "{}: ({})".format(self.nazev, self.soustredeni)
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
|
||||||
super().save(*args, **kwargs)
|
|
||||||
# *Node.save() aktualizuje název *Nodu.
|
|
||||||
try:
|
|
||||||
self.konferanode.save()
|
|
||||||
except ObjectDoesNotExist:
|
|
||||||
# Neexistující *Node nemá smysl aktualizovat.
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
# Vazebna tabulka. Mozna se generuje automaticky.
|
# Vazebna tabulka. Mozna se generuje automaticky.
|
||||||
@reversion.register(ignore_duplicates=True)
|
@reversion.register(ignore_duplicates=True)
|
||||||
|
@ -1417,36 +1371,30 @@ class TemaVCisleNode(TreeNode):
|
||||||
def getOdkazStr(self):
|
def getOdkazStr(self):
|
||||||
return str(self.tema)
|
return str(self.tema)
|
||||||
|
|
||||||
class KonferaNode(TreeNode):
|
class OrgTextNode(TreeNode):
|
||||||
class Meta:
|
class Meta:
|
||||||
db_table = 'seminar_nodes_konfera'
|
db_table = 'seminar_nodes_orgtextnode'
|
||||||
verbose_name = 'Konfera (Node)'
|
verbose_name = 'Organizátorský článek (Node)'
|
||||||
verbose_name_plural = 'Konfery (Node)'
|
verbose_name_plural = 'Organizátorské články (Node)'
|
||||||
konfera = models.OneToOneField(Konfera,
|
|
||||||
on_delete=models.PROTECT, # Pokud chci mazat téma, musím si Node pořešit ručně
|
organizator = models.ForeignKey(Organizator,
|
||||||
verbose_name = "konfera",
|
null=False,
|
||||||
null=True,
|
blank=False,
|
||||||
blank=False)
|
on_delete=models.DO_NOTHING,
|
||||||
|
verbose_name="Organizátor",
|
||||||
|
)
|
||||||
|
org_verejny = models.BooleanField(default = True,
|
||||||
|
verbose_name = "Org je veřejný?",
|
||||||
|
help_text = "Pokud ano, bude org pod článkem podepsaný",
|
||||||
|
null=False,
|
||||||
|
)
|
||||||
|
|
||||||
def aktualizuj_nazev(self):
|
def aktualizuj_nazev(self):
|
||||||
self.nazev = "KonferaNode: "+str(self.konfera)
|
return f"OrgTextNode začínající následujícim: {self.first_child.nazev}"
|
||||||
|
|
||||||
class ClanekNode(TreeNode):
|
# FIXME!!!
|
||||||
class Meta:
|
#def getOdkazStr(self):
|
||||||
db_table = 'seminar_nodes_clanek'
|
# return str(self.clanek)
|
||||||
verbose_name = 'Článek (Node)'
|
|
||||||
verbose_name_plural = 'Články (Node)'
|
|
||||||
clanek = models.OneToOneField(Clanek,
|
|
||||||
on_delete=models.PROTECT, # Pokud chci mazat téma, musím si Node pořešit ručně
|
|
||||||
verbose_name = "článek",
|
|
||||||
null=True,
|
|
||||||
blank=False)
|
|
||||||
|
|
||||||
def aktualizuj_nazev(self):
|
|
||||||
self.nazev = "ClanekNode: "+str(self.clanek)
|
|
||||||
|
|
||||||
def getOdkazStr(self):
|
|
||||||
return str(self.clanek)
|
|
||||||
|
|
||||||
|
|
||||||
class UlohaZadaniNode(TreeNode):
|
class UlohaZadaniNode(TreeNode):
|
||||||
|
@ -1527,7 +1475,7 @@ class CastNode(TreeNode):
|
||||||
def getOdkazStr(self):
|
def getOdkazStr(self):
|
||||||
return str(self.nadpis)
|
return str(self.nadpis)
|
||||||
|
|
||||||
class OtisteneReseniNode(TreeNode):
|
class ReseniNode(TreeNode):
|
||||||
class Meta:
|
class Meta:
|
||||||
db_table = 'seminar_nodes_otistene_reseni'
|
db_table = 'seminar_nodes_otistene_reseni'
|
||||||
verbose_name = 'Otištěné řešení (Node)'
|
verbose_name = 'Otištěné řešení (Node)'
|
||||||
|
|
|
@ -8,18 +8,56 @@
|
||||||
{% endblock %}{% endblock %}
|
{% endblock %}{% endblock %}
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<div class='nahledy_cisel'>
|
<!-- <div class='nahledy_cisel'>
|
||||||
{% autoescape off %}{{ nahledy }}{% endautoescape %}
|
{% autoescape off %}{{ nahledy }}{% endautoescape %}
|
||||||
</div>
|
</div>-->
|
||||||
|
|
||||||
|
{% for rocnik, url_png in object_list.items %}
|
||||||
|
|
||||||
|
<div class="rocnik_pole">
|
||||||
|
|
||||||
|
<h3>
|
||||||
|
<a href='{{ rocnik.verejne_url }}'>Ročník {{ rocnik }}</a>
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
|
||||||
|
{# karta ročníku - zepředu obrázek prvního čísla, zezadu odkaz na jednotlivá čísla a výsledkovku #}
|
||||||
|
|
||||||
|
<div class="flip-card" id="archiv">
|
||||||
|
|
||||||
|
<div class="flip-card-inner">
|
||||||
|
<div class="flip-card-front">
|
||||||
|
|
||||||
|
<div class="flip-card-foto">
|
||||||
|
<img src="{{ url_png }}" height=200px alt="{{ rocnik }}">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="flip-card-back">
|
||||||
|
<div class="popis_rocniku">
|
||||||
|
Jednotlivá čísla:
|
||||||
|
<ul>
|
||||||
|
{% for cislo in rocnik.cisla.all reversed %}
|
||||||
|
<li><a href='{{ cislo.verejne_url }}'>{{ cislo.poradi }}. číslo</a> {% if cislo.pdf %}(<a href='{{ cislo.pdf.url }}'>pdf</a>) {% endif %}
|
||||||
|
{% empty %}
|
||||||
|
Žádná čísla k zobrazení
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
<a href='{{ rocnik.verejne_url }}'>Výsledková listina</a> <!-- FIXME: url výsledkovky-->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{# konec karty ročníku #}
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
</div>
|
||||||
|
|
||||||
<ul>
|
|
||||||
{% for r in object_list %}
|
|
||||||
<li><a href='{{ r.verejne_url }}'>Ročník {{ r }}</a>
|
|
||||||
{% empty %}
|
{% empty %}
|
||||||
Nejsou žádné ročníky
|
Nejsou žádné ročníky
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|
||||||
|
|
|
@ -46,15 +46,15 @@
|
||||||
<li><a href="obalkovani">Obálkování</a></li>
|
<li><a href="obalkovani">Obálkování</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if cislo.verejna_vysledkovka %}
|
{% if cislo.verejna_vysledkovka %}
|
||||||
<h2>Výsledkovka ({% now "jS F Y H:i" %})</h2>
|
<h2>Výsledkovka</h2>
|
||||||
|
|
||||||
{% else %}
|
{% else %}
|
||||||
{% if user.is_staff %}
|
{% if user.is_staff %}
|
||||||
<div class='mam-org-only'>
|
<div class='mam-org-only'>
|
||||||
<h2>Výsledkovka (neveřejná, {% now "jS F Y H:i:s" %})</h2>
|
<h2>Výsledkovka (neveřejná)</h2>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@
|
||||||
<tr>
|
<tr>
|
||||||
<td class='border-r'>{% autoescape off %}{{ rv.poradi }}{% endautoescape %}
|
<td class='border-r'>{% autoescape off %}{{ rv.poradi }}{% endautoescape %}
|
||||||
<th class='border-r'>
|
<th class='border-r'>
|
||||||
{% if rv.titul is not '' %}
|
{% if rv.titul %}
|
||||||
{{ rv.titul }}<sup>MM</sup>
|
{{ rv.titul }}<sup>MM</sup>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{{ rv.resitel.osoba.plne_jmeno }}
|
{{ rv.resitel.osoba.plne_jmeno }}
|
||||||
|
@ -86,14 +86,11 @@
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if not cislo.verejna_vysledkovka and user.is_staff %}
|
{% if not cislo.verejna_vysledkovka and user.is_staff %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
Čas: {% now "jS F Y H:i:s" %}
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
\setlength{\tabcolsep}{3pt}
|
\setlength{\tabcolsep}{3pt}
|
||||||
\begin{longtable}{|r|l|c|r|{% for p in problemy %}c@{\hskip.5em}{% endfor %}|r|r|}\hline
|
\begin{longtable}{|r|l|c|r|{% for p in problemy %}c@{\hskip.5em}{% endfor %}|r|r|}\hline
|
||||||
& & & & \multicolumn{ {{ problemy|length}} }{c|}{\textbf{Úlohy}} & & \\\textbf{Poř.}& \textbf{Jméno}& \textbf{R.}& \raisebox{0.7mm}{$\sum_{-1}$}& {% for p in problemy %}{% if p.typ == "uloha" %}\textbf{r{{p.kod}}}&{% elif p.typ == "tema" %}\textbf{t{{p.kod}}}&{% else %}\textbf{ {{p.kod}} }&{% endif %}{% endfor %}\raisebox{0.7mm}{$\sum_0$}&\raisebox{0.7mm}{$\sum_1$}\\\hline
|
& & & & \multicolumn{ {{ problemy|length}} }{c|}{\textbf{Úlohy}} & & \\\textbf{Poř.}& \textbf{Jméno}& \textbf{R.}& \raisebox{0.7mm}{$\sum_{-1}$}& {% for p in problemy %}\textbf{ {{ p.kod_v_rocniku }} }&{% endfor %}\raisebox{0.7mm}{$\sum_0$}&\raisebox{0.7mm}{$\sum_1$}\\\hline
|
||||||
\endhead
|
\endhead
|
||||||
\hline
|
\hline
|
||||||
\endfoot
|
\endfoot
|
||||||
{% for rv in vysledkovka %}{{rv.poradi}}&{% if rv.titul %}\titul{ {{ rv.titul}}}{% endif %}{{rv.resitel.inicial_krestni}} {{rv.resitel.prijmeni}}&{{rv.resitel.rocnik|default:""}}&{{rv.body_celkem_odjakziva}}&{% for b in rv.body_ulohy %}{{b}}&{% endfor %}{{rv.body_cislo}}&{{rv.body_celkem_rocnik|default:0}}\\
|
{% for rv in radky_vysledkovky %}{{rv.poradi}}&{% if rv.titul %}\titul{ {{ rv.titul}}}{% endif %}{{rv.resitel.osoba.jmeno|slice:":1"}}. {{rv.resitel.osoba.prijmeni}}&{{rv.rocnik_resitele|default:""}}&{{rv.body_celkem_odjakziva}}&{% for b in rv.body_problemy_sezn %}{{b}}&{% endfor %}{{rv.body_cislo}}&{{rv.body_rocnik|default:0}}\\
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
\end{longtable}
|
\end{longtable}
|
||||||
|
|
|
@ -2,22 +2,11 @@
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div>
|
<div>
|
||||||
<h1>
|
<h2>
|
||||||
{% block nadpis1a %}{% block nadpis1b %}
|
{% block nadpis1a %}{% block nadpis1b %}
|
||||||
Ročník {{ rocnik.roman }}
|
Ročník {{ rocnik }}
|
||||||
{% endblock %}{% endblock %}
|
{% endblock %}{% endblock %}
|
||||||
</h1>
|
</h2>
|
||||||
|
|
||||||
<p>Ročník číslo {{ rocnik.rocnik }} ({{ rocnik.prvni_rok }}/{{ rocnik.druhy_rok }})
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
{% for c in rocnik.verejna_cisla %}
|
|
||||||
<li><a href="{{ c.verejne_url }}">Číslo {{ c.kod }}</a>
|
|
||||||
{% if c.pdf %}
|
|
||||||
(<a href='{{ c.pdf.url }}'>pdf</a>)
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
{% if temata_v_rocniku %}
|
{% if temata_v_rocniku %}
|
||||||
<h2>Témata</h2>
|
<h2>Témata</h2>
|
||||||
|
@ -28,6 +17,50 @@
|
||||||
</ul>
|
</ul>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
<div class="cisla-v-rocniku">
|
||||||
|
{% for c in rocnik.verejna_cisla %}
|
||||||
|
<div class="cislo_pole">
|
||||||
|
|
||||||
|
<h6> Číslo {{ c.kod }}</h6>
|
||||||
|
|
||||||
|
<div class="flip-card" id="archiv-rocnik">
|
||||||
|
|
||||||
|
<div class="flip-card-inner">
|
||||||
|
<div class="flip-card-front">
|
||||||
|
|
||||||
|
<div class="flip-card-foto">
|
||||||
|
{% if c.titulka_nahled %}
|
||||||
|
<img src="{{ c.titulka_nahled.url }}" alt="{{ c.kod }}" height=180px>
|
||||||
|
{% else %}
|
||||||
|
<img src="" alt="no image" height=180px>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="flip-card-back">
|
||||||
|
|
||||||
|
<div class="cislo_odkazy">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="{{ c.verejne_url }}">archiv čísla</a>
|
||||||
|
</li>
|
||||||
|
{% if c.pdf %}
|
||||||
|
<li>
|
||||||
|
<a href='{{ c.pdf.url }}'>pdf</a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
|
||||||
{% if vysledkovka %}
|
{% if vysledkovka %}
|
||||||
{% if user.is_staff %}
|
{% if user.is_staff %}
|
||||||
<div class='mam-org-only'>
|
<div class='mam-org-only'>
|
||||||
|
@ -42,7 +75,7 @@
|
||||||
{% if user.is_staff and vysledkovka_s_neverejnymi %}
|
{% if user.is_staff and vysledkovka_s_neverejnymi %}
|
||||||
<div class='mam-org-only'>
|
<div class='mam-org-only'>
|
||||||
<h2>Výsledková listina včetně neveřejných bodů</h2>
|
<h2>Výsledková listina včetně neveřejných bodů</h2>
|
||||||
{% with vysledkovka_s_neverejnymi as vysledkovka %}
|
{% with radky_vyledkovky_s_neverejnymi as radky_vysledkovky %}
|
||||||
{% include "seminar/vysledkovka_rocnik.html" %}
|
{% include "seminar/vysledkovka_rocnik.html" %}
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
</div>
|
</div>
|
||||||
|
@ -50,7 +83,3 @@
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
{% with lb="{" %}
|
{% with lb="{" %}
|
||||||
{% with rb="}" %}
|
{% with rb="}" %}
|
||||||
\setlength{\tabcolsep}{3pt}
|
\setlength{\tabcolsep}{3pt}
|
||||||
\begin{longtable}{|r|l|c|r|{% for cislo in vysledkovka.cisla %}c{% if not forloop.last %}@{\hskip.5em}{% endif %}{% endfor %}|r|}
|
\begin{longtable}{|r|l|c|r|{% for cislo in cisla %}c{% if not forloop.last %}@{\hskip.5em}{% endif %}{% endfor %}|r|}\hline
|
||||||
\hline
|
& & & & \multicolumn{{ lb }}{{ cisla|length }}}{c|}{\textbf{Číslo}} & \\\textbf{Poř.} & \textbf{Jméno} & \textbf{R.} & \raisebox{0.7mm}{$\sum_{-1}$} & {% for cislo in cisla %}\textbf{{ lb }}{{ cislo.poradi }}{{ rb }} & {% endfor %}\raisebox{0.7mm}{$\sum_1$} \\\hline
|
||||||
& & & & \multicolumn{{ lb }}{{ vysledkovka.cisla|length }}}{c|}{\textbf{Číslo}} & \\\textbf{Poř.} & \textbf{Jméno} & \textbf{R.} & \raisebox{0.7mm}{$\sum_{-1}$} & {% for cislo in vysledkovka.cisla %}\textbf{{ lb }}{{ cislo.cislo }}{{ rb }} & {% endfor %}\raisebox{0.7mm}{$\sum_1$} \\\hline
|
|
||||||
\endhead
|
\endhead
|
||||||
\hline
|
\hline
|
||||||
\endfoot
|
\endfoot
|
||||||
{% for rv in vysledkovka.radky %}{{ rv.poradi }} & {% if rv.titul %}\titul{{ lb }}{{ rv.titul }}}~{% endif %}{{ rv.resitel.jmeno|slice:":1" }}.~{{ rv.resitel.prijmeni }} & {% if rv.resitel.rocnik %}{{ rv.resitel.rocnik }}.{% endif %} & {{ rv.body_odjakziva }} {% for b in rv.body_cisla %} & {{ b }}{% endfor %} & {{ rv.body_rocnik }} \\
|
{% for rv in radky_vysledkovky %}{{ rv.poradi }} & {% if rv.titul %}\titul{{ lb }}{{ rv.titul }}}~{% endif %}{{ rv.resitel.osoba.jmeno|slice:":1" }}.~{{ rv.resitel.osoba.prijmeni }} & {% if rv.rocnik_resitele %}{{ rv.rocnik_resitele }}{% endif %} & {{ rv.body_celkem_odjakziva }} {% for b in rv.body_cisla_sezn %} & {{ b }}{% endfor %} & {{ rv.body_rocnik }} \\
|
||||||
{% endfor %}\end{longtable}
|
{% endfor %}\end{longtable}
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
{% if broken %}
|
{% if broken %}
|
||||||
%% POZOR! %% Dva resitele maji stejne makro!!!
|
POZOR! Kolize jmen! Dva řešitelé mají stejné makro!
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% autoescape off %}
|
{% autoescape off %}
|
||||||
|
|
|
@ -46,12 +46,12 @@
|
||||||
|
|
||||||
{# karta organizátora - zepředu fotka, zezadu popis, u neaktivních data kdy organizovali #}
|
{# karta organizátora - zepředu fotka, zezadu popis, u neaktivních data kdy organizovali #}
|
||||||
|
|
||||||
<div class="flip-card">
|
<div class="flip-card" id="organizatori">
|
||||||
|
|
||||||
<div class="flip-card-inner">
|
<div class="flip-card-inner">
|
||||||
<div class="flip-card-front">
|
<div class="flip-card-front">
|
||||||
|
|
||||||
<div class="foto_org">
|
<div class="flip-card-foto">
|
||||||
{% if org.osoba.foto %}
|
{% if org.osoba.foto %}
|
||||||
<a href="{{org.osoba.foto.url}}"><img src="{{org.osoba.foto_male.url}}" height="{{org.osoba.foto_male.height}}" alt="{{org.osoba.jmeno}} {{org.osoba.prijmeni}}"></a>
|
<a href="{{org.osoba.foto.url}}"><img src="{{org.osoba.foto_male.url}}" height="{{org.osoba.foto_male.height}}" alt="{{org.osoba.jmeno}} {{org.osoba.prijmeni}}"></a>
|
||||||
{% else %} {# pokud osoba nemá fotku, zobrazuje se defaultní obrázek #}
|
{% else %} {# pokud osoba nemá fotku, zobrazuje se defaultní obrázek #}
|
||||||
|
|
|
@ -4,23 +4,23 @@
|
||||||
<th class='border-r'>Jméno
|
<th class='border-r'>Jméno
|
||||||
<th class='border-r'>R.
|
<th class='border-r'>R.
|
||||||
<th class='border-r'>Odjakživa
|
<th class='border-r'>Odjakživa
|
||||||
{% for c in vysledkovka.cisla %}
|
{% for c in cisla %}
|
||||||
<th class='border-r'><a href="{{ c.verejne_url }}">
|
<th class='border-r'><a href="{{ c.verejne_url }}">
|
||||||
{{c.rocnik.rocnik}}.{{ c.cislo }}</a>
|
{{c.rocnik.rocnik}}.{{ c.poradi }}</a>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<th class='border-r'>Celkem
|
<th class='border-r'>Celkem
|
||||||
|
|
||||||
{% for rv in vysledkovka.radky %}
|
{% for rv in radky_vysledkovky %}
|
||||||
<tr>
|
<tr>
|
||||||
<td class='border-r'>{% autoescape off %}{{ rv.poradi }}{% endautoescape %}
|
<td class='border-r'>{% autoescape off %}{{ rv.poradi }}{% endautoescape %}
|
||||||
<th class='border-r'>
|
<th class='border-r'>
|
||||||
{% if rv.titul %}
|
{% if rv.titul %}
|
||||||
{{ rv.titul }}<sup>MM</sup>
|
{{ rv.titul }}<sup>MM</sup>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{{ rv.resitel.plne_jmeno }}
|
{{ rv.resitel.osoba.plne_jmeno }}
|
||||||
<td class='border-r'>{{ rv.resitel.rocnik }}
|
<td class='border-r'>{{ rv.rocnik_resitele }}
|
||||||
<td class='border-r'>{{ rv.body_odjakziva }}
|
<td class='border-r'>{{ rv.body_celkem_odjakziva }}
|
||||||
{% for b in rv.body_cisla %}
|
{% for b in rv.body_cisla_sezn %}
|
||||||
<td class='border-r'>{{ b }}
|
<td class='border-r'>{{ b }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<td class='border-r'><b>{{ rv.body_rocnik }}</b>
|
<td class='border-r'><b>{{ rv.body_rocnik }}</b>
|
||||||
|
|
|
@ -9,7 +9,7 @@ from django.db import transaction
|
||||||
import unidecode
|
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, KonferaNode, 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
|
||||||
|
|
||||||
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
|
||||||
|
@ -270,9 +270,12 @@ def gen_ulohy_do_cisla(rnd, organizatori, resitele, rocnik_cisla, rocniky, size)
|
||||||
#print("Generuji {}-té řešení".format(ri))
|
#print("Generuji {}-té řešení".format(ri))
|
||||||
if rnd.randint(1, 10) == 6:
|
if rnd.randint(1, 10) == 6:
|
||||||
# cca desetina řešení od více řešitelů
|
# cca desetina řešení od více řešitelů
|
||||||
res_vyber = rnd.sample(resitele_cisla, rnd.randint(2, 5))
|
res_vyber = rnd.sample(resitele_cisla,
|
||||||
|
rnd.randint(2, 5))
|
||||||
else:
|
else:
|
||||||
res_vyber = rnd.sample(resitele_cisla, 1)
|
res_vyber = rnd.sample(resitele_cisla, 1)
|
||||||
|
if resitele[0] in res_vyber:
|
||||||
|
res_vyber.remove(resitele[0])
|
||||||
res = Reseni.objects.create(forma=rnd.choice(Reseni.FORMA_CHOICES)[0])
|
res = Reseni.objects.create(forma=rnd.choice(Reseni.FORMA_CHOICES)[0])
|
||||||
# problem a resitele přiřadíme později, ManyToManyField
|
# problem a resitele přiřadíme později, ManyToManyField
|
||||||
# se nedá vyplnit v create()
|
# se nedá vyplnit v create()
|
||||||
|
@ -336,7 +339,7 @@ def gen_konfery(size, rnd, organizatori, resitele, soustredeni):
|
||||||
nazev=rnd.choice(['Pozorování', 'Zkoumání', 'Modelování', 'Počítání', 'Zkoušení']) + rnd.choice([' vlastností', ' jevů', ' charakteristik']) + rnd.choice([' vektorových prostorů', ' kinetické terorie látek', ' molekulární biologie', ' syntentických stromů']),
|
nazev=rnd.choice(['Pozorování', 'Zkoumání', 'Modelování', 'Počítání', 'Zkoušení']) + rnd.choice([' vlastností', ' jevů', ' charakteristik']) + rnd.choice([' vektorových prostorů', ' kinetické terorie látek', ' molekulární biologie', ' syntentických stromů']),
|
||||||
anotace=lorem.paragraph(),
|
anotace=lorem.paragraph(),
|
||||||
abstrakt=lorem.paragraph(),
|
abstrakt=lorem.paragraph(),
|
||||||
organizator=rnd.choice(organizatori),
|
garant=rnd.choice(organizatori),
|
||||||
soustredeni=rnd.choice(soustredeni),
|
soustredeni=rnd.choice(soustredeni),
|
||||||
typ_prezentace=rnd.choice(['veletrh', 'prezentace']))
|
typ_prezentace=rnd.choice(['veletrh', 'prezentace']))
|
||||||
ucastnici_sous = list(konfera.soustredeni.ucastnici.all())
|
ucastnici_sous = list(konfera.soustredeni.ucastnici.all())
|
||||||
|
@ -346,9 +349,6 @@ def gen_konfery(size, rnd, organizatori, resitele, soustredeni):
|
||||||
# Konfery_Ucastnici.objects.create(resitel=res, konfera=konfera)
|
# Konfery_Ucastnici.objects.create(resitel=res, konfera=konfera)
|
||||||
konfera.save()
|
konfera.save()
|
||||||
konfery.append(konfera)
|
konfery.append(konfera)
|
||||||
|
|
||||||
konferanode = KonferaNode.objects.create(konfera=konfera)
|
|
||||||
konferanode.save()
|
|
||||||
return konfery
|
return konfery
|
||||||
|
|
||||||
def gen_cisla(rnd, rocniky):
|
def gen_cisla(rnd, rocniky):
|
||||||
|
@ -407,7 +407,8 @@ def gen_temata(rnd, rocniky, rocnik_cisla, organizatori):
|
||||||
poc_oboru = rnd.randint(1, 2)
|
poc_oboru = rnd.randint(1, 2)
|
||||||
|
|
||||||
rocnik_temata = []
|
rocnik_temata = []
|
||||||
# Věříme, že rocnik_cisla je pole polí čísel podle ročníků, tak si necháme dát vždycky jeden ročník a k němu příslušná čísla.
|
# Věříme, že rocnik_cisla je pole polí čísel podle ročníků, tak si necháme dát
|
||||||
|
# vždycky jeden ročník a k němu příslušná čísla.
|
||||||
for rocnik, cisla in zip(rocniky, rocnik_cisla):
|
for rocnik, cisla in zip(rocniky, rocnik_cisla):
|
||||||
kod = 1
|
kod = 1
|
||||||
letosni_temata = []
|
letosni_temata = []
|
||||||
|
|
|
@ -81,18 +81,20 @@ urlpatterns = [
|
||||||
path('aesop-export/index.csv', export.ExportIndexView.as_view(), name='seminar_export_index'),
|
path('aesop-export/index.csv', export.ExportIndexView.as_view(), name='seminar_export_index'),
|
||||||
|
|
||||||
# Stranky viditelne pouze pro orgy:
|
# Stranky viditelne pouze pro orgy:
|
||||||
#path(
|
path(
|
||||||
# 'rocnik/(?P<rocnik>\d+)/vysledkovka.tex',
|
'rocnik/<int:rocnik>/vysledkovka.tex',
|
||||||
# staff_member_required(views.RocnikVysledkovkaView.as_view()),
|
staff_member_required(views.RocnikVysledkovkaView.as_view()),
|
||||||
# name='seminar_cislo_vysledkovka'
|
name='seminar_rocnik_vysledkovka'
|
||||||
#),
|
),
|
||||||
#path('cislo/(?P<rocnik>\d+).(?P<cislo>[0-9-]+)/vysledkovka.tex',
|
path('cislo/<int:rocnik>.<int:cislo>/vysledkovka.tex',
|
||||||
# staff_member_required(views.CisloVysledkovkaView.as_view()), name='seminar_cislo_vysledkovka'),
|
staff_member_required(views.CisloVysledkovkaView.as_view()),
|
||||||
|
name='seminar_cislo_vysledkovka'
|
||||||
|
),
|
||||||
path('cislo/<int:rocnik>.<int:cislo>/obalky.pdf',
|
path('cislo/<int:rocnik>.<int:cislo>/obalky.pdf',
|
||||||
staff_member_required(views.cisloObalkyView), name='seminar_cislo_obalky'),
|
staff_member_required(views.cisloObalkyView), name='seminar_cislo_obalky'),
|
||||||
|
|
||||||
#path('cislo/(?P<rocnik>\d+).(?P<cislo>[0-9-]+)/tituly.tex',
|
path('cislo/<int:rocnik>.<int:cislo>/tituly.tex',
|
||||||
# staff_member_required(views.TitulyView), name='seminar_cislo_titul'),
|
staff_member_required(views.TitulyView), name='seminar_cislo_titul'),
|
||||||
path('stav',
|
path('stav',
|
||||||
staff_member_required(views.StavDatabazeView), name='stav_databaze'),
|
staff_member_required(views.StavDatabazeView), name='stav_databaze'),
|
||||||
path('cislo/<int:rocnik>.<int:cislo>/obalkovani',
|
path('cislo/<int:rocnik>.<int:cislo>/obalkovani',
|
||||||
|
|
|
@ -40,6 +40,7 @@ import traceback
|
||||||
import sys
|
import sys
|
||||||
import csv
|
import csv
|
||||||
import logging
|
import logging
|
||||||
|
import time
|
||||||
|
|
||||||
|
|
||||||
def verejna_temata(rocnik):
|
def verejna_temata(rocnik):
|
||||||
|
@ -340,93 +341,32 @@ class ArchivView(generic.ListView):
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super(ArchivView, self).get_context_data(**kwargs)
|
context = super(ArchivView, self).get_context_data(**kwargs)
|
||||||
|
|
||||||
vyska = 297 # px
|
cisla = Cislo.objects.filter(poradi=1)
|
||||||
sirka = 210 # px
|
urls ={}
|
||||||
|
|
||||||
# nejnovějších 10 zveřejněných čísel
|
|
||||||
# cisla = Cislo.objects.filter(verejne_db=True)[:10]
|
|
||||||
cisla = Cislo.objects.filter(poradi=1)[:10]
|
|
||||||
|
|
||||||
# op == os.path, udělá z argumentů cestu
|
|
||||||
png_dir = op.join(settings.MEDIA_ROOT, "cislo", "png")
|
|
||||||
|
|
||||||
# seznam [(url obrázku, číslo)]
|
|
||||||
urls = []
|
|
||||||
|
|
||||||
for i, c in enumerate(cisla):
|
for i, c in enumerate(cisla):
|
||||||
if not c.pdf:
|
if c.titulka_nahled:
|
||||||
continue
|
urls[c.rocnik] = c.titulka_nahled.url
|
||||||
filename = os.path.split(c.pdf.file.name)[1].split(".")[0]
|
else:
|
||||||
png_filename = "{}-{}px.png".format(filename, vyska)
|
urls[c.rocnik] = op.join(settings.MEDIA_URL, "cislo", "png", "default.png")
|
||||||
|
|
||||||
# Pokud obrázek neexistuje nebo není aktuální, vytvoř jej
|
context["object_list"] = urls
|
||||||
png_path = op.join(png_dir, png_filename)
|
|
||||||
if not op.exists(png_path) or \
|
|
||||||
op.getmtime(png_path) < op.getmtime(c.pdf.path):
|
|
||||||
|
|
||||||
subprocess.call([
|
|
||||||
"convert",
|
|
||||||
"-density", "300x300",
|
|
||||||
"-geometry", "{}x{}".format(vyska, sirka),
|
|
||||||
"-background", "white",
|
|
||||||
"-flatten",
|
|
||||||
"-rotate", str(90 * i),
|
|
||||||
"{}[0]".format(c.pdf.path), # titulní strana
|
|
||||||
png_path
|
|
||||||
])
|
|
||||||
|
|
||||||
urls.append(
|
|
||||||
(op.join(settings.MEDIA_URL, "cislo", "png", png_filename), c)
|
|
||||||
)
|
|
||||||
vyska, sirka = sirka, vyska / 2
|
|
||||||
|
|
||||||
tags = []
|
|
||||||
|
|
||||||
def spirala(urls, tags, idx):
|
|
||||||
"""Rekurzivně prochází urls a generuje strom elementů do tags"""
|
|
||||||
if idx >= len(urls):
|
|
||||||
return
|
|
||||||
|
|
||||||
img_url, cislo = urls[idx]
|
|
||||||
tags.append(
|
|
||||||
"<div style='top:{}%;left:{}%;width:{}%;height:{}%;'>"
|
|
||||||
.format(
|
|
||||||
50 if idx % 4 == 2 else 0,
|
|
||||||
50 if idx % 4 == 1 else 0,
|
|
||||||
50 if idx % 2 == 1 else 100,
|
|
||||||
50 if idx > 0 and idx % 2 == 0 else 100
|
|
||||||
)
|
|
||||||
)
|
|
||||||
tags.append("<a href='{}' title='{}'>".format(
|
|
||||||
cislo.verejne_url(), cislo.kod()
|
|
||||||
))
|
|
||||||
tags.append(
|
|
||||||
"<img src='{}' style='top:{}%;left:{}%;width:{}%;height:{}%;'>"
|
|
||||||
.format(
|
|
||||||
img_url,
|
|
||||||
50 if idx % 4 == 3 else 0,
|
|
||||||
50 if idx % 4 == 2 else 0,
|
|
||||||
50 if idx % 2 == 0 else 100,
|
|
||||||
50 if idx % 2 == 1 else 100
|
|
||||||
)
|
|
||||||
)
|
|
||||||
tags.append("</a>")
|
|
||||||
spirala(urls, tags, idx + 1)
|
|
||||||
tags.append("</div>")
|
|
||||||
spirala(urls, tags, 0)
|
|
||||||
|
|
||||||
context["nahledy"] = "\n".join(tags)
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
### Výsledky
|
### Výsledky
|
||||||
|
|
||||||
# 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.)
|
# ze seznamu obsahujícího sestupně setřízené body řešitelů za daný ročník
|
||||||
def sloupec_s_poradim(seznam_s_body):
|
# vytvoří seznam s pořadími (včetně 3.-5. a pak 2 volná místa atp.),
|
||||||
|
# podle toho, jak jdou za sebou ve výsledkovce
|
||||||
|
def sloupec_s_poradim(setrizene_body):
|
||||||
|
|
||||||
|
# ze seznamu obsahujícího setřízené body spočítáme sloupec s pořadím
|
||||||
aktualni_poradi = 1
|
aktualni_poradi = 1
|
||||||
sloupec_s_poradim = []
|
sloupec_s_poradim = []
|
||||||
|
|
||||||
# seskupíme seznam všech bodů podle hodnot
|
# seskupíme seznam všech bodů podle hodnot
|
||||||
for index in range(0, len(seznam_s_body)):
|
for index in range(0, len(setrizene_body)):
|
||||||
# pokud je pořadí větší než číslo řádku, tak jsme vypsali větší rozsah a chceme
|
# 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
|
# vypsat už jen prázdné místo, než dojdeme na správný řádek
|
||||||
if (index + 1) < aktualni_poradi:
|
if (index + 1) < aktualni_poradi:
|
||||||
|
@ -434,10 +374,10 @@ def sloupec_s_poradim(seznam_s_body):
|
||||||
continue
|
continue
|
||||||
velikost_skupiny = 0
|
velikost_skupiny = 0
|
||||||
# zjistíme počet po sobě jdoucích stejných hodnot
|
# zjistíme počet po sobě jdoucích stejných hodnot
|
||||||
while seznam_s_body[index] == seznam_s_body[index + velikost_skupiny]:
|
while setrizene_body[index] == setrizene_body[index + velikost_skupiny]:
|
||||||
velikost_skupiny = velikost_skupiny + 1
|
velikost_skupiny = velikost_skupiny + 1
|
||||||
# na konci musíme ošetřit přetečení seznamu
|
# na konci musíme ošetřit přetečení seznamu
|
||||||
if (index + velikost_skupiny) > len(seznam_s_body) - 1:
|
if (index + velikost_skupiny) > len(setrizene_body) - 1:
|
||||||
break
|
break
|
||||||
# pokud je velikost skupiny 1, vypíšu pořadí
|
# pokud je velikost skupiny 1, vypíšu pořadí
|
||||||
if velikost_skupiny == 1:
|
if velikost_skupiny == 1:
|
||||||
|
@ -450,28 +390,12 @@ def sloupec_s_poradim(seznam_s_body):
|
||||||
aktualni_poradi = aktualni_poradi + velikost_skupiny
|
aktualni_poradi = aktualni_poradi + velikost_skupiny
|
||||||
return sloupec_s_poradim
|
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
|
# vrátí všechna čísla daného ročníku
|
||||||
#def __soucet_resitele_problemu(problem, resitel, cislo, soucet):
|
def cisla_rocniku(rocnik, jen_verejne=True):
|
||||||
# # sečteme body za daný problém přes všechna řešení daného problému
|
if jen_verejne:
|
||||||
# # od daného řešitele
|
return rocnik.verejna_cisla()
|
||||||
# reseni_resitele = s.Reseni_Resitele.objects.filter(resitele=resitel)
|
else:
|
||||||
# hodnoceni_resitele = problem.hodnoceni.filter(reseni__in=reseni_resitele,
|
return rocnik.cisla.all()
|
||||||
# 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 hodnoceni_resitele:
|
|
||||||
# soucet += r.body
|
|
||||||
#
|
|
||||||
# # a přičteme k tomu hodnocení všech podproblémů
|
|
||||||
# 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
|
|
||||||
|
|
||||||
## 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):
|
|
||||||
# # probably FIXED: nezohledňuje číslo, do kterého se body počítají
|
|
||||||
# return __soucet_resitele_problemu(problem, resitel, cislo, 0)
|
|
||||||
|
|
||||||
# pro daný problém vrátí jeho nejvyšší nadproblém
|
# pro daný problém vrátí jeho nejvyšší nadproblém
|
||||||
def hlavni_problem(problem):
|
def hlavni_problem(problem):
|
||||||
|
@ -479,6 +403,17 @@ def hlavni_problem(problem):
|
||||||
problem = problem.nadproblem
|
problem = problem.nadproblem
|
||||||
return problem
|
return problem
|
||||||
|
|
||||||
|
def hlavni_problemy_rocniku(rocnik, jen_verejne=True):
|
||||||
|
hlavni_problemy = []
|
||||||
|
for cislo in cisla_rocniku(rocnik, jen_verejne):
|
||||||
|
for problem in hlavni_problemy_cisla(cislo):
|
||||||
|
hlavni_problemy.append(problem)
|
||||||
|
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 pořadí
|
||||||
|
|
||||||
|
return hlavni_problemy
|
||||||
|
|
||||||
# vrátí list všech problémů s body v daném čísle, které již nemají nadproblém
|
# vrátí list všech problémů s body v daném čísle, které již nemají nadproblém
|
||||||
def hlavni_problemy_cisla(cislo):
|
def hlavni_problemy_cisla(cislo):
|
||||||
hodnoceni = cislo.hodnoceni.select_related('problem', 'reseni').all()
|
hodnoceni = cislo.hodnoceni.select_related('problem', 'reseni').all()
|
||||||
|
@ -504,31 +439,12 @@ def hlavni_problemy_cisla(cislo):
|
||||||
|
|
||||||
# vrátí slovník řešitel:body obsahující počty bodů zadaných řešitelů za daný ročník
|
# vrátí slovník řešitel:body obsahující počty bodů zadaných řešitelů za daný ročník
|
||||||
def body_resitelu_odjakziva(rocnik, resitele):
|
def body_resitelu_odjakziva(rocnik, resitele):
|
||||||
body_odjakziva = {}
|
# Následující řádek přidá ke každému řešiteli údaj ".body" se součtem jejich bodů
|
||||||
|
resitele_s_body = Resitel.objects.annotate(body=Sum('reseni__hodnoceni__body'))
|
||||||
for r in resitele:
|
# Teď jen z QuerySetu řešitelů anotovaných body vygenerujeme slovník indexovaný řešitelským id obsahující body
|
||||||
body_odjakziva[str(r.id)] = 0
|
# ... ale jen ro řešitele, které dostaneme jako parametr.
|
||||||
# POZOR! Aktuálně počítá jen za posledních 10 let od zadaného ročníku
|
# TODO: Zjistit, co ten parametr říká a proč je potřeba
|
||||||
# # Body za posledních 10 let je dobrá aproximace pro naše potřeby (výsledkovka
|
body_odjakziva = {int(res.id) : res.body for res in resitele_s_body if res in resitele}
|
||||||
# # s aktivními řešiteli)
|
|
||||||
#
|
|
||||||
# body_pred_roky = []
|
|
||||||
# for i in range(0, 10):
|
|
||||||
# body_pred_roky.append(body_resitelu_za_rocnik(rocnik-i, resitele))
|
|
||||||
#
|
|
||||||
# for r in resitele:
|
|
||||||
# for i in range(0,10):
|
|
||||||
# body_odjakziva[str(r.id)] += body_pred_roky[i][str(r.id)]
|
|
||||||
|
|
||||||
|
|
||||||
# Nasledující řešení je sice správné, ale moc pomalé:
|
|
||||||
for res in Reseni.objects.prefetch_related('resitele', 'hodnoceni_set').all():
|
|
||||||
for r in res.resitele.all():
|
|
||||||
# daný řešitel nemusí být v naší podmnožině
|
|
||||||
if r not in resitele: continue
|
|
||||||
|
|
||||||
for hodn in res.hodnoceni_set.all():
|
|
||||||
pricti_body(body_odjakziva, r, hodn.body)
|
|
||||||
return body_odjakziva
|
return body_odjakziva
|
||||||
|
|
||||||
# vrátí slovník řešitel:body obsahující počty bodů zadaných řešitelů za daný ročník
|
# vrátí slovník řešitel:body obsahující počty bodů zadaných řešitelů za daný ročník
|
||||||
|
@ -536,74 +452,90 @@ def body_resitelu_za_rocnik(rocnik, aktivni_resitele):
|
||||||
body_za_rocnik = {}
|
body_za_rocnik = {}
|
||||||
# inicializujeme na 0 pro všechny aktivní řešitele
|
# inicializujeme na 0 pro všechny aktivní řešitele
|
||||||
for ar in aktivni_resitele:
|
for ar in aktivni_resitele:
|
||||||
body_za_rocnik[str(ar.id)] = 0
|
body_za_rocnik[ar.id] = 0
|
||||||
|
|
||||||
# spočítáme body řešitelům přes všechna řešení s hodnocením v daném ročníku
|
# spočítáme body řešitelům přes všechna řešení s hodnocením v daném ročníku
|
||||||
|
print("Před dotazem:{}".format(time.time()))
|
||||||
reseni = Reseni.objects.prefetch_related('resitele', 'hodnoceni_set').filter(hodnoceni__cislo_body__rocnik=rocnik)
|
reseni = Reseni.objects.prefetch_related('resitele', 'hodnoceni_set').filter(hodnoceni__cislo_body__rocnik=rocnik)
|
||||||
|
print("Po dotazu:{}".format(time.time()))
|
||||||
for res in reseni:
|
for res in reseni:
|
||||||
for resitel in res.resitele.all():
|
for resitel in res.resitele.all():
|
||||||
for hodn in res.hodnoceni_set.all():
|
for hodn in res.hodnoceni_set.all():
|
||||||
pricti_body(body_za_rocnik, resitel, hodn.body)
|
pricti_body(body_za_rocnik, resitel, hodn.body)
|
||||||
|
print("Po for-cyklu:{}".format(time.time()))
|
||||||
return body_za_rocnik
|
return body_za_rocnik
|
||||||
|
|
||||||
# TODO: předělat na nový model
|
class RadekVysledkovkyRocniku(object):
|
||||||
#def vysledkovka_rocniku(rocnik, jen_verejne=True):
|
"""Obsahuje věci, které se hodí vědět při konstruování výsledkovky.
|
||||||
# """Přebírá ročník (např. context["rocnik"]) a vrací výsledkovou listinu ve
|
Umožňuje snazší práci v templatu (lepší, než seznam)."""
|
||||||
# formě vhodné pro šablonu "seminar/vysledkovka_rocniku.html"
|
|
||||||
# """
|
|
||||||
#
|
|
||||||
# #vyberu vsechny vysledky z rocniku
|
|
||||||
# cisla_v_rocniku = VysledkyKCisluZaRocnik.objects.filter(cislo__rocnik=rocnik).order_by('cislo')
|
|
||||||
# if jen_verejne:
|
|
||||||
# cisla_v_rocniku = cisla_v_rocniku.filter(cislo__verejna_vysledkovka=True)
|
|
||||||
#
|
|
||||||
# #pokud žádné nejsou, výsledkovka se nezobrazí
|
|
||||||
# if not cisla_v_rocniku:
|
|
||||||
# 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].poradi).order_by('-body', 'resitel__prijmeni', 'resitel__jmeno').select_related('resitel'))
|
|
||||||
#
|
|
||||||
# class Vysledkovka:
|
|
||||||
# def __init__(self):
|
|
||||||
# self.rocnik = rocnik.rocnik
|
|
||||||
# self.radky = []
|
|
||||||
# self.cisla = []
|
|
||||||
#
|
|
||||||
# vysledkovka = Vysledkovka()
|
|
||||||
# vysledkovka.cisla = (rocnik.verejne_vysledkovky_cisla() if jen_verejne else rocnik.cisla.all().order_by('cislo'))
|
|
||||||
#
|
|
||||||
# # doplníme některé údaje do řádků výsledkovky pro řešitele ve skupině
|
|
||||||
# for poradi, v in zip(sloupec_s_poradim(vysledky), vysledky):
|
|
||||||
# v.poradi = poradi
|
|
||||||
# v.resitel.rocnik = v.resitel.rocnik(rocnik)
|
|
||||||
#
|
|
||||||
# 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)
|
|
||||||
#
|
|
||||||
# v.body_odjakziva = verejne_vysl_odjakziva.filter(resitel = v.resitel)[0].body
|
|
||||||
# v.titul = v.resitel.get_titul(v.body_odjakziva)
|
|
||||||
# v.body_rocnik = v.body
|
|
||||||
# v.body_cisla = []
|
|
||||||
#
|
|
||||||
# #pokud pro dany rok a cislo nema resitel vysledky, ma defaultne 0
|
|
||||||
# for cis in vysledkovka.cisla:
|
|
||||||
# if not jen_verejne or cis.verejna_vysledkovka:
|
|
||||||
# #seznam vysledku se spravnym rocnikem a cislem pro resitele
|
|
||||||
# #zobrazim jen je-li vysledkovka verejna
|
|
||||||
# body_za_cislo = VysledkyZaCislo.objects.filter(cislo__rocnik=rocnik).filter(cislo = cis).filter(resitel = v.resitel)
|
|
||||||
# if body_za_cislo:
|
|
||||||
# #neprazdne vysledky by mely obsahovat prave jeden vysledek
|
|
||||||
# v.body_cisla.append(body_za_cislo[0].body)
|
|
||||||
# else:
|
|
||||||
# #resitel nema za cislo body
|
|
||||||
# v.body_cisla.append(0)
|
|
||||||
#
|
|
||||||
# vysledkovka.radky.append(v)
|
|
||||||
#
|
|
||||||
# return vysledkovka
|
|
||||||
|
|
||||||
|
def __init__(self, poradi, resitel, body_cisla_sezn, body_rocnik, body_odjakziva, rok):
|
||||||
|
self.poradi = poradi
|
||||||
|
self.resitel = resitel
|
||||||
|
self.rocnik_resitele = resitel.rocnik(rok)
|
||||||
|
self.body_rocnik = body_rocnik
|
||||||
|
self.body_celkem_odjakziva = body_odjakziva
|
||||||
|
self.body_cisla_sezn = body_cisla_sezn
|
||||||
|
self.titul = resitel.get_titul(body_odjakziva)
|
||||||
|
|
||||||
|
def vysledkovka_rocniku(rocnik, jen_verejne=True):
|
||||||
|
"""Přebírá ročník (např. context["rocnik"]) a vrací výsledkovou listinu ve
|
||||||
|
formě vhodné pro šablonu "seminar/vysledkovka_rocniku.html"
|
||||||
|
"""
|
||||||
|
|
||||||
|
## TODO možná chytřeji vybírat aktivní řešitele
|
||||||
|
# aktivní řešitelé - chceme letos něco poslal, TODO později vyfiltrujeme ty, kdo mají
|
||||||
|
# u alespoň jedné hodnoty něco jiného než NULL
|
||||||
|
aktivni_resitele = list(Resitel.objects.filter(
|
||||||
|
rok_maturity__gte=rocnik.druhy_rok()))
|
||||||
|
# TODO: zkusit hodnoceni__rocnik...
|
||||||
|
#.filter(hodnoceni_set__rocnik__eq=cislo_rocnik)
|
||||||
|
cisla = cisla_rocniku(rocnik, jen_verejne)
|
||||||
|
body_cisla_slov = {}
|
||||||
|
print("Jen veřejná: {}, čísla: {}".format(jen_verejne, cisla))
|
||||||
|
for cislo in cisla:
|
||||||
|
# získáme body za číslo
|
||||||
|
_, cislobody = secti_body_za_cislo(cislo, aktivni_resitele)
|
||||||
|
body_cisla_slov[cislo.id] = cislobody
|
||||||
|
|
||||||
|
# získáme body za ročník, seznam obsahuje dvojice (řešitel_id, body) setřízené sestupně
|
||||||
|
resitel_rocnikbody_sezn = secti_body_za_rocnik(rocnik, aktivni_resitele)
|
||||||
|
|
||||||
|
# setřídíme řešitele podle počtu bodů a získáme seznam s body od nejvyšších po nenižší
|
||||||
|
setrizeni_resitele_id = [dvojice[0] for dvojice in resitel_rocnikbody_sezn]
|
||||||
|
setrizeni_resitele = [Resitel.objects.get(id=i) for i in setrizeni_resitele_id]
|
||||||
|
setrizene_body = [dvojice[1] for dvojice in resitel_rocnikbody_sezn]
|
||||||
|
poradi = sloupec_s_poradim(setrizene_body)
|
||||||
|
|
||||||
|
# získáme body odjakživa
|
||||||
|
resitel_odjakzivabody_slov = body_resitelu_odjakziva(rocnik, aktivni_resitele)
|
||||||
|
|
||||||
|
# vytvoříme jednotlivé sloupce výsledkovky
|
||||||
|
radky_vysledkovky = []
|
||||||
|
i = 0
|
||||||
|
for ar_id in setrizeni_resitele_id:
|
||||||
|
# seznam počtu bodů daného řešitele pro jednotlivá čísla
|
||||||
|
body_cisla_sezn = []
|
||||||
|
for cislo in cisla:
|
||||||
|
body_cisla_sezn.append(body_cisla_slov[cislo.id][ar_id])
|
||||||
|
|
||||||
|
# vytáhneme informace pro daného řešitele
|
||||||
|
radek = RadekVysledkovkyRocniku(
|
||||||
|
poradi[i], # pořadí
|
||||||
|
Resitel.objects.get(id=ar_id), # řešitel (z id)
|
||||||
|
body_cisla_sezn, # seznam bodů za čísla
|
||||||
|
setrizene_body[i], # body za ročník (spočítané výše s pořadím)
|
||||||
|
resitel_odjakzivabody_slov[ar_id], # body odjakživa
|
||||||
|
rocnik) # ročník semináře pro získání ročníku řešitele
|
||||||
|
print("{}: číslobody - {}, ročníkbody - {},"
|
||||||
|
"odjakživabody - {}".format(radek.resitel, radek.body_cisla_sezn,
|
||||||
|
radek.body_rocnik, radek.body_celkem_odjakziva))
|
||||||
|
radky_vysledkovky.append(radek)
|
||||||
|
print("Přikládám {}-tý řádek.".format(i))
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
return radky_vysledkovky
|
||||||
|
|
||||||
|
|
||||||
class RocnikView(generic.DetailView):
|
class RocnikView(generic.DetailView):
|
||||||
model = Rocnik
|
model = Rocnik
|
||||||
|
@ -626,10 +558,16 @@ class RocnikView(generic.DetailView):
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super(RocnikView, self).get_context_data(**kwargs)
|
context = super(RocnikView, self).get_context_data(**kwargs)
|
||||||
|
|
||||||
#context['vysledkovka'] = vysledkovka_rocniku(context["rocnik"])
|
# vysledkovka = True zajistí vykreslení,
|
||||||
#context['vysledkovka_s_neverejnymi'] = vysledkovka_rocniku(context["rocnik"], jen_verejne=False)
|
# zkontrolovat, kdy se má a nemá vykreslovat
|
||||||
#context['temata_v_rocniku'] = verejna_temata(context["rocnik"])
|
context['vysledkovka'] = True
|
||||||
# FIXME: opravit vylistování témat v ročníku
|
context['cisla_s_neverejnymi'] = cisla_rocniku(context["rocnik"], jen_verejne=False)
|
||||||
|
context['cisla'] = cisla_rocniku(context["rocnik"])
|
||||||
|
context['radky_vysledkovky'] = vysledkovka_rocniku(context["rocnik"])
|
||||||
|
context['radky_vysledkovky_s_neverejnymi'] = vysledkovka_rocniku(
|
||||||
|
context["rocnik"], jen_verejne=False)
|
||||||
|
context['hlavni_problemy_v_rocniku'] = hlavni_problemy_rocniku(context["rocnik"])
|
||||||
|
context['hlavni_problemy_v_rocniku_s_neverejnymi'] = hlavni_problemy_rocniku(context["rocnik"], jen_verejne=False)
|
||||||
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
@ -637,29 +575,36 @@ class RocnikView(generic.DetailView):
|
||||||
class ProblemView(generic.DetailView):
|
class ProblemView(generic.DetailView):
|
||||||
model = Problem
|
model = Problem
|
||||||
|
|
||||||
def _je_clanek(self, problem):
|
# Používáme funkci, protože přímo template_name neumí mít v přiřazení dost logiky. Ledaže by se to udělalo polymorfně...
|
||||||
return problem.typ in [Problem.TYP_ORG_CLANEK, Problem.TYP_RES_CLANEK]
|
|
||||||
|
|
||||||
def get_template_names(self, **kwargs):
|
def get_template_names(self, **kwargs):
|
||||||
context = super(ProblemView, self).get_context_data(**kwargs)
|
# FIXME: Switch podle typu není hezký, ale nechtělo se mi to přepisovat celé. Správně by se tohle mělo řešit polymorfismem.
|
||||||
return ['seminar/archiv/problem_' + ('clanek.html' if self._je_clanek(context['problem']) else 'uloha_tema.html')]
|
spravne_templaty = {
|
||||||
|
s.Uloha: "uloha",
|
||||||
|
s.Tema: "tema",
|
||||||
|
s.Konfera: "konfera",
|
||||||
|
s.Clanek: "clanek",
|
||||||
|
}
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
return ['seminar/archiv/problem_' + spravne_templaty[context['object'].__class__] + '.html']
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super(ProblemView, self).get_context_data(**kwargs)
|
context = super().get_context_data(**kwargs)
|
||||||
if not context['problem'].verejne() and not self.request.user.is_staff:
|
# Musí se používat context['object'], protože nevíme, jestli dostaneme úložku, téma, článek, .... a tyhle věci vyrábějí různé klíče.
|
||||||
|
if not context['object'].verejne() and not self.request.user.is_staff:
|
||||||
raise PermissionDenied()
|
raise PermissionDenied()
|
||||||
if context['problem'].typ == Problem.TYP_RES_CLANEK:
|
if isinstance(context['object'], Clanek):
|
||||||
context['reseni'] = Reseni.objects.filter(problem=context['problem']).select_related('resitel').order_by('resitel__prijmeni')
|
context['reseni'] = Reseni.objects.filter(problem=context['object']).select_related('resitel').order_by('resitel__prijmeni')
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
class RadekVysledkovky(object):
|
class RadekVysledkovkyCisla(object):
|
||||||
"""Obsahuje věci, které se hodí vědět při konstruování výsledkovky.
|
"""Obsahuje věci, které se hodí vědět při konstruování výsledkovky.
|
||||||
Umožňuje snazší práci v templatu (lepší, než seznam)."""
|
Umožňuje snazší práci v templatu (lepší, než seznam)."""
|
||||||
|
|
||||||
def __init__(self, poradi, resitel, body_problemy_sezn,
|
def __init__(self, poradi, resitel, body_problemy_sezn,
|
||||||
body_cislo, body_rocnik, body_odjakziva):
|
body_cislo, body_rocnik, body_odjakziva, rok):
|
||||||
self.resitel = resitel
|
self.resitel = resitel
|
||||||
|
self.rocnik_resitele = resitel.rocnik(rok)
|
||||||
self.body_cislo = body_cislo
|
self.body_cislo = body_cislo
|
||||||
self.body_rocnik = body_rocnik
|
self.body_rocnik = body_rocnik
|
||||||
self.body_celkem_odjakziva = body_odjakziva
|
self.body_celkem_odjakziva = body_odjakziva
|
||||||
|
@ -674,36 +619,39 @@ def pricti_body(slovnik, resitel, body):
|
||||||
# daného řešitele, předěláme na 0
|
# daného řešitele, předěláme na 0
|
||||||
# (v dalším kroku přičteme reálný počet bodů),
|
# (v dalším kroku přičteme reálný počet bodů),
|
||||||
# rozlišujeme tím mezi 0 a neodevzdaným řešením
|
# rozlišujeme tím mezi 0 a neodevzdaným řešením
|
||||||
if slovnik[str(resitel.id)] == "":
|
if slovnik[resitel.id] == "":
|
||||||
slovnik[str(resitel.id)] = 0
|
slovnik[resitel.id] = 0
|
||||||
|
|
||||||
slovnik[str(resitel.id)] += body
|
slovnik[resitel.id] += body
|
||||||
|
|
||||||
def secti_body_za_rocnik(cislo, aktivni_resitele):
|
def secti_body_za_rocnik(rocnik, aktivni_resitele):
|
||||||
# spočítáme všem řešitelům jejich body za ročník
|
# spočítáme všem řešitelům jejich body za ročník
|
||||||
resitel_rocnikbody_slov = body_resitelu_za_rocnik(cislo.rocnik, aktivni_resitele)
|
resitel_rocnikbody_slov = body_resitelu_za_rocnik(rocnik, aktivni_resitele)
|
||||||
# zeptáme se na dvojice (řešitel, body) za ročník a setřídíme sestupně
|
# zeptáme se na dvojice (řešitel, body) za ročník a setřídíme sestupně
|
||||||
resitel_rocnikbody_sezn = sorted(resitel_rocnikbody_slov.items(),
|
resitel_rocnikbody_sezn = sorted(resitel_rocnikbody_slov.items(),
|
||||||
key = lambda x: x[1], reverse = True)
|
key = lambda x: x[1], reverse = True)
|
||||||
return resitel_rocnikbody_sezn
|
return resitel_rocnikbody_sezn
|
||||||
|
|
||||||
# spočítá u řešitelů body za číslo a za jednotlivé hlavní problémy (témata)
|
# spočítá u řešitelů body za číslo a za jednotlivé hlavní problémy (témata)
|
||||||
def secti_body_za_cislo(cislo, aktivni_resitele, hlavni_problemy):
|
def secti_body_za_cislo(cislo, aktivni_resitele, hlavni_problemy=None):
|
||||||
# TODO setřídit hlavní problémy čísla podle id, ať jsou ve stejném pořadí pokaždé
|
# TODO setřídit hlavní problémy čísla podle id, ať jsou ve stejném pořadí pokaždé
|
||||||
# pro každý hlavní problém zavedeme slovník s body za daný hlavní problém
|
# pro každý hlavní problém zavedeme slovník s body za daný hlavní problém
|
||||||
# pro jednotlivé řešitele (slovník slovníků hlavních problémů)
|
# pro jednotlivé řešitele (slovník slovníků hlavních problémů)
|
||||||
|
if hlavni_problemy is None:
|
||||||
|
hlavni_problemy = hlavni_problemy_cisla(cislo)
|
||||||
|
|
||||||
hlavni_problemy_slovnik = {}
|
hlavni_problemy_slovnik = {}
|
||||||
for hp in hlavni_problemy:
|
for hp in hlavni_problemy:
|
||||||
hlavni_problemy_slovnik[str(hp.id)] = {}
|
hlavni_problemy_slovnik[hp.id] = {}
|
||||||
|
|
||||||
# zakládání prázdných záznamů pro řešitele
|
# zakládání prázdných záznamů pro řešitele
|
||||||
cislobody = {}
|
cislobody = {}
|
||||||
for ar in aktivni_resitele:
|
for ar in aktivni_resitele:
|
||||||
# řešitele převedeme na řetězec pomocí unikátního id
|
# řešitele převedeme na řetězec pomocí unikátního id
|
||||||
cislobody[str(ar.id)] = ""
|
cislobody[ar.id] = ""
|
||||||
for hp in hlavni_problemy:
|
for hp in hlavni_problemy:
|
||||||
slovnik = hlavni_problemy_slovnik[str(hp.id)]
|
slovnik = hlavni_problemy_slovnik[hp.id]
|
||||||
slovnik[str(ar.id)] = ""
|
slovnik[ar.id] = ""
|
||||||
|
|
||||||
# vezmeme všechna řešení s body do daného čísla
|
# vezmeme všechna řešení s body do daného čísla
|
||||||
reseni_do_cisla = Reseni.objects.prefetch_related('problem', 'resitele',
|
reseni_do_cisla = Reseni.objects.prefetch_related('problem', 'resitele',
|
||||||
|
@ -716,7 +664,7 @@ def secti_body_za_cislo(cislo, aktivni_resitele, hlavni_problemy):
|
||||||
# řešení může řešit více problémů
|
# řešení může řešit více problémů
|
||||||
for prob in list(reseni.problem.all()):
|
for prob in list(reseni.problem.all()):
|
||||||
nadproblem = hlavni_problem(prob)
|
nadproblem = hlavni_problem(prob)
|
||||||
nadproblem_slovnik = hlavni_problemy_slovnik[str(nadproblem.id)]
|
nadproblem_slovnik = hlavni_problemy_slovnik[nadproblem.id]
|
||||||
|
|
||||||
# a mít více hodnocení
|
# a mít více hodnocení
|
||||||
for hodn in list(reseni.hodnoceni_set.all()):
|
for hodn in list(reseni.hodnoceni_set.all()):
|
||||||
|
@ -727,14 +675,12 @@ def secti_body_za_cislo(cislo, aktivni_resitele, hlavni_problemy):
|
||||||
pricti_body(cislobody, resitel, body)
|
pricti_body(cislobody, resitel, body)
|
||||||
pricti_body(nadproblem_slovnik, resitel, body)
|
pricti_body(nadproblem_slovnik, resitel, body)
|
||||||
return hlavni_problemy_slovnik, cislobody
|
return hlavni_problemy_slovnik, cislobody
|
||||||
|
|
||||||
|
|
||||||
def spocti_vysledkovku_cisla(cislo, context=None):
|
def vysledkovka_cisla(cislo, context=None):
|
||||||
if context is None:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
|
|
||||||
hlavni_problemy = hlavni_problemy_cisla(cislo)
|
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
|
## TODO možná chytřeji vybírat aktivní řešitele
|
||||||
# aktivní řešitelé - chceme letos něco poslal, TODO později vyfiltrujeme ty, kdo mají
|
# aktivní řešitelé - chceme letos něco poslal, TODO později vyfiltrujeme ty, kdo mají
|
||||||
# u alespoň jedné hodnoty něco jiného než NULL
|
# u alespoň jedné hodnoty něco jiného než NULL
|
||||||
|
@ -747,10 +693,10 @@ def spocti_vysledkovku_cisla(cislo, context=None):
|
||||||
hlavni_problemy_slovnik, cislobody = secti_body_za_cislo(cislo, aktivni_resitele, hlavni_problemy)
|
hlavni_problemy_slovnik, cislobody = secti_body_za_cislo(cislo, aktivni_resitele, hlavni_problemy)
|
||||||
|
|
||||||
# získáme body za ročník, seznam obsahuje dvojice (řešitel_id, body) setřízené sestupně
|
# získáme body za ročník, seznam obsahuje dvojice (řešitel_id, body) setřízené sestupně
|
||||||
resitel_rocnikbody_sezn = secti_body_za_rocnik(cislo, aktivni_resitele)
|
resitel_rocnikbody_sezn = secti_body_za_rocnik(cislo.rocnik, aktivni_resitele)
|
||||||
|
|
||||||
# získáme body odjakživa
|
# získáme body odjakživa
|
||||||
resitel_odjakzivabody_slov = body_resitelu_odjakziva(cislo.rocnik.druhy_rok(),
|
resitel_odjakzivabody_slov = body_resitelu_odjakziva(cislo.rocnik,
|
||||||
aktivni_resitele)
|
aktivni_resitele)
|
||||||
|
|
||||||
# řešitelé setřídění podle bodů za číslo sestupně
|
# řešitelé setřídění podle bodů za číslo sestupně
|
||||||
|
@ -768,22 +714,22 @@ def spocti_vysledkovku_cisla(cislo, context=None):
|
||||||
# získáme seznam bodů za problémy pro daného řešitele
|
# získáme seznam bodů za problémy pro daného řešitele
|
||||||
problemy = []
|
problemy = []
|
||||||
for hp in hlavni_problemy:
|
for hp in hlavni_problemy:
|
||||||
problemy.append(hlavni_problemy_slovnik[str(hp.id)][ar_id])
|
problemy.append(hlavni_problemy_slovnik[hp.id][ar_id])
|
||||||
# vytáhneme informace pro daného řešitele
|
# vytáhneme informace pro daného řešitele
|
||||||
radek = RadekVysledkovky(
|
radek = RadekVysledkovkyCisla(
|
||||||
poradi[i], # pořadí
|
poradi[i], # pořadí
|
||||||
Resitel.objects.get(id=ar_id), # řešitel (z id)
|
Resitel.objects.get(id=ar_id), # řešitel (z id)
|
||||||
problemy, # seznam bodů za hlavní problémy čísla
|
problemy, # seznam bodů za hlavní problémy čísla
|
||||||
cislobody[ar_id], # body za číslo
|
cislobody[ar_id], # body za číslo
|
||||||
setrizeni_resitele_body[i], # body za ročník (spočítané výše s pořadím)
|
setrizeni_resitele_body[i], # body za ročník (spočítané výše s pořadím)
|
||||||
resitel_odjakzivabody_slov[ar_id]) # body odjakživa
|
resitel_odjakzivabody_slov[ar_id], # body odjakživa
|
||||||
|
cislo.rocnik) # ročník semináře pro zjištění ročníku řešitele
|
||||||
print("{}: body za problémy - {}, číslobody - {}, ročníkbody - {}, odjakživabody - {}".format(radek.resitel,
|
print("{}: body za problémy - {}, číslobody - {}, ročníkbody - {}, odjakživabody - {}".format(radek.resitel,
|
||||||
radek.body_problemy_sezn, radek.body_cislo, radek.body_rocnik, radek.body_celkem_odjakziva))
|
radek.body_problemy_sezn, radek.body_cislo, radek.body_rocnik, radek.body_celkem_odjakziva))
|
||||||
radky_vysledkovky.append(radek)
|
radky_vysledkovky.append(radek)
|
||||||
print("Přikládám {}-tý řádek.".format(i))
|
print("Přikládám {}-tý řádek.".format(i))
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
print("Následuje předávání do kontextu.")
|
|
||||||
# vytahané informace předáváme do kontextu
|
# vytahané informace předáváme do kontextu
|
||||||
context['cislo'] = cislo
|
context['cislo'] = cislo
|
||||||
context['radky_vysledkovky'] = radky_vysledkovky
|
context['radky_vysledkovky'] = radky_vysledkovky
|
||||||
|
@ -817,45 +763,8 @@ class CisloView(generic.DetailView):
|
||||||
|
|
||||||
cislo = context['cislo']
|
cislo = context['cislo']
|
||||||
# vrátíme context (aktuálně obsahuje jen věci ohledně výsledkovky
|
# vrátíme context (aktuálně obsahuje jen věci ohledně výsledkovky
|
||||||
return spocti_vysledkovku_cisla(cislo, context)
|
return vysledkovka_cisla(cislo, 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
|
|
||||||
# problem_index = {}
|
|
||||||
# for i in range(len(problemy)):
|
|
||||||
# #umoznuje zjistit index podle id problemu
|
|
||||||
#
|
|
||||||
# vysledky_resitele = {}
|
|
||||||
# vysledkovka = []
|
|
||||||
#
|
|
||||||
# # doplníme některé údaje do řádků výsledkovky pro řešitele ve skupině
|
|
||||||
# for poradi, v in zip(sloupec_s_poradim(vysledky), vysledky):
|
|
||||||
# v.poradi = poradi
|
|
||||||
# v.body_celkem_rocnik = v.body
|
|
||||||
# v.body_celkem_odjakziva = VysledkyKCisluOdjakziva.objects.get(resitel=v.resitel, cislo=context['cislo']).body
|
|
||||||
# v.resitel.rocnik = v.resitel.rocnik(v.cislo.rocnik)
|
|
||||||
#
|
|
||||||
# # je tady '', aby se nezobrazovala 0, pokud se řešitel o řešení úlohy ani nepokusil
|
|
||||||
# v.body_ulohy = [''] * len(problemy)
|
|
||||||
#
|
|
||||||
# v.titul = v.resitel.get_titul(v.body_celkem_odjakziva)
|
|
||||||
#
|
|
||||||
# body_cislo_q = VysledkyZaCislo.objects.filter(resitel=v.resitel, cislo=context['cislo'])
|
|
||||||
# v.body_cislo = body_cislo_q[0].body if body_cislo_q else 0
|
|
||||||
#
|
|
||||||
# vysledkovka.append(v)
|
|
||||||
#
|
|
||||||
# # připravíme si odkaz na řádek, abychom do něj mohli doplnit body za jednotlivé úlohy
|
|
||||||
# vysledky_resitele[v.resitel.id] = v
|
|
||||||
#
|
|
||||||
# # za každé řešení doplníme k příslušnému řešiteli a úloze body
|
|
||||||
# for r in reseni:
|
|
||||||
# vysledky_resitele[r.resitel.id].body_ulohy[problem_index[r.problem.id]] = r.body
|
|
||||||
#
|
|
||||||
# context['vysledkovka'] = vysledkovka
|
|
||||||
# context['problemy'] = problemy
|
|
||||||
# context['v_cisle_zadane'] = v_cisle_zadane
|
|
||||||
# context['resene_problemy'] = resene_problemy
|
|
||||||
|
|
||||||
class ArchivTemataView(generic.ListView):
|
class ArchivTemataView(generic.ListView):
|
||||||
model = Problem
|
model = Problem
|
||||||
|
@ -864,25 +773,24 @@ class ArchivTemataView(generic.ListView):
|
||||||
|
|
||||||
### Generovani vysledkovky
|
### Generovani vysledkovky
|
||||||
|
|
||||||
#class CisloVysledkovkaView(CisloView):i
|
class CisloVysledkovkaView(CisloView):
|
||||||
# poradi | titul. jmeno prijmeni | ulohy | za cislo | celkem | odjakziva
|
"View vytvořené pro stránku zobrazující výsledkovku čísla v TeXu."
|
||||||
#
|
|
||||||
#
|
model = Cislo
|
||||||
#
|
template_name = 'seminar/archiv/cislo_vysledkovka.tex'
|
||||||
# model = Cislo
|
#content_type = 'application/x-tex; charset=UTF8'
|
||||||
# template_name = 'seminar/archiv/cislo_vysledkovka.tex'
|
#umozni rovnou stahnout TeXovsky dokument
|
||||||
# #content_type = 'application/x-tex; charset=UTF8'
|
content_type = 'text/plain; charset=UTF8'
|
||||||
# #umozni rovnou stahnout TeXovsky dokument
|
#vypise na stranku textovy obsah vyTeXane vysledkovky k okopirovani
|
||||||
# content_type = 'text/plain; charset=UTF8'
|
|
||||||
# #vypise na stranku textovy obsah vyTeXane vysledkovky k okopirovani
|
class RocnikVysledkovkaView(RocnikView):
|
||||||
#
|
"View vytvořené pro stránku zobrazující výsledkovku ročníku v TeXu."
|
||||||
#class RocnikVysledkovkaView(RocnikView):
|
model = Rocnik
|
||||||
# model = Rocnik
|
template_name = 'seminar/archiv/rocnik_vysledkovka.tex'
|
||||||
# template_name = 'seminar/archiv/rocnik_vysledkovka.tex'
|
#content_type = 'application/x-tex; charset=UTF8'
|
||||||
# #content_type = 'application/x-tex; charset=UTF8'
|
#umozni rovnou stahnout TeXovsky dokument
|
||||||
# #umozni rovnou stahnout TeXovsky dokument
|
content_type = 'text/plain; charset=UTF8'
|
||||||
# content_type = 'text/plain; charset=UTF8'
|
#vypise na stranku textovy obsah vyTeXane vysledkovky k okopirovani
|
||||||
# #vypise na stranku textovy obsah vyTeXane vysledkovky k okopirovani
|
|
||||||
|
|
||||||
### Generovani obalek
|
### Generovani obalek
|
||||||
class CisloObalkyStruct:
|
class CisloObalkyStruct:
|
||||||
|
@ -961,30 +869,31 @@ def oldObalkovaniView(request, rocnik, cislo):
|
||||||
|
|
||||||
### Tituly
|
### Tituly
|
||||||
|
|
||||||
# TODO udelat neco jako get_objects_or_404
|
def TitulyView(request, rocnik, cislo):
|
||||||
# FIXME: prepsat, aby nepouzivalo VysledkyK...
|
rocnik_obj = Rocnik.objects.get(rocnik = rocnik)
|
||||||
#def TitulyView(request, rocnik, cislo):
|
resitele = Resitel.objects.filter(rok_maturity__gte = rocnik_obj.prvni_rok)
|
||||||
# rocnik_obj = Rocnik.objects.get(rocnik = rocnik)
|
cislo_obj = Cislo.objects.get(rocnik = rocnik_obj, poradi = cislo)
|
||||||
# resitele = Resitel.objects.filter(rok_maturity__gte = rocnik_obj.prvni_rok)
|
|
||||||
# cislo_obj = Cislo.objects.get(rocnik = rocnik_obj, cislo = cislo)
|
asciijmena = []
|
||||||
#
|
jmenovci = False # detekuje, zda jsou dva řešitelé jmenovci (modulo nabodeníčka), pokud ano, vrátí se jako true
|
||||||
# asciijmena = []
|
slovnik_s_body = body_resitelu_odjakziva(rocnik_obj, resitele)
|
||||||
# broken = False
|
|
||||||
#
|
for resitel in resitele:
|
||||||
# for resitel in resitele:
|
resitel.titul = resitel.get_titul(slovnik_s_body[resitel.id])
|
||||||
# try:
|
jmeno = resitel.osoba.jmeno+resitel.osoba.prijmeni
|
||||||
# vys = VysledkyKCisluOdjakziva.objects.get(resitel = resitel, cislo = cislo_obj)
|
# převedeme jména a příjmení řešitelů do ASCII
|
||||||
# body = vys.body
|
ascii_jmeno_bytes = unicodedata.normalize('NFKD', jmeno).encode("ascii","ignore")
|
||||||
# except ObjectDoesNotExist:
|
# vrátí se byte string, převedeme na standardní string
|
||||||
# body = 0
|
ascii_jmeno_divnoznaky = str(ascii_jmeno_bytes, "utf-8", "ignore").replace(" ","")
|
||||||
# resitel.titul = resitel.get_titul(body)
|
resitel.ascii = ''.join(a for a in ascii_jmeno_divnoznaky if a.isalnum())
|
||||||
# resitel.ascii = unicodedata.normalize('NFKD',resitel.jmeno+resitel.prijmeni).encode("ascii","ignore").replace(" ","")
|
if resitel.ascii not in asciijmena:
|
||||||
# if resitel.ascii not in asciijmena:
|
asciijmena.append(resitel.ascii)
|
||||||
# asciijmena.append(resitel.ascii)
|
else:
|
||||||
# else:
|
jmenovci = True
|
||||||
# broken = True
|
|
||||||
#
|
return render(request, 'seminar/archiv/tituly.tex',
|
||||||
# return render(request, 'seminar/archiv/tituly.tex',{'resitele': resitele,'broken':broken},content_type="text/plain")
|
{'resitele': resitele,'jmenovci':jmenovci},content_type="text/plain")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Soustredeni
|
### Soustredeni
|
||||||
|
|
Loading…
Reference in a new issue