diff --git a/galerie/admin.py b/galerie/admin.py index 4f95c951..1441ce09 100644 --- a/galerie/admin.py +++ b/galerie/admin.py @@ -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) diff --git a/galerie/autocomplete_light_registry.py b/galerie/autocomplete_light_registry.py new file mode 100644 index 00000000..7b624d20 --- /dev/null +++ b/galerie/autocomplete_light_registry.py @@ -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 = ''' + + + {} + {} + + + ''' + + def choice_label(self, obrazek): + cesta = "/".join(g.nazev for g in cesta_od_korene(obrazek.galerie)) + popis = "{}
".format(obrazek.popis) if obrazek.popis else "" + return '{}
{}{}'.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) diff --git a/galerie/models.py b/galerie/models.py index 9f3b1478..4c08c4f2 100644 --- a/galerie/models.py +++ b/galerie/models.py @@ -56,6 +56,12 @@ class Obrazek(models.Model): verbose_name = 'Obrázek' verbose_name_plural = 'Obrázky' ordering = ['nazev'] + + def obrazek_maly_tag(self): + return u''.format(self.obrazek_maly.url) + obrazek_maly_tag.short_description = "Náhled" + obrazek_maly_tag.allow_tags = True + class Galerie(models.Model): diff --git a/galerie/templates/galerie/GalerieNahled.html b/galerie/templates/galerie/GalerieNahled.html index 9a26f101..bb475b50 100644 --- a/galerie/templates/galerie/GalerieNahled.html +++ b/galerie/templates/galerie/GalerieNahled.html @@ -6,6 +6,10 @@ Galerie {{galerie.nazev}} {% block content %} + {% if galerie.zobrazit > 0 %} +
+ {% endif %} +

{% for g in cesta %} {% if not forloop.last %} @@ -19,7 +23,7 @@ Galerie {{galerie.nazev}} {% if not obrazky %}
{% if galerie.titulni_obrazek %} - + {% endif %}
{% endif %} @@ -45,8 +49,8 @@ Galerie {{galerie.nazev}} {% if galerie.titulni_obrazek %} {% with galerie.titulni_obrazek.obrazek_maly as obrazek %} + width="{% widthratio obrazek.width 167 obrazek.width %}" + height="{% widthratio obrazek.width 167 obrazek.height %}" /> {% endwith %} {% endif %}
@@ -103,4 +107,9 @@ Galerie {{galerie.nazev}}
{% endif %} {% endif %} + + {% if galerie.zobrazit > 0 %} +

{# mam-org-only #} + {% endif %} + {% endblock content %} diff --git a/mamweb/static/css/mamweb.css b/mamweb/static/css/mamweb.css index 1daecacc..8b1ef07d 100644 --- a/mamweb/static/css/mamweb.css +++ b/mamweb/static/css/mamweb.css @@ -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; } @@ -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; diff --git a/seminar/admin.py b/seminar/admin.py index 3a680fc4..b86d933a 100644 --- a/seminar/admin.py +++ b/seminar/admin.py @@ -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): diff --git a/seminar/templates/seminar/archiv/cislo.html b/seminar/templates/seminar/archiv/cislo.html index 2978cc84..a398a6cb 100644 --- a/seminar/templates/seminar/archiv/cislo.html +++ b/seminar/templates/seminar/archiv/cislo.html @@ -27,6 +27,16 @@ {% endfor %} + {% if user.is_staff %} +
+

Orgovské odkazy

+ +
+ {% endif %} + {% if cislo.verejna_vysledkovka %}

Výsledkovka

{% else %} diff --git a/seminar/templates/seminar/soustredeni/seznam_soustredeni.html b/seminar/templates/seminar/soustredeni/seznam_soustredeni.html index 121d19b0..f7bc73a8 100644 --- a/seminar/templates/seminar/soustredeni/seznam_soustredeni.html +++ b/seminar/templates/seminar/soustredeni/seznam_soustredeni.html @@ -21,47 +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}}
- - Toto soustředění není veřejné, vidíte ho jen proto, - že jste přihlášení.
+ {% if soustredeni.verejne_db or user.is_staff %} + {% if not soustredeni.verejne_db and user.is_staff %} +
+ {% endif %} {# misto soustredeni TODO upravit#} -

- {{soustredeni.get_typ_display}} - {{soustredeni.misto}} -

- - {% if user.is_staff %} -
- Vytvořit novou fotogalerii
- Vygenerovat obálky pro účastníky -
- {% endif %} - {# popis soustredeni #} - {% if soustredeni.text %} - {% autoescape off %}{{soustredeni.text}}{% endautoescape %} - {% endif %} + {# popis soustredeni #} + {% if soustredeni.text %} + {% autoescape off %}{{soustredeni.text}}{% endautoescape %} + {% endif %} {% if user.is_authenticated %} {# Účastníci #}

Soustředění se zúčastnili tito účastníci:

@@ -73,9 +70,12 @@ {% endfor %} {% endif %} + {% if not soustredeni.verejne_db and user.is_staff %} +
{# 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 %} diff --git a/seminar/templates/seminar/titulnistrana.html b/seminar/templates/seminar/titulnistrana.html index c6c1a522..ae949d7e 100644 --- a/seminar/templates/seminar/titulnistrana.html +++ b/seminar/templates/seminar/titulnistrana.html @@ -22,23 +22,9 @@ M&M je korespondeční seminář. Několikrát do roka zdarma vydáváme ča

Do konce odeslání řešení zbývá:
{{ted|timesince:dead}}

- - - -
{% endif %} + {# Novinky #}

Novinky

{% include 'seminar/novinky.html' %} diff --git a/seminar/views.py b/seminar/views.py index 5a11f42a..bc43d6fc 100644 --- a/seminar/views.py +++ b/seminar/views.py @@ -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 @@ -72,16 +73,16 @@ class TitulniStranaView(generic.ListView): 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 @@ -344,28 +345,42 @@ class RocnikVysledkovkaView(RocnikView): ### Generovani obalek class CisloObalkyStruct: - resitele = None rocnik = None - problemy = None - -def cisloObalkyView(request,rocnik,cislo): + cisla = None + + +# 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):