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 | ||||||
| 
 | 
 | ||||||
|  | @ -28,16 +31,24 @@ def prepnout_fotogalerii_do_org_rezimu(modeladmin, request, queryset): | ||||||
| 
 | 
 | ||||||
| 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): | ||||||
|  |     form = autocomplete_light.modelform_factory(Galerie, autocomplete_fields=['titulni_obrazek'], fields=['titulni_obrazek']) | ||||||
|     model = Galerie |     model = Galerie | ||||||
|     fields = ('zobrazit', 'nazev', 'titulni_obrazek', 'popis', 'galerie_up', 'soustredeni', 'poradi') |     fields = ('zobrazit', 'nazev', 'titulni_obrazek', 'popis', 'galerie_up', 'soustredeni', 'poradi') | ||||||
|   list_display = ('nazev', 'pk', 'datum_zmeny', 'zobrazit', 'soustredeni') |     list_display = ('nazev', 'pk', 'poradi', 'datum_zmeny', 'zobrazit', 'soustredeni') | ||||||
|     inlines = [GalerieInline] |     inlines = [GalerieInline] | ||||||
|     actions = [zverejnit_fotogalerii, prepnout_fotogalerii_do_org_rezimu] |     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,10 +31,19 @@ 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, | ||||||
|  | @ -60,26 +54,32 @@ class Obrazek(models.Model): | ||||||
|     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: |     class Meta: | ||||||
|       verbose_name = 'Obrázek' |       verbose_name = 'Obrázek' | ||||||
|       verbose_name_plural = 'Obrázky' |       verbose_name_plural = 'Obrázky' | ||||||
|     ordering = ['datum'] |       ordering = ['nazev'] | ||||||
|   def save(self): | 
 | ||||||
|     original = Image.open(self.obrazek_velky) |     def obrazek_maly_tag(self): | ||||||
|     # vycteni EXIFu |       return u'<img src="{}">'.format(self.obrazek_maly.url) | ||||||
|     exif = get_exif(original) |     obrazek_maly_tag.short_description = "Náhled" | ||||||
|     if exif['DateTimeOriginal']: |     obrazek_maly_tag.allow_tags = True | ||||||
|         datum_ints = map(int, ":".join(exif['DateTimeOriginal'].split(' ')).split(":")) | 
 | ||||||
|         self.datum = datetime(*datum_ints) |     def save(self, *args, **kwargs): | ||||||
|     super(Obrazek, self).save() |         # 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>. | ||||||
|  |   {% endif %} | ||||||
|   {% if problem.cislo_reseni %} |   {% if problem.cislo_reseni %} | ||||||
|     <p>Řešeno v čísle <a href='{{ problem.cislo_reseni.verejne_url }}'>{{ problem.cislo_reseni.kod }}</a>. |     <p>Řešeno v čísle <a href='{{ problem.cislo_reseni.verejne_url }}'>{{ problem.cislo_reseni.kod }}</a>. | ||||||
|   {% endif %} |   {% endif %} | ||||||
|   {% else %} |  | ||||||
|     {# TODO ? #} |  | ||||||
|     <h2>Problém {{ problem.nazev }}</h2> |  | ||||||
|   {% 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,13 +21,10 @@ | ||||||
|   {# 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> | ||||||
|  | @ -42,7 +39,7 @@ | ||||||
|         {% if soustredeni.galerie_set.all %} |         {% if soustredeni.galerie_set.all %} | ||||||
|           {% for galerie in soustredeni.galerie_set.all %} |           {% for galerie in soustredeni.galerie_set.all %} | ||||||
|             {% if galerie.zobrazit == 0 or user.is_staff %} |             {% if galerie.zobrazit == 0 or user.is_staff %} | ||||||
|         <li> |               <li {% if galerie.zobrazit > 0 and user.is_staff %}class="mam-org-only"{% endif %}> | ||||||
|                 <a href="../{{soustredeni.pk}}/fotogalerie/{{galerie.pk}}">Fotogalerie</a> |                 <a href="../{{soustredeni.pk}}/fotogalerie/{{galerie.pk}}">Fotogalerie</a> | ||||||
|                 {# TODO kdyz je titulni obrazek, tak asi i titulni obrazek #} |                 {# TODO kdyz je titulni obrazek, tak asi i titulni obrazek #} | ||||||
|               </li> |               </li> | ||||||
|  | @ -63,15 +60,29 @@ | ||||||
|         {% autoescape off %}{{soustredeni.text}}{% endautoescape %} |         {% autoescape off %}{{soustredeni.text}}{% endautoescape %} | ||||||
|       {% endif %} |       {% 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 %} | ||||||
|  |  | ||||||
|  | @ -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,17 +75,17 @@ 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 | ||||||
|  |         # Pokud neni zverejnene cislo nezverejnuj odpocet | ||||||
|  |         if nastaveni.aktualni_cislo.verejne(): | ||||||
|  |           # pokus se zjistit termin odeslani a pokud neni zadany, | ||||||
|  |           # nezverejnuj odpocet | ||||||
|           try: |           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['dead'] = datetime.combine(cas_deadline, datetime.max.time()) | ||||||
|             context['ted'] = datetime.now() |             context['ted'] = datetime.now() | ||||||
|           except: |           except: | ||||||
|               context['dead'] = None |               context['dead'] = None | ||||||
|  |         else: | ||||||
|  |             context['dead'] = None | ||||||
|         return context |         return context | ||||||
| 
 | 
 | ||||||
| class StareNovinkyView(generic.ListView): | class StareNovinkyView(generic.ListView): | ||||||
|  | @ -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)) |  | ||||||
|     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) |  | ||||||
|      |      | ||||||
|  |     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: |     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