Merge branch 'master' into stable
This commit is contained in:
commit
ff7f52c85d
23 changed files with 362 additions and 301 deletions
|
@ -3,6 +3,9 @@
|
|||
from galerie.models import Obrazek, Galerie
|
||||
from django.contrib import admin
|
||||
from django.http import HttpResponseRedirect
|
||||
from django import forms
|
||||
from django.db import models
|
||||
import autocomplete_light
|
||||
|
||||
# akction
|
||||
|
||||
|
@ -27,17 +30,25 @@ def prepnout_fotogalerii_do_org_rezimu(modeladmin, request, queryset):
|
|||
'Přepnout do režimu úprav (zneveřejní galerii)'
|
||||
|
||||
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):
|
||||
list_display = ('obrazek_velky', 'nazev', 'popis')
|
||||
list_display = ('obrazek_velky', 'nazev', 'popis', 'obrazek_maly_tag')
|
||||
|
||||
class GalerieAdmin(admin.ModelAdmin):
|
||||
model = Galerie
|
||||
fields = ('zobrazit', 'nazev', 'titulni_obrazek', 'popis', 'galerie_up', 'soustredeni', 'poradi')
|
||||
list_display = ('nazev', 'pk', 'datum_zmeny', 'zobrazit', 'soustredeni')
|
||||
inlines = [GalerieInline]
|
||||
actions = [zverejnit_fotogalerii, prepnout_fotogalerii_do_org_rezimu]
|
||||
class GalerieAdmin(admin.ModelAdmin):
|
||||
form = autocomplete_light.modelform_factory(Galerie, autocomplete_fields=['titulni_obrazek'], fields=['titulni_obrazek'])
|
||||
model = Galerie
|
||||
fields = ('zobrazit', 'nazev', 'titulni_obrazek', 'popis', 'galerie_up', 'soustredeni', 'poradi')
|
||||
list_display = ('nazev', 'pk', 'poradi', 'datum_zmeny', 'zobrazit', 'soustredeni')
|
||||
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(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/0006_django_imagekit.py
Normal file
22
galerie/migrations/0006_django_imagekit.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', '0005_obrazek_ordering_datum'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='obrazek',
|
||||
name='obrazek_maly',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='obrazek',
|
||||
name='obrazek_stredni',
|
||||
),
|
||||
]
|
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,17 +1,12 @@
|
|||
# coding: utf-8
|
||||
|
||||
from django.db import models
|
||||
import seminar.models
|
||||
from django.db.models import Q
|
||||
from django.utils import timezone
|
||||
#from django.db.models import Q
|
||||
from django.utils.encoding import force_unicode
|
||||
from imagekit.models import ImageSpecField
|
||||
from imagekit.processors import ResizeToFit, Transpose
|
||||
|
||||
from PIL import Image
|
||||
from PIL.ExifTags import TAGS
|
||||
import os
|
||||
from cStringIO import StringIO
|
||||
from django.core.files.base import ContentFile
|
||||
from datetime import datetime
|
||||
|
||||
from seminar.models import Soustredeni
|
||||
|
||||
|
@ -24,120 +19,49 @@ VIDITELNOST = (
|
|||
(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
|
||||
|
||||
def flip_horizontal(im): return im.transpose(Image.FLIP_LEFT_RIGHT)
|
||||
def flip_vertical(im): return im.transpose(Image.FLIP_TOP_BOTTOM)
|
||||
def rotate_180(im): return im.transpose(Image.ROTATE_180)
|
||||
def rotate_90(im): return im.transpose(Image.ROTATE_90)
|
||||
def rotate_270(im): return im.transpose(Image.ROTATE_270)
|
||||
def transpose(im): return rotate_90(flip_horizontal(im))
|
||||
def transverse(im): return rotate_90(flip_vertical(im))
|
||||
orientation_funcs = [None,
|
||||
lambda x: x,
|
||||
flip_horizontal,
|
||||
rotate_180,
|
||||
flip_vertical,
|
||||
transpose,
|
||||
rotate_270,
|
||||
transverse,
|
||||
rotate_90
|
||||
]
|
||||
|
||||
# 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
|
||||
def obrazek_filename_maly():
|
||||
pass
|
||||
def obrazek_filename_stredni():
|
||||
pass
|
||||
def obrazek_filename_velky():
|
||||
pass
|
||||
|
||||
def obrazek_filename(self, filename):
|
||||
return obrazek_filename_obecny(self, filename, "velky")
|
||||
|
||||
def obrazek_filename_stredni(self, filename):
|
||||
return obrazek_filename_obecny(self, filename, "stredni")
|
||||
|
||||
def obrazek_filename_maly(self, filename):
|
||||
return obrazek_filename_obecny(self, filename, "maly")
|
||||
|
||||
def obrazek_filename_obecny(self, filename, typ):
|
||||
gal = self.galerie
|
||||
cislo_gal = force_unicode(gal.pk)
|
||||
cesta = ""
|
||||
while(not gal.soustredeni):
|
||||
gal = gal.galerie_up
|
||||
return os.path.join('Galerie', "soustredeni_" + force_unicode(gal.soustredeni.pk), "galerie_" + cislo_gal, typ, force_unicode(self.nazev))
|
||||
return os.path.join('Galerie', "soustredeni_" + force_unicode(gal.soustredeni.pk), "galerie_" + cislo_gal, "velky", force_unicode(self.nazev))
|
||||
|
||||
class Obrazek(models.Model):
|
||||
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.")
|
||||
obrazek_stredni = models.ImageField(upload_to=obrazek_filename_stredni, null = True, editable = False)
|
||||
obrazek_maly = models.ImageField(upload_to=obrazek_filename_maly, null = True, editable = False)
|
||||
obrazek_stredni = ImageSpecField(source='obrazek_velky',
|
||||
processors=[Transpose(Transpose.AUTO), ResizeToFit(900, 675, upscale=False)],
|
||||
options={'quality': 95})
|
||||
obrazek_maly = ImageSpecField(source='obrazek_velky',
|
||||
processors=[Transpose(Transpose.AUTO), ResizeToFit(167, 167, upscale=False)],
|
||||
options={'quality': 95})
|
||||
nazev = models.CharField('Název', max_length=50, blank = True, null = True)
|
||||
popis = models.TextField('Popis', blank = True, null = 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)
|
||||
poradi = models.IntegerField('Pořadí', blank = True, null = True)
|
||||
def __unicode__(self):
|
||||
return self.nazev + " -- " + unicode(self.obrazek_velky.name) + " (" + str(self.datum) + ")"
|
||||
return self.nazev + " -- " + unicode(self.obrazek_velky.name)
|
||||
class Meta:
|
||||
verbose_name = 'Obrázek'
|
||||
verbose_name_plural = 'Obrázky'
|
||||
ordering = ['datum']
|
||||
def save(self):
|
||||
original = Image.open(self.obrazek_velky)
|
||||
# vycteni EXIFu
|
||||
exif = get_exif(original)
|
||||
# otoceni podle EXIFu
|
||||
if exif['Orientation']:
|
||||
f = orientation_funcs[exif['Orientation']]
|
||||
original_otoceny = f(original)
|
||||
original_otoceny.format = original.format
|
||||
original = original_otoceny
|
||||
# datum podle EXIfu
|
||||
if exif['DateTimeOriginal']:
|
||||
datum_string = ":".join(exif['DateTimeOriginal'].split(' ')).split(":")
|
||||
datum_int = []
|
||||
for retezec in datum_string:
|
||||
datum_int.append(int(retezec))
|
||||
self.datum = datetime(datum_int[0], datum_int[1], datum_int[2],
|
||||
datum_int[3], datum_int[4], datum_int[5])
|
||||
jmeno = os.path.basename(self.obrazek_velky.file.name)
|
||||
if not self.obrazek_stredni:
|
||||
Obrazek._vyrobMiniaturu(original, jmeno, 1024, self.obrazek_stredni)
|
||||
if not self.obrazek_maly:
|
||||
Obrazek._vyrobMiniaturu(original, jmeno, 200, self.obrazek_maly)
|
||||
super(Obrazek, self).save()
|
||||
ordering = ['nazev']
|
||||
|
||||
@staticmethod
|
||||
def _vyrobMiniaturu(original, jmeno, maximum, field):
|
||||
zmensenina = Obrazek._zmensiObrazek(original, maximum)
|
||||
f = StringIO()
|
||||
try:
|
||||
zmensenina.save(f, format=original.format)
|
||||
data = ContentFile(f.getvalue())
|
||||
finally:
|
||||
f.close()
|
||||
field.save(jmeno, data, save = False)
|
||||
|
||||
@staticmethod
|
||||
def _zmensiObrazek(original, maximum):
|
||||
"""Preskaluje obrazek tak, aby byl zachovan pomer stran a zadny rozmer
|
||||
nepresahoval maxRozmer. Pokud zadny rozmer nepresahuje maxRozmer, tak
|
||||
vrati puvodni obrazek (tj. nedojde ke zvetseni obrazku)."""
|
||||
novaVelikost = Obrazek._zmensiVelikost(original.size, maximum)
|
||||
return original.resize(novaVelikost, Image.ANTIALIAS)
|
||||
def obrazek_maly_tag(self):
|
||||
return u'<img src="{}">'.format(self.obrazek_maly.url)
|
||||
obrazek_maly_tag.short_description = "Náhled"
|
||||
obrazek_maly_tag.allow_tags = True
|
||||
|
||||
@staticmethod
|
||||
def _zmensiVelikost(velikost, maximum):
|
||||
maximum = float(maximum)
|
||||
w, h = velikost
|
||||
soucasneMaximum = max(w, h)
|
||||
if soucasneMaximum <= maximum:
|
||||
return velikost
|
||||
pomer = maximum/soucasneMaximum
|
||||
return (int(w * pomer), int(h * pomer))
|
||||
|
||||
|
||||
class Galerie(models.Model):
|
||||
|
|
|
@ -6,6 +6,10 @@ Galerie {{galerie.nazev}}
|
|||
|
||||
{% block content %}
|
||||
|
||||
{% if galerie.zobrazit > 0 %}
|
||||
<div class="mam-org-only">
|
||||
{% endif %}
|
||||
|
||||
<h2>
|
||||
{% for g in cesta %}
|
||||
{% if not forloop.last %}
|
||||
|
@ -19,7 +23,7 @@ Galerie {{galerie.nazev}}
|
|||
{% if not obrazky %}
|
||||
<div class="galerie_hlavicka">
|
||||
{% 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 %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
@ -45,8 +49,8 @@ Galerie {{galerie.nazev}}
|
|||
{% if galerie.titulni_obrazek %}
|
||||
{% with galerie.titulni_obrazek.obrazek_maly as obrazek %}
|
||||
<img src="{{ obrazek.url }}"
|
||||
width={% widthratio obrazek.width 200 167 %}
|
||||
height={% widthratio obrazek.height 200 167 %} />
|
||||
width="{% widthratio obrazek.width 167 obrazek.width %}"
|
||||
height="{% widthratio obrazek.width 167 obrazek.height %}" />
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
<div>
|
||||
|
@ -76,8 +80,8 @@ Galerie {{galerie.nazev}}
|
|||
{% for obrazek in obrazky %}
|
||||
<a title="Zobrazit tuto fotografii" href="./{{obrazek.pk}}#nahoru" class="galerie_nahled"><span class="vystredeno"></span><img
|
||||
src="{{obrazek.obrazek_maly.url}}"
|
||||
width={% widthratio obrazek.obrazek_maly.width 200 167 %}
|
||||
height={% widthratio obrazek.obrazek_maly.height 200 167 %} />
|
||||
width="{{ obrazek.obrazek_maly.width }}"
|
||||
height="{{ obrazek.obrazek_maly.height }}" />
|
||||
</a>
|
||||
{% endfor %}
|
||||
<br>
|
||||
|
@ -103,4 +107,9 @@ Galerie {{galerie.nazev}}
|
|||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if galerie.zobrazit > 0 %}
|
||||
</div> {# mam-org-only #}
|
||||
{% endif %}
|
||||
|
||||
{% endblock content %}
|
||||
|
|
|
@ -38,7 +38,7 @@ def nahled(request, pk, soustredeni):
|
|||
if not request.user.is_staff:
|
||||
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)
|
||||
|
||||
sourozenci = []
|
||||
|
@ -82,7 +82,7 @@ def detail(request, pk, fotka, soustredeni):
|
|||
galerie = get_object_or_404(Galerie, pk=pk)
|
||||
preview = zobrazit(galerie, request)
|
||||
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
|
||||
if request.method == 'POST':
|
||||
|
|
|
@ -111,6 +111,8 @@ INSTALLED_APPS = (
|
|||
'django.contrib.flatpages',
|
||||
'django.contrib.humanize',
|
||||
|
||||
'imagekit',
|
||||
|
||||
# MaMweb
|
||||
'mamweb',
|
||||
'seminar',
|
||||
|
@ -155,6 +157,7 @@ CKEDITOR_IMAGE_BACKEND = 'pillow'
|
|||
#CKEDITOR_JQUERY_URL = '//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js'
|
||||
CKEDITOR_CONFIGS = {
|
||||
'default': {
|
||||
'entities': False,
|
||||
'toolbar': [
|
||||
['Source', 'ShowBlocks', '-', 'Maximize'],
|
||||
['Bold', 'Italic', 'Subscript', 'Superscript', '-', 'RemoveFormat'],
|
||||
|
@ -233,12 +236,3 @@ LOGGING = {
|
|||
# MaM specific
|
||||
|
||||
SEMINAR_RESENI_DIR = os.path.join(BASE_DIR, 'media', 'reseni')
|
||||
|
||||
|
||||
CKEDITOR_CONFIGS = {
|
||||
'default': {
|
||||
'entities': False
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@ ADMINS = [
|
|||
('Petr Pecha', 'nejlepsitextovyeditorjevim@gmail.com'),
|
||||
('Tomas Gavenciak', 'gavento@gmail.com'),
|
||||
('Matěj Kocián', 'matej.kocian@gmail.com'),
|
||||
('M&M ERRORs', 'mam-errors@atrey.karlin.mff.cuni.cz'),
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@ import os
|
|||
SERVER_EMAIL = 'mamweb-test-errors@mam.mff.cuni.cz'
|
||||
ADMINS = [
|
||||
('Petr Pecha', 'nejlepsitextovyeditorjevim@gmail.com'),
|
||||
('M&M ERRORs', 'mam-errors@atrey.karlin.mff.cuni.cz'),
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -18,6 +18,15 @@ body {
|
|||
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 {
|
||||
border-right: solid 1px;
|
||||
}
|
||||
|
@ -437,7 +446,7 @@ div.zadani_azad_termin {
|
|||
float: none;
|
||||
width: 70%;
|
||||
margin-left: auto;
|
||||
margin-right: auto
|
||||
margin-right: auto;
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -446,7 +455,8 @@ div.zadani_azad_termin {
|
|||
/* galerie */
|
||||
|
||||
/* velká fotka */
|
||||
.galerie .obrazek {
|
||||
/* zmenšování spolu s oknem prohlížeče */
|
||||
.galerie .obrazek, .titulni_obrazek {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
width: auto\9; /* ie8 */
|
||||
|
@ -482,7 +492,6 @@ div.zadani_azad_termin {
|
|||
.galerie {
|
||||
position: relative;
|
||||
text-align: center;
|
||||
/*width: 100%;*/
|
||||
margin: 20px auto 0 auto;
|
||||
}
|
||||
|
||||
|
@ -503,6 +512,11 @@ div.zadani_azad_termin {
|
|||
text-align: center;
|
||||
}
|
||||
|
||||
/* titulní obrázek hlavní galerie soustředění */
|
||||
.titulni_obrazek {
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
.galerie_nahledy{
|
||||
/*margin: 1em 0;*/
|
||||
margin: 0 auto 30px auto;
|
||||
|
@ -649,3 +663,11 @@ div.zadani_azad_termin {
|
|||
float: right;
|
||||
max-width: 42%;
|
||||
}
|
||||
|
||||
.novinka_obrazek img {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
div.novinka_obrazek {
|
||||
width: 100%;
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ django-flat-theme==0.9.3
|
|||
django-taggit==0.17
|
||||
django-autocomplete-light==2.2.6
|
||||
django-crispy-forms==1.4.0
|
||||
django-imagekit==3.2.7
|
||||
|
||||
# Comments
|
||||
akismet==0.2.0
|
||||
|
@ -32,7 +33,7 @@ django-contrib-comments==1.6.1
|
|||
|
||||
# debug tools/extensions
|
||||
|
||||
django-debug-toolbar==1.3.2
|
||||
django-debug-toolbar==1.4
|
||||
django-extensions==1.5.6
|
||||
sqlparse==0.1.16
|
||||
Werkzeug==0.10.4
|
||||
|
|
|
@ -334,7 +334,7 @@ create_modeladmin(ProblemNavrhAdmin, Problem, 'ProblemNavrh', verbose_name=u'Pro
|
|||
|
||||
class ProblemZadanyAdmin(ProblemAdmin):
|
||||
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]
|
||||
|
||||
def get_queryset(self, request):
|
||||
|
|
25
seminar/migrations/0035_django_imagekit.py
Normal file
25
seminar/migrations/0035_django_imagekit.py
Normal file
|
@ -0,0 +1,25 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
import imagekit.models.fields
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('seminar', '0034_reseni_forma_default_email'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='organizator',
|
||||
name='foto_male',
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='organizator',
|
||||
name='foto',
|
||||
field=imagekit.models.fields.ProcessedImageField(help_text=b'Vlo\xc5\xbe fotografii organiz\xc3\xa1tora o libovoln\xc3\xa9 velikosti', upload_to=b'image_organizatori/velke/%Y/', null=True, verbose_name=b'Fotografie organiz\xc3\xa1tora', blank=True),
|
||||
preserve_default=True,
|
||||
),
|
||||
]
|
|
@ -11,6 +11,8 @@ from django.utils.encoding import force_unicode
|
|||
from django.utils.text import slugify
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.core.cache import cache
|
||||
from imagekit.models import ImageSpecField, ProcessedImageField
|
||||
from imagekit.processors import ResizeToFit, Transpose
|
||||
|
||||
from PIL import Image
|
||||
import os
|
||||
|
@ -183,6 +185,9 @@ class Resitel(SeminarModelBase):
|
|||
def plne_jmeno(self):
|
||||
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):
|
||||
return force_unicode(self.plne_jmeno())
|
||||
|
||||
|
@ -755,6 +760,12 @@ class Novinky(models.Model):
|
|||
text = models.TextField('Text novinky', blank=True, null=True)
|
||||
obrazek = models.ImageField('Obrázek', upload_to='image_novinky/%Y/%m/%d/',
|
||||
null=True, blank=True)
|
||||
obrazek_maly = ImageSpecField(source='obrazek',
|
||||
processors=[
|
||||
ResizeToFit(350, 200, upscale=False)
|
||||
],
|
||||
options={'quality': 95})
|
||||
|
||||
autor = models.ForeignKey(settings.AUTH_USER_MODEL,
|
||||
verbose_name='Autor novinky')
|
||||
zverejneno = models.BooleanField('Zveřejněno', default="False")
|
||||
|
@ -785,11 +796,19 @@ class Organizator(models.Model):
|
|||
"'Přednáší na MFF'")
|
||||
strucny_popis_organizatora = models.TextField('Stručný popis organizátora',
|
||||
null = True, blank = True)
|
||||
foto = models.ImageField('Fotografie organizátora',
|
||||
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')
|
||||
foto_male = models.ImageField(upload_to='image_organizatori/male/%Y/',
|
||||
null = True, blank = True, editable = False)
|
||||
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)
|
||||
|
@ -797,52 +816,3 @@ class Organizator(models.Model):
|
|||
class Meta:
|
||||
verbose_name = 'Organizátor'
|
||||
verbose_name_plural = 'Organizátoři'
|
||||
|
||||
def save(self):
|
||||
# v databázi uložený záznam o organizátorovi
|
||||
puvodni = None
|
||||
|
||||
# pokud už organizátor v databázi existuje, nastav puvodni
|
||||
if self.id is not None:
|
||||
puvodni = Organizator.objects.get(id=self.id)
|
||||
# pokud nahráváme fotku
|
||||
if self.foto:
|
||||
# a je jiná než ta stará
|
||||
if not puvodni or puvodni.foto != self.foto:
|
||||
# uložíme ji
|
||||
original = Image.open(self.foto)
|
||||
jmeno = os.path.basename(self.foto.file.name)
|
||||
Organizator._vyrobMiniaturu(original, jmeno, 500, self.foto)
|
||||
Organizator._vyrobMiniaturu(original, jmeno, 200, self.foto_male)
|
||||
super(Organizator, self).save()
|
||||
|
||||
@staticmethod
|
||||
def _vyrobMiniaturu(original, jmeno, maximum, field):
|
||||
zmensenina = Organizator._zmensiObrazek(original, maximum)
|
||||
f = StringIO()
|
||||
try:
|
||||
zmensenina.save(f, format=original.format)
|
||||
data = ContentFile(f.getvalue())
|
||||
finally:
|
||||
f.close()
|
||||
field.save(jmeno, data, save = False)
|
||||
|
||||
@staticmethod
|
||||
def _zmensiObrazek(original, maximum):
|
||||
"""Preskaluje obrazek tak, aby byl zachovan pomer stran
|
||||
a zadny rozmer nepresahoval maxRozmer. Pokud zadny rozmer
|
||||
nepresahuje maxRozmer, tak vrati puvodni obrazek
|
||||
(tj. nedojde ke zvetseni obrazku)."""
|
||||
novaVelikost = Organizator._zmensiVelikost(original.size, maximum)
|
||||
return original.resize(novaVelikost, Image.ANTIALIAS)
|
||||
|
||||
@staticmethod
|
||||
def _zmensiVelikost(velikost, maximum):
|
||||
maximum = float(maximum)
|
||||
w, h = velikost
|
||||
soucasneMaximum = max(w, h)
|
||||
if soucasneMaximum <= maximum:
|
||||
return velikost
|
||||
pomer = maximum/soucasneMaximum
|
||||
return (int(w * pomer), int(h * pomer))
|
||||
|
||||
|
|
|
@ -27,6 +27,16 @@
|
|||
{% endfor %}
|
||||
</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 %}
|
||||
<h3>Výsledkovka</h3>
|
||||
{% else %}
|
||||
|
|
|
@ -1,33 +1,9 @@
|
|||
\begin{longtable}{r|l|c|l|c
|
||||
{% for p in problemy %}
|
||||
@\hskip.5em}c {% endfor %}
|
||||
|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
|
||||
\setlength{\tabcolsep}{3pt}
|
||||
\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
|
||||
\endhead
|
||||
\hline
|
||||
\endfoot
|
||||
|
||||
{% 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 }} \\
|
||||
\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}}\\
|
||||
{% endfor %}
|
||||
\end{longtable}
|
||||
|
|
|
@ -1,21 +1,24 @@
|
|||
{% for novinka in object_list %}
|
||||
{# pripravene div-y na stylovani#}
|
||||
<div>
|
||||
{% if not novinka.zverejneno and user.is_staff %}
|
||||
<div class="mam-org-only">
|
||||
{% endif %}
|
||||
{% if novinka.zverejneno or user.is_staff %}
|
||||
{# datum #}
|
||||
<div><b>{{novinka.datum}}</b></div>
|
||||
{# text #}
|
||||
{{ novinka.text | safe }}
|
||||
{# obrazek #}
|
||||
{% if novinka.obrazek %}
|
||||
<div>
|
||||
<img src='{{novinka.obrazek.url}}'
|
||||
height='
|
||||
{% if novinka.obrazek.height > 200 %} {# vyska obrazku natvrdo #}
|
||||
200
|
||||
<div class='novinka_obrazek'>
|
||||
{% if novinka.obrazek.height > novinka.obrazek_maly.height %}
|
||||
<a href='{{ novinka.obrazek.url }}'>
|
||||
<img src='{{ novinka.obrazek.url }}' height='{{ novinka.obrazek_maly.height }}'>
|
||||
</a>
|
||||
{% else %}
|
||||
{{novinka.obrazek.height}}
|
||||
<img src='{{ novinka.obrazek.url }}' height='{{ novinka.obrazek_maly.height }}'>
|
||||
{% endif%}
|
||||
'>
|
||||
</div>
|
||||
{% endif %}
|
||||
{# autor #}
|
||||
|
@ -26,6 +29,10 @@
|
|||
{{novinka.autor.last_name}}
|
||||
</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if not novinka.zverejneno and user.is_staff %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor%}
|
||||
|
||||
|
|
|
@ -21,46 +21,44 @@
|
|||
{# Projdi vsechna soustredeni #}
|
||||
{% for soustredeni in object_list %}
|
||||
{# Kdyz je verejne -> zobraz #}
|
||||
{% if soustredeni.verejne_db or user.is_authenticated %}
|
||||
{% if not soustredeni.verejne_db and user.is_authenticated %}
|
||||
Groups of user: {{user.groups.all}} <br>
|
||||
<!-- TODO pri prihlasovani ucastniku dodelat prava
|
||||
jen na group org ve view -->
|
||||
Toto soustředění není veřejné, vidíte ho jen proto,
|
||||
že jste přihlášení. <br>
|
||||
{% if soustredeni.verejne_db or user.is_staff %}
|
||||
{% if not soustredeni.verejne_db and user.is_staff %}
|
||||
<div class="mam-org-only">
|
||||
<!--Groups of user: {{user.groups.all}} <br>-->
|
||||
{% endif %}
|
||||
{# misto soustredeni TODO upravit#}
|
||||
<h2>
|
||||
{{soustredeni.get_typ_display}}
|
||||
{{soustredeni.misto}}
|
||||
</h2>
|
||||
<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 %}
|
||||
<h2>
|
||||
{{soustredeni.get_typ_display}}
|
||||
{{soustredeni.misto}}
|
||||
</h2>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="../{{soustredeni.pk}}/fotogalerie/{{galerie.pk}}">Fotogalerie</a>
|
||||
{# TODO kdyz je titulni obrazek, tak asi i titulni obrazek #}
|
||||
{{soustredeni.datum_zacatku}} – {{soustredeni.datum_konce}}
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</ul>
|
||||
{% if user.is_staff %}
|
||||
<div class="mam-org-only">
|
||||
<a href="../{{soustredeni.pk}}/fotogalerie/0/new/">Vytvořit novou fotogalerii</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
{# popis soustredeni #}
|
||||
{% if soustredeni.text %}
|
||||
{% autoescape off %}{{soustredeni.text}}{% endautoescape %}
|
||||
{# 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 {% if galerie.zobrazit > 0 and user.is_staff %}class="mam-org-only"{% endif %}>
|
||||
<a href="../{{soustredeni.pk}}/fotogalerie/{{galerie.pk}}">Fotogalerie</a>
|
||||
{# TODO kdyz je titulni obrazek, tak asi i titulni obrazek #}
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% 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 %}
|
||||
{# Účastníci #}
|
||||
<h3>Soustředění se zúčastnili tito účastníci:</h3>
|
||||
|
@ -72,9 +70,12 @@
|
|||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% if not soustredeni.verejne_db and user.is_staff %}
|
||||
</div> {# class="mam-org-only" #}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% empty %}
|
||||
Žádná soustředění zatím neproběhla!
|
||||
{% empty %}
|
||||
Žádná soustředění zatím neproběhla!
|
||||
{% endfor %}
|
||||
|
||||
{% endblock %}
|
||||
|
|
|
@ -20,25 +20,11 @@ M&M je korespondeční seminář. Několikrát do roka zdarma vydáváme ča
|
|||
<div class="novinky">
|
||||
{% if dead %}
|
||||
<div class="odpocet">
|
||||
<p><b>Do konce odeslání řešení 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>
|
||||
|
||||
|
||||
<!--
|
||||
{{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>
|
||||
{% endif %}
|
||||
|
||||
{# Novinky #}
|
||||
<h2>Novinky</h2>
|
||||
{% include 'seminar/novinky.html' %}
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
{% if vysledkovka %}
|
||||
{% include "seminar/vysledkovka_rocnik.html" %}
|
||||
{% else %}
|
||||
V tomto ročníku zatím žádné výsledky nejsou
|
||||
V tomto ročníku zatím žádné výsledky nejsou.
|
||||
{% endif %}
|
||||
|
||||
{% if user.is_staff and vysledkovka_s_neverejnymi %}
|
||||
|
|
|
@ -13,7 +13,11 @@
|
|||
{% block content %}
|
||||
<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 %}
|
||||
<div class="zadani_azad_termin">
|
||||
|
@ -45,6 +49,12 @@
|
|||
Aktuálně nejsou zadané žádné úlohy k řešení.
|
||||
{% 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>
|
||||
<ul>
|
||||
{% for problem in temata %}
|
||||
|
@ -56,7 +66,8 @@
|
|||
Aktuálně nejsou zadána žádná témata k řešení.
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endwith %}
|
||||
|
||||
{% endwith %}
|
||||
|
||||
</div>
|
||||
{% endblock content %}
|
||||
|
|
|
@ -7,6 +7,7 @@ from django.core.urlresolvers import reverse
|
|||
from django.views import generic
|
||||
from django.utils.translation import ugettext as _
|
||||
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 VysledkyZaCislo, VysledkyKCisluZaRocnik, VysledkyKCisluOdjakziva
|
||||
|
@ -29,6 +30,7 @@ def verejna_temata(rocnik):
|
|||
|
||||
def AktualniZadaniView(request):
|
||||
nastaveni = get_object_or_404(Nastaveni)
|
||||
verejne = nastaveni.aktualni_cislo.verejne()
|
||||
problemy = Problem.objects.filter(cislo_zadani=nastaveni.aktualni_cislo).filter(stav = 'zadany')
|
||||
ulohy = problemy.filter(typ = 'uloha').order_by('kod')
|
||||
serialy = problemy.filter(typ = 'serial').order_by('kod')
|
||||
|
@ -37,6 +39,7 @@ def AktualniZadaniView(request):
|
|||
{'nastaveni': nastaveni,
|
||||
'jednorazove_problemy': jednorazove_problemy,
|
||||
'temata': verejna_temata(nastaveni.aktualni_rocnik),
|
||||
'verejne': verejne,
|
||||
},
|
||||
)
|
||||
|
||||
|
@ -66,22 +69,22 @@ def ZadaniAktualniVysledkovkaView(request):
|
|||
class TitulniStranaView(generic.ListView):
|
||||
model = Novinky
|
||||
template_name='seminar/titulnistrana.html'
|
||||
queryset = Novinky.objects.filter(zverejneno=True).order_by('-datum')[:5]
|
||||
queryset = Novinky.objects.order_by('-datum')[:5]
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(TitulniStranaView, self).get_context_data(**kwargs)
|
||||
nastaveni = get_object_or_404(Nastaveni)
|
||||
cas_deadline = nastaveni.aktualni_cislo.datum_deadline
|
||||
try:
|
||||
rozdil_casu = datetime.combine(cas_deadline, datetime.max.time()) \
|
||||
- datetime.now()
|
||||
context['cas_do_konce_dni'] = rozdil_casu.days
|
||||
context['cas_do_konce_hodin'] = rozdil_casu.seconds / 3600
|
||||
context['cas_do_konce_minut'] = (rozdil_casu.seconds / 60) % 60
|
||||
context['cas_do_konce_sekund'] = rozdil_casu.seconds % 60
|
||||
context['dead'] = datetime.combine(cas_deadline, datetime.max.time())
|
||||
context['ted'] = datetime.now()
|
||||
except:
|
||||
# Pokud neni zverejnene cislo nezverejnuj odpocet
|
||||
if nastaveni.aktualni_cislo.verejne():
|
||||
# pokus se zjistit termin odeslani a pokud neni zadany,
|
||||
# nezverejnuj odpocet
|
||||
try:
|
||||
context['dead'] = datetime.combine(cas_deadline, datetime.max.time())
|
||||
context['ted'] = datetime.now()
|
||||
except:
|
||||
context['dead'] = None
|
||||
else:
|
||||
context['dead'] = None
|
||||
return context
|
||||
|
||||
|
@ -128,8 +131,9 @@ def sloupec_s_poradim(vysledky):
|
|||
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
|
||||
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)
|
||||
#pomlcka je opravdu pomlcka v unicode!!dulezite pro vysledkovku v TeXu
|
||||
|
||||
return poradi_l
|
||||
|
||||
|
@ -293,6 +297,7 @@ class CisloView(generic.DetailView):
|
|||
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)
|
||||
|
@ -342,28 +347,42 @@ class RocnikVysledkovkaView(RocnikView):
|
|||
|
||||
### Generovani obalek
|
||||
class CisloObalkyStruct:
|
||||
resitele = 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()
|
||||
loni = CisloObalkyStruct()
|
||||
|
||||
letos.rocnik = Rocnik.objects.filter(rocnik = rocnik)[0]
|
||||
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))
|
||||
loni.problemy = Problem.objects.filter(cislo_zadani = Cislo.objects.filter(rocnik=loni.rocnik))
|
||||
letos.resitele = Resitel.objects.filter(reseni = Reseni.objects.filter(problem=letos.problemy)).distinct()
|
||||
loni.resitele = Resitel.objects.filter(reseni = Reseni.objects.filter(problem=loni.problemy)).distinct()
|
||||
|
||||
loni.resitele = loni.resitele.filter(rok_maturity__gt = letos.rocnik.prvni_rok)
|
||||
|
||||
aktualni_resitele = aktualniResitele(rocnik)
|
||||
|
||||
letos.rocnik = Rocnik.objects.filter(rocnik = rocnik).first()
|
||||
loni.rocnik = Rocnik.objects.filter(rocnik = int(rocnik)-1).first()
|
||||
letos.cisla = Cislo.objects.filter(rocnik=letos.rocnik,cislo__lte = cislo)
|
||||
loni.cisla = Cislo.objects.filter(rocnik=loni.rocnik)
|
||||
if int(cislo) > 3:
|
||||
resitele = letos.resitele
|
||||
problemy = Problem.objects.filter(cislo_zadani = letos.cisla)
|
||||
else:
|
||||
resitele = list(letos.resitele) + list(loni.resitele)
|
||||
return obalkyView(request,resitele)
|
||||
problemy = Problem.objects.filter(Q(cislo_zadani = letos.cisla)|Q(cislo_zadani=loni.cisla))
|
||||
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):
|
||||
|
|
Loading…
Reference in a new issue