Merge branch 'opraf' of atrey.karlin.mff.cuni.cz:/akce/MaM/MaMweb/mamweb into opraf
This commit is contained in:
commit
80a38c26be
24 changed files with 505 additions and 252 deletions
|
@ -3,6 +3,9 @@
|
||||||
from galerie.models import Obrazek, Galerie
|
from galerie.models import Obrazek, Galerie
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponseRedirect
|
||||||
|
from django import forms
|
||||||
|
from django.db import models
|
||||||
|
import autocomplete_light
|
||||||
|
|
||||||
# akction
|
# akction
|
||||||
|
|
||||||
|
@ -27,17 +30,25 @@ def prepnout_fotogalerii_do_org_rezimu(modeladmin, request, queryset):
|
||||||
'Přepnout do režimu úprav (zneveřejní galerii)'
|
'Přepnout do režimu úprav (zneveřejní galerii)'
|
||||||
|
|
||||||
class GalerieInline(admin.TabularInline):
|
class GalerieInline(admin.TabularInline):
|
||||||
model = Obrazek
|
model = Obrazek
|
||||||
|
fields = ['obrazek_velky', 'nazev', 'popis', 'obrazek_maly_tag']
|
||||||
|
readonly_fields = ['nazev', 'obrazek_maly_tag']
|
||||||
|
formfield_overrides = {
|
||||||
|
models.TextField: {'widget': forms.TextInput},
|
||||||
|
}
|
||||||
|
|
||||||
class ObrazekAdmin(admin.ModelAdmin):
|
class ObrazekAdmin(admin.ModelAdmin):
|
||||||
list_display = ('obrazek_velky', 'nazev', 'popis')
|
list_display = ('obrazek_velky', 'nazev', 'popis', 'obrazek_maly_tag')
|
||||||
|
|
||||||
class GalerieAdmin(admin.ModelAdmin):
|
class GalerieAdmin(admin.ModelAdmin):
|
||||||
model = Galerie
|
form = autocomplete_light.modelform_factory(Galerie, autocomplete_fields=['titulni_obrazek'], fields=['titulni_obrazek'])
|
||||||
fields = ('zobrazit', 'nazev', 'titulni_obrazek', 'popis', 'galerie_up', 'soustredeni', 'poradi')
|
model = Galerie
|
||||||
list_display = ('nazev', 'pk', 'datum_zmeny', 'zobrazit', 'soustredeni')
|
fields = ('zobrazit', 'nazev', 'titulni_obrazek', 'popis', 'galerie_up', 'soustredeni', 'poradi')
|
||||||
inlines = [GalerieInline]
|
list_display = ('nazev', 'pk', 'poradi', 'datum_zmeny', 'zobrazit', 'soustredeni')
|
||||||
actions = [zverejnit_fotogalerii, prepnout_fotogalerii_do_org_rezimu]
|
inlines = [GalerieInline]
|
||||||
|
actions = [zverejnit_fotogalerii, prepnout_fotogalerii_do_org_rezimu]
|
||||||
|
save_on_top = True
|
||||||
|
ordering = ['galerie_up__nazev', 'poradi']
|
||||||
|
|
||||||
admin.site.register(Obrazek, ObrazekAdmin)
|
admin.site.register(Obrazek, ObrazekAdmin)
|
||||||
admin.site.register(Galerie, GalerieAdmin)
|
admin.site.register(Galerie, GalerieAdmin)
|
||||||
|
|
49
galerie/autocomplete_light_registry.py
Normal file
49
galerie/autocomplete_light_registry.py
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import autocomplete_light
|
||||||
|
|
||||||
|
from models import Obrazek, Galerie
|
||||||
|
from views import cesta_od_korene
|
||||||
|
|
||||||
|
|
||||||
|
class ObrazekAutocomplete(autocomplete_light.AutocompleteModelBase):
|
||||||
|
|
||||||
|
model = Obrazek
|
||||||
|
search_fields = ['nazev', 'popis']
|
||||||
|
split_words = True
|
||||||
|
limit_choices = 15
|
||||||
|
attrs = {
|
||||||
|
# This will set the input placeholder attribute:
|
||||||
|
'placeholder': u'Obrázek',
|
||||||
|
# This will set the yourlabs.Autocomplete.minimumCharacters
|
||||||
|
# options, the naming conversion is handled by jQuery
|
||||||
|
'data-autocomplete-minimum-characters': 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
choice_html_format = '''
|
||||||
|
<span class="block" data-value="{}">
|
||||||
|
<span class="block">
|
||||||
|
{}
|
||||||
|
<span class="block">{}</span>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
'''
|
||||||
|
|
||||||
|
def choice_label(self, obrazek):
|
||||||
|
cesta = "/".join(g.nazev for g in cesta_od_korene(obrazek.galerie))
|
||||||
|
popis = "{}<br>".format(obrazek.popis) if obrazek.popis else ""
|
||||||
|
return '{}<br>{}{}'.format(obrazek.nazev, popis, cesta)
|
||||||
|
|
||||||
|
def choice_html(self, obrazek):
|
||||||
|
"""Vrátí kus html i s obrázkem, které se pak ukazuje v nabídce"""
|
||||||
|
return self.choice_html_format.format(self.choice_value(obrazek),
|
||||||
|
obrazek.obrazek_maly_tag(), self.choice_label(obrazek))
|
||||||
|
|
||||||
|
widget_attrs={
|
||||||
|
'data-widget-maximum-values': 15,
|
||||||
|
'class': 'modern-style',
|
||||||
|
}
|
||||||
|
|
||||||
|
autocomplete_light.register(ObrazekAutocomplete)
|
22
galerie/migrations/0007_obrazek_odstranen_datum.py
Normal file
22
galerie/migrations/0007_obrazek_odstranen_datum.py
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import models, migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('galerie', '0006_django_imagekit'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='obrazek',
|
||||||
|
options={'ordering': ['nazev'], 'verbose_name': 'Obr\xe1zek', 'verbose_name_plural': 'Obr\xe1zky'},
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='obrazek',
|
||||||
|
name='datum',
|
||||||
|
),
|
||||||
|
]
|
|
@ -1,19 +1,12 @@
|
||||||
# coding: utf-8
|
# coding: utf-8
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
import seminar.models
|
#from django.db.models import Q
|
||||||
from django.db.models import Q
|
|
||||||
from django.utils import timezone
|
|
||||||
from django.utils.encoding import force_unicode
|
from django.utils.encoding import force_unicode
|
||||||
from imagekit.models import ImageSpecField
|
from imagekit.models import ImageSpecField
|
||||||
from imagekit.processors import ResizeToFit, Transpose
|
from imagekit.processors import ResizeToFit, Transpose
|
||||||
|
|
||||||
from PIL import Image
|
|
||||||
from PIL.ExifTags import TAGS
|
|
||||||
import os
|
import os
|
||||||
from cStringIO import StringIO
|
|
||||||
from django.core.files.base import ContentFile
|
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
from seminar.models import Soustredeni
|
from seminar.models import Soustredeni
|
||||||
|
|
||||||
|
@ -26,14 +19,6 @@ VIDITELNOST = (
|
||||||
(NIKDY, 'Nikdy'),
|
(NIKDY, 'Nikdy'),
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_exif(fn):
|
|
||||||
ret = {}
|
|
||||||
info = fn._getexif()
|
|
||||||
for tag, value in info.items():
|
|
||||||
decoded = TAGS.get(tag, tag)
|
|
||||||
ret[decoded] = value
|
|
||||||
return ret
|
|
||||||
|
|
||||||
# tyhle funkce jsou tady jen kvůli starým migracím, které se na ně odkazují
|
# tyhle funkce jsou tady jen kvůli starým migracím, které se na ně odkazují
|
||||||
# až se ty migrace někdy squashnou, tak by mělo být možné funkce smazat
|
# až se ty migrace někdy squashnou, tak by mělo být možné funkce smazat
|
||||||
def obrazek_filename_maly():
|
def obrazek_filename_maly():
|
||||||
|
@ -46,40 +31,55 @@ def obrazek_filename_velky():
|
||||||
def obrazek_filename(self, filename):
|
def obrazek_filename(self, filename):
|
||||||
gal = self.galerie
|
gal = self.galerie
|
||||||
cislo_gal = force_unicode(gal.pk)
|
cislo_gal = force_unicode(gal.pk)
|
||||||
cesta = ""
|
|
||||||
while(not gal.soustredeni):
|
# najdi kořenovou galerii
|
||||||
|
while (gal.galerie_up):
|
||||||
gal = gal.galerie_up
|
gal = gal.galerie_up
|
||||||
return os.path.join('Galerie', "soustredeni_" + force_unicode(gal.soustredeni.pk), "galerie_" + cislo_gal, "velky", force_unicode(self.nazev))
|
|
||||||
|
# soustředění je v cestě jen pokud galerie pod nějaké patří
|
||||||
|
cesta = (
|
||||||
|
['Galerie'] +
|
||||||
|
(["soustredeni_" + force_unicode(gal.soustredeni.pk)] if gal.soustredeni else []) +
|
||||||
|
["galerie_" + cislo_gal, force_unicode(self.nazev)]
|
||||||
|
)
|
||||||
|
|
||||||
|
return os.path.join(*cesta)
|
||||||
|
|
||||||
class Obrazek(models.Model):
|
class Obrazek(models.Model):
|
||||||
obrazek_velky = models.ImageField(upload_to=obrazek_filename,
|
obrazek_velky = models.ImageField(upload_to=obrazek_filename,
|
||||||
help_text = "Lze vložit libovolně velký obrázek. Ideální je, aby alespoň jeden rozměr měl alespoň 500px.")
|
help_text = "Lze vložit libovolně velký obrázek. Ideální je, aby alespoň jeden rozměr měl alespoň 500px.")
|
||||||
obrazek_stredni = ImageSpecField(source='obrazek_velky',
|
obrazek_stredni = ImageSpecField(source='obrazek_velky',
|
||||||
processors=[Transpose(Transpose.AUTO), ResizeToFit(900, 675, upscale=False)],
|
processors=[Transpose(Transpose.AUTO), ResizeToFit(900, 675, upscale=False)],
|
||||||
options={'quality': 95})
|
options={'quality': 95})
|
||||||
obrazek_maly = ImageSpecField(source='obrazek_velky',
|
obrazek_maly = ImageSpecField(source='obrazek_velky',
|
||||||
processors=[Transpose(Transpose.AUTO), ResizeToFit(167, 167, upscale=False)],
|
processors=[Transpose(Transpose.AUTO), ResizeToFit(167, 167, upscale=False)],
|
||||||
options={'quality': 95})
|
options={'quality': 95})
|
||||||
nazev = models.CharField('Název', max_length=50, blank = True, null = True)
|
nazev = models.CharField('Název', max_length=50, blank=True, null=True)
|
||||||
popis = models.TextField('Popis', blank = True, null = True)
|
popis = models.TextField('Popis', blank=True, null=True)
|
||||||
datum_vlozeni = models.DateTimeField('Datum vložení', auto_now_add = True)
|
datum_vlozeni = models.DateTimeField('Datum vložení', auto_now_add=True)
|
||||||
datum = models.DateTimeField('Datum pořízení fotografie', blank = True, null = True)
|
galerie = models.ForeignKey('Galerie', blank=True, null=True)
|
||||||
galerie = models.ForeignKey('Galerie', blank=True, null=True)
|
poradi = models.IntegerField('Pořadí', blank=True, null=True)
|
||||||
poradi = models.IntegerField('Pořadí', blank = True, null = True)
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return self.nazev + " -- " + unicode(self.obrazek_velky.name) + " (" + str(self.datum) + ")"
|
return unicode(self.obrazek_velky.name)
|
||||||
class Meta:
|
|
||||||
verbose_name = 'Obrázek'
|
class Meta:
|
||||||
verbose_name_plural = 'Obrázky'
|
verbose_name = 'Obrázek'
|
||||||
ordering = ['datum']
|
verbose_name_plural = 'Obrázky'
|
||||||
def save(self):
|
ordering = ['nazev']
|
||||||
original = Image.open(self.obrazek_velky)
|
|
||||||
# vycteni EXIFu
|
def obrazek_maly_tag(self):
|
||||||
exif = get_exif(original)
|
return u'<img src="{}">'.format(self.obrazek_maly.url)
|
||||||
if exif['DateTimeOriginal']:
|
obrazek_maly_tag.short_description = "Náhled"
|
||||||
datum_ints = map(int, ":".join(exif['DateTimeOriginal'].split(' ')).split(":"))
|
obrazek_maly_tag.allow_tags = True
|
||||||
self.datum = datetime(*datum_ints)
|
|
||||||
super(Obrazek, self).save()
|
def save(self, *args, **kwargs):
|
||||||
|
# obrázek potřebuje název, protože se z něj generuje cesta pro jeho uložení
|
||||||
|
# (a pak se podle něj taky řadí)
|
||||||
|
if self.nazev is None:
|
||||||
|
self.nazev = os.path.basename(self.obrazek_velky.name)
|
||||||
|
super(Obrazek, self).save(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Galerie(models.Model):
|
class Galerie(models.Model):
|
||||||
|
|
|
@ -6,6 +6,10 @@ Galerie {{galerie.nazev}}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
|
{% if galerie.zobrazit > 0 %}
|
||||||
|
<div class="mam-org-only">
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
<h2>
|
<h2>
|
||||||
{% for g in cesta %}
|
{% for g in cesta %}
|
||||||
{% if not forloop.last %}
|
{% if not forloop.last %}
|
||||||
|
@ -19,7 +23,7 @@ Galerie {{galerie.nazev}}
|
||||||
{% if not obrazky %}
|
{% if not obrazky %}
|
||||||
<div class="galerie_hlavicka">
|
<div class="galerie_hlavicka">
|
||||||
{% if galerie.titulni_obrazek %}
|
{% if galerie.titulni_obrazek %}
|
||||||
<img src="{{ galerie.titulni_obrazek.obrazek_stredni.url }}" style="border: 1px solid black;">
|
<img src="{{ galerie.titulni_obrazek.obrazek_stredni.url }}" class="titulni_obrazek">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -39,18 +43,22 @@ Galerie {{galerie.nazev}}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if podgalerie %}
|
{% if podgalerie %}
|
||||||
|
{% with 22 as max_delka_nazvu %}
|
||||||
<div class="galerie_nahledy">
|
<div class="galerie_nahledy">
|
||||||
{% for galerie in podgalerie %}
|
{% for galerie in podgalerie %}
|
||||||
<a href="../{{galerie.pk}}" class="podgalerie_nahled">
|
<a href="../{{galerie.pk}}"
|
||||||
|
{% if galerie.nazev|length > max_delka_nazvu %}
|
||||||
|
title="{{ galerie.nazev }}"
|
||||||
|
{% endif %}
|
||||||
|
class="podgalerie_nahled">
|
||||||
{% if galerie.titulni_obrazek %}
|
{% if galerie.titulni_obrazek %}
|
||||||
{% with galerie.titulni_obrazek.obrazek_maly as obrazek %}
|
{% with galerie.titulni_obrazek.obrazek_maly as obrazek %}
|
||||||
<img src="{{ obrazek.url }}"
|
<img src="{{ obrazek.url }}"
|
||||||
width="{{ obrazek.width }}"
|
/>
|
||||||
height="{{ obrazek.height }}" />
|
{% endwith %}
|
||||||
{% endwith %}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div>
|
<div class="nazev_galerie">
|
||||||
{{ galerie }}
|
{{ galerie|truncatechars:max_delka_nazvu }}
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
{% if user.is_staff and galerie.zobrazit > 0 %}
|
{% if user.is_staff and galerie.zobrazit > 0 %}
|
||||||
|
@ -62,6 +70,7 @@ Galerie {{galerie.nazev}}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
{% endwith %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if user.is_staff and galerie.zobrazit > 0 %}
|
{% if user.is_staff and galerie.zobrazit > 0 %}
|
||||||
|
@ -74,8 +83,15 @@ Galerie {{galerie.nazev}}
|
||||||
{% if obrazky %}
|
{% if obrazky %}
|
||||||
<div class="galerie_nahledy">
|
<div class="galerie_nahledy">
|
||||||
{% for obrazek in obrazky %}
|
{% for obrazek in obrazky %}
|
||||||
<a title="Zobrazit tuto fotografii" href="./{{obrazek.pk}}#nahoru" class="galerie_nahled"><span class="vystredeno"></span><img
|
<a
|
||||||
|
{% if obrazek.popis %}
|
||||||
|
title="{{ obrazek.popis }}"
|
||||||
|
{% endif %}
|
||||||
|
href="./{{obrazek.pk}}#nahoru" class="galerie_nahled"><span class="vystredeno"></span><img
|
||||||
src="{{obrazek.obrazek_maly.url}}"
|
src="{{obrazek.obrazek_maly.url}}"
|
||||||
|
{% if obrazek.popis %}
|
||||||
|
title="{{ obrazek.popis }}"
|
||||||
|
{% endif %}
|
||||||
width="{{ obrazek.obrazek_maly.width }}"
|
width="{{ obrazek.obrazek_maly.width }}"
|
||||||
height="{{ obrazek.obrazek_maly.height }}" />
|
height="{{ obrazek.obrazek_maly.height }}" />
|
||||||
</a>
|
</a>
|
||||||
|
@ -103,4 +119,9 @@ Galerie {{galerie.nazev}}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
{% if galerie.zobrazit > 0 %}
|
||||||
|
</div> {# mam-org-only #}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|
|
@ -38,7 +38,7 @@ def nahled(request, pk, soustredeni):
|
||||||
if not request.user.is_staff:
|
if not request.user.is_staff:
|
||||||
podgalerie = podgalerie.filter(zobrazit__lt=1)
|
podgalerie = podgalerie.filter(zobrazit__lt=1)
|
||||||
|
|
||||||
obrazky = Obrazek.objects.filter(galerie = galerie).order_by('datum')
|
obrazky = Obrazek.objects.filter(galerie = galerie)
|
||||||
preview = zobrazit(galerie, request)
|
preview = zobrazit(galerie, request)
|
||||||
|
|
||||||
sourozenci = []
|
sourozenci = []
|
||||||
|
@ -82,7 +82,7 @@ def detail(request, pk, fotka, soustredeni):
|
||||||
galerie = get_object_or_404(Galerie, pk=pk)
|
galerie = get_object_or_404(Galerie, pk=pk)
|
||||||
preview = zobrazit(galerie, request)
|
preview = zobrazit(galerie, request)
|
||||||
obrazek = get_object_or_404(Obrazek, pk=fotka)
|
obrazek = get_object_or_404(Obrazek, pk=fotka)
|
||||||
obrazky = galerie.obrazek_set.all().order_by('datum')
|
obrazky = galerie.obrazek_set.all()
|
||||||
|
|
||||||
# vytvoreni a obslouzeni formulare
|
# vytvoreni a obslouzeni formulare
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
{% block title %} Nápověda ke korigovátku {% endblock title %}
|
{% block title %} Nápověda ke korigovátku {% endblock title %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<link rel="stylesheet" type="text/css" media="screen, projection" href="{% static "korektury/opraf.css"%}" />
|
|
||||||
<h1> Nápověda ke korigovátku</h1>
|
<h1> Nápověda ke korigovátku</h1>
|
||||||
<p> Korigovátko slouží ke korigování PDF souborů. Umožňuje přidávat a komentovat
|
<p> Korigovátko slouží ke korigování PDF souborů. Umožňuje přidávat a komentovat
|
||||||
korektury a označovat je jako zanesené / irelevantní. Rovněž umožňuje o PDF
|
korektury a označovat je jako zanesené / irelevantní. Rovněž umožňuje o PDF
|
||||||
|
@ -32,17 +31,17 @@ původní korekturou.
|
||||||
<h2> Stavy </h2>
|
<h2> Stavy </h2>
|
||||||
<h3> Korektura </h3>
|
<h3> Korektura </h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li> <span class="box"> K opravě </span>- zadaná, čeká na zanesení / zahození
|
<li> K opravě - zadaná, čeká na zanesení / zahození
|
||||||
<li> <span class="box-done">Zanesená</span> - zanesená v TeXu
|
<li> Zanesená - zanesená v TeXu
|
||||||
<li> <span class="box-wontfix">Irelevantní</span> - není to chyba, nebude zanesena
|
<li> Irelevantní - není to chyba, nebude zanesena
|
||||||
<li> K reakci - vyžaduje reakci od autora <i>(zatím není
|
<li> K reakci - vyžaduje reakci od autora <i>(zatím není
|
||||||
implementováno)</i>
|
implementováno)</i>
|
||||||
</ul>
|
</ul>
|
||||||
<h3> PDF </h3>
|
<h3> PDF </h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li><span class="adding"> Přidávání </span> - šedé pozadí - probíhá přidávání korektur
|
<li> Přidávání - probíhá přidávání korektur
|
||||||
<li><span class="comitting"> Zanášení </span>- probíhá zanášení korektur do TeXu
|
<li> Zanášení - probíhá zanášení korektur do TeXu
|
||||||
<li><span class="deprecated"> Zastaralé </span> - PDF je zastaralé, nepřidávat nové korektury
|
<li> Zastaralé - PDF je zastaralé, nepřidávat nové korektury
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|
|
@ -161,6 +161,7 @@ CKEDITOR_IMAGE_BACKEND = 'pillow'
|
||||||
#CKEDITOR_JQUERY_URL = '//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js'
|
#CKEDITOR_JQUERY_URL = '//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js'
|
||||||
CKEDITOR_CONFIGS = {
|
CKEDITOR_CONFIGS = {
|
||||||
'default': {
|
'default': {
|
||||||
|
'entities': False,
|
||||||
'toolbar': [
|
'toolbar': [
|
||||||
['Source', 'ShowBlocks', '-', 'Maximize'],
|
['Source', 'ShowBlocks', '-', 'Maximize'],
|
||||||
['Bold', 'Italic', 'Subscript', 'Superscript', '-', 'RemoveFormat'],
|
['Bold', 'Italic', 'Subscript', 'Superscript', '-', 'RemoveFormat'],
|
||||||
|
@ -241,12 +242,3 @@ LOGGING = {
|
||||||
SEMINAR_RESENI_DIR = os.path.join(BASE_DIR, 'media', 'reseni')
|
SEMINAR_RESENI_DIR = os.path.join(BASE_DIR, 'media', 'reseni')
|
||||||
KOREKTURY_PDF_DIR = os.path.join(BASE_DIR, 'media', 'korektury','pdf')
|
KOREKTURY_PDF_DIR = os.path.join(BASE_DIR, 'media', 'korektury','pdf')
|
||||||
KOREKTURY_IMG_DIR = os.path.join(BASE_DIR, 'media', 'korektury','img')
|
KOREKTURY_IMG_DIR = os.path.join(BASE_DIR, 'media', 'korektury','img')
|
||||||
|
|
||||||
|
|
||||||
CKEDITOR_CONFIGS = {
|
|
||||||
'default': {
|
|
||||||
'entities': False
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,15 @@ body {
|
||||||
border: orange 2px dashed;
|
border: orange 2px dashed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mam-org-only .mam-org-only {
|
||||||
|
border: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
li.mam-org-only {
|
||||||
|
padding: 3px 0px;
|
||||||
|
margin: -2px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
table .border-r {
|
table .border-r {
|
||||||
border-right: solid 1px;
|
border-right: solid 1px;
|
||||||
}
|
}
|
||||||
|
@ -446,7 +455,8 @@ div.zadani_azad_termin {
|
||||||
/* galerie */
|
/* galerie */
|
||||||
|
|
||||||
/* velká fotka */
|
/* velká fotka */
|
||||||
.galerie .obrazek {
|
/* zmenšování spolu s oknem prohlížeče */
|
||||||
|
.galerie .obrazek, .titulni_obrazek {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
height: auto;
|
height: auto;
|
||||||
width: auto\9; /* ie8 */
|
width: auto\9; /* ie8 */
|
||||||
|
@ -482,7 +492,6 @@ div.zadani_azad_termin {
|
||||||
.galerie {
|
.galerie {
|
||||||
position: relative;
|
position: relative;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
/*width: 100%;*/
|
|
||||||
margin: 20px auto 0 auto;
|
margin: 20px auto 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -503,6 +512,11 @@ div.zadani_azad_termin {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* titulní obrázek hlavní galerie soustředění */
|
||||||
|
.titulni_obrazek {
|
||||||
|
border: 1px solid black;
|
||||||
|
}
|
||||||
|
|
||||||
.galerie_nahledy{
|
.galerie_nahledy{
|
||||||
/*margin: 1em 0;*/
|
/*margin: 1em 0;*/
|
||||||
margin: 0 auto 30px auto;
|
margin: 0 auto 30px auto;
|
||||||
|
@ -599,6 +613,14 @@ div.zadani_azad_termin {
|
||||||
.podgalerie_nahled img {
|
.podgalerie_nahled img {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
|
max-height: 125px;
|
||||||
|
max-width: 167px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.podgalerie_nahled .nazev_galerie {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
top: 160px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* plus a minus tlacitka */
|
/* plus a minus tlacitka */
|
||||||
|
|
|
@ -22,6 +22,10 @@
|
||||||
{% with "jak-resit" as selected %}
|
{% with "jak-resit" as selected %}
|
||||||
{% include "seminar/cojemam/submenu.html" %}
|
{% include "seminar/cojemam/submenu.html" %}
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
|
{% elif "odmeny" in flatpage.url %}
|
||||||
|
{% with "odmeny" as selected %}
|
||||||
|
{% include "seminar/cojemam/submenu.html" %}
|
||||||
|
{% endwith %}
|
||||||
{% elif "FAQ" in flatpage.url %}
|
{% elif "FAQ" in flatpage.url %}
|
||||||
{% with "FAQ" as selected %}
|
{% with "FAQ" as selected %}
|
||||||
{% include "seminar/cojemam/submenu.html" %}
|
{% include "seminar/cojemam/submenu.html" %}
|
||||||
|
|
|
@ -11,7 +11,7 @@ from django.db import models
|
||||||
|
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
|
|
||||||
from seminar.models import Skola, Resitel, Rocnik, Cislo, Problem, Reseni, PrilohaReseni, Nastaveni, Soustredeni, Soustredeni_Ucastnici, Novinky, Organizator
|
from seminar.models import Skola, Resitel, Rocnik, Cislo, Problem, Reseni, PrilohaReseni, Nastaveni, Soustredeni, Soustredeni_Ucastnici, Soustredeni_Organizatori, Novinky, Organizator
|
||||||
import autocomplete_light
|
import autocomplete_light
|
||||||
|
|
||||||
|
|
||||||
|
@ -163,6 +163,19 @@ class Soustredeni_UcastniciInline(admin.TabularInline):
|
||||||
qs = super(Soustredeni_UcastniciInline, self).get_queryset(request)
|
qs = super(Soustredeni_UcastniciInline, self).get_queryset(request)
|
||||||
return qs.select_related('resitel', 'soustredeni')
|
return qs.select_related('resitel', 'soustredeni')
|
||||||
|
|
||||||
|
class Soustredeni_OrganizatoriInline(admin.TabularInline):
|
||||||
|
form = autocomplete_light.modelform_factory(Soustredeni_Organizatori, autocomplete_fields=['organizator'], fields=['organizator'],)
|
||||||
|
model = Soustredeni_Organizatori
|
||||||
|
fields = ['organizator', 'poznamka', ]
|
||||||
|
extra = 0
|
||||||
|
formfield_overrides = {
|
||||||
|
models.TextField: {'widget': forms.TextInput},
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_queryset(self, request):
|
||||||
|
qs = super(Soustredeni_OrganizatoriInline, self).get_queryset(request)
|
||||||
|
return qs.select_related('organizator', 'soustredeni')
|
||||||
|
|
||||||
### Resitel
|
### Resitel
|
||||||
|
|
||||||
class ResitelAdmin(VersionAdmin):
|
class ResitelAdmin(VersionAdmin):
|
||||||
|
@ -334,7 +347,7 @@ create_modeladmin(ProblemNavrhAdmin, Problem, 'ProblemNavrh', verbose_name=u'Pro
|
||||||
|
|
||||||
class ProblemZadanyAdmin(ProblemAdmin):
|
class ProblemZadanyAdmin(ProblemAdmin):
|
||||||
list_display = ['nazev', 'typ', 'autor', 'opravovatel', 'kod', 'cislo_zadani', 'pocet_reseni', 'verejne']
|
list_display = ['nazev', 'typ', 'autor', 'opravovatel', 'kod', 'cislo_zadani', 'pocet_reseni', 'verejne']
|
||||||
list_filter = ['typ', 'cislo_zadani__cislo', 'cislo_zadani__rocnik']
|
list_filter = ['typ', 'zamereni', 'cislo_zadani__cislo', 'cislo_zadani__rocnik']
|
||||||
inlines = [ReseniKProblemuInline]
|
inlines = [ReseniKProblemuInline]
|
||||||
|
|
||||||
def get_queryset(self, request):
|
def get_queryset(self, request):
|
||||||
|
@ -362,7 +375,7 @@ class SoustredeniAdmin(VersionAdmin):
|
||||||
(u'Data', {'fields': ['datum_zacatku', 'datum_konce']}),
|
(u'Data', {'fields': ['datum_zacatku', 'datum_konce']}),
|
||||||
]
|
]
|
||||||
list_display = ['rocnik', 'misto', 'datum_zacatku', 'typ', 'exportovat', 'verejne']
|
list_display = ['rocnik', 'misto', 'datum_zacatku', 'typ', 'exportovat', 'verejne']
|
||||||
inlines = [Soustredeni_UcastniciInline]
|
inlines = [Soustredeni_UcastniciInline, Soustredeni_OrganizatoriInline]
|
||||||
list_filter = ['typ', 'rocnik']
|
list_filter = ['typ', 'rocnik']
|
||||||
view_on_site = Soustredeni.verejne_url
|
view_on_site = Soustredeni.verejne_url
|
||||||
actions = [
|
actions = [
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
import autocomplete_light
|
import autocomplete_light
|
||||||
|
|
||||||
from models import Skola, Resitel, Problem
|
from models import Skola, Resitel, Problem, Organizator
|
||||||
from taggit.models import Tag
|
from taggit.models import Tag
|
||||||
|
|
||||||
|
|
||||||
|
@ -64,6 +64,38 @@ class ResitelAutocomplete(autocomplete_light.AutocompleteModelBase):
|
||||||
|
|
||||||
autocomplete_light.register(ResitelAutocomplete)
|
autocomplete_light.register(ResitelAutocomplete)
|
||||||
|
|
||||||
|
class OrganizatorAutocomplete(autocomplete_light.AutocompleteModelBase):
|
||||||
|
|
||||||
|
model = Organizator
|
||||||
|
|
||||||
|
search_fields=['user__first_name', 'user__last_name', 'prezdivka']
|
||||||
|
|
||||||
|
split_words = False
|
||||||
|
|
||||||
|
limit_choices = 15
|
||||||
|
|
||||||
|
def choice_label(self, organizator):
|
||||||
|
return u"%s '%s' %s" % (organizator.user.first_name,
|
||||||
|
organizator.prezdivka,
|
||||||
|
organizator.user.last_name)
|
||||||
|
|
||||||
|
attrs={
|
||||||
|
# This will set the input placeholder attribute:
|
||||||
|
'placeholder': u'Organizátor',
|
||||||
|
# This will set the yourlabs.Autocomplete.minimumCharacters
|
||||||
|
# options, the naming conversion is handled by jQuery
|
||||||
|
'data-autocomplete-minimum-characters': 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
widget_attrs={
|
||||||
|
'data-widget-maximum-values': 15,
|
||||||
|
# Enable modern-style widget !
|
||||||
|
'class': 'modern-style',
|
||||||
|
}
|
||||||
|
|
||||||
|
autocomplete_light.register(OrganizatorAutocomplete)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ProblemAutocomplete(autocomplete_light.AutocompleteModelBase):
|
class ProblemAutocomplete(autocomplete_light.AutocompleteModelBase):
|
||||||
|
|
||||||
|
|
36
seminar/migrations/0036_add_org_to_soustredeni.py
Normal file
36
seminar/migrations/0036_add_org_to_soustredeni.py
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import models, migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('seminar', '0035_django_imagekit'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Soustredeni_Organizatori',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(serialize=False, primary_key=True)),
|
||||||
|
('poznamka', models.TextField(help_text='Neve\u0159ejn\xe1 pozn\xe1mka k \xfa\u010dasti organiz\xe1tora (plain text)', verbose_name='neve\u0159ejn\xe1 pozn\xe1mka', blank=True)),
|
||||||
|
('organizator', models.ForeignKey(verbose_name='organiz\xe1tor', to='seminar.Organizator')),
|
||||||
|
('soustredeni', models.ForeignKey(verbose_name='soust\u0159ed\u011bn\xed', to='seminar.Soustredeni')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'ordering': ['soustredeni', 'organizator'],
|
||||||
|
'db_table': 'seminar_soustredeni_organizatori',
|
||||||
|
'verbose_name': '\xda\u010dast organiz\xe1tor\u016f na soust\u0159ed\u011bn\xed',
|
||||||
|
'verbose_name_plural': '\xda\u010dasti organiz\xe1tor\u016f na soust\u0159ed\u011bn\xed',
|
||||||
|
},
|
||||||
|
bases=(models.Model,),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='soustredeni',
|
||||||
|
name='organizatori',
|
||||||
|
field=models.ManyToManyField(help_text='Seznam organiz\xe1tor\u016f soust\u0159ed\u011bn\xed', to='seminar.Organizator', verbose_name='Organiz\xe1to\u0159i soust\u0159ed\u011bn\xed', through='seminar.Soustredeni_Organizatori'),
|
||||||
|
preserve_default=True,
|
||||||
|
),
|
||||||
|
]
|
|
@ -185,6 +185,9 @@ class Resitel(SeminarModelBase):
|
||||||
def plne_jmeno(self):
|
def plne_jmeno(self):
|
||||||
return force_unicode(u'%s %s' % (self.jmeno, self.prijmeni))
|
return force_unicode(u'%s %s' % (self.jmeno, self.prijmeni))
|
||||||
|
|
||||||
|
def inicial_krestni(self):
|
||||||
|
return force_unicode(u'%s.' % (self.jmeno[0]))
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return force_unicode(self.plne_jmeno())
|
return force_unicode(self.plne_jmeno())
|
||||||
|
|
||||||
|
@ -576,6 +579,51 @@ class PrilohaReseni(SeminarModelBase):
|
||||||
return force_unicode(self.soubor)
|
return force_unicode(self.soubor)
|
||||||
|
|
||||||
|
|
||||||
|
@reversion.register(ignore_duplicate_revisions=True)
|
||||||
|
@python_2_unicode_compatible
|
||||||
|
class Organizator(models.Model):
|
||||||
|
user = models.OneToOneField(settings.AUTH_USER_MODEL, verbose_name='Osoba',
|
||||||
|
help_text = 'Vyber účet spřažený s organizátorem.')
|
||||||
|
prezdivka = models.CharField('Přezdívka', max_length = 32,
|
||||||
|
null = True, blank = True)
|
||||||
|
organizuje_od_roku = models.IntegerField('Organizuje od roku',
|
||||||
|
null = True, blank = True)
|
||||||
|
organizuje_do_roku = models.IntegerField('Organizuje do roku',
|
||||||
|
null = True, blank = True)
|
||||||
|
studuje = models.CharField('Studium aj.', max_length = 256,
|
||||||
|
null = True, blank = True,
|
||||||
|
help_text="Např. 'Studuje Obecnou fyziku (Bc.), 3. ročník', "
|
||||||
|
"'Vystudovala Diskrétní modely a algoritmy (Mgr.)' nebo "
|
||||||
|
"'Přednáší na MFF'")
|
||||||
|
strucny_popis_organizatora = models.TextField('Stručný popis organizátora',
|
||||||
|
null = True, blank = True)
|
||||||
|
foto = ProcessedImageField(verbose_name='Fotografie organizátora',
|
||||||
|
upload_to='image_organizatori/velke/%Y/', null = True, blank = True,
|
||||||
|
help_text = 'Vlož fotografii organizátora o libovolné velikosti',
|
||||||
|
processors=[
|
||||||
|
Transpose(Transpose.AUTO),
|
||||||
|
ResizeToFit(500, 500, upscale=False)
|
||||||
|
],
|
||||||
|
options={'quality': 95})
|
||||||
|
foto_male = ImageSpecField(source='foto',
|
||||||
|
processors=[
|
||||||
|
ResizeToFit(200, 200, upscale=False)
|
||||||
|
],
|
||||||
|
options={'quality': 95})
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
if self.prezdivka:
|
||||||
|
return u"%s '%s' %s" % (self.user.first_name,
|
||||||
|
self.prezdivka,
|
||||||
|
self.user.last_name)
|
||||||
|
else:
|
||||||
|
return u"%s %s" % (self.user.first_name, self.user.last_name)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = 'Organizátor'
|
||||||
|
verbose_name_plural = 'Organizátoři'
|
||||||
|
|
||||||
|
|
||||||
@reversion.register(ignore_duplicate_revisions=True)
|
@reversion.register(ignore_duplicate_revisions=True)
|
||||||
@python_2_unicode_compatible
|
@python_2_unicode_compatible
|
||||||
class Soustredeni(SeminarModelBase):
|
class Soustredeni(SeminarModelBase):
|
||||||
|
@ -605,6 +653,11 @@ class Soustredeni(SeminarModelBase):
|
||||||
ucastnici = models.ManyToManyField(Resitel, verbose_name=u'účastníci soustředění',
|
ucastnici = models.ManyToManyField(Resitel, verbose_name=u'účastníci soustředění',
|
||||||
help_text=u'Seznam účastníků soustředění', through='Soustredeni_Ucastnici')
|
help_text=u'Seznam účastníků soustředění', through='Soustredeni_Ucastnici')
|
||||||
|
|
||||||
|
organizatori = models.ManyToManyField(Organizator,
|
||||||
|
verbose_name=u'Organizátoři soustředění',
|
||||||
|
help_text=u'Seznam organizátorů soustředění',
|
||||||
|
through='Soustredeni_Organizatori')
|
||||||
|
|
||||||
text = models.TextField(u'text k soustředění (HTML)', blank=True, default='')
|
text = models.TextField(u'text k soustředění (HTML)', blank=True, default='')
|
||||||
|
|
||||||
TYP_JARNI = 'jarni'
|
TYP_JARNI = 'jarni'
|
||||||
|
@ -656,6 +709,30 @@ class Soustredeni_Ucastnici(models.Model):
|
||||||
return force_unicode(u'%s na %s' % (self.resitel, self.soustredeni, ))
|
return force_unicode(u'%s na %s' % (self.resitel, self.soustredeni, ))
|
||||||
# NOTE: Poteciální DB HOG bez select_related
|
# NOTE: Poteciální DB HOG bez select_related
|
||||||
|
|
||||||
|
@reversion.register(ignore_duplicate_revisions=True)
|
||||||
|
@python_2_unicode_compatible
|
||||||
|
class Soustredeni_Organizatori(models.Model):
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
db_table = 'seminar_soustredeni_organizatori'
|
||||||
|
verbose_name = u'Účast organizátorů na soustředění'
|
||||||
|
verbose_name_plural = u'Účasti organizátorů na soustředění'
|
||||||
|
ordering = ['soustredeni', 'organizator']
|
||||||
|
|
||||||
|
# Interní ID
|
||||||
|
id = models.AutoField(primary_key = True)
|
||||||
|
|
||||||
|
organizator = models.ForeignKey(Organizator, verbose_name=u'organizátor')
|
||||||
|
|
||||||
|
soustredeni = models.ForeignKey(Soustredeni, verbose_name=u'soustředění')
|
||||||
|
|
||||||
|
poznamka = models.TextField(u'neveřejná poznámka', blank=True,
|
||||||
|
help_text=u'Neveřejná poznámka k účasti organizátora (plain text)')
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return force_unicode(u'%s na %s' % (self.organizator, self.soustredeni, ))
|
||||||
|
# NOTE: Poteciální DB HOG bez select_related
|
||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
@python_2_unicode_compatible
|
||||||
class VysledkyBase(SeminarModelBase):
|
class VysledkyBase(SeminarModelBase):
|
||||||
|
@ -775,41 +852,3 @@ class Novinky(models.Model):
|
||||||
verbose_name_plural = 'Novinky'
|
verbose_name_plural = 'Novinky'
|
||||||
|
|
||||||
|
|
||||||
@reversion.register(ignore_duplicate_revisions=True)
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class Organizator(models.Model):
|
|
||||||
user = models.OneToOneField(settings.AUTH_USER_MODEL, verbose_name='Osoba',
|
|
||||||
help_text = 'Vyber účet spřažený s organizátorem.')
|
|
||||||
prezdivka = models.CharField('Přezdívka', max_length = 32,
|
|
||||||
null = True, blank = True)
|
|
||||||
organizuje_od_roku = models.IntegerField('Organizuje od roku',
|
|
||||||
null = True, blank = True)
|
|
||||||
organizuje_do_roku = models.IntegerField('Organizuje do roku',
|
|
||||||
null = True, blank = True)
|
|
||||||
studuje = models.CharField('Studium aj.', max_length = 256,
|
|
||||||
null = True, blank = True,
|
|
||||||
help_text="Např. 'Studuje Obecnou fyziku (Bc.), 3. ročník', "
|
|
||||||
"'Vystudovala Diskrétní modely a algoritmy (Mgr.)' nebo "
|
|
||||||
"'Přednáší na MFF'")
|
|
||||||
strucny_popis_organizatora = models.TextField('Stručný popis organizátora',
|
|
||||||
null = True, blank = True)
|
|
||||||
foto = ProcessedImageField(verbose_name='Fotografie organizátora',
|
|
||||||
upload_to='image_organizatori/velke/%Y/', null = True, blank = True,
|
|
||||||
help_text = 'Vlož fotografii organizátora o libovolné velikosti',
|
|
||||||
processors=[
|
|
||||||
Transpose(Transpose.AUTO),
|
|
||||||
ResizeToFit(500, 500, upscale=False)
|
|
||||||
],
|
|
||||||
options={'quality': 95})
|
|
||||||
foto_male = ImageSpecField(source='foto',
|
|
||||||
processors=[
|
|
||||||
ResizeToFit(200, 200, upscale=False)
|
|
||||||
],
|
|
||||||
options={'quality': 95})
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return str(self.user)
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
verbose_name = 'Organizátor'
|
|
||||||
verbose_name_plural = 'Organizátoři'
|
|
||||||
|
|
|
@ -27,6 +27,16 @@
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
{% if user.is_staff %}
|
||||||
|
<div class="mam-org-only">
|
||||||
|
<h3> Orgovské odkazy </h3>
|
||||||
|
<ul>
|
||||||
|
<li><a href="obalky.pdf">Obálky (PDF)</a></li>
|
||||||
|
<li><a href="tituly.tex">Tituly (TeX)</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% if cislo.verejna_vysledkovka %}
|
{% if cislo.verejna_vysledkovka %}
|
||||||
<h3>Výsledkovka</h3>
|
<h3>Výsledkovka</h3>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|
|
@ -1,33 +1,9 @@
|
||||||
\begin{longtable}{r|l|c|l|c
|
\setlength{\tabcolsep}{3pt}
|
||||||
{% for p in problemy %}
|
\begin{longtable}{|r|l|c|r|{% for p in problemy %}c@{\hskip.5em}{% endfor %}|r|r|}\hline
|
||||||
@\hskip.5em}c {% endfor %}
|
& & & & \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
|
||||||
|c|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 }} } &
|
|
||||||
{% else %}
|
|
||||||
\textbf{ t{{ p.kod }} } &
|
|
||||||
{% endif %}
|
|
||||||
{% 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 vysledkovka %}
|
|
||||||
{{ rv.poradi }} &
|
|
||||||
{% if rv.resitel.titul %}
|
|
||||||
\titul{ {{ rv.titul }} }
|
|
||||||
{% endif %}
|
|
||||||
{{ rv.resitel.plne_jmeno }} & {{ rv.resitel.rocnik |default:"" }} & {{ rv.body_minule }}
|
|
||||||
{% for b in rv.body %}
|
|
||||||
{{ b }} &
|
|
||||||
{% endfor %}
|
|
||||||
{{ rv.body_celkem_rocnik |default:0 }} & {{ rv.body_celkem_minule }} \\
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
\end{longtable}
|
\end{longtable}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
{% load comments %}
|
{% load comments %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div>
|
<div {% if not problem.verejne and user.is_staff %}class="mam-org-only"{% endif %}>
|
||||||
{% block problem %}
|
{% block problem %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
|
@ -8,14 +8,10 @@
|
||||||
</h2>
|
</h2>
|
||||||
{% if problem.cislo_zadani %}
|
{% if problem.cislo_zadani %}
|
||||||
<p>Zadáno v čísle <a href='{{ problem.cislo_zadani.verejne_url }}'>{{ problem.cislo_zadani.kod }}</a>.
|
<p>Zadáno v čísle <a href='{{ problem.cislo_zadani.verejne_url }}'>{{ problem.cislo_zadani.kod }}</a>.
|
||||||
{% if problem.cislo_reseni %}
|
|
||||||
<p>Řešeno v čísle <a href='{{ problem.cislo_reseni.verejne_url }}'>{{ problem.cislo_reseni.kod }}</a>.
|
|
||||||
{% endif %}
|
|
||||||
{% else %}
|
|
||||||
{# TODO ? #}
|
|
||||||
<h2>Problém {{ problem.nazev }}</h2>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if problem.cislo_reseni %}
|
||||||
|
<p>Řešeno v čísle <a href='{{ problem.cislo_reseni.verejne_url }}'>{{ problem.cislo_reseni.kod }}</a>.
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
<h3>Zadání</h3>
|
<h3>Zadání</h3>
|
||||||
{{ problem.text_zadani |safe }}
|
{{ problem.text_zadani |safe }}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
<ul>
|
<ul>
|
||||||
<li class="{% if selected == "uvod" %}selected{% endif %}"><a href="{{cesta}}/uvod/">Úvod</a>
|
<li class="{% if selected == "uvod" %}selected{% endif %}"><a href="{{cesta}}/uvod/">Úvod</a>
|
||||||
<li class="{% if selected == "jak-resit" %}selected{% endif %}"><a href="{{cesta}}/jak-resit/">Jak řešit</a>
|
<li class="{% if selected == "jak-resit" %}selected{% endif %}"><a href="{{cesta}}/jak-resit/">Jak řešit</a>
|
||||||
|
<li class="{% if selected == "odmeny" %}selected{% endif %}"><a href="{{cesta}}/odmeny/">Odměny</a>
|
||||||
<li class="{% if selected == "org" %}selected{% endif %}"><a href="{{cesta}}/organizatori/">Organizátoři</a>
|
<li class="{% if selected == "org" %}selected{% endif %}"><a href="{{cesta}}/organizatori/">Organizátoři</a>
|
||||||
<li class="{% if selected == "FAQ" %}selected{% endif %}"><a href="{{cesta}}/FAQ/">Často kladené dotazy</a>
|
<li class="{% if selected == "FAQ" %}selected{% endif %}"><a href="{{cesta}}/FAQ/">Často kladené dotazy</a>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -21,61 +21,72 @@
|
||||||
{# Projdi vsechna soustredeni #}
|
{# Projdi vsechna soustredeni #}
|
||||||
{% for soustredeni in object_list %}
|
{% for soustredeni in object_list %}
|
||||||
{# Kdyz je verejne -> zobraz #}
|
{# Kdyz je verejne -> zobraz #}
|
||||||
{% if soustredeni.verejne_db or user.is_authenticated %}
|
{% if soustredeni.verejne_db or user.is_staff %}
|
||||||
{% if not soustredeni.verejne_db and user.is_authenticated %}
|
{% if not soustredeni.verejne_db and user.is_staff %}
|
||||||
Groups of user: {{user.groups.all}} <br>
|
<div class="mam-org-only">
|
||||||
<!-- TODO pri prihlasovani ucastniku dodelat prava
|
<!--Groups of user: {{user.groups.all}} <br>-->
|
||||||
jen na group org ve view -->
|
|
||||||
Toto soustředění není veřejné, vidíte ho jen proto,
|
|
||||||
že jste přihlášení. <br>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{# misto soustredeni TODO upravit#}
|
{# misto soustredeni TODO upravit#}
|
||||||
<h2>
|
<h2>
|
||||||
{{soustredeni.get_typ_display}}
|
{{soustredeni.get_typ_display}}
|
||||||
{{soustredeni.misto}}
|
{{soustredeni.misto}}
|
||||||
</h2>
|
</h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
|
||||||
{{soustredeni.datum_zacatku}} – {{soustredeni.datum_konce}}
|
|
||||||
</li>
|
|
||||||
{# Zobrazeni odkazu na galerie #}
|
|
||||||
{% if soustredeni.galerie_set.all %}
|
|
||||||
{% for galerie in soustredeni.galerie_set.all %}
|
|
||||||
{% if galerie.zobrazit == 0 or user.is_staff %}
|
|
||||||
<li>
|
<li>
|
||||||
<a href="../{{soustredeni.pk}}/fotogalerie/{{galerie.pk}}">Fotogalerie</a>
|
{{soustredeni.datum_zacatku}} – {{soustredeni.datum_konce}}
|
||||||
{# TODO kdyz je titulni obrazek, tak asi i titulni obrazek #}
|
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{# Zobrazeni odkazu na galerie #}
|
||||||
{% endfor %}
|
{% if soustredeni.galerie_set.all %}
|
||||||
{% endif %}
|
{% for galerie in soustredeni.galerie_set.all %}
|
||||||
</ul>
|
{% if galerie.zobrazit == 0 or user.is_staff %}
|
||||||
{% if user.is_staff %}
|
<li {% if galerie.zobrazit > 0 and user.is_staff %}class="mam-org-only"{% endif %}>
|
||||||
<div class="mam-org-only">
|
<a href="../{{soustredeni.pk}}/fotogalerie/{{galerie.pk}}">Fotogalerie</a>
|
||||||
<a href="../{{soustredeni.pk}}/fotogalerie/0/new/">Vytvořit novou fotogalerii</a><br>
|
{# TODO kdyz je titulni obrazek, tak asi i titulni obrazek #}
|
||||||
<a href="../{{soustredeni.pk}}/obalky.pdf">Vygenerovat obálky pro účastníky</a>
|
</li>
|
||||||
</div>
|
{% endif %}
|
||||||
{% endif %}
|
{% endfor %}
|
||||||
|
|
||||||
|
|
||||||
{# popis soustredeni #}
|
|
||||||
{% if soustredeni.text %}
|
|
||||||
{% autoescape off %}{{soustredeni.text}}{% endautoescape %}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
</ul>
|
||||||
|
{% if user.is_staff %}
|
||||||
|
<div class="mam-org-only">
|
||||||
|
<a href="../{{soustredeni.pk}}/fotogalerie/0/new/">Vytvořit novou fotogalerii</a><br>
|
||||||
|
<a href="../{{soustredeni.pk}}/obalky.pdf">Vygenerovat obálky pro účastníky</a>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
{# popis soustredeni #}
|
||||||
|
{% if soustredeni.text %}
|
||||||
|
{% autoescape off %}{{soustredeni.text}}{% endautoescape %}
|
||||||
|
{% endif %}
|
||||||
{% if user.is_authenticated %}
|
{% if user.is_authenticated %}
|
||||||
|
<div class="mam-org-only">
|
||||||
{# Účastníci #}
|
{# Účastníci #}
|
||||||
<h3>Soustředění se zúčastnili tito účastníci:</h3>
|
<h3>Soustředění se zúčastnili tito účastníci:</h3>
|
||||||
<ul>
|
<p>
|
||||||
{% for i in soustredeni.soustredeni_ucastnici_set.all %}
|
{% for i in soustredeni.soustredeni_ucastnici_set.all %}
|
||||||
<li>{{i.resitel}}
|
{{i.resitel}}{% if forloop.last %}.{% else %},{% endif %}
|
||||||
{% empty %}
|
{% empty %}
|
||||||
<li>Nic!
|
Nic!
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</p>
|
||||||
|
<h3>Soustředění se účastnili tito organizátoři:</h3>
|
||||||
|
<p>
|
||||||
|
{% for i in soustredeni.soustredeni_organizatori_set.all %}
|
||||||
|
{{i.organizator}}{% if forloop.last %}.{% else %},{% endif %}
|
||||||
|
{% empty %}
|
||||||
|
Nic!
|
||||||
|
{% endfor %}
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% if not soustredeni.verejne_db and user.is_staff %}
|
||||||
|
</div> {# class="mam-org-only" #}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% empty %}
|
{% empty %}
|
||||||
Žádná soustředění zatím neproběhla!
|
Žádná soustředění zatím neproběhla!
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -22,23 +22,9 @@ M&M je korespondeční seminář. Několikrát do roka zdarma vydáváme ča
|
||||||
<div class="odpocet">
|
<div class="odpocet">
|
||||||
<p><b>Do konce <a href="https://mam.mff.cuni.cz/zadani/aktualni/">odeslání řešení</a> zbývá:<br>
|
<p><b>Do konce <a href="https://mam.mff.cuni.cz/zadani/aktualni/">odeslání řešení</a> zbývá:<br>
|
||||||
<big>{{ted|timesince:dead}}</big></b></p>
|
<big>{{ted|timesince:dead}}</big></b></p>
|
||||||
|
|
||||||
|
|
||||||
<!--
|
|
||||||
{{cas_do_konce_dni}} dní
|
|
||||||
{% if cas_do_konce_dni < 5 %}
|
|
||||||
{{cas_do_konce_hodin}} hodin
|
|
||||||
{% if cas_do_konce_hodin < 5 %}
|
|
||||||
{{cas_do_konce_minut}} minut
|
|
||||||
{% if cas_do_konce_minut < 5 %}
|
|
||||||
{{cas_do_konce_sekund}}
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
-->
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{# Novinky #}
|
{# Novinky #}
|
||||||
<h2>Novinky</h2>
|
<h2>Novinky</h2>
|
||||||
{% include 'seminar/novinky.html' %}
|
{% include 'seminar/novinky.html' %}
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
{% if vysledkovka %}
|
{% if vysledkovka %}
|
||||||
{% include "seminar/vysledkovka_rocnik.html" %}
|
{% include "seminar/vysledkovka_rocnik.html" %}
|
||||||
{% else %}
|
{% else %}
|
||||||
V tomto ročníku zatím žádné výsledky nejsou
|
V tomto ročníku zatím žádné výsledky nejsou.
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if user.is_staff and vysledkovka_s_neverejnymi %}
|
{% if user.is_staff and vysledkovka_s_neverejnymi %}
|
||||||
|
|
|
@ -13,7 +13,11 @@
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div>
|
<div>
|
||||||
|
|
||||||
{% with nastaveni.aktualni_cislo as ac %}
|
{% with nastaveni.aktualni_cislo as ac %}
|
||||||
|
|
||||||
|
{# Zobrazovani neverejnych zadani jen organizatorum #}
|
||||||
|
{% if user.is_staff or verejne %}
|
||||||
|
{% if user.is_staff and not verejne %}<div class="mam-org-only">{% endif %}
|
||||||
|
|
||||||
{% if ac.zadane_problemy.all %}
|
{% if ac.zadane_problemy.all %}
|
||||||
<div class="zadani_azad_termin">
|
<div class="zadani_azad_termin">
|
||||||
|
@ -45,6 +49,12 @@
|
||||||
Aktuálně nejsou zadané žádné úlohy k řešení.
|
Aktuálně nejsou zadané žádné úlohy k řešení.
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
|
{% if user.is_staff and not verejne%}</div>{% endif %}
|
||||||
|
{% else %}
|
||||||
|
<h3>Aktuálně nejsou zveřejněny žádné úlohy</h3>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
<h3>Témata</h3>
|
<h3>Témata</h3>
|
||||||
<ul>
|
<ul>
|
||||||
{% for problem in temata %}
|
{% for problem in temata %}
|
||||||
|
@ -56,7 +66,8 @@
|
||||||
Aktuálně nejsou zadána žádná témata k řešení.
|
Aktuálně nejsou zadána žádná témata k řešení.
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
{% endwith %}
|
|
||||||
|
{% endwith %}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
# coding:utf-8
|
# coding:utf-8
|
||||||
|
|
||||||
from django.shortcuts import get_object_or_404, render
|
from django.shortcuts import get_object_or_404, render
|
||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden
|
||||||
from django.http import HttpResponse
|
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
|
from django.core.exceptions import PermissionDenied
|
||||||
from django.views import generic
|
from django.views import generic
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
from django.http import Http404
|
from django.http import Http404
|
||||||
|
from django.db.models import Q
|
||||||
|
|
||||||
from .models import Problem, Cislo, Reseni, Nastaveni, Rocnik, Soustredeni, Organizator, Resitel, Novinky, Soustredeni_Ucastnici
|
from .models import Problem, Cislo, Reseni, Nastaveni, Rocnik, Soustredeni, Organizator, Resitel, Novinky, Soustredeni_Ucastnici
|
||||||
from .models import VysledkyZaCislo, VysledkyKCisluZaRocnik, VysledkyKCisluOdjakziva
|
from .models import VysledkyZaCislo, VysledkyKCisluZaRocnik, VysledkyKCisluOdjakziva
|
||||||
|
@ -29,6 +30,7 @@ def verejna_temata(rocnik):
|
||||||
|
|
||||||
def AktualniZadaniView(request):
|
def AktualniZadaniView(request):
|
||||||
nastaveni = get_object_or_404(Nastaveni)
|
nastaveni = get_object_or_404(Nastaveni)
|
||||||
|
verejne = nastaveni.aktualni_cislo.verejne()
|
||||||
problemy = Problem.objects.filter(cislo_zadani=nastaveni.aktualni_cislo).filter(stav = 'zadany')
|
problemy = Problem.objects.filter(cislo_zadani=nastaveni.aktualni_cislo).filter(stav = 'zadany')
|
||||||
ulohy = problemy.filter(typ = 'uloha').order_by('kod')
|
ulohy = problemy.filter(typ = 'uloha').order_by('kod')
|
||||||
serialy = problemy.filter(typ = 'serial').order_by('kod')
|
serialy = problemy.filter(typ = 'serial').order_by('kod')
|
||||||
|
@ -37,6 +39,7 @@ def AktualniZadaniView(request):
|
||||||
{'nastaveni': nastaveni,
|
{'nastaveni': nastaveni,
|
||||||
'jednorazove_problemy': jednorazove_problemy,
|
'jednorazove_problemy': jednorazove_problemy,
|
||||||
'temata': verejna_temata(nastaveni.aktualni_rocnik),
|
'temata': verejna_temata(nastaveni.aktualni_rocnik),
|
||||||
|
'verejne': verejne,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -72,16 +75,16 @@ class TitulniStranaView(generic.ListView):
|
||||||
context = super(TitulniStranaView, self).get_context_data(**kwargs)
|
context = super(TitulniStranaView, self).get_context_data(**kwargs)
|
||||||
nastaveni = get_object_or_404(Nastaveni)
|
nastaveni = get_object_or_404(Nastaveni)
|
||||||
cas_deadline = nastaveni.aktualni_cislo.datum_deadline
|
cas_deadline = nastaveni.aktualni_cislo.datum_deadline
|
||||||
try:
|
# Pokud neni zverejnene cislo nezverejnuj odpocet
|
||||||
rozdil_casu = datetime.combine(cas_deadline, datetime.max.time()) \
|
if nastaveni.aktualni_cislo.verejne():
|
||||||
- datetime.now()
|
# pokus se zjistit termin odeslani a pokud neni zadany,
|
||||||
context['cas_do_konce_dni'] = rozdil_casu.days
|
# nezverejnuj odpocet
|
||||||
context['cas_do_konce_hodin'] = rozdil_casu.seconds / 3600
|
try:
|
||||||
context['cas_do_konce_minut'] = (rozdil_casu.seconds / 60) % 60
|
context['dead'] = datetime.combine(cas_deadline, datetime.max.time())
|
||||||
context['cas_do_konce_sekund'] = rozdil_casu.seconds % 60
|
context['ted'] = datetime.now()
|
||||||
context['dead'] = datetime.combine(cas_deadline, datetime.max.time())
|
except:
|
||||||
context['ted'] = datetime.now()
|
context['dead'] = None
|
||||||
except:
|
else:
|
||||||
context['dead'] = None
|
context['dead'] = None
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
@ -128,8 +131,9 @@ def sloupec_s_poradim(vysledky):
|
||||||
poradi_l += ["{}.".format(lepsich_resitelu + 1)]
|
poradi_l += ["{}.".format(lepsich_resitelu + 1)]
|
||||||
# je-li účastníků se stejným počtem bodů víc, pořadí (rozsah X.-Y.) je jen u prvního
|
# je-li účastníků se stejným počtem bodů víc, pořadí (rozsah X.-Y.) je jen u prvního
|
||||||
else:
|
else:
|
||||||
poradi_l += ["{}.–{}.".format(lepsich_resitelu + 1, lepsich_resitelu + len(skupina))] + [""] * (len(skupina)-1)
|
poradi_l += [u"{}. – {}.".format(lepsich_resitelu + 1, lepsich_resitelu + len(skupina))] + [""] * (len(skupina)-1)
|
||||||
lepsich_resitelu += len(skupina)
|
lepsich_resitelu += len(skupina)
|
||||||
|
#pomlcka je opravdu pomlcka v unicode!!dulezite pro vysledkovku v TeXu
|
||||||
|
|
||||||
return poradi_l
|
return poradi_l
|
||||||
|
|
||||||
|
@ -231,11 +235,14 @@ class ProblemView(generic.DetailView):
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super(ProblemView, self).get_context_data(**kwargs)
|
context = super(ProblemView, self).get_context_data(**kwargs)
|
||||||
|
if not context['problem'].verejne() and not self.request.user.is_staff:
|
||||||
|
raise PermissionDenied()
|
||||||
if context['problem'].typ == Problem.TYP_RES_CLANEK:
|
if context['problem'].typ == Problem.TYP_RES_CLANEK:
|
||||||
context['reseni'] = Reseni.objects.filter(problem=context['problem']).select_related('resitel').order_by('resitel__prijmeni')
|
context['reseni'] = Reseni.objects.filter(problem=context['problem']).select_related('resitel').order_by('resitel__prijmeni')
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class RadekVysledkovky(object):
|
class RadekVysledkovky(object):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -293,6 +300,7 @@ class CisloView(generic.DetailView):
|
||||||
v.poradi = poradi
|
v.poradi = poradi
|
||||||
v.body_celkem_rocnik = v.body
|
v.body_celkem_rocnik = v.body
|
||||||
v.body_celkem_odjakziva = VysledkyKCisluOdjakziva.objects.get(resitel=v.resitel, cislo=context['cislo']).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
|
# je tady '', aby se nezobrazovala 0, pokud se řešitel o řešení úlohy ani nepokusil
|
||||||
v.body_ulohy = [''] * len(problemy)
|
v.body_ulohy = [''] * len(problemy)
|
||||||
|
@ -342,28 +350,42 @@ class RocnikVysledkovkaView(RocnikView):
|
||||||
|
|
||||||
### Generovani obalek
|
### Generovani obalek
|
||||||
class CisloObalkyStruct:
|
class CisloObalkyStruct:
|
||||||
resitele = None
|
|
||||||
rocnik = None
|
rocnik = None
|
||||||
problemy = None
|
cisla = None
|
||||||
|
|
||||||
def cisloObalkyView(request,rocnik,cislo):
|
|
||||||
|
# Vraci QuerySet aktualnich resitelu = nekdy neco poslali, ale jeste neodmaturovali
|
||||||
|
def aktualniResitele(rocnik):
|
||||||
|
letos = Rocnik.objects.filter(rocnik = rocnik).first()
|
||||||
|
return Resitel.objects.filter(rok_maturity__gt = letos.prvni_rok)
|
||||||
|
# # ALERT: pokud nekdo nema vypleny rok maturity, tak neni aktualni, protoze Karel Tesar a jini
|
||||||
|
# return Resitel.objects.filter(Q(rok_maturity__gt = letos.prvni_rok)|Q(rok_maturity = None))
|
||||||
|
|
||||||
|
# Vraci QuerySet aktivnich resitelu =
|
||||||
|
# jeste neodmaturovali &&
|
||||||
|
# (pokud je aktualni cislo mensi nez 3, pak (letos || loni) neco poslali
|
||||||
|
# jinak letos neco poslali)
|
||||||
|
def aktivniResitele(rocnik,cislo):
|
||||||
letos = CisloObalkyStruct()
|
letos = CisloObalkyStruct()
|
||||||
loni = CisloObalkyStruct()
|
loni = CisloObalkyStruct()
|
||||||
|
|
||||||
letos.rocnik = Rocnik.objects.filter(rocnik = rocnik)[0]
|
aktualni_resitele = aktualniResitele(rocnik)
|
||||||
loni.rocnik = Rocnik.objects.filter(rocnik = int(rocnik)-1)[0]
|
|
||||||
letos.problemy = Problem.objects.filter(cislo_zadani = Cislo.objects.filter(rocnik=letos.rocnik,cislo__lte = cislo))
|
letos.rocnik = Rocnik.objects.filter(rocnik = rocnik).first()
|
||||||
loni.problemy = Problem.objects.filter(cislo_zadani = Cislo.objects.filter(rocnik=loni.rocnik))
|
loni.rocnik = Rocnik.objects.filter(rocnik = int(rocnik)-1).first()
|
||||||
letos.resitele = Resitel.objects.filter(reseni = Reseni.objects.filter(problem=letos.problemy)).distinct()
|
letos.cisla = Cislo.objects.filter(rocnik=letos.rocnik,cislo__lte = cislo)
|
||||||
loni.resitele = Resitel.objects.filter(reseni = Reseni.objects.filter(problem=loni.problemy)).distinct()
|
loni.cisla = Cislo.objects.filter(rocnik=loni.rocnik)
|
||||||
|
|
||||||
loni.resitele = loni.resitele.filter(rok_maturity__gt = letos.rocnik.prvni_rok)
|
|
||||||
|
|
||||||
if int(cislo) > 3:
|
if int(cislo) > 3:
|
||||||
resitele = letos.resitele
|
problemy = Problem.objects.filter(cislo_zadani = letos.cisla)
|
||||||
else:
|
else:
|
||||||
resitele = list(letos.resitele) + list(loni.resitele)
|
problemy = Problem.objects.filter(Q(cislo_zadani = letos.cisla)|Q(cislo_zadani=loni.cisla))
|
||||||
return obalkyView(request,resitele)
|
resitele = aktualni_resitele.filter(reseni = Reseni.objects.filter(problem=problemy)).distinct()
|
||||||
|
|
||||||
|
return resitele
|
||||||
|
|
||||||
|
|
||||||
|
def cisloObalkyView(request,rocnik,cislo):
|
||||||
|
return obalkyView(request,aktivniResitele(rocnik,cislo))
|
||||||
|
|
||||||
|
|
||||||
def obalkyView(request,resitele):
|
def obalkyView(request,resitele):
|
||||||
|
|
Loading…
Reference in a new issue