Browse Source

Merge branch 'master' into stable

remotes/origin/temata v1.3
Bc. Petr Pecha 9 years ago
parent
commit
2eb9481d8d
  1. 2
      galerie/admin.py
  2. 2
      galerie/forms.py
  3. 20
      galerie/migrations/0004_nepovinna_galerie_u_obrazku.py
  4. 4
      galerie/models.py
  5. BIN
      galerie/static/galerie/prvky/dalsi.png
  6. BIN
      galerie/static/galerie/prvky/nahoru.png
  7. BIN
      galerie/static/galerie/prvky/predchozi.png
  8. 108
      galerie/templates/galerie/Galerie.html
  9. 135
      galerie/templates/galerie/GalerieNahled.html
  10. 96
      galerie/views.py
  11. 42
      mamweb/settings_common.py
  12. 9
      mamweb/settings_local.py
  13. 19
      mamweb/settings_prod.py
  14. 6
      mamweb/settings_test.py
  15. 169
      mamweb/static/css/mamweb.css
  16. 3
      mamweb/templates/base.html
  17. 1603
      obalky/lisak.eps
  18. 78
      obalky/obalky-template.tex
  19. 53
      obalky/obalky.py
  20. 26
      obalky/obalky.sql
  21. 21
      seminar/admin.py
  22. 3
      seminar/models.py
  23. 1603
      seminar/static/seminar/lisak.eps
  24. 103
      seminar/templates/seminar/archiv/obalky.tex
  25. 9
      seminar/templates/seminar/archiv/tituly.tex
  26. 10
      seminar/templates/seminar/soustredeni/seznam_soustredeni.html
  27. 6
      seminar/templatetags/tex.py
  28. 82
      seminar/tools.py
  29. 5
      seminar/urls.py
  30. 76
      seminar/views.py

2
galerie/admin.py

@ -34,7 +34,7 @@ class ObrazekAdmin(admin.ModelAdmin):
class GalerieAdmin(admin.ModelAdmin): class GalerieAdmin(admin.ModelAdmin):
model = Galerie model = Galerie
fields = ('zobrazit', 'nazev', 'titulni_obrazek', 'popis', 'galerie_up', 'soustredeni') fields = ('zobrazit', 'nazev', 'titulni_obrazek', 'popis', 'galerie_up', 'soustredeni', 'poradi')
list_display = ('nazev', 'pk', 'datum_zmeny', 'zobrazit', 'soustredeni') list_display = ('nazev', 'pk', 'datum_zmeny', 'zobrazit', 'soustredeni')
inlines = [GalerieInline] inlines = [GalerieInline]
actions = [zverejnit_fotogalerii, prepnout_fotogalerii_do_org_rezimu] actions = [zverejnit_fotogalerii, prepnout_fotogalerii_do_org_rezimu]

2
galerie/forms.py

@ -8,4 +8,4 @@ class KomentarForm(forms.Form):
class NewGalerieForm(forms.Form): class NewGalerieForm(forms.Form):
nazev = forms.CharField(label = "Název galerie", max_length = 100) nazev = forms.CharField(label = "Název galerie", max_length = 100)
popis = forms.CharField(label = "Popis", required = False, max_length = 2000, widget = forms.Textarea) #popis = forms.CharField(label = "Popis", required = False, max_length = 2000, widget = forms.Textarea)

20
galerie/migrations/0004_nepovinna_galerie_u_obrazku.py

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('galerie', '0003_add_galerie_poradi'),
]
operations = [
migrations.AlterField(
model_name='obrazek',
name='galerie',
field=models.ForeignKey(blank=True, to='galerie.Galerie', null=True),
preserve_default=True,
),
]

4
galerie/models.py

@ -77,7 +77,7 @@ class Obrazek(models.Model):
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) datum = models.DateTimeField('Datum pořízení fotografie', blank = True, null = True)
galerie = models.ForeignKey('Galerie') 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 self.nazev + " -- " + unicode(self.obrazek_velky.name) + " (" + str(self.datum) + ")"
@ -104,7 +104,7 @@ class Obrazek(models.Model):
datum_int[3], datum_int[4], datum_int[5]) datum_int[3], datum_int[4], datum_int[5])
jmeno = os.path.basename(self.obrazek_velky.file.name) jmeno = os.path.basename(self.obrazek_velky.file.name)
if not self.obrazek_stredni: if not self.obrazek_stredni:
Obrazek._vyrobMiniaturu(original, jmeno, 600, self.obrazek_stredni) Obrazek._vyrobMiniaturu(original, jmeno, 1024, self.obrazek_stredni)
if not self.obrazek_maly: if not self.obrazek_maly:
Obrazek._vyrobMiniaturu(original, jmeno, 200, self.obrazek_maly) Obrazek._vyrobMiniaturu(original, jmeno, 200, self.obrazek_maly)
super(Obrazek, self).save() super(Obrazek, self).save()

BIN
galerie/static/galerie/prvky/dalsi.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 15 KiB

BIN
galerie/static/galerie/prvky/nahoru.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
galerie/static/galerie/prvky/predchozi.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 15 KiB

108
galerie/templates/galerie/Galerie.html

@ -1,40 +1,85 @@
{% extends "galerie/Base.html" %} {% extends "galerie/Base.html" %}
{% block title %}{% block nadpis1a %}
{{galerie.nazev}} | Galerie {% block nadpis1a %}
{% endblock %}{% endblock %} {{galerie.nazev}}: {{ obrazek.popis | default:"Fotka" }}
{% endblock %}
{# přecházení mezi fotkami pomocí šipek #}
{% block script %}
{% with obrazky_predchozi|last as predchozi_obrazek %}
{% with obrazky_dalsi|first as dalsi_obrazek %}
<script type="text/javascript">
$(document).ready(function() {
$(document).keydown(function(e) {
{% if predchozi_obrazek %}
// doleva
if (e.which == 37) {
window.location.assign("../{{ predchozi_obrazek.pk }}#nahoru");
}
{% endif %}
{% if dalsi_obrazek %}
// doprava
if (e.which == 39) {
window.location.assign("../{{ dalsi_obrazek.pk }}#nahoru");
}
{% endif %}
if (e.which == 27) {
window.location.assign("../#obsah");
}
});
$("#prostredni").click(function() {
$("#prostredni").parent().append("<p style='text-align: center;'>Prohrál jsi</p>");
$("#prostredni").off("click");
});
})
</script>
{% endwith %}
{% endwith %}
{% endblock %}
{% block content %} {% block content %}
<h1><a title="Zpět na náhled fotek" href="../#obsah">{{galerie.nazev}}</a></h1>
{# TODO šipky na přecházeni dodelat ve stylech #} <h2>
{% for g in cesta %}
<a href="../../{{ g.pk }}">{{ g.nazev }}</a>{% if not forloop.last %} >{% endif %}
{% endfor %}
</h2>
<div class="galerie"> <div class="galerie">
{% if obrazky_predchozi %} {% if obrazky_predchozi %}
{% with obrazky_predchozi|last as predchozi_obrazek %} {% with obrazky_predchozi|last as predchozi_obrazek %}
<div id="popis"> <div>
<a title="Předchozí" class="predchozi_obrazek" href="../{{predchozi_obrazek.pk}}#popis"></a> <a title="Předchozí" class="predchozi_obrazek" href="../{{predchozi_obrazek.pk}}#nahoru"></a>
</div> </div>
{% endwith %} {% endwith %}
{% endif%} {% endif%}
<img src={{obrazek.obrazek_stredni.url}} <img src="{{obrazek.obrazek_stredni.url}}"
height="{{vyska}}" height="{{vyska}}"
width="{{sirka}}" width="{{sirka}}"
alt="{{obrazek.popis}}" alt="{{obrazek.popis}}"
class="obrazek"> class="obrazek" id="nahoru">
{% if obrazky_dalsi %} {% if obrazky_dalsi %}
{% with obrazky_dalsi|first as dalsi_obrazek %} {% with obrazky_dalsi|first as dalsi_obrazek %}
<div> <div>
<a title="Další" class="dalsi_obrazek" href="../{{dalsi_obrazek.pk}}#popis"></a> <a title="Další" class="dalsi_obrazek" href="../{{dalsi_obrazek.pk}}#nahoru"></a>
</div> </div>
{% endwith %} {% endwith %}
{% endif%} {% endif%}
</div> </div>
<!--<div>-->
<!--<a href="{{ obrazek.obrazek_velky.url }}">Obrázek v plné velikosti</a>-->
<!--</div>-->
{# Popisek fotky #} {# Popisek fotky #}
<div class="popis"> <div class="popis">
{% if preview %} {% if preview %}
<form action=".#popis" method="post"> <form action=".#nahoru" method="post">
{% csrf_token %} {% csrf_token %}
<table> <table>
<tr><td><label>Aktuální komentář:</label></td><td>{{obrazek.popis}}</td> <tr><td><label>Aktuální komentář:</label></td><td>{{obrazek.popis}}</td>
@ -50,16 +95,37 @@
</div> </div>
<div class="galerie_nahledy"> <div class="galerie_nahledy">
{% for obrazek in obrazky_predchozi %} {# odkaz na predchozi galerii #}
<a href="../{{obrazek.pk}}#popis"><img src="{{obrazek.obrazek_maly.url}}" height="100"></a> <div class="navigace">
{% endfor %} {% if predchozi_galerie %}
Předchozí: <a href="../../{{predchozi_galerie.pk}}/{{predchozi_galerie.obrazek_set.last.pk}}/#nahoru">
{{predchozi_galerie}}
</a>
{% endif %}
{# nahledy predchozich obrazku #}
{% for obrazek in obrazky_predchozi %}
<a href="../{{obrazek.pk}}#nahoru"><img src="{{obrazek.obrazek_maly.url}}" height="100"></a>
{% endfor %}
</div>
<img src={{obrazek.obrazek_maly.url}} <img src={{obrazek.obrazek_maly.url}}
height="{{obrazek.obrazek_maly.height}}" height="{{obrazek.obrazek_maly.height}}"
width="{{obrazek.obrazek_maly.width}}" width="{{obrazek.obrazek_maly.width}}"
alt="{{obrazek.popis}}" alt="{{obrazek.popis}}"
class="obrazek"> class="obrazek"
{% for obrazek in obrazky_dalsi %} id="prostredni">
<a href="../{{obrazek.pk}}#popis"><img src="{{obrazek.obrazek_maly.url}}" height="100"></a>
{% endfor %} <div class="navigace">
{# nahledy nasledujicich obrazku #}
{% for obrazek in obrazky_dalsi %}
<a href="../{{obrazek.pk}}#nahoru"><img src="{{obrazek.obrazek_maly.url}}" height="100"></a>
{% endfor %}
{# odkaz na nasledujici galerii #}
{% if nasledujici_galerie %}
Následující: <a href="../../{{nasledujici_galerie.pk}}/{{nasledujici_galerie.obrazek_set.first.pk}}/#nahoru">
{{nasledujici_galerie}}
</a>
{% endif %}
</div>
</div> </div>
{% endblock %} {% endblock %}

135
galerie/templates/galerie/GalerieNahled.html

@ -1,77 +1,106 @@
{% extends "galerie/Base.html" %} {% extends "galerie/Base.html" %}
{% block title %}{% block nadpis1a %} {% block nadpis1a %}
{{galerie.nazev}} | Galerie TODO title Galerie {{galerie.nazev}}
{% endblock %}{% endblock %} {% endblock %}
{% block content %} {% block content %}
<h2>{{galerie.nazev}}</h2>
<h2>
{% for g in cesta %}
{% if not forloop.last %}
<a href="../{{ g.pk }}">{{ g.nazev }}</a> >
{% else %}
{{ g.nazev }}
{% endif %}
{% endfor %}
</h2>
{% if not obrazky %}
<div class="galerie_hlavicka">
{% if galerie.titulni_obrazek %}
<img src="{{ galerie.titulni_obrazek.obrazek_stredni.url }}" style="border: 1px solid black;">
{% endif %}
</div>
{% endif %}
{# podgalerie #} {# podgalerie #}
{% if podgalerie or galerie.galerie_up %} {% if podgalerie or galerie.galerie_up %}
<h3> PODGALERIE </h3>
<ul> {% if sourozenci|length > 1 %}
{% if galerie.galerie_up %} {% for g in sourozenci %}
<li><a href="../{{galerie.galerie_up.pk}}">..</a> {% if g.pk != galerie.pk %}
<a href="../{{ g.pk }}">{{ g.nazev }}</a>
{% else %}
{{ g.nazev }}
{% endif %}
<span style="width: 1em; display: inline-block;"></span>
{% endfor %}
{% endif %} {% endif %}
{% for galerie in podgalerie %}
{% if galerie.zobrazit < 1 or user.is_staff %} {% if podgalerie %}
<li><a href="../{{galerie.pk}}">{{galerie}}</a> <div class="galerie_nahledy">
{% for galerie in podgalerie %}
<a href="../{{galerie.pk}}" class="podgalerie_nahled">
{% 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 %} />
{% endwith %}
{% endif %}
<div>
{{ galerie }}
</div>
</a>
{% if user.is_staff and galerie.zobrazit > 0 %} {% if user.is_staff and galerie.zobrazit > 0 %}
({{galerie.poradi}}) <div class="mam-org-only-galerie">
<span class="plus"><a href="plus/{{galerie.pk}}/">+</a></span> ({{galerie.poradi}})
<span class="minus"><a href="minus/{{galerie.pk}}/">-</a></span> <span class="plus"><a href="plus/{{galerie.pk}}/">+</a></span>
<span class="minus"><a href="minus/{{galerie.pk}}/">-</a></span>
</div>
{% endif %} {% endif %}
{% endif %} {% endfor %}
{% endfor %} </div>
</ul> {% endif %}
{% endif %} {% endif %}
{% if user.is_staff and galerie.zobrazit > 0 %} {% if user.is_staff and galerie.zobrazit > 0 %}
<ul> <div class="mam-org-only">
<li><a href="./new">VYTVOŘIT NOVOU PODGALERII </a> <a href="./new">Vytvořit novou podgalerii </a>
</ul> </div>
{% endif %} {% endif %}
{# obrazky v galerii #} {# obrazky v galerii #}
{% if obrazky %} {% if obrazky %}
<table class="galerie_nahled"> <div class="galerie_nahledy">
{% for obrazek in obrazky %} {% for obrazek in obrazky %}
{% if forloop.counter|add:-1|divisibleby:3 %} <a title="Zobrazit tuto fotografii" href="./{{obrazek.pk}}#nahoru" class="galerie_nahled"><span class="vystredeno"></span><img
<tr>
{% endif %}
<td class="vystredeno">
<a title="Zobrazit tuto fotografii" href="./{{obrazek.pk}}#popis"
class="jednoducha-galerie">
<img
src="{{obrazek.obrazek_maly.url}}" src="{{obrazek.obrazek_maly.url}}"
width={% widthratio obrazek.obrazek_maly.width 200 167 %} width={% widthratio obrazek.obrazek_maly.width 200 167 %}
height={% widthratio obrazek.obrazek_maly.height 200 167 %} /> height={% widthratio obrazek.obrazek_maly.height 200 167 %} />
</a> </a>
<!--<a href="{{obrazek.obrazek_velky.url}}"
class="javascript-galerie" data-lightbox="galerie" data-title="{{obrazek.popis}}"
style="display: none;">
<img
src="{{obrazek.obrazek_maly.url}}"
width={% widthratio obrazek.obrazek_maly.width 200 167 %}
height={% widthratio obrazek.obrazek_maly.height 200 167 %} />
</a>-->
</td>
{% if forloop.last %}
{% if not forloop.counter|divisibleby:3 %}
<td></td>
{% endif %}
{% if not forloop.counter|divisibleby:2 %}
<td></td>
{% endif %}
{% endif %}
{% if forloop.counter|divisibleby:3 or forloop.last %}
</tr>
{% endif %}
{% endfor %} {% endfor %}
</table> <br>
</div>
<div class="galerie_predchozi_nasledujici">
{% if predchozi %}
<div class="predchozi">
<a href="../{{ predchozi.pk }}">Předchozí: {{ predchozi.nazev }}</a>
</div>
{% endif %}
{% if nasledujici %}
<div class="nasledujici">
<a href="../{{ nasledujici.pk }}">Následující: {{ nasledujici.nazev }}</a>
</div>
{% endif %}
</div>
{% else %} {% else %}
<div class="zadne-vysledky"> {% if not podgalerie %}
V galerii nejsou žádné fotky. <div class="zadne-vysledky">
</div> V galerii nejsou žádné fotky.
</div>
{% endif %}
{% endif %} {% endif %}
{% endblock content %} {% endblock content %}

96
galerie/views.py

@ -20,23 +20,61 @@ def zobrazit(galerie, request):
raise Http404 raise Http404
return preview return preview
def cesta_od_korene(g):
"""Vrátí seznam galerií od kořene ke g"""
cesta = []
while g != None:
cesta.append(g)
g = g.galerie_up
return reversed(cesta)
def nahled(request, pk, soustredeni): def nahled(request, pk, soustredeni):
"""Zobrazeni nahledu vsech fotek ve skupine.""" """Zobrazeni nahledu vsech fotek ve skupine."""
galerie = get_object_or_404(Galerie, pk=pk) galerie = get_object_or_404(Galerie, pk=pk)
podgalerie = Galerie.objects.filter(galerie_up = galerie).order_by('poradi')
obrazky = Obrazek.objects.filter(galerie = galerie).order_by('datum') podgalerie = Galerie.objects.filter(galerie_up = galerie).order_by('poradi')
preview = zobrazit(galerie, request) if not request.user.is_staff:
return render(request, 'galerie/GalerieNahled.html', podgalerie = podgalerie.filter(zobrazit__lt=1)
{'galerie' : galerie,
'podgalerie' : podgalerie, obrazky = Obrazek.objects.filter(galerie = galerie).order_by('datum')
'obrazky' : obrazky, preview = zobrazit(galerie, request)
'preview' : preview,
}) sourozenci = []
if galerie.galerie_up:
sourozenci = galerie.galerie_up.galerie_set.all().order_by('poradi')
if not request.user.is_staff:
sourozenci = sourozenci.filter(zobrazit__lt=1)
predchozi = None
nasledujici = None
minuly = None
for g in sourozenci:
if g.pk == galerie.pk:
predchozi = minuly
if minuly != None and minuly.pk == galerie.pk:
nasledujici = g
break
minuly = g
cesta = cesta_od_korene(galerie)
return render(request, 'galerie/GalerieNahled.html',
{'galerie' : galerie,
'podgalerie' : podgalerie,
'obrazky' : obrazky,
'preview' : preview,
'cesta': cesta,
'sourozenci': sourozenci,
'predchozi': predchozi,
'nasledujici': nasledujici,
})
def detail(request, pk, fotka, soustredeni): def detail(request, pk, fotka, soustredeni):
"""Zobrazeni nahledu fotky s id 'fotka'.""" """Zobrazeni nahledu fotky s id 'fotka'."""
MAX_VYSKA = 600 MAX_VYSKA = 900
MAX_SIRKA = 600 MAX_SIRKA = 900
MAX_VYSKA_MALA = 100 MAX_VYSKA_MALA = 100
MAX_SIRKA_MALA = 200 MAX_SIRKA_MALA = 200
NAHLEDU = 1 NAHLEDU = 1
@ -64,12 +102,35 @@ def detail(request, pk, fotka, soustredeni):
# Obrazek neni v galerii/stitku. # Obrazek neni v galerii/stitku.
raise Http404 raise Http404
# Nacteni okolnich obrazku.
# Nacteni okolnich obrazku a galerii
# TODO vyjmout zjisteni predchozich a nasledujicich galerii
# a udelat z toho funkci, ktera se pouzije u nahledu
predchozi_galerie = None
nasledujici_galerie = None
obrazky_dalsi = obrazky[znacka+1:znacka+NAHLEDU+1] obrazky_dalsi = obrazky[znacka+1:znacka+NAHLEDU+1]
if znacka > NAHLEDU: if (znacka+1) > NAHLEDU:
obrazky_predchozi = obrazky[znacka-NAHLEDU:znacka] obrazky_predchozi = obrazky[znacka-NAHLEDU:znacka]
else: else:
obrazky_predchozi = obrazky[0:znacka] obrazky_predchozi = obrazky[0:znacka]
if galerie.poradi > 1:
predchozi_galerie = Galerie.objects.\
filter(galerie_up=galerie.galerie_up).\
filter(poradi=(galerie.poradi-1))
if predchozi_galerie:
predchozi_galerie = predchozi_galerie[0]
else:
predchozi_galerie = None
if (znacka+1) == len(obrazky):
nasledujici_galerie = Galerie.objects.\
filter(galerie_up=galerie.galerie_up).\
filter(poradi=(galerie.poradi+1))
if nasledujici_galerie:
nasledujici_galerie = nasledujici_galerie[0]
else:
nasledujici_galerie = None
# Preskalovani obrazku do vybraneho prostoru. # Preskalovani obrazku do vybraneho prostoru.
vyska = obrazek.obrazek_stredni.height vyska = obrazek.obrazek_stredni.height
@ -83,6 +144,8 @@ def detail(request, pk, fotka, soustredeni):
return render(request, 'galerie/Galerie.html', return render(request, 'galerie/Galerie.html',
{'galerie' : galerie, {'galerie' : galerie,
'predchozi_galerie' : predchozi_galerie,
'nasledujici_galerie' : nasledujici_galerie,
'obrazek' : obrazek, 'obrazek' : obrazek,
'vyska' : vyska, 'vyska' : vyska,
'sirka' : sirka, 'sirka' : sirka,
@ -90,6 +153,7 @@ def detail(request, pk, fotka, soustredeni):
'obrazky_dalsi' : obrazky_dalsi, 'obrazky_dalsi' : obrazky_dalsi,
'preview' : preview, 'preview' : preview,
'form' : form, 'form' : form,
'cesta': cesta_od_korene(galerie),
}) })
@ -113,7 +177,7 @@ def new_galerie(request, galerie, soustredeni):
# vytvoreni nove galerie # vytvoreni nove galerie
gal = Galerie() gal = Galerie()
gal.nazev = form.cleaned_data['nazev'] gal.nazev = form.cleaned_data['nazev']
gal.popis = form.cleaned_data['popis'] #gal.popis = form.cleaned_data['popis'] # popis nepouzivame
gal.zobrazit = 1 # galerie je v procesu vytvareni gal.zobrazit = 1 # galerie je v procesu vytvareni
''' pokud je to podgalerie pridej nadrazenou galerii ''' pokud je to podgalerie pridej nadrazenou galerii
a nadrazene soustredeni nechej volne, a nadrazene soustredeni nechej volne,

42
mamweb/settings_common.py

@ -57,6 +57,7 @@ TEMPLATE_LOADERS = (
) )
MIDDLEWARE_CLASSES = ( MIDDLEWARE_CLASSES = (
'reversion.middleware.RevisionMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware', 'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware', 'django.middleware.csrf.CsrfViewMiddleware',
@ -186,7 +187,48 @@ try:
except: except:
SECRET_KEY = '12345zmr_k53a*@f4q_+ji^o@!pgpef*5&8c7zzdqwkdlkj' SECRET_KEY = '12345zmr_k53a*@f4q_+ji^o@!pgpef*5&8c7zzdqwkdlkj'
# Logging
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'verbose': {
'format': '%(levelname)s %(asctime)s %(module)s: %(message)s'
},
},
'loggers': {
'django': {
'handlers': ['console'],
'level': 'DEBUG',
},
# Catch-all logger
'': {
'handlers': ['console'], # Add 'mail_admins' in prod and test
'level': 'DEBUG',
},
},
'handlers': {
'console': {
'level': 'WARNING', ## Set to 'DEBUG' in local
'class': 'logging.StreamHandler',
'formatter': 'verbose',
},
'mail_admins': {
'level': 'ERROR',
'class': 'django.utils.log.AdminEmailHandler',
'formatter': 'verbose',
},
},
}
# MaM specific # MaM specific

9
mamweb/settings_local.py

@ -36,3 +36,12 @@ DATABASES = {
} }
} }
# LOGGING
# set to 'DEBUG' for EXTRA verbose output
LOGGING['handlers']['console']['level'] = 'INFO'
# So that it is not necessary to restart the server every time a template is
# changed
TEMPLATE_LOADERS = ('django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader')

19
mamweb/settings_prod.py

@ -60,20 +60,9 @@ CSRF_COOKIE_SECURE = True
# LOGGING = { # LOGGING
# 'version': 1,
# 'disable_existing_loggers': True, LOGGING['loggers']['']['handlers'] = ['console', 'mail_admins']
# 'handlers': { LOGGING['loggers']['django']['handlers'] = ['console', 'mail_admins']
# 'console': {
# 'class': 'logging.StreamHandler',
# },
# },
# 'loggers': {
# 'django': {
# 'handlers': ['console'],
# 'level': os.getenv('DJANGO_LOG_LEVEL', 'INFO'),
# },
# },
# }

6
mamweb/settings_test.py

@ -50,7 +50,6 @@ import os
SERVER_EMAIL = 'mamweb-test-errors@mam.mff.cuni.cz' SERVER_EMAIL = 'mamweb-test-errors@mam.mff.cuni.cz'
ADMINS = [ ADMINS = [
('Petr Pecha', 'nejlepsitextovyeditorjevim@gmail.com'), ('Petr Pecha', 'nejlepsitextovyeditorjevim@gmail.com'),
('Tomas Gavenciak', 'gavento@gmail.com'),
] ]
@ -59,5 +58,10 @@ ADMINS = [
SESSION_COOKIE_SECURE = True SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True CSRF_COOKIE_SECURE = True
# LOGGING
LOGGING['loggers']['']['handlers'] = ['console', 'mail_admins']
LOGGING['loggers']['django']['handlers'] = ['console', 'mail_admins']

169
mamweb/static/css/mamweb.css

@ -1,4 +1,4 @@
@import url(http://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,400,300,600&subset=latin,latin-ext); @import url(https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,400,300,600&subset=latin,latin-ext);
body { body {
font-family: 'Open Sans', sans-serif; font-family: 'Open Sans', sans-serif;
@ -15,6 +15,7 @@ body {
background: #fff0d7; background: #fff0d7;
padding: 10px; padding: 10px;
margin: 10px -10px; margin: 10px -10px;
border: orange 2px dashed;
} }
table .border-r { table .border-r {
@ -150,6 +151,10 @@ div.menu li.selected a {
z-index: 15px; z-index: 15px;
} }
h2 a:hover {
text-decoration: none;
}
#submenu { #submenu {
position: relative; position: relative;
top: -15px; top: -15px;
@ -440,6 +445,13 @@ div.zadani_azad_termin {
/* galerie */ /* galerie */
/* velká fotka */
.galerie .obrazek {
max-width: 100%;
height: auto;
width: auto\9; /* ie8 */
}
.predchozi_obrazek{ .predchozi_obrazek{
position: absolute; position: absolute;
z-index: 1; z-index: 1;
@ -467,27 +479,162 @@ div.zadani_azad_termin {
background-repeat: no-repeat; background-repeat: no-repeat;
} }
.galerie{ .galerie {
position: relative; position: relative;
text-align: center;
/*width: 100%;*/
margin: 20px auto 0 auto;
}
.galerie h2 {
text-align: center;
}
.galerie_hlavicka {
margin: 30px auto 30px auto;
}
.popis {
margin: 10px 10px 30px 0px;
text-align: center;
}
#nahoru {
text-align: center;
} }
.galerie_nahledy{ .galerie_nahledy{
margin: 1em 0; /*margin: 1em 0;*/
margin: 0 auto 30px auto;
text-align: center; text-align: center;
overflow: auto;
} }
.galerie_index{
width: 100%; .galerie_nahledy div.navigace {
display: inline-block;
width: 150px;
}
/*.galerie_nahledy img{*/
/*margin: 0 10px 0 10px;*/
/*}*/
/*.galerie_nahledy a{*/
/*height: 100%;*/
/*width: 100%;*/
/*}*/
.galerie_nahled { /* frame */
display: block;
position: relative;
float: left;
width: 200px;
height: 200px;
text-align: center;
border: solid;
border-width: 2px;
border-radius: 5px;
/*border-color: #ffa500;*/
border-color: #ffd546;
/*background-color: #ffb52d;*/
background-color: white;
white-space: nowrap;
margin: 10px 20px 10px 0px;
} }
.galerie_index td{
width: 50%; .galerie_nahled:hover {
background-color: #ffd546;
border-color: #ffa500;
} }
.galerie_nahled{
width: 100%; .vystredeno{ /* helper */
display: inline-block;
height: 100%;
vertical-align: middle;
} }
.galerie_nahled td{
width: 33%; .galerie_nahled img {
vertical-align: middle;
max-height: 180px;
max-width: 180px;
/*border: 1px solid white;*/
}
.galerie_nahled img, .podgalerie_nahled img {
border-radius: 2px;
}
.galerie_nahled div {
position: absolute;
bottom: 0px;
width: 100%;
text-align: center;
}
.podgalerie_nahled {
display: block;
position: relative;
float: left;
width: 200px;
height: 200px;
text-align: center;
border: solid;
border-width: 2px;
border-radius: 5px;
border-color: #ffa500;
/*border-color: #ffd546;*/
background-color: #ffd546;
/*background-color: white;*/
white-space: nowrap;
margin: 10px 20px 10px 0px;
font-weight: bold;
}
.podgalerie_nahled:hover {
background-color: #ffa500;
}
.podgalerie_nahled img {
margin-top: 20px;
margin-bottom: 15px;
} }
/* plus a minus tlacitka */
.mam-org-only-galerie {
background: #fff0d7;
padding: 10px;
margin: 10px 10px 10px -20px;
border: orange 2px dashed;
float: left;
}
.mam-org-only-galerie a{
padding: 3px 5px;
margin: 5px;
border-radius: 20px;
background-color: lightblue;
color: black;
float: left;
}
/* Odkazy na předchozí a následující podgalerii */
.galerie_predchozi_nasledujici {
overflow: auto;
margin: 10px auto 10px auto;
}
.galerie_predchozi_nasledujici .predchozi {
float: left;
}
.galerie_predchozi_nasledujici .nasledujici {
float: right;
}
/* titulni stranka */ /* titulni stranka */
.zjistit_vic{ .zjistit_vic{

3
mamweb/templates/base.html

@ -29,6 +29,9 @@
src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"> src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script> </script>
{# script specifický pro stránku #}
{% block script %}{% endblock %}
</head> </head>
<body class='{% if user.is_staff %}org-logged-in{% endif %}'> <body class='{% if user.is_staff %}org-logged-in{% endif %}'>
{% if user.is_staff %} {% if user.is_staff %}

1603
obalky/lisak.eps

File diff suppressed because it is too large

78
obalky/obalky-template.tex

@ -0,0 +1,78 @@
\input czech.sty
\input epsf
\special{landscape}
\nopagenumbers
\hoffset=-1in
\voffset=-1in
\advance\voffset by 0.9cm
%nove pridano, aby to fungovalo...
\advance\hoffset by 6.5cm
\hsize=22cm
\vsize=16cm
\font\adrfonta=csssbx10 at 14pt
\font\adrfontb=csssbx10 at 12pt
\font\adrfontc=csss12
\font\tofont=csr12 at 16pt
\newdimen\fromskip
\newdimen\toskip
\fromskip=4.35cm
\toskip=13.2cm
\def\first{\relax}
\catcode`_=13
%\catcode`_=12
\def_{$\_$}
\advance\voffset by 2.5cm
\def\obalka#1#2#3#4#5#6#7{
\def\jmeno{#1}
\def\prijm{#2}
\def\skola{#3}
\def\popis{}
\def\first{}
\def\ulice{#4}
\def\PSC{#5}
\def\mesto{#6}
\def\stat{#7}
\vskip-4mm\vbox to 0pt{\hbox to 0pt{\hskip1.4cm\epsfysize=2.55cm\epsfbox{lisak.eps}\hss}\vss}
\baselineskip=13pt
\parindent=\fromskip
\line{\indent\adrfonta Časopis M\&M,\hfil}
\vskip3pt
\line{\indent\adrfontb OVVP UK MFF\hfil}
\vskip3pt
\line{\indent\adrfontc Ke Karlovu 3, 121 16 Praha 2\hfil}
\line{\indent\adrfontc Tel.: +420 221 911 235\hss}
\line{\indent\adrfontc mam@atrey.karlin.mff.cuni.cz\hfil}
\vskip6.15cm
\vbox to 0pt{\parindent=1.4cm\hsize=\toskip\advance\hsize by -1cm
\vbox to 60pt{\vfil} \popis\vss}
\parindent=\toskip
\baselineskip=18pt
\line{\indent\tofont\first\hfil}
\line{\indent\tofont\jmeno\ \prijm\hfil}
\ifx \skola \empty
{}
\else
\line{\indent\tofont\skola\hfil}
\fi
\line{\indent\tofont\ulice\hfil}
\line{\tofont\item{\PSC} \mesto\hfil}
\vskip5pt
\line{\indent\tofont\stat\hfil}
\vfil\eject
}
%\obalka{Lenka}{Kopfová}{Leknínová 10}{746 01}{Opava}

53
obalky/obalky.py

@ -0,0 +1,53 @@
#!/usr/bin/python
#coding: utf-8
import psycopg2
import sys
import subprocess
import re
dbname="mam-prod"
user="mam"
conn = psycopg2.connect("dbname={0} user={1}".format(dbname,user))
cur = conn.cursor()
names = []
with open("obalky.sql") as qfile, open("obalky-template.tex") as texheader, open("obalky.tex","w") as texout :
texout.write(texheader.read())
cur.execute(qfile.read())
for row in cur.fetchall():
(muz,jmeno,prijmeni,skola,ulice,mesto,psc,stat)=row
if (stat=='CZ'):
stat = ""
elif (stat=='SK'):
stat = "Slovenská republika"
else:
print("Neznamy stat: {}\n".format(stat))
if (skola==None):
skola=""
psc = psc.replace(" ","")
psc = psc[0:3]+" "+psc[3:]
texout.write("\\obalka{{{0}}}{{{1}}}{{{2}}}{{{3}}}{{{4}}}{{{5}}}{{{6}}}\n".format(jmeno,prijmeni,skola,ulice,psc,mesto,stat))
names.append((jmeno,prijmeni))
texout.write("\\bye\n")
cur.close()
conn.close()
print("Spoustim csplain ...")
output = subprocess.check_output(["csplain","obalky.tex"],stderr=subprocess.STDOUT)
page = 0
for line in output.decode("utf-8").splitlines():
pmatch = re.search("\[([0-9]+)\]",line)
if pmatch:
page = int(pmatch.group(1))
errmatch = re.match("Overfull",line)
if errmatch:
print("Preteceni na strane",page,"u osoby",names[page][0],names[page][1])
print("Spoustim dvipdf ...")
subprocess.call(["dvipdf","obalky.dvi"])
print("Hotovo.")

26
obalky/obalky.sql

@ -0,0 +1,26 @@
WITH akt_rocnik AS (
SELECT rocnik FROM seminar_rocniky
WHERE id=(SELECT aktualni_rocnik_id FROM seminar_nastaveni)
), id_rocniku AS (
SELECT id,prvni_rok FROM seminar_rocniky
WHERE rocnik=(SELECT * FROM akt_rocnik) OR rocnik=(SELECT * FROM akt_rocnik)-1
), id_cisel AS (
SELECT seminar_cisla.id FROM seminar_cisla
INNER JOIN id_rocniku ON rocnik_id=id_rocniku.id
), problemy AS (
SELECT seminar_problemy.id FROM seminar_problemy
INNER JOIN id_cisel ON cislo_zadani_id = id_cisel.id
), resitele AS(
SELECT DISTINCT resitel_id FROM seminar_reseni
INNER JOIN problemy ON problem_id=problemy.id
)
SELECT pohlavi_muz,jmeno,prijmeni,NULL AS skola,ulice,mesto,psc,stat FROM seminar_resitele
INNER JOIN resitele ON seminar_resitele.id=resitel_id
WHERE zasilat='domu' AND rok_maturity > (SELECT MAX(prvni_rok) FROM id_rocniku)
UNION
SELECT res.pohlavi_muz,res.jmeno,res.prijmeni,sk.nazev,sk.ulice,sk.mesto,sk.psc,sk.stat
FROM seminar_resitele AS res
INNER JOIN resitele ON res.id=resitel_id
INNER JOIN seminar_skoly AS sk ON sk.id=skola_id
WHERE zasilat='do_skoly' AND rok_maturity > (SELECT MAX(prvni_rok) FROM id_rocniku)
ORDER BY prijmeni ASC, jmeno ASC

21
seminar/admin.py

@ -3,7 +3,7 @@
from django.contrib import admin from django.contrib import admin
from django import forms from django import forms
from django.forms import widgets from django.forms import widgets
import reversion from reversion.admin import VersionAdmin
from solo.admin import SingletonModelAdmin from solo.admin import SingletonModelAdmin
from ckeditor.widgets import CKEditorWidget from ckeditor.widgets import CKEditorWidget
from django.db.models import Count from django.db.models import Count
@ -165,7 +165,7 @@ class Soustredeni_UcastniciInline(admin.TabularInline):
### Resitel ### Resitel
class ResitelAdmin(reversion.VersionAdmin): class ResitelAdmin(VersionAdmin):
form = autocomplete_light.modelform_factory(Resitel, autocomplete_fields=['skola'], fields=['skola']) form = autocomplete_light.modelform_factory(Resitel, autocomplete_fields=['skola'], fields=['skola'])
fieldsets = [ fieldsets = [
(None, {'fields': ['jmeno', 'prijmeni', 'user']}), (None, {'fields': ['jmeno', 'prijmeni', 'user']}),
@ -192,7 +192,7 @@ admin.site.register(Resitel, ResitelAdmin)
### Skola ### Skola
class SkolaAdmin(reversion.VersionAdmin): class SkolaAdmin(VersionAdmin):
fieldsets = [ fieldsets = [
(None, {'fields': ['nazev', 'kratky_nazev', 'je_zs', 'je_ss']}), (None, {'fields': ['nazev', 'kratky_nazev', 'je_zs', 'je_ss']}),
(u'Interní ID', {'fields': ['aesop_id', 'izo'], 'classes': ['collapse']}), (u'Interní ID', {'fields': ['aesop_id', 'izo'], 'classes': ['collapse']}),
@ -209,7 +209,7 @@ admin.site.register(Skola, SkolaAdmin)
### Cislo ### Cislo
class CisloAdmin(reversion.VersionAdmin): class CisloAdmin(VersionAdmin):
fieldsets = [ fieldsets = [
(None, {'fields': ['cislo', 'rocnik', 'verejne_db', 'verejna_vysledkovka', 'poznamka', 'pdf']}), (None, {'fields': ['cislo', 'rocnik', 'verejne_db', 'verejna_vysledkovka', 'poznamka', 'pdf']}),
(u'Data', {'fields': ['datum_vydani', 'datum_deadline']}), (u'Data', {'fields': ['datum_vydani', 'datum_deadline']}),
@ -232,7 +232,7 @@ admin.site.register(Cislo, CisloAdmin)
### Rocnik ### Rocnik
class RocnikAdmin(reversion.VersionAdmin): class RocnikAdmin(VersionAdmin):
fieldsets = [ fieldsets = [
(None, {'fields': ['rocnik', 'prvni_rok', 'exportovat']}), (None, {'fields': ['rocnik', 'prvni_rok', 'exportovat']}),
] ]
@ -264,7 +264,7 @@ admin.site.register(Rocnik, RocnikAdmin)
### Reseni ### Reseni
class ReseniAdmin(reversion.VersionAdmin): class ReseniAdmin(VersionAdmin):
form = autocomplete_light.modelform_factory(Reseni, autocomplete_fields=['problem', 'resitel'], fields=['problem', 'resitel']) form = autocomplete_light.modelform_factory(Reseni, autocomplete_fields=['problem', 'resitel'], fields=['problem', 'resitel'])
fieldsets = [ fieldsets = [
(None, {'fields': ['problem', 'resitel', 'forma', 'body', 'cislo_body', 'timestamp']}), (None, {'fields': ['problem', 'resitel', 'forma', 'body', 'cislo_body', 'timestamp']}),
@ -299,7 +299,7 @@ class ProblemAdminForm(forms.ModelForm):
model = Problem model = Problem
exclude = [] exclude = []
class ProblemAdmin(reversion.VersionAdmin): class ProblemAdmin(VersionAdmin):
form = ProblemAdminForm form = ProblemAdminForm
fieldsets = [ fieldsets = [
(None, {'fields': ['nazev', 'typ', 'stav', 'autor', 'zamereni', 'body', 'timestamp', 'import_dakos_id']}), (None, {'fields': ['nazev', 'typ', 'stav', 'autor', 'zamereni', 'body', 'timestamp', 'import_dakos_id']}),
@ -310,6 +310,7 @@ class ProblemAdmin(reversion.VersionAdmin):
list_select_related = True list_select_related = True
search_fields = ['nazev', 'text_zadani', 'text_reseni', 'text_org'] search_fields = ['nazev', 'text_zadani', 'text_reseni', 'text_org']
view_on_site = Problem.verejne_url view_on_site = Problem.verejne_url
ordering = ['-timestamp']
def get_queryset(self, request): def get_queryset(self, request):
qs = super(ProblemAdmin, self).get_queryset(request) qs = super(ProblemAdmin, self).get_queryset(request)
@ -354,7 +355,7 @@ class SoustredeniAdminForm(forms.ModelForm):
model = Soustredeni model = Soustredeni
exclude = [] exclude = []
class SoustredeniAdmin(reversion.VersionAdmin): class SoustredeniAdmin(VersionAdmin):
form = SoustredeniAdminForm form = SoustredeniAdminForm
fieldsets = [ fieldsets = [
(None, {'fields': ['rocnik', 'misto', 'typ', 'verejne_db', 'exportovat', 'text']}), (None, {'fields': ['rocnik', 'misto', 'typ', 'verejne_db', 'exportovat', 'text']}),
@ -399,7 +400,7 @@ def zneverejnit_novinky(modeladmin, request, queryset):
zneverejnit_novinky.short_description = 'Zneveřejnit vybrané novinky' zneverejnit_novinky.short_description = 'Zneveřejnit vybrané novinky'
class NovinkyAdmin(admin.ModelAdmin): class NovinkyAdmin(VersionAdmin):
form = NovinkyAdminForm form = NovinkyAdminForm
list_display = ['datum', 'autor', 'text', 'zverejneno', 'obrazek'] list_display = ['datum', 'autor', 'text', 'zverejneno', 'obrazek']
actions = [zverejnit_novinky, zneverejnit_novinky] actions = [zverejnit_novinky, zneverejnit_novinky]
@ -444,7 +445,7 @@ deaktivovat_organizatory.short_description = 'Deaktivovat organizátory'
@admin.register(Organizator) @admin.register(Organizator)
class OrganizatorAdmin(admin.ModelAdmin): class OrganizatorAdmin(VersionAdmin):
list_filter = ['organizuje_do_roku'] list_filter = ['organizuje_do_roku']
list_display = [jmeno_organizatora, je_organizator_aktivni,] list_display = [jmeno_organizatora, je_organizator_aktivni,]
actions = [zaktivovat_organizatory, deaktivovat_organizatory,] actions = [zaktivovat_organizatory, deaktivovat_organizatory,]

3
seminar/models.py

@ -630,6 +630,7 @@ class Soustredeni(SeminarModelBase):
return reverse('seminar_seznam_soustredeni') return reverse('seminar_seznam_soustredeni')
@reversion.register(ignore_duplicate_revisions=True)
@python_2_unicode_compatible @python_2_unicode_compatible
class Soustredeni_Ucastnici(models.Model): class Soustredeni_Ucastnici(models.Model):
@ -747,6 +748,7 @@ class Nastaveni(SingletonModel):
return False return False
@reversion.register(ignore_duplicate_revisions=True)
@python_2_unicode_compatible @python_2_unicode_compatible
class Novinky(models.Model): class Novinky(models.Model):
datum = models.DateField(auto_now_add=True) datum = models.DateField(auto_now_add=True)
@ -765,6 +767,7 @@ class Novinky(models.Model):
verbose_name_plural = 'Novinky' verbose_name_plural = 'Novinky'
@reversion.register(ignore_duplicate_revisions=True)
@python_2_unicode_compatible @python_2_unicode_compatible
class Organizator(models.Model): class Organizator(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, verbose_name='Osoba', user = models.OneToOneField(settings.AUTH_USER_MODEL, verbose_name='Osoba',

1603
seminar/static/seminar/lisak.eps

File diff suppressed because it is too large

103
seminar/templates/seminar/archiv/obalky.tex

@ -0,0 +1,103 @@
{% autoescape off %}
{% load staticfiles %}
{% load tex %}
\input czech.sty
\input epsf
\special{landscape}
\nopagenumbers
\hoffset=-1in
\voffset=-1in
\advance\voffset by 0.9cm
%nove pridano, aby to fungovalo...
\advance\hoffset by 6.5cm
\hsize=22cm
\vsize=16cm
\font\adrfonta=csssbx10 at 14pt
\font\adrfontb=csssbx10 at 12pt
\font\adrfontc=csss12
\font\tofont=csr12 at 16pt
\newdimen\fromskip
\newdimen\toskip
\fromskip=4.35cm
\toskip=13.2cm
\def\first{\relax}
\catcode`_=13
%\catcode`_=12
\def_{$\_$}
\advance\voffset by 2.5cm
\def\obalka#1#2#3#4#5#6#7{
\def\jmeno{#1}
\def\prijm{#2}
\def\skola{#3}
\def\popis{}
\def\first{}
\def\ulice{#4}
\def\PSC{#5}
\def\mesto{#6}
\def\stat{#7}
\vskip-4mm\vbox to 0pt{\hbox to 0pt{\hskip1.4cm\epsfysize=2.55cm\epsfbox{lisak.eps}\hss}\vss}
\baselineskip=13pt
\parindent=\fromskip
\line{\indent\adrfonta Časopis M\&M,\hfil}
\vskip3pt
\line{\indent\adrfontb OVVP UK MFF\hfil}
\vskip3pt
\line{\indent\adrfontc Ke Karlovu 3, 121 16 Praha 2\hfil}
\line{\indent\adrfontc Tel.: +420 221 911 235\hss}
\line{\indent\adrfontc mam@atrey.karlin.mff.cuni.cz\hfil}
\vskip6.15cm
\vbox to 0pt{\parindent=1.4cm\hsize=\toskip\advance\hsize by -1cm
\vbox to 60pt{\vfil} \popis\vss}
\parindent=\toskip
\baselineskip=18pt
\line{\indent\tofont\first\hfil}
\line{\indent\tofont\jmeno\ \prijm\hfil}
\ifx \skola \empty
{}
\else
\line{\indent\tofont\skola\hfil}
\fi
\line{\indent\tofont\ulice\hfil}
\line{\tofont\item{\PSC} \mesto\hfil}
\vskip5pt
\line{\indent\tofont\stat\hfil}
\vfil\eject
}
{% for r in resitele %}
{% spaceless %}
{% if r.zasilat == "do_skoly" %}
{% if r.stat == "CZ" %}
\obalka{{r.jmeno|sloz}}{{r.prijmeni|sloz}}{{r.skola.nazev|sloz}}{{r.skola.ulice|sloz}}{{r.skola.psc|sloz}}{{r.skola.mesto|sloz}}{{''|sloz}}
{% else %}
\obalka{{r.jmeno|sloz}}{{r.prijmeni|sloz}}{{r.skola.nazev|sloz}}{{r.skola.ulice|sloz}}{{r.skola.psc|sloz}}{{r.skola.mesto|sloz}}{{r.stat.name|sloz}}
{% endif %}
{% elif r.zasilat == "domu" %}
{% if r.stat == "CZ" %}
\obalka{{r.jmeno|sloz}}{{r.prijmeni|sloz}}{{''|sloz}}{{r.ulice|sloz}}{{r.psc|sloz}}{{r.mesto|sloz}}{{''|sloz}}
{% else %}
\obalka{{r.jmeno|sloz}}{{r.prijmeni|sloz}}{{''|sloz}}{{r.ulice|sloz}}{{r.psc|sloz}}{{r.mesto|sloz}}{{r.stat.name|sloz}}
{% endif %}
{% else %}
% zasilat: {{r.zasilat}}
%\obalka{{r.jmeno|sloz}}{{r.prijmeni|sloz}}{{''|sloz}}{{r.ulice|sloz}}{{r.psc|sloz}}{{r.mesto|sloz}}{{r.stat.name|sloz}}
{% endif %}
{% endspaceless %}
{% endfor %}
\bye
{% endautoescape %}

9
seminar/templates/seminar/archiv/tituly.tex

@ -0,0 +1,9 @@
{% autoescape off %}
{% load tex %}
{% for r in resitele %}
{% spaceless %}
\def\{{r.ascii}}{\titul{{r.titul|sloz}}\relax}
{% endspaceless %}
{% endfor %}
{% endautoescape %}

10
seminar/templates/seminar/soustredeni/seznam_soustredeni.html

@ -43,19 +43,19 @@
{% 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>
<a href="../{{soustredeni.pk}}/fotogalerie/{{galerie.pk}}">FOTOGALERIE: {{galerie}}</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>
{% endif %} {% endif %}
{% endfor %} {% endfor %}
{% endif %} {% endif %}
</ul>
{% if user.is_staff %} {% if user.is_staff %}
<li> <div class="mam-org-only">
<a href="../{{soustredeni.pk}}/fotogalerie/0/new/"> VYTVOŘIT NOVOU FOTOGALERII </a> <a href="../{{soustredeni.pk}}/fotogalerie/0/new/">Vytvořit novou fotogalerii</a>
</li> </div>
{% endif %} {% endif %}
</ul>
{# popis soustredeni #} {# popis soustredeni #}
{% if soustredeni.text %} {% if soustredeni.text %}

6
seminar/templatetags/tex.py

@ -0,0 +1,6 @@
from django import template
register = template.Library()
@register.filter(name='sloz')
def sloz(value):
return u"{{{}}}".format(value)

82
seminar/tools.py

@ -0,0 +1,82 @@
# -*- coding: utf-8 -*-
import logging as log
from .models import Resitel
import reversion
def merge_props(r1, r2, prop, pretend=True, smaller=False, equal=True):
"""Merge r2.`prop` into r1.`prop`.
If r1.`prop` unset, use r1.`prop`=r2.`prop`.
If both set and equal=True, warn if not equal.
If both set and smaller=True, use the smaller one.
With pretend=True does not modify r1.
"""
a1 = r1.__getattribute__(prop)
a2 = r2.__getattribute__(prop)
if not a1:
if not pretend:
r1.__setattr__(prop, a2)
elif a2:
if equal and a1 != a2:
log.warn(u"merge: Ruzna %s: %s VS %s", prop, a1, a2)
if smaller:
if not pretend:
r1.__setattr__(prop, min(a1, a2))
def merge_Resitel(rbase, rmerge, pretend=True):
"""Zahrne data a vztahy Resitele rmerge do Resitele rbase, pak smaze rmerge.
Selze pro uzivatele s user!=NULL. S pretend=True nezmeni databazi.
"""
# Ma relace: skola
# Je v relaci: user, reseni, soustredeni_ucastnici, vysledky_base(VIEW)
log.info(u"merge: %s <- %s", unicode(rbase), unicode(rmerge))
assert not rbase.user
assert not rmerge.user
assert rbase != rmerge
if (rbase.jmeno != rmerge.jmeno) or (rbase.prijmeni != rmerge.prijmeni):
log.error(u"merge: Ruzna jmena: %s VS %s", rbase, rmerge)
if rbase.rok_maturity != rmerge.rok_maturity:
log.error(u"merge: Ruzne roky maturity: %s VS %s", rbase.rok_maturity, rmerge.rok_maturity)
with reversion.create_revision():
reversion.set_comment('Merge duplicitnich Resitelu: %r <- %r' % (rbase.pk, rmerge.pk))
merge_props(rbase, rmerge, 'skola', pretend=pretend)
merge_props(rbase, rmerge, 'datum_narozeni', pretend=pretend)
merge_props(rbase, rmerge, 'datum_prihlaseni', pretend=pretend)
merge_props(rbase, rmerge, 'datum_souhlasu_zasilani', pretend=pretend, smaller=True, equal=False)
merge_props(rbase, rmerge, 'datum_souhlasu_udaje', pretend=pretend, smaller=True, equal=False)
merge_props(rbase, rmerge, 'email', pretend=pretend)
if rmerge.import_mamoper_id and not pretend:
rbase.import_mamoper_id += ' ' + rmerge.import_mamoper_id
if rmerge.poznamka and not pretend:
rbase.poznamka += ' ' + rmerge.poznamka
merge_props(rbase, rmerge, 'mesto', pretend=pretend)
merge_props(rbase, rmerge, 'pohlavi_muz', pretend=pretend)
merge_props(rbase, rmerge, 'psc', pretend=pretend)
merge_props(rbase, rmerge, 'stat', pretend=pretend)
merge_props(rbase, rmerge, 'telefon', pretend=pretend)
merge_props(rbase, rmerge, 'ulice', pretend=pretend)
merge_props(rbase, rmerge, 'zasilat', pretend=pretend)
for res in rmerge.reseni.all():
if not pretend:
res.resitel = rbase
res.save()
for uc in rmerge.soustredeni_ucastnici_set.all():
if not pretend:
uc.resitel = rbase
uc.save()
if not pretend:
rmerge.delete()
rbase.save()

5
seminar/urls.py

@ -18,6 +18,7 @@ urlpatterns = patterns('',
name = 'seminar_seznam_soustredeni'), name = 'seminar_seznam_soustredeni'),
url(r'^soustredeni/probehlo/(?P<soustredeni>\d+)/$', views.SoustredeniView.as_view(), name='seminar_soustredeni'), url(r'^soustredeni/probehlo/(?P<soustredeni>\d+)/$', views.SoustredeniView.as_view(), name='seminar_soustredeni'),
url(r'^soustredeni/(?P<soustredeni>\d+)/fotogalerie/', include('galerie.urls')), url(r'^soustredeni/(?P<soustredeni>\d+)/fotogalerie/', include('galerie.urls')),
url(r'^soustredeni/(?P<soustredeni>\d+)/obalky.pdf', views.soustredeniObalkyView,name='seminar_soustredeni_obalky'),
url(r'^zadani/aktualni/$', views.AktualniZadaniView, name='seminar_aktualni_zadani'), url(r'^zadani/aktualni/$', views.AktualniZadaniView, name='seminar_aktualni_zadani'),
url(r'^zadani/temata/$', views.ZadaniTemataView, name='seminar_temata'), url(r'^zadani/temata/$', views.ZadaniTemataView, name='seminar_temata'),
@ -35,4 +36,8 @@ urlpatterns = patterns('',
url(r'^aesop-export/mam-sous-(?P<datum_zacatku>[\d-]+)\.csv$', export.ExportSousView.as_view(), name='seminar_export_sous'), url(r'^aesop-export/mam-sous-(?P<datum_zacatku>[\d-]+)\.csv$', export.ExportSousView.as_view(), name='seminar_export_sous'),
url(r'^aesop-export/index.csv$', export.ExportIndexView.as_view(), name='seminar_export_index'), url(r'^aesop-export/index.csv$', export.ExportIndexView.as_view(), name='seminar_export_index'),
url(r'^cislo/(?P<rocnik>\d+).(?P<cislo>\d+)/vysledkovka.tex$', views.CisloVysledkovkaView.as_view(), name='seminar_cislo_vysledkovka'), url(r'^cislo/(?P<rocnik>\d+).(?P<cislo>\d+)/vysledkovka.tex$', views.CisloVysledkovkaView.as_view(), name='seminar_cislo_vysledkovka'),
url(r'^cislo/(?P<rocnik>\d+).(?P<cislo>\d+)/obalky.pdf$',views.cisloObalkyView, name='seminar_cislo_obalky'),
url(r'^cislo/(?P<rocnik>\d+).(?P<cislo>\d+)/tituly.tex$', views.TitulyView,
name='seminar_cislo_titul'),
) )

76
seminar/views.py

@ -2,18 +2,24 @@
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 HttpResponseRedirect
from django.http import HttpResponse
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
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 .models import Problem, Cislo, Reseni, Nastaveni, Rocnik, Soustredeni, Organizator, Resitel, Novinky 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
from . import utils from . import utils
from datetime import timedelta, date, datetime from datetime import timedelta, date, datetime
from itertools import groupby from itertools import groupby
import tempfile
import subprocess
import shutil
import os
from django.conf import settings
import unicodedata
def verejna_temata(rocnik): def verejna_temata(rocnik):
"""Vrací queryset zveřejněných témat v daném ročníku. """Vrací queryset zveřejněných témat v daném ročníku.
@ -334,6 +340,67 @@ class RocnikVysledkovkaView(RocnikView):
content_type = 'text/plain; charset=UTF8' content_type = 'text/plain; charset=UTF8'
#vypise na stranku textovy obsah vyTeXane vysledkovky k okopirovani #vypise na stranku textovy obsah vyTeXane vysledkovky k okopirovani
### Generovani obalek
class CisloObalkyStruct:
resitele = None
rocnik = None
problemy = None
def cisloObalkyView(request,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)
if int(cislo) > 3:
resitele = letos.resitele
else:
resitele = list(letos.resitele) + list(loni.resitele)
return obalkyView(request,resitele)
def obalkyView(request,resitele):
tex = render(request,'seminar/archiv/obalky.tex', {'resitele': resitele}).content
tempdir = tempfile.mkdtemp()
with open(tempdir+"/obalky.tex","w") as texfile:
# Pokud TeX chce ISO Latin, tak se da encode nastavit
texfile.write(tex.decode("utf-8").encode("iso-8859-2"))
shutil.copy(os.path.join(settings.STATIC_ROOT, 'seminar/lisak.eps'),tempdir)
subprocess.call(["csplain","obalky.tex"],cwd = tempdir)
subprocess.call(["dvipdf","obalky.dvi"],cwd = tempdir)
with open(tempdir+"/obalky.pdf","rb") as pdffile:
response = HttpResponse(pdffile.read(),content_type='application/pdf')
shutil.rmtree(tempdir)
return response
### Tituly
# TODO udelat neco jako get_objects_or_404
def TitulyView(request, rocnik, cislo):
rocnik_obj = Rocnik.objects.filter(rocnik = rocnik).first()
resitele = Resitel.objects.filter(rok_maturity__gte = rocnik_obj.prvni_rok)
cislo_obj = Cislo.objects.filter(rocnik = rocnik_obj, cislo = cislo).first()
for resitel in resitele:
vys = VysledkyKCisluOdjakziva.objects.filter(resitel = resitel, cislo = cislo_obj).first()
if vys == None:
body = 0
else:
body = vys.body
resitel.titul = resitel.get_titul(body)
resitel.ascii = unicodedata.normalize('NFKD',resitel.jmeno+resitel.prijmeni).encode("ascii","ignore").replace(" ","")
return render(request, 'seminar/archiv/tituly.tex',{'resitele': resitele})
### Soustredeni ### Soustredeni
@ -345,6 +412,11 @@ class SoustredeniView(generic.DetailView):
model = Soustredeni model = Soustredeni
template_name = 'seminar/archiv/soustredeni.html' template_name = 'seminar/archiv/soustredeni.html'
def soustredeniObalkyView(request,soustredeni):
soustredeni = Soustredeni.objects.filter(id = soustredeni)[0]
return obalkyView(request,soustredeni.ucastnici.all())
### Články ### Články
class ClankyResitelView(generic.ListView): class ClankyResitelView(generic.ListView):

Loading…
Cancel
Save