Browse Source

Merge branch 'master' into stable

remotes/origin/posli-mail-autorovi-korektury v1.7
Bc. Petr Pecha 9 years ago
parent
commit
1d78128ecb
  1. 15
      Makefile
  2. 2
      korektury/admin.py
  3. 4
      korektury/models.py
  4. 2
      korektury/static/korektury/opraf.js
  5. 2
      korektury/templates/korektury/opraf.html
  6. 4
      korektury/views.py
  7. 9
      mamweb/settings_common.py
  8. 14
      mamweb/static/css/mamweb.css
  9. 62
      seminar/admin.py
  10. 29
      seminar/migrations/0037_prispevek.py
  11. 18
      seminar/migrations/0038_change_meta_prispevek.py
  12. 34
      seminar/migrations/0039_pohadka.py
  13. 20
      seminar/migrations/0040_pohadka_nepovinny_autor.py
  14. 70
      seminar/migrations/0041_konfery.py
  15. 214
      seminar/models.py
  16. 22
      seminar/templates/seminar/archiv/cislo.html
  17. 24
      seminar/templates/seminar/archiv/prispevek.html
  18. 4
      seminar/templates/seminar/archiv/problem.html
  19. 6
      seminar/templates/seminar/archiv/problem_clanek.html
  20. 8
      seminar/templates/seminar/archiv/problem_uloha_tema.html
  21. 10
      seminar/templates/seminar/archiv/rocnik.html
  22. 6
      seminar/templates/seminar/archiv/temata.html
  23. 6
      seminar/templates/seminar/clanky/resitelske_clanky.html
  24. 4
      seminar/templates/seminar/cojemam/organizatori.html
  25. 3
      seminar/templates/seminar/novinky.html
  26. 4
      seminar/templates/seminar/pracuje_se.html
  27. 12
      seminar/templates/seminar/soustredeni/seznam_soustredeni.html
  28. 4
      seminar/templates/seminar/stare_novinky.html
  29. 10
      seminar/templates/seminar/stav_databaze.html
  30. 8
      seminar/templates/seminar/titulnistrana.html
  31. 6
      seminar/templates/seminar/zadani/AktualniVysledkovka.html
  32. 8
      seminar/templates/seminar/zadani/AktualniZadani.html
  33. 31
      seminar/templates/seminar/zadani/Temata.html
  34. 20
      seminar/urls.py
  35. 250
      seminar/views.py

15
Makefile

@ -44,7 +44,7 @@ clean_virtualenv:
rm -rf virtualenv-*.tar.gz rm -rf virtualenv-*.tar.gz
run: run:
./manage.py runserver_plus ./manage.py runserver
test: test:
./manage.py test -v2 seminar mamweb ./manage.py test -v2 seminar mamweb
@ -93,3 +93,16 @@ deploy_prod:
touch mamweb/wsgi.py touch mamweb/wsgi.py
@echo Done. @echo Done.
# Sync media directory with atrey. Useful for local development with production database
# Does not sync Galerie and CACHE (too huge).
sync_media:
rsync -ave ssh --exclude Galerie --exclude CACHE\
atrey.karlin.mff.cuni.cz:/akce/MaM/WWW/mamweb-prod/media/ ./media/
# Downloads and restores production database to local database. PostgreSQL only.
sync_db:
scp atrey.karlin.mff.cuni.cz:`ssh atrey.karlin.mff.cuni.cz 'ls -v /akce/MaM/WWW/backups/mam-prod-*\.pgdump | tail -n 1'` \
./last.pgdump
pg_restore -c -d mam -U mam last.pgdump
# Sync database and media. See above lines
sync: sync_media sync_db

2
korektury/admin.py

@ -9,7 +9,7 @@ class KorekturovanePDFAdmin(VersionAdmin):
(None, {'fields': ['pdf', 'cas', 'stran', 'nazev', 'komentar']}), (None, {'fields': ['pdf', 'cas', 'stran', 'nazev', 'komentar']}),
# (u'PDF', {'fields': ['pdf']}), # (u'PDF', {'fields': ['pdf']}),
] ]
list_display = ['pdf', 'cas', 'stran'] list_display = ['nazev', 'cas', 'stran']
list_filter = [] list_filter = []
search_fields = [] search_fields = []

4
korektury/models.py

@ -78,7 +78,9 @@ class KorekturovanePDF(models.Model):
"-density","180x180", "-density","180x180",
"-geometry"," 1024x1448", "-geometry"," 1024x1448",
self.pdf.path+"[%d]"%self.stran, self.pdf.path+"[%d]"%self.stran,
os.path.join(settings.KOREKTURY_IMG_DIR, "%s-%d.png"%(filename,self.stran))]) os.path.join(settings.BASE_DIR, "media",
settings.KOREKTURY_IMG_DIR,
"%s-%d.png"%(filename,self.stran))])
if res==1: if res==1:
break break
self.stran +=1 self.stran +=1

2
korektury/static/korektury/opraf.js

@ -126,7 +126,7 @@ function img_click(element, ev) {
function toggle_visibility(button){ function toggle_visibility(button){
var divbox = button.parentNode.parentNode.parentNode; var divbox = button.parentNode.parentNode.parentNode;
var id = divbox.id; var id = divbox.id;
var text = document.getElementById(id+'-text'); var text = document.getElementById(id+'-body');
if (text.style.display == 'none'){ if (text.style.display == 'none'){
text.style.display = 'block'; text.style.display = 'block';
}else { }else {

2
korektury/templates/korektury/opraf.html

@ -150,6 +150,7 @@
</div> </div>
</div> </div>
<div class='corr-body' id='op{{o.id}}-body'>
<div id='op{{o.id}}-text'>{{o.text}}</div> <div id='op{{o.id}}-text'>{{o.text}}</div>
{% for k in o.komentare %} {% for k in o.komentare %}
@ -178,6 +179,7 @@
<div id='kt{{k.id}}'>{{k.text}}</div> <div id='kt{{k.id}}'>{{k.text}}</div>
</div> </div>
{% endfor %} {% endfor %}
</div>
</div> </div>
{% endfor %} {% endfor %}

4
korektury/views.py

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.shortcuts import render from django.shortcuts import get_object_or_404, render
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.conf import settings from django.conf import settings
@ -114,7 +114,7 @@ class KorekturyView(generic.TemplateView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(KorekturyView,self).get_context_data(**kwargs) context = super(KorekturyView,self).get_context_data(**kwargs)
pdf = KorekturovanePDF.objects.get(id=self.kwargs['pdf']) pdf = get_object_or_404(KorekturovanePDF, id=self.kwargs['pdf'])
context['pdf'] = pdf context['pdf'] = pdf
context['img_name'] = os.path.split(pdf.pdf.path)[1].split('.')[0] context['img_name'] = os.path.split(pdf.pdf.path)[1].split('.')[0]
context['img_path'] = settings.KOREKTURY_IMG_DIR context['img_path'] = settings.KOREKTURY_IMG_DIR

9
mamweb/settings_common.py

@ -240,7 +240,8 @@ LOGGING = {
# MaM specific # MaM specific
SEMINAR_RESENI_DIR = os.path.join(BASE_DIR, 'media', 'reseni') SEMINAR_RESENI_DIR = os.path.join('reseni')
SEMINAR_KONFERY_DIR = os.path.join(BASE_DIR, 'media', 'konfery') SEMINAR_KONFERY_DIR = os.path.join('konfery')
KOREKTURY_PDF_DIR = os.path.join(BASE_DIR, 'media', 'korektury','pdf') KOREKTURY_PDF_DIR = os.path.join('korektury','pdf')
KOREKTURY_IMG_DIR = os.path.join(BASE_DIR, 'media', 'korektury','img') KOREKTURY_IMG_DIR = os.path.join('korektury','img')
CISLO_IMG_DIR = os.path.join('cislo','img')

14
mamweb/static/css/mamweb.css

@ -52,7 +52,7 @@ div.content {
padding: 15px 30px; padding: 15px 30px;
} }
h2 { h1 {
margin-top: 0px; margin-top: 0px;
} }
@ -92,6 +92,7 @@ h2 {
top: 40px; top: 40px;
left: 55px; left: 55px;
} }
/*
#header h1 { #header h1 {
font-size: 130%; font-size: 130%;
position: absolute; position: absolute;
@ -99,6 +100,7 @@ h2 {
left: 30px; left: 30px;
height: 110px; height: 110px;
} }
*/
#header img.header { #header img.header {
margin: -25px 20px 0px 0px; margin: -25px 20px 0px 0px;
height: 145px; height: 145px;
@ -160,7 +162,7 @@ div.menu li.selected a {
z-index: 15px; z-index: 15px;
} }
h2 a:hover { h1 a:hover {
text-decoration: none; text-decoration: none;
} }
@ -263,7 +265,7 @@ div.zadani_azad_termin {
text-align: center; text-align: center;
} }
#seznam_orgu h2 { #seznam_orgu h1 {
text-align: center; text-align: center;
} }
@ -495,7 +497,7 @@ div.zadani_azad_termin {
margin: 20px auto 0 auto; margin: 20px auto 0 auto;
} }
.galerie h2 { .galerie h1 {
text-align: center; text-align: center;
} }
@ -679,3 +681,7 @@ div.zadani_azad_termin {
div.novinka_obrazek { div.novinka_obrazek {
width: 100%; width: 100%;
} }
div.org-text {
font-style: italic;
}

62
seminar/admin.py

@ -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, Soustredeni_Organizatori, Novinky, Organizator from seminar.models import Skola, Resitel, Rocnik, Cislo, Problem, Reseni, PrilohaReseni, Nastaveni, Soustredeni, Soustredeni_Ucastnici, Soustredeni_Organizatori, Novinky, Organizator, Prispevek, Pohadka
from autocomplete_light import shortcuts as autocomplete_light from autocomplete_light import shortcuts as autocomplete_light
@ -296,6 +296,39 @@ class ReseniAdmin(VersionAdmin):
admin.site.register(Reseni, ReseniAdmin) admin.site.register(Reseni, ReseniAdmin)
### Pohádka
class PohadkaAdminForm(forms.ModelForm):
class Meta:
model = Pohadka
exclude = []
autor = UserModelChoiceField(User.objects.filter(is_staff=True))
uloha = forms.ModelChoiceField(Problem.objects.filter(typ=Problem.TYP_ULOHA))
class PohadkaAdmin(VersionAdmin):
form = PohadkaAdminForm
def get_kod_ulohy(self, obj):
return obj.uloha.kod_v_rocniku()
get_kod_ulohy.short_description = u'Kód úlohy'
def get_rocnik(self, obj):
return obj.uloha.cislo_zadani.rocnik.rocnik
get_rocnik.short_description = u'Ročník'
list_display = ['__str__', 'get_rocnik', 'get_kod_ulohy', 'uloha', 'autor', 'timestamp']
get_form = get_form_predvypln_autora
class PohadkaKProblemuInline(admin.TabularInline):
form = PohadkaAdminForm
model = Pohadka
exclude = []
extra = 0
admin.site.register(Pohadka, PohadkaAdmin)
### Problem ### Problem
from autocomplete_light.contrib.taggit_field import TaggitField, TaggitWidget from autocomplete_light.contrib.taggit_field import TaggitField, TaggitWidget
@ -348,7 +381,14 @@ 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', 'zamereni', 'cislo_zadani__cislo', 'cislo_zadani__rocnik'] list_filter = ['typ', 'zamereni', 'cislo_zadani__cislo', 'cislo_zadani__rocnik']
inlines = [ReseniKProblemuInline]
def get_inline_instances(self, request, obj=None):
if obj and obj.typ == Problem.TYP_ULOHA:
inlines = [ReseniKProblemuInline, PohadkaKProblemuInline]
else:
inlines = [ReseniKProblemuInline]
return [inline(self.model, self.admin_site) for inline in inlines]
def get_queryset(self, request): def get_queryset(self, request):
qs = super(ProblemZadanyAdmin, self).get_queryset(request) qs = super(ProblemZadanyAdmin, self).get_queryset(request)
@ -360,6 +400,24 @@ create_modeladmin(ProblemZadanyAdmin, Problem, 'ProblemZadany', verbose_name=u'P
#admin.site.register(Problem, ProblemAdmin) #admin.site.register(Problem, ProblemAdmin)
### Prispevek (k tematkum)
class PrispevekAdminForm(forms.ModelForm):
text_org = forms.CharField(widget=CKEditorWidget(), required=False,
**field_labels(Prispevek, 'text_org'))
text_resitel = forms.CharField(widget=CKEditorWidget(), required=False,
**field_labels(Prispevek, 'text_resitel'))
class Meta:
model = Prispevek
exclude = []
class PrispevekAdmin(VersionAdmin):
form = PrispevekAdminForm
list_display = ['nazev', 'problem', 'reseni', 'zverejnit']
admin.site.register(Prispevek, PrispevekAdmin)
### Soustredeni ### Soustredeni
class SoustredeniAdminForm(forms.ModelForm): class SoustredeniAdminForm(forms.ModelForm):

29
seminar/migrations/0037_prispevek.py

@ -0,0 +1,29 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('seminar', '0036_add_org_to_soustredeni'),
]
operations = [
migrations.CreateModel(
name='Prispevek',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('nazev', models.CharField(max_length=200, verbose_name=b'N\xc3\xa1zev')),
('text_org', models.TextField(null=True, verbose_name=b'Orgovsk\xc3\xbd text', blank=True)),
('text_resitel', models.TextField(null=True, verbose_name=b'\xc5\x98e\xc5\xa1itelsk\xc3\xbd text', blank=True)),
('zverejnit', models.BooleanField(verbose_name=b'Zve\xc5\x99ejnit?')),
('problem', models.ForeignKey(verbose_name=b'Probl\xc3\xa9m', to='seminar.Problem')),
('reseni', models.OneToOneField(null=True, blank=True, to='seminar.Reseni', verbose_name=b'\xc5\x98e\xc5\xa1en\xc3\xad')),
],
options={
'abstract': False,
},
),
]

18
seminar/migrations/0038_change_meta_prispevek.py

@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('seminar', '0037_prispevek'),
]
operations = [
migrations.AlterModelOptions(
name='prispevek',
options={'verbose_name': 'P\u0159\xedsp\u011bvek k probl\xe9mu', 'verbose_name_plural': 'P\u0159\xedsp\u011bvky k probl\xe9m\u016fm'},
),
]

34
seminar/migrations/0039_pohadka.py

@ -0,0 +1,34 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
import django.utils.timezone
from django.conf import settings
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('seminar', '0038_change_meta_prispevek'),
]
operations = [
migrations.CreateModel(
name='Pohadka',
fields=[
('id', models.AutoField(serialize=False, primary_key=True)),
('text', models.TextField(verbose_name='Text poh\xe1dky')),
('pred', models.BooleanField(default=True, verbose_name='P\u0159ed \xfalohou')),
('timestamp', models.DateTimeField(default=django.utils.timezone.now, verbose_name='Vytvo\u0159eno', editable=False, blank=True)),
('autor', models.ForeignKey(verbose_name=b'Autor poh\xc3\xa1dky', to=settings.AUTH_USER_MODEL)),
('uloha', models.ForeignKey(related_name='pohadky', verbose_name='\xdaloha', to='seminar.Problem')),
],
options={
'ordering': ['uloha__cislo_zadani', 'uloha__kod', '-pred'],
'db_table': 'seminar_pohadky',
'verbose_name': 'Poh\xe1dka',
'verbose_name_plural': 'Poh\xe1dky',
},
),
]

20
seminar/migrations/0040_pohadka_nepovinny_autor.py

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
from django.conf import settings
class Migration(migrations.Migration):
dependencies = [
('seminar', '0039_pohadka'),
]
operations = [
migrations.AlterField(
model_name='pohadka',
name='autor',
field=models.ForeignKey(verbose_name=b'Autor poh\xc3\xa1dky', to=settings.AUTH_USER_MODEL, null=True),
),
]

70
seminar/migrations/0041_konfery.py

@ -0,0 +1,70 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
import seminar.models
class Migration(migrations.Migration):
dependencies = [
('seminar', '0040_pohadka_nepovinny_autor'),
]
operations = [
migrations.CreateModel(
name='Konfera',
fields=[
('id', models.AutoField(serialize=False, primary_key=True)),
('nazev', models.CharField(help_text='N\xe1zev konfery', max_length=40, verbose_name='n\xe1zev konfery')),
('popis', models.TextField(help_text='Popis konfery k zobrazen\xed na webu', verbose_name='popis konfery', blank=True)),
('abstrakt', models.TextField(help_text='Abstrakt konfery tak, jak byl uveden ve sborn\xedku', verbose_name='abstrakt', blank=True)),
('org_poznamka', models.TextField(help_text='Neve\u0159ejn\xe1 pozn\xe1mka ke konfe\u0159e(plain text)', verbose_name='neve\u0159ejn\xe1 pozn\xe1mka', blank=True)),
('typ_prezentace', models.CharField(default=b'veletrh', max_length=16, verbose_name='typ prezentace', choices=[(b'veletrh', 'Veletrh (postery)'), (b'prezentace', 'Prezentace (p\u0159edn\xe1\u0161ka)')])),
('prezentace', models.FileField(help_text='Prezentace nebo fotka posteru', upload_to=seminar.models.generate_filename_konfera, verbose_name='prezentace')),
('materialy', models.FileField(help_text='Dal\u0161\xed materi\xe1ly ke konfe\u0159e zabalen\xe9 do jednoho souboru', upload_to=seminar.models.generate_filename_konfera, verbose_name='materialy')),
('organizator', models.ForeignKey(related_name='konfery', on_delete=django.db.models.deletion.SET_NULL, verbose_name='organiz\xe1tor', to='seminar.Organizator', null=True)),
],
options={
'db_table': 'seminar_konfera',
'verbose_name': 'Konfera',
'verbose_name_plural': 'Konfery',
},
),
migrations.CreateModel(
name='Konfery_Ucastnici',
fields=[
('id', models.AutoField(serialize=False, primary_key=True)),
('poznamka', models.TextField(help_text='Neve\u0159ejn\xe1 pozn\xe1mka k \xfa\u010dasti (plain text)', verbose_name='neve\u0159ejn\xe1 pozn\xe1mka', blank=True)),
('konfera', models.ForeignKey(verbose_name='konfera', to='seminar.Konfera')),
('resitel', models.ForeignKey(verbose_name='\u0159e\u0161itel', to='seminar.Resitel')),
],
options={
'ordering': ['konfera', 'resitel'],
'db_table': 'seminar_konfery_ucastnici',
'verbose_name': '\xda\u010dast na konfe\u0159e',
'verbose_name_plural': '\xda\u010dasti na konfe\u0159e',
},
),
migrations.AlterField(
model_name='problem',
name='typ',
field=models.CharField(default=b'uloha', max_length=32, verbose_name='typ probl\xe9mu', choices=[(b'uloha', '\xdaloha'), (b'tema', 'T\xe9ma'), (b'serial', 'Seri\xe1l'), (b'konfera', 'Konfera'), (b'org-clanek', 'Organiz\xe1torsk\xfd \u010dl\xe1nek'), (b'res-clanek', '\u0158e\u0161itelsk\xfd \u010dl\xe1nek')]),
),
migrations.AddField(
model_name='konfera',
name='prispevek',
field=models.ForeignKey(related_name='konfery', on_delete=django.db.models.deletion.SET_NULL, verbose_name='p\u0159\xedsp\u011bvek do \u010d\xedsla', to='seminar.Problem', help_text='\xda\u010dastnick\xfd p\u0159\xedp\u011bvek o konfe\u0159e', null=True),
),
migrations.AddField(
model_name='konfera',
name='soustredeni',
field=models.ForeignKey(related_name='konfery', on_delete=django.db.models.deletion.SET_NULL, verbose_name='soust\u0159ed\u011bn\xed', to='seminar.Soustredeni', null=True),
),
migrations.AddField(
model_name='konfera',
name='ucastnici',
field=models.ManyToManyField(help_text='Seznam \xfa\u010dastn\xedk\u016f konfery', to='seminar.Resitel', verbose_name='\xfa\u010dastn\xedci konfery', through='seminar.Konfery_Ucastnici'),
),
]

214
seminar/models.py

@ -16,7 +16,7 @@ from imagekit.processors import ResizeToFit, Transpose
from PIL import Image from PIL import Image
import os import os
from functools import partial #from functools import partial
from cStringIO import StringIO from cStringIO import StringIO
from django.core.files.base import ContentFile from django.core.files.base import ContentFile
@ -402,12 +402,14 @@ class Problem(SeminarModelBase):
TYP_ULOHA = 'uloha' TYP_ULOHA = 'uloha'
TYP_TEMA = 'tema' TYP_TEMA = 'tema'
TYP_SERIAL = 'serial' TYP_SERIAL = 'serial'
TYP_KONFERA = 'konfera'
TYP_ORG_CLANEK = 'org-clanek' TYP_ORG_CLANEK = 'org-clanek'
TYP_RES_CLANEK = 'res-clanek' TYP_RES_CLANEK = 'res-clanek'
TYP_CHOICES = [ TYP_CHOICES = [
(TYP_ULOHA, u'Úloha'), (TYP_ULOHA, u'Úloha'),
(TYP_TEMA, u'Téma'), (TYP_TEMA, u'Téma'),
(TYP_SERIAL, u'Seriál'), (TYP_SERIAL, u'Seriál'),
(TYP_KONFERA, u'Konfera'),
(TYP_ORG_CLANEK, u'Organizátorský článek'), (TYP_ORG_CLANEK, u'Organizátorský článek'),
(TYP_RES_CLANEK, u'Řešitelský článek'), (TYP_RES_CLANEK, u'Řešitelský článek'),
] ]
@ -545,6 +547,10 @@ class Reseni(SeminarModelBase):
# PrilohaReseni method # PrilohaReseni method
# TODO vyresit partial, tak aby slo migrovat
#def generate_filename(self, filename, directory):
# Django 1.9 podporuje partial
def generate_filename(self, filename): def generate_filename(self, filename):
clean = filename.replace('/','-').replace('\0', '') clean = filename.replace('/','-').replace('\0', '')
datedir = timezone.now().strftime('%Y-%m') datedir = timezone.now().strftime('%Y-%m')
@ -553,6 +559,16 @@ def generate_filename(self, filename):
clean) clean)
return os.path.join(settings.SEMINAR_RESENI_DIR, datedir, fname) return os.path.join(settings.SEMINAR_RESENI_DIR, datedir, fname)
def generate_filename_konfera(self, filename):
clean = filename.replace('/','-').replace('\0', '')
datedir = timezone.now().strftime('%Y-%m')
fname = "%s_%s" % (
timezone.now().strftime('%Y-%m-%d-%H:%M'),
clean)
return os.path.join(settings.SEMINAR_KONFERY_DIR, datedir, fname)
# TODO vyresit partial tak, aby slo migrovat
# return os.path.join(directory, datedir, fname)
@reversion.register(ignore_duplicate_revisions=True) @reversion.register(ignore_duplicate_revisions=True)
@python_2_unicode_compatible @python_2_unicode_compatible
@ -580,6 +596,75 @@ class PrilohaReseni(SeminarModelBase):
return force_unicode(self.soubor) return force_unicode(self.soubor)
@python_2_unicode_compatible
class Pohadka(SeminarModelBase):
u"""Kus pohádky před/za úlohou v čísle"""
class Meta:
db_table = 'seminar_pohadky'
verbose_name = u'Pohádka'
verbose_name_plural = u'Pohádky'
ordering = ['uloha__cislo_zadani', 'uloha__kod', '-pred']
# Interní ID
id = models.AutoField(primary_key=True)
text = models.TextField(u'Text pohádky')
uloha = models.ForeignKey(
Problem,
verbose_name=u'Úloha',
related_name='pohadky'
)
# Kusů pohádky je v čísle obvykle o 1 více, než úloh. Jeden bude za úlohou
# místo před ní.
pred = models.BooleanField(u'Před úlohou', default=True)
autor = models.ForeignKey(
settings.AUTH_USER_MODEL,
verbose_name="Autor pohádky",
# Při nahrávání z TeXu není vyplnění vyžadováno, v adminu je
null=True,
blank=False
)
timestamp = models.DateTimeField(
u'Vytvořeno',
default=timezone.now,
blank=True,
editable=False
)
def __str__(self):
uryvek = self.text if len(self.text) < (50-3) else self.text[:50]+"..."
return force_unicode(uryvek)
@reversion.register(ignore_duplicate_revisions=True)
class Prispevek(SeminarModelBase):
problem = models.ForeignKey(Problem, verbose_name='Problém') # TODO autokompleet
nazev = models.CharField('Název', max_length=200)
reseni = models.OneToOneField(Reseni, verbose_name='Řešení',
blank = True, null = True)
text_org = models.TextField('Orgovský text', blank = True, null = True)
text_resitel = models.TextField('Řešitelský text', blank = True, null = True)
zverejnit = models.BooleanField('Zveřejnit?')
class Meta:
verbose_name = 'Příspěvek k problému'
verbose_name_plural = 'Příspěvky k problémům'
def __unicode__(self):
if self.reseni:
return force_unicode(self.nazev) + ' (' + \
force_unicode(self.reseni.resitel) + ') <Problem: ' + \
force_unicode(self.problem) + '>'
else:
return force_unicode(self.nazev) + ' <Problem: ' + \
force_unicode(self.problem) + '>'
@reversion.register(ignore_duplicate_revisions=True) @reversion.register(ignore_duplicate_revisions=True)
@python_2_unicode_compatible @python_2_unicode_compatible
class Organizator(models.Model): class Organizator(models.Model):
@ -736,69 +821,70 @@ class Soustredeni_Organizatori(models.Model):
#@reversion.register(ignore_duplicate_revisions=True) @reversion.register(ignore_duplicate_revisions=True)
#@python_2_unicode_compatible @python_2_unicode_compatible
#class Konfera(models.Model): class Konfera(models.Model):
# class Meta: class Meta:
# db_table = 'seminar_konfera' db_table = 'seminar_konfera'
# verbose_name = u'Konfera' verbose_name = u'Konfera'
# verbose_name_plural = u'Konfery' verbose_name_plural = u'Konfery'
# # Interní ID # Interní ID
# id = models.AutoField(primary_key = True) id = models.AutoField(primary_key = True)
# nazev = models.CharField(u'název konfery', max_length=40, help_text = u'Název konfery') nazev = models.CharField(u'název konfery', max_length=40, help_text = u'Název konfery')
# popis = models.TextField(u'popis konfery', blank=True, popis = models.TextField(u'popis konfery', blank=True,
# help_text=u'Popis konfery k zobrazení na webu') help_text=u'Popis konfery k zobrazení na webu')
# abstrakt = models.TextField(u'abstrakt', blank=True, abstrakt = models.TextField(u'abstrakt', blank=True,
# help_text=u'Abstrakt konfery tak, jak byl uveden ve sborníku') help_text=u'Abstrakt konfery tak, jak byl uveden ve sborníku')
# organizator = models.ForeignKey(Organizator, verbose_name=u'organizátor', related_name='konfery', organizator = models.ForeignKey(Organizator, verbose_name=u'organizátor', related_name='konfery',
# on_delete = models.SET_NULL, null=True) on_delete = models.SET_NULL, null=True)
# ucastnici = models.ManyToManyField(Resitel, verbose_name=u'účastníci konfery', ucastnici = models.ManyToManyField(Resitel, verbose_name=u'účastníci konfery',
# help_text=u'Seznam účastníků konfery', through='Konfery_Ucastnici') help_text=u'Seznam účastníků konfery', through='Konfery_Ucastnici')
# soustredeni = models.ForeignKey(Soustredeni, verbose_name=u'soustředění', related_name='konfery', soustredeni = models.ForeignKey(Soustredeni, verbose_name=u'soustředění', related_name='konfery',
# on_delete = models.SET_NULL, null=True) on_delete = models.SET_NULL, null=True)
# org_poznamka = models.TextField(u'neveřejná poznámka', blank=True, org_poznamka = models.TextField(u'neveřejná poznámka', blank=True,
# help_text=u'Neveřejná poznámka ke konfeře(plain text)') help_text=u'Neveřejná poznámka ke konfeře(plain text)')
# #prispevek #TODO prispevek = models.ForeignKey(Problem, verbose_name=u'příspěvek do čísla', related_name='konfery',
# TYP_VELETRH = 'veletrh' help_text=u'Účastnický přípěvek o konfeře',on_delete = models.SET_NULL, null=True)
# TYP_PREZENTACE = 'prezentace' TYP_VELETRH = 'veletrh'
# TYP_CHOICES = [ TYP_PREZENTACE = 'prezentace'
# (TYP_VELETRH, u'Veletrh (postery)'), TYP_CHOICES = [
# (TYP_PREZENTACE, u'Prezentace (přednáška)'), (TYP_VELETRH, u'Veletrh (postery)'),
# ] (TYP_PREZENTACE, u'Prezentace (přednáška)'),
# typ_prezentace = models.CharField(u'typ prezentace', max_length=16, choices=TYP_CHOICES, blank=False, default=TYP_VELETRH) ]
# prezentace = models.FileField(u'prezentace',help_text = u'Prezentace nebo fotka posteru', typ_prezentace = models.CharField(u'typ prezentace', max_length=16, choices=TYP_CHOICES, blank=False, default=TYP_VELETRH)
# upload_to = partial(generate_filename,directory=settings.SEMINAR_KONFERY_DIR)) prezentace = models.FileField(u'prezentace',help_text = u'Prezentace nebo fotka posteru',
# materialy = models.FileField(u'materialy',help_text = u'Další materiály ke konfeře zabalené do jednoho souboru', upload_to = generate_filename_konfera)
# upload_to = partial(generate_filename,directory=settings.SEMINAR_KONFERY_DIR)) materialy = models.FileField(u'materialy',help_text = u'Další materiály ke konfeře zabalené do jednoho souboru',
# upload_to = generate_filename_konfera)
# def __str__(self):
# return force_unicode(u"%s: (%s)" % (self.nazev, self.soustredeni)) def __str__(self):
# return force_unicode(u"%s: (%s)" % (self.nazev, self.soustredeni))
#
#
#@reversion.register(ignore_duplicate_revisions=True)
#@python_2_unicode_compatible @reversion.register(ignore_duplicate_revisions=True)
#class Konfery_Ucastnici(models.Model): @python_2_unicode_compatible
# class Konfery_Ucastnici(models.Model):
# class Meta:
# db_table = 'seminar_konfery_ucastnici' class Meta:
# verbose_name = u'Účast na konfeře' db_table = 'seminar_konfery_ucastnici'
# verbose_name_plural = u'Účasti na konfeře' verbose_name = u'Účast na konfeře'
# ordering = ['konfera', 'resitel'] verbose_name_plural = u'Účasti na konfeře'
# ordering = ['konfera', 'resitel']
# # Interní ID
# id = models.AutoField(primary_key = True) # Interní ID
# id = models.AutoField(primary_key = True)
# resitel = models.ForeignKey(Resitel, verbose_name=u'řešitel')
# resitel = models.ForeignKey(Resitel, verbose_name=u'řešitel')
# konfera = models.ForeignKey(Konfera, verbose_name=u'konfera')
# konfera = models.ForeignKey(Konfera, verbose_name=u'konfera')
# poznamka = models.TextField(u'neveřejná poznámka', blank=True,
# help_text=u'Neveřejná poznámka k účasti (plain text)') poznamka = models.TextField(u'neveřejná poznámka', blank=True,
# help_text=u'Neveřejná poznámka k účasti (plain text)')
# def __str__(self):
# return force_unicode(u'%s na %s' % (self.resitel, self.konfera, )) def __str__(self):
# # NOTE: Poteciální DB HOG bez select_related return force_unicode(u'%s na %s' % (self.resitel, self.konfera, ))
# NOTE: Poteciální DB HOG bez select_related
@python_2_unicode_compatible @python_2_unicode_compatible

22
seminar/templates/seminar/archiv/cislo.html

@ -2,34 +2,38 @@
{% block content %} {% block content %}
<div> <div>
<h2> <h1>
{% block nadpis1a %}{% block nadpis1b %} {% block nadpis1a %}{% block nadpis1b %}
Číslo {{ cislo }} Číslo {{ cislo }}
{% endblock %}{% endblock %} {% endblock %}{% endblock %}
</h2> </h1>
{% if cislo.pdf %} {% if cislo.pdf %}
<p><a href='{{ cislo.pdf.url }}'>Číslo v pdf</a> <p><a href='{{ cislo.pdf.url }}'>Číslo v pdf</a>
{% endif %} {% endif %}
<p><a href='{{ cislo.rocnik.verejne_url }}'>Ročník {{ cislo.rocnik }}</a> <p><a href='{{ cislo.rocnik.verejne_url }}'>Ročník {{ cislo.rocnik }}</a>
<h3>Zadané problémy</h3> <h2>Zadané problémy</h2>
<ul> <ul>
{% for p in v_cisle_zadane %} {% for p in v_cisle_zadane %}
<li>{# TODO zprovoznit odkazy, až bude na co <a href='{{ p.verejne_url }}'> #}{{ p.kod_v_rocniku }} {{ p.nazev }} {{ p.body_v_zavorce }}{# </a> #} <li>{# TODO zprovoznit odkazy i pro účastníky, až bude na co #}
{% if user.is_staff %}
<a href='{{ p.verejne_url }}'>{% endif %}{{ p.kod_v_rocniku }} {{ p.nazev }} {{ p.body_v_zavorce }}{% if user.is_staff %}</a>{% endif %}
{% endfor %} {% endfor %}
</ul> </ul>
<h3>Řešené problémy</h3> <h2>Řešené problémy</h2>
<ul> <ul>
{% for p in resene_problemy %} {% for p in resene_problemy %}
<li>{# TODO zprovoznit odkazy, až bude na co <a href='{{ p.verejne_url }}'> #}{{ p.kod_v_rocniku }} {{ p.nazev }} {{ p.body_v_zavorce }}{# </a> #} <li>{# TODO zprovoznit odkazy i pro účastníky, až bude na co #}
{% if user.is_staff %}
<a href='{{ p.verejne_url }}'>{% endif %}{{ p.kod_v_rocniku }} {{ p.nazev }} {{ p.body_v_zavorce }}{% if user.is_staff %}</a>{% endif %}
{% endfor %} {% endfor %}
</ul> </ul>
{% if user.is_staff %} {% if user.is_staff %}
<div class="mam-org-only"> <div class="mam-org-only">
<h3> Orgovské odkazy </h3> <h2> Orgovské odkazy </h2>
<ul> <ul>
<li><a href="obalky.pdf">Obálky (PDF)</a></li> <li><a href="obalky.pdf">Obálky (PDF)</a></li>
<li><a href="tituly.tex">Tituly (TeX)</a></li> <li><a href="tituly.tex">Tituly (TeX)</a></li>
@ -40,11 +44,11 @@
{% endif %} {% endif %}
{% if cislo.verejna_vysledkovka %} {% if cislo.verejna_vysledkovka %}
<h3>Výsledkovka</h3> <h2>Výsledkovka</h2>
{% else %} {% else %}
{% if user.is_staff %} {% if user.is_staff %}
<div class='mam-org-only'> <div class='mam-org-only'>
<h3>Výsledkovka (neveřejná)</h3> <h2>Výsledkovka (neveřejná)</h2>
{% endif %} {% endif %}
{% endif %} {% endif %}

24
seminar/templates/seminar/archiv/prispevek.html

@ -0,0 +1,24 @@
{% extends "seminar/archiv/base_temata.html" %}
{% block title %}
{{prispevek.nazev}}
{% endblock title %}
{% block content %}
{% if not prispevek.zverejnit %}<div class="mam-org-only">{% endif %}
<h1>{{prispevek.nazev}}</h1>
<h2>{{titul}} {{prispevek.reseni.resitel}}</h2>
<h3>Příspěvek k tématu <a href="..">{{prispevek.problem.nazev}}</a></h3>
{% if prispevek.reseni.body %}
<div class="body">({{prispevek.reseni.body}} b)</div>
{% endif %}
{% if prispevek.text_org %}
<div class="org-text">{% autoescape off %}{{prispevek.text_org}}{% endautoescape %}</div>
{% endif %}
{% if prispevek.text_resitel %}
{% autoescape off %}{{prispevek.text_resitel}}{% endautoescape %}
{% endif %}
{% if not prispevek.zverejnit %}</div>{% endif %}
{% endblock content %}

4
seminar/templates/seminar/archiv/problem.html

@ -10,10 +10,10 @@
{% if user.is_staff %} {% if user.is_staff %}
<div class='mam-org-only'> <div class='mam-org-only'>
<h3>Text - org</h3> <h2>Text - org</h2>
{{ problem.text_org |safe }} {{ problem.text_org |safe }}
<h3>Diskuse - org</h3> <h2>Diskuse - org</h2>
{% render_comment_list for object %} {% render_comment_list for object %}
{% render_comment_form for object %} {% render_comment_form for object %}

6
seminar/templates/seminar/archiv/problem_clanek.html

@ -3,12 +3,12 @@
{% block problem %} {% block problem %}
{% if problem.cislo_zadani %} {% if problem.cislo_zadani %}
<h2> <h1>
{{ problem.nazev_typu }}: {{ problem.nazev_typu }}:
{% block nadpis1a %}{% block nadpis1b %} {% block nadpis1a %}{% block nadpis1b %}
{{ problem.nazev }} {{ problem.nazev }}
{% endblock %}{% endblock %} {% endblock %}{% endblock %}
</h2> </h1>
<div class='problem-autori'> <div class='problem-autori'>
{% if problem.typ == 'res-clanek' %} {% if problem.typ == 'res-clanek' %}
@ -30,7 +30,7 @@
{% else %} {% else %}
{# TODO ? #} {# TODO ? #}
<h2>Problém {{ problem.nazev }}</h2> <h1>Problém {{ problem.nazev }}</h1>
{% endif %} {% endif %}
{{ problem.text_zadani |safe }} {{ problem.text_zadani |safe }}

8
seminar/templates/seminar/archiv/problem_uloha_tema.html

@ -1,11 +1,11 @@
{% extends "seminar/archiv/problem.html" %} {% extends "seminar/archiv/problem.html" %}
{% block problem %} {% block problem %}
<h2> <h1>
{% block nadpis1a %}{% block nadpis1b %} {% block nadpis1a %}{% block nadpis1b %}
{{ problem.nazev_typu }} {{ problem.kod_v_rocniku }}: {{ problem.nazev }} {{ problem.body_v_zavorce }} {{ problem.nazev_typu }} {{ problem.kod_v_rocniku }}: {{ problem.nazev }} {{ problem.body_v_zavorce }}
{% endblock %}{% endblock %} {% endblock %}{% endblock %}
</h2> </h1>
{% 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 %} {% endif %}
@ -13,10 +13,10 @@
<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 %}
<h3>Zadání</h3> <h2>Zadání</h2>
{{ problem.text_zadani |safe }} {{ problem.text_zadani |safe }}
{% if problem.text_reseni %} {% if problem.text_reseni %}
<h3>Řešení</h3> <h2>Řešení</h2>
{{ problem.text_reseni |safe }} {{ problem.text_reseni |safe }}
{% endif %} {% endif %}

10
seminar/templates/seminar/archiv/rocnik.html

@ -2,11 +2,11 @@
{% block content %} {% block content %}
<div> <div>
<h2> <h1>
{% block nadpis1a %}{% block nadpis1b %} {% block nadpis1a %}{% block nadpis1b %}
Ročník {{ rocnik.roman }} Ročník {{ rocnik.roman }}
{% endblock %}{% endblock %} {% endblock %}{% endblock %}
</h2> </h1>
<p>Ročník číslo {{ rocnik.rocnik }} ({{ rocnik.prvni_rok }}/{{ rocnik.druhy_rok }}) <p>Ročník číslo {{ rocnik.rocnik }} ({{ rocnik.prvni_rok }}/{{ rocnik.druhy_rok }})
@ -20,7 +20,7 @@
</ul> </ul>
{% if temata_v_rocniku %} {% if temata_v_rocniku %}
<h3>Témata</h3> <h2>Témata</h2>
<ul> <ul>
{% for tema in temata_v_rocniku %} {% for tema in temata_v_rocniku %}
<li>{# TODO zprovoznit odkaz až bude na co <a href="{{ tema.verejne_url }}"> #}{{ tema.kod_v_rocniku }}: {{ tema.nazev }}{# TODO </a> #} <li>{# TODO zprovoznit odkaz až bude na co <a href="{{ tema.verejne_url }}"> #}{{ tema.kod_v_rocniku }}: {{ tema.nazev }}{# TODO </a> #}
@ -29,13 +29,13 @@
{% endif %} {% endif %}
{% if vysledkovka %} {% if vysledkovka %}
<h3>Výsledková listina</h3> <h2>Výsledková listina</h2>
{% include "seminar/vysledkovka_rocnik.html" %} {% include "seminar/vysledkovka_rocnik.html" %}
{% endif %} {% endif %}
{% if user.is_staff and vysledkovka_s_neverejnymi %} {% if user.is_staff and vysledkovka_s_neverejnymi %}
<div class='mam-org-only'> <div class='mam-org-only'>
<h3>Výsledková listina včetně neveřejných bodů</h3> <h2>Výsledková listina včetně neveřejných bodů</h2>
{% with vysledkovka_s_neverejnymi as vysledkovka %} {% with vysledkovka_s_neverejnymi as vysledkovka %}
{% include "seminar/vysledkovka_rocnik.html" %} {% include "seminar/vysledkovka_rocnik.html" %}
{% endwith %} {% endwith %}

6
seminar/templates/seminar/archiv/temata.html

@ -1,17 +1,17 @@
{% extends "seminar/archiv/base_temata.html" %} {% extends "seminar/archiv/base_temata.html" %}
{% block content %} {% block content %}
<h2> <h1>
{% block nadpis1a %}{% block nadpis1b %} {% block nadpis1a %}{% block nadpis1b %}
Archiv témat Archiv témat
{% endblock %}{% endblock%} {% endblock %}{% endblock%}
</h2> </h1>
{% for tema in object_list %} {% for tema in object_list %}
{% with tema.cislo_zadani.rocnik.rocnik as rocnik %} {% with tema.cislo_zadani.rocnik.rocnik as rocnik %}
{% ifchanged rocnik %} {% ifchanged rocnik %}
{% if not forloop.first %}</ul>{% endif %} {% if not forloop.first %}</ul>{% endif %}
<h3>{{ rocnik }}. ročník</h3> <h2>{{ rocnik }}. ročník</h2>
<ul> <ul>
{% endifchanged %} {% endifchanged %}
<li> <li>

6
seminar/templates/seminar/clanky/resitelske_clanky.html

@ -10,17 +10,17 @@
{% block content %} {% block content %}
<h2> <h1>
{% block nadpis1a %}{% block nadpis1b %} {% block nadpis1a %}{% block nadpis1b %}
Řešitelské články Řešitelské články
{% endblock %}{% endblock %} {% endblock %}{% endblock %}
</h2> </h1>
{% for clanek in object_list %} {% for clanek in object_list %}
{% with clanek.cislo_zadani.rocnik.rocnik as rocnik %} {% with clanek.cislo_zadani.rocnik.rocnik as rocnik %}
{% ifchanged rocnik %} {% ifchanged rocnik %}
{% if not forloop.first %}</ul>{% endif %} {% if not forloop.first %}</ul>{% endif %}
<h3>{{ rocnik }}. ročník</h3> <h2>{{ rocnik }}. ročník</h2>
<ul> <ul>
{% endifchanged %} {% endifchanged %}
<li> <li>

4
seminar/templates/seminar/cojemam/organizatori.html

@ -24,13 +24,13 @@
<br> <br>
{% endif %} {% endif %}
{% for org in object_list %} {% for org in object_list %}
<h2> <h1>
{{org.user.first_name}} {{org.user.first_name}}
{% if org.prezdivka %} {% if org.prezdivka %}
&bdquo;{{org.prezdivka}}&ldquo; &bdquo;{{org.prezdivka}}&ldquo;
{% endif %} {% endif %}
{{org.user.last_name}} {{org.user.last_name}}
</h2> </h1>
<table> <table>
<tr> <tr>
<td> <td>

3
seminar/templates/seminar/novinky.html

@ -3,6 +3,9 @@
<div> <div>
{% if not novinka.zverejneno and user.is_staff %} {% if not novinka.zverejneno and user.is_staff %}
<div class="mam-org-only"> <div class="mam-org-only">
<ul>
<li><a href="/admin/seminar/novinky/{{novinka.pk}}">Upravit novinku</a>
</ul>
{% endif %} {% endif %}
{% if novinka.zverejneno or user.is_staff %} {% if novinka.zverejneno or user.is_staff %}
{# datum #} {# datum #}

4
seminar/templates/seminar/pracuje_se.html

@ -1,11 +1,11 @@
{% load staticfiles %} {% load staticfiles %}
{% block content %} {% block content %}
<h2> <h1>
{% block nadpis1a %}{% block nadpis1b %} {% block nadpis1a %}{% block nadpis1b %}
Tady se pracuje Tady se pracuje
{% endblock %}{% endblock %} {% endblock %}{% endblock %}
</h2> </h1>
<p> <p>
Na této stránce velmi intenzivně pracujeme. Na této stránce velmi intenzivně pracujeme.

12
seminar/templates/seminar/soustredeni/seznam_soustredeni.html

@ -14,10 +14,6 @@
{% endblock %}{% endblock %} {% endblock %}{% endblock %}
{% block content %} {% block content %}
<em>
Na galeriích ze soustředění a dalších informacích ještě pracujeme.
</em><br><br>
{# Projdi vsechna soustredeni #} {# Projdi vsechna soustredeni #}
{% for soustredeni in object_list %} {% for soustredeni in object_list %}
{# Kdyz je verejne -> zobraz #} {# Kdyz je verejne -> zobraz #}
@ -27,10 +23,10 @@
<!--Groups of user: {{user.groups.all}} <br>--> <!--Groups of user: {{user.groups.all}} <br>-->
{% endif %} {% endif %}
{# misto soustredeni TODO upravit#} {# misto soustredeni TODO upravit#}
<h2> <h1>
{{soustredeni.get_typ_display}} {{soustredeni.get_typ_display}}
{{soustredeni.misto}} {{soustredeni.misto}}
</h2> </h1>
<ul> <ul>
<li> <li>
{{soustredeni.datum_zacatku}}&thinsp;&ndash;&thinsp;{{soustredeni.datum_konce}} {{soustredeni.datum_zacatku}}&thinsp;&ndash;&thinsp;{{soustredeni.datum_konce}}
@ -62,7 +58,7 @@
{% if user.is_staff %} {% if user.is_staff %}
<div class="mam-org-only"> <div class="mam-org-only">
{# Účastníci #} {# Účastníci #}
<h3>Soustředění se zúčastnili tito účastníci:</h3> <h2>Soustředění se zúčastnili tito účastníci:</h2>
<p> <p>
{% for i in soustredeni.soustredeni_ucastnici_set.all %} {% for i in soustredeni.soustredeni_ucastnici_set.all %}
{{i.resitel}}{% if forloop.last %}.{% else %},{% endif %} {{i.resitel}}{% if forloop.last %}.{% else %},{% endif %}
@ -70,7 +66,7 @@
Nic! Nic!
{% endfor %} {% endfor %}
</p> </p>
<h3>Soustředění se účastnili tito organizátoři:</h3> <h2>Soustředění se účastnili tito organizátoři:</h2>
<p> <p>
{% for i in soustredeni.soustredeni_organizatori_set.all %} {% for i in soustredeni.soustredeni_organizatori_set.all %}
{{i.organizator}}{% if forloop.last %}.{% else %},{% endif %} {{i.organizator}}{% if forloop.last %}.{% else %},{% endif %}

4
seminar/templates/seminar/stare_novinky.html

@ -2,11 +2,11 @@
{% block content %} {% block content %}
<h2> <h1>
{% block nadpis1a %}{% block nadpis1b %} {% block nadpis1a %}{% block nadpis1b %}
Archiv novinek Archiv novinek
{% endblock %}{% endblock %} {% endblock %}{% endblock %}
</h2> </h1>
{% include 'seminar/novinky.html' %} {% include 'seminar/novinky.html' %}

10
seminar/templates/seminar/stav_databaze.html

@ -2,13 +2,13 @@
{% block content %} {% block content %}
<div> <div>
<h2> <h1>
{% block nadpis1a %}{% block nadpis1b %} {% block nadpis1a %}{% block nadpis1b %}
Stav databáze Stav databáze
{% endblock %}{% endblock %} {% endblock %}{% endblock %}
</h2> </h1>
<h3>Řešitelé</h3> <h2>Řešitelé</h2>
<div>Řešitelů: {{ resitele |length}} ({{ muzi |length}} mužů, {{ zeny |length}} žen)</div> <div>Řešitelů: {{ resitele |length}} ({{ muzi |length}} mužů, {{ zeny |length}} žen)</div>
<div>Křestní jména mužů:</div> <div>Křestní jména mužů:</div>
@ -16,9 +16,9 @@
<div>Křestní jména žen:</div> <div>Křestní jména žen:</div>
<p><code>{% for n, c in jmena_zen.items %}{{ n }} ({{ c }}), {% endfor %}</code> <p><code>{% for n, c in jmena_zen.items %}{{ n }} ({{ c }}), {% endfor %}</code>
<h3>Nastavení</h3> <h2>Nastavení</h2>
<h3>Problémy</h3> <h2>Problémy</h2>
{% for p in problemy %} {% for p in problemy %}
<div>{{ p |safe }}</div> <div>{{ p |safe }}</div>
{% endfor %} {% endfor %}

8
seminar/templates/seminar/titulnistrana.html

@ -6,11 +6,11 @@
{% block content %} {% block content %}
{# Uvitaci text #} {# Uvitaci text #}
<h2> <h1>
{% block nadpis1a %}{% block nadpis1b %} {% block nadpis1a %}{% block nadpis1b %}
Vítej! Vítej!
{% endblock %}{% endblock %} {% endblock %}{% endblock %}
</h2> </h1>
<p> <p>
M&amp;M je korespondeční seminář. Několikrát do roka zdarma vydáváme časopis a v něm zajímavé podněty k přemýšlení. Ty na ně můžeš reagovat.<br> M&amp;M je korespondeční seminář. Několikrát do roka zdarma vydáváme časopis a v něm zajímavé podněty k přemýšlení. Ty na ně můžeš reagovat.<br>
@ -26,7 +26,7 @@ M&amp;M je korespondeční seminář. Několikrát do roka zdarma vydáváme ča
{% endif %} {% endif %}
{# Novinky #} {# Novinky #}
<h2>Novinky</h2> <h1>Novinky</h1>
{% include 'seminar/novinky.html' %} {% include 'seminar/novinky.html' %}
<a href='/stare-novinky/'>Archiv novinek</a> <a href='/stare-novinky/'>Archiv novinek</a>
@ -59,7 +59,7 @@ M&amp;M je korespondeční seminář. Několikrát do roka zdarma vydáváme ča
</map> </map>
<span class="zjistit_vic"> <span class="zjistit_vic">
<h3><a href="/co-je-MaM/uvod/">Zjistit víc!</a></h3> <h2><a href="/co-je-MaM/uvod/">Zjistit víc!</a></h2>
</span> </span>
</div> </div>

6
seminar/templates/seminar/zadani/AktualniVysledkovka.html

@ -10,11 +10,11 @@
{% block content %} {% block content %}
{% with nastaveni.aktualni_rocnik as rocnik %} {% with nastaveni.aktualni_rocnik as rocnik %}
<h2> <h1>
{% block nadpis1a %}{% block nadpis1b %} {% block nadpis1a %}{% block nadpis1b %}
Výsledky Výsledky
{% endblock %}{% endblock %} {% endblock %}{% endblock %}
</h2> </h1>
{% if vysledkovka %} {% if vysledkovka %}
{% include "seminar/vysledkovka_rocnik.html" %} {% include "seminar/vysledkovka_rocnik.html" %}
@ -24,7 +24,7 @@
{% if user.is_staff and vysledkovka_s_neverejnymi %} {% if user.is_staff and vysledkovka_s_neverejnymi %}
<div class='mam-org-only'> <div class='mam-org-only'>
<h2>Výsledky včetně neveřejných</h2> <h1>Výsledky včetně neveřejných</h1>
{% with vysledkovka_s_neverejnymi as vysledkovka %} {% with vysledkovka_s_neverejnymi as vysledkovka %}
{% include "seminar/vysledkovka_rocnik.html" %} {% include "seminar/vysledkovka_rocnik.html" %}
{% endwith %} {% endwith %}

8
seminar/templates/seminar/zadani/AktualniZadani.html

@ -32,7 +32,7 @@
{% for sada in jednorazove_problemy %} {% for sada in jednorazove_problemy %}
{# podnadpisy, kdyz neni zakomentuje se nadpis #} {# podnadpisy, kdyz neni zakomentuje se nadpis #}
{% if not sada %}<!--{% endif %} {% if not sada %}<!--{% endif %}
<h3>{% cycle 'Úlohy' 'Seriál' %}</h3> <h2>{% cycle 'Úlohy' 'Seriál' %}</h2>
{% if not sada %}-->{% endif %} {% if not sada %}-->{% endif %}
{# publikace jednotlivych zadani #} {# publikace jednotlivych zadani #}
{% for problem in sada %} {% for problem in sada %}
@ -41,7 +41,7 @@
{% endfor %} {% endfor %}
{# TODO použít {{problem.kod_v_rocniku}} ? vrací 4.u1 místo 4.1 #} {# TODO použít {{problem.kod_v_rocniku}} ? vrací 4.u1 místo 4.1 #}
<h4>{{problem.cislo_zadani.cislo}}.{{problem.kod}} {{problem.nazev}} {{ problem.body_v_zavorce }}</h4> <h3>{{problem.cislo_zadani.cislo}}.{{problem.kod}} {{problem.nazev}} {{ problem.body_v_zavorce }}</h3>
{% autoescape off %}{{problem.text_zadani}}{% endautoescape %} {% autoescape off %}{{problem.text_zadani}}{% endautoescape %}
<hr> <hr>
{% endfor %} {% endfor %}
@ -51,11 +51,11 @@
{% if user.is_staff and not verejne%}</div>{% endif %} {% if user.is_staff and not verejne%}</div>{% endif %}
{% else %} {% else %}
<h3>Aktuálně nejsou zveřejněny žádné úlohy</h3> <h2>Aktuálně nejsou zveřejněny žádné úlohy</h2>
{% endif %} {% endif %}
<h3>Témata</h3> <h2>Témata</h2>
<ul> <ul>
{% for problem in temata %} {% for problem in temata %}
{# TODO použít {{problem.kod_v_rocniku}} ? vrací t4 místo 4 #} {# TODO použít {{problem.kod_v_rocniku}} ? vrací t4 místo 4 #}

31
seminar/templates/seminar/zadani/Temata.html

@ -10,11 +10,11 @@
{% block content %} {% block content %}
{% with nastaveni.aktualni_rocnik as ar %} {% with nastaveni.aktualni_rocnik as ar %}
<div> <div>
<h2> <h1>
{% block nadpis1a %}{% block nadpis1b %} {% block nadpis1a %}{% block nadpis1b %}
Témata Témata
{% endblock %}{% endblock %} {% endblock %}{% endblock %}
</h2> </h1>
<p> <p>
Témata jsou hlavním obsahem časopisu M&amp;M. Obvykle představují Témata jsou hlavním obsahem časopisu M&amp;M. Obvykle představují
@ -30,6 +30,7 @@
Letos jsme pro tebe připravili tato témata: Letos jsme pro tebe připravili tato témata:
</p> </p>
{% endif %} {% endif %}
{# seznam temat s odkazy doprostred teto stranky #}
<ul> <ul>
{% for problem in temata %} {% for problem in temata %}
{# TODO použít {{problem.kod_v_rocniku}} ? vrací t4 místo 4 #} {# TODO použít {{problem.kod_v_rocniku}} ? vrací t4 místo 4 #}
@ -38,11 +39,35 @@
</li> </li>
{% endfor %} {% endfor %}
</ul> </ul>
{# nahled kazdeho tematu #}
{% for problem in temata %} {% for problem in temata %}
{# TODO použít {{problem.kod_v_rocniku}} ? vrací t4 místo 4 #} {# TODO použít {{problem.kod_v_rocniku}} ? vrací t4 místo 4 #}
<a name="t{{problem.kod}}"></a> <a name="t{{problem.kod}}"></a>
<a href="{{problem.verejne_url}}"><h3>Téma {{problem.kod}}: {{problem.nazev}}</h3></a> <h2>Téma {{problem.kod}}: {{problem.nazev}}</h2>
{% autoescape off %}{{problem.text_zadani}}{% endautoescape %} {% autoescape off %}{{problem.text_zadani}}{% endautoescape %}
{# kdyz je reseni pridej odkaz na samostatnou stranku s tematem #}
{% if problem.text_reseni %}
<p><a href="{{problem.verejne_url}}">Více</a></p>
{% else %}
<p><a href="{{problem.verejne_url}}">Stejně</a></p>
{% endif%}
{# prime odkazy na prispevky #}
{% if problem.prispevky %}
<h3> K&nbsp;tématu přišly a zveřejnili jsme následující příspěvky</h3>
<div class="seznam_prispeveku">
<ul>
{% for prispevek in problem.prispevky %}
{% if not prispevek.zverejnit %}<div class=mam-org-only>{% endif %}
<li><a href="{{problem.verejne_url}}{{prispevek.id}}">
{{prispevek.nazev}},
{{prispevek.reseni.resitel}}
({{prispevek.reseni.body}} b)
</a>
{% if not prispevek.zverejnit %}</div>{% endif %}
{% endfor %}
</ul>
</div>
{% endif %}
<hr> <hr>
{% empty %} {% empty %}
Aktuálně nejsou zadána žádná témata k řešení. Aktuálně nejsou zadána žádná témata k řešení.

20
seminar/urls.py

@ -4,38 +4,49 @@ from django.contrib.auth.decorators import user_passes_test
from . import views, export from . import views, export
from utils import staff_member_required from utils import staff_member_required
from prednasky.views import newPrednaska, Prednaska_hotovo from prednasky.views import newPrednaska, Prednaska_hotovo
from django.views.generic.base import RedirectView
staff_member_required = user_passes_test(lambda u: u.is_staff) staff_member_required = user_passes_test(lambda u: u.is_staff)
urlpatterns = [ urlpatterns = [
# prednasky # prednasky
url(r'^prednasky/$', newPrednaska), #url(r'^prednasky/$', newPrednaska),
url(r'^prednasky/hotovo$', Prednaska_hotovo), #url(r'^prednasky/hotovo$', Prednaska_hotovo),
# REDIRECTy
url(r'^jak-resit/$', RedirectView.as_view(url='/co-je-MaM/jak-resit/')),
# Organizatori
url(r'^co-je-MaM/organizatori/$', views.CojemamOrganizatoriView.as_view(), name='organizatori'), url(r'^co-je-MaM/organizatori/$', views.CojemamOrganizatoriView.as_view(), name='organizatori'),
url(r'^co-je-MaM/organizatori/organizovali/$', views.CojemamOrganizatoriStariView.as_view(), name='stari_organizatori'), url(r'^co-je-MaM/organizatori/organizovali/$', views.CojemamOrganizatoriStariView.as_view(), name='stari_organizatori'),
# Archiv
url(r'^archiv/cisla/$', views.CislaView.as_view()), url(r'^archiv/cisla/$', views.CislaView.as_view()),
url(r'^archiv/temata/$', views.ArchivTemataView.as_view()), url(r'^archiv/temata/$', views.ArchivTemataView.as_view()),
url(r'^rocnik/(?P<rocnik>\d+)/$', views.RocnikView.as_view(), name='seminar_rocnik'), url(r'^rocnik/(?P<rocnik>\d+)/$', views.RocnikView.as_view(), name='seminar_rocnik'),
url(r'^cislo/(?P<rocnik>\d+)\.(?P<cislo>[0-9-]+)/$', views.CisloView.as_view(), name='seminar_cislo'), url(r'^cislo/(?P<rocnik>\d+)\.(?P<cislo>[0-9-]+)/$', views.CisloView.as_view(), name='seminar_cislo'),
url(r'^problem/(?P<pk>\d+)/$', views.ProblemView.as_view(), name='seminar_problem'), url(r'^problem/(?P<pk>\d+)/$', views.ProblemView.as_view(), name='seminar_problem'),
url(r'^problem/(?P<pk>\d+)/(?P<prispevek>\d+)/$', views.PrispevekView.as_view(), name='seminar_problem_prispevek'),
# Soustredeni
url(r'^soustredeni/probehlo/$', views.SoustredeniListView.as_view(), url(r'^soustredeni/probehlo/$', views.SoustredeniListView.as_view(),
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')),
# Zadani
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'),
url(r'^zadani/vysledkova-listina/$', views.ZadaniAktualniVysledkovkaView, name='seminar_vysledky'), url(r'^zadani/vysledkova-listina/$', views.ZadaniAktualniVysledkovkaView, name='seminar_vysledky'),
url(r'^$', views.TitulniStranaView.as_view(), name='titulni_strana'), url(r'^$', views.TitulniStranaView.as_view(), name='titulni_strana'),
url(r'^stare-novinky/$', views.StareNovinkyView.as_view(), name='stare_novinky'), url(r'^stare-novinky/$', views.StareNovinkyView.as_view(), name='stare_novinky'),
# Clanky
url(r'^clanky/resitel/$', views.ClankyResitelView.as_view(), name='clanky_resitel'), url(r'^clanky/resitel/$', views.ClankyResitelView.as_view(), name='clanky_resitel'),
url(r'^clanky/org/$', views.ClankyOrganizatorView.as_view(), name='clanky_organizator'), url(r'^clanky/org/$', views.ClankyOrganizatorView.as_view(), name='clanky_organizator'),
# Aesop
url(r'^aesop-export/mam-rocnik-(?P<prvni_rok>\d+)\.csv$', export.ExportRocnikView.as_view(), name='seminar_export_rocnik'), url(r'^aesop-export/mam-rocnik-(?P<prvni_rok>\d+)\.csv$', export.ExportRocnikView.as_view(), name='seminar_export_rocnik'),
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'),
@ -52,6 +63,11 @@ urlpatterns = [
staff_member_required(views.StavDatabazeView), name='stav_databaze'), staff_member_required(views.StavDatabazeView), name='stav_databaze'),
url(r'^cislo/(?P<rocnik>\d+).(?P<cislo>[0-9-]+)/obalkovani$', url(r'^cislo/(?P<rocnik>\d+).(?P<cislo>[0-9-]+)/obalkovani$',
staff_member_required(views.obalkovaniView), name='seminar_cislo_resitel_obalkovani'), staff_member_required(views.obalkovaniView), name='seminar_cislo_resitel_obalkovani'),
url(r'^cislo/(?P<rocnik>\d+).(?P<cislo>[0-9-]+)/tex-download.json$',
staff_member_required(views.texDownloadView), name='seminar_tex_download'),
url(r'^soustredeni/(?P<soustredeni>\d+)/obalky.pdf', url(r'^soustredeni/(?P<soustredeni>\d+)/obalky.pdf',
staff_member_required(views.soustredeniObalkyView), name='seminar_soustredeni_obalky'), staff_member_required(views.soustredeniObalkyView), name='seminar_soustredeni_obalky'),
url(r'^tex-upload/login/$', views.LoginView, name='seminar_login'),
url(r'^tex-upload/$', staff_member_required(views.texUploadView), name='seminar_tex_upload'),
] ]

250
seminar/views.py

@ -1,15 +1,17 @@
# 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 HttpResponse, HttpResponseRedirect, HttpResponseForbidden from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden, JsonResponse
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.core.exceptions import PermissionDenied, ObjectDoesNotExist from django.core.exceptions import PermissionDenied, ObjectDoesNotExist
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 django.db.models import Q
from django.views.decorators.csrf import ensure_csrf_cookie
from django.contrib.auth import authenticate, login
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, Pohadka, Prispevek
from .models import VysledkyZaCislo, VysledkyKCisluZaRocnik, VysledkyKCisluOdjakziva from .models import VysledkyZaCislo, VysledkyKCisluZaRocnik, VysledkyKCisluOdjakziva
from . import utils from . import utils
@ -21,6 +23,10 @@ import shutil
import os import os
from django.conf import settings from django.conf import settings
import unicodedata import unicodedata
import json
import traceback
import sys
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.
@ -45,9 +51,15 @@ def AktualniZadaniView(request):
def ZadaniTemataView(request): def ZadaniTemataView(request):
nastaveni = get_object_or_404(Nastaveni) nastaveni = get_object_or_404(Nastaveni)
temata = verejna_temata(nastaveni.aktualni_rocnik)
for t in temata:
if request.user.is_staff:
t.prispevky = t.prispevek_set.filter(problem=t)
else:
t.prispevky = t.prispevek_set.filter(problem=t, zverejnit=True)
return render(request, 'seminar/zadani/Temata.html', return render(request, 'seminar/zadani/Temata.html',
{ {
'temata': verejna_temata(nastaveni.aktualni_rocnik) 'temata': temata,
} }
) )
@ -241,6 +253,45 @@ class ProblemView(generic.DetailView):
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 PrispevekView(generic.DetailView):
model = Prispevek
template_name = 'seminar/archiv/prispevek.html'
# Vlastni ziskavani objektu z databaze podle prispevku
# pokud je prispevek neverejny zobrazi se jenom orgum
def get_object(self, queryset=None):
if queryset is None:
queryset = self.get_queryset()
problem_arg = self.kwargs.get('pk')
prispevek_arg = self.kwargs.get('prispevek')
queryset = queryset.filter(pk=prispevek_arg)
try:
obj = queryset.get()
except queryset.model.DoesNotExist:
raise Http404(_("No %(verbose_name)s found matching the query") %
{'verbose_name': queryset.model._meta.verbose_name})
if self.request.user.is_staff or obj.zverejnit:
return obj
else:
raise Http404()
def get_context_data(self, **kwargs):
context = super(PrispevekView, self).get_context_data(**kwargs)
# snaho o ziskani titulu
titul = ''
try:
resitel = context['prispevek'].reseni.resitel
cislo = context['prispevek'].reseni.cislo_body
body = VysledkyKCisluOdjakziva.objects.get(resitel=resitel,
cislo=cislo).body
titul = resitel.get_titul(body)
except:
pass
context['titul'] = titul
return context
class RadekVysledkovky(object): class RadekVysledkovky(object):
@ -408,11 +459,22 @@ def obalkovaniView(request, rocnik, cislo):
rocnik = Rocnik.objects.get(rocnik=rocnik) rocnik = Rocnik.objects.get(rocnik=rocnik)
cislo = Cislo.objects.get(rocnik=rocnik, cislo=cislo) cislo = Cislo.objects.get(rocnik=rocnik, cislo=cislo)
reseni = Reseni.objects.filter(cislo_body=cislo) reseni = (
serazena_reseni = sorted(reseni, key=lambda r: (r.resitel.prijmeni, r.resitel.jmeno, r.problem.typ, r.problem.kod)) Reseni.objects.filter(cislo_body=cislo)
.order_by(
'resitel__prijmeni',
'resitel__jmeno',
'problem__typ',
'problem__kod'
)
)
problemy = sorted(set(r.problem for r in reseni), key=lambda p: (p.typ, p.kod)) problemy = sorted(set(r.problem for r in reseni), key=lambda p: (p.typ, p.kod))
return render(request, 'seminar/archiv/cislo_obalkovani.html', {'cislo': cislo, 'problemy': problemy, 'reseni': serazena_reseni}) return render(
request,
'seminar/archiv/cislo_obalkovani.html',
{'cislo': cislo, 'problemy': problemy, 'reseni': reseni}
)
### Tituly ### Tituly
@ -438,7 +500,7 @@ def TitulyView(request, rocnik, cislo):
else: else:
broken = True broken = True
return render(request, 'seminar/archiv/tituly.tex',{'resitele': resitele,'broken':broken}) return render(request, 'seminar/archiv/tituly.tex',{'resitele': resitele,'broken':broken},content_type="text/plain")
### Soustredeni ### Soustredeni
@ -487,3 +549,177 @@ def StavDatabazeView(request):
'jmena_muzu': utils.histogram([r.jmeno for r in muzi]), 'jmena_muzu': utils.histogram([r.jmeno for r in muzi]),
'jmena_zen': utils.histogram([r.jmeno for r in zeny]), 'jmena_zen': utils.histogram([r.jmeno for r in zeny]),
}) })
@ensure_csrf_cookie
def LoginView(request):
"""Pro přihlášení při nahrávání z texu"""
q = request.POST
# nastavení cookie csrftoken
if not q:
return JsonResponse({"ok": 1})
if "username" in q:
username = q["username"]
password = q["password"]
user = authenticate(username=username, password=password)
if user is not None and user.is_staff:
login(request, user)
return JsonResponse({"ok": 1})
else:
return JsonResponse({"error": "Neplatné uživatelské jméno nebo heslo"})
@ensure_csrf_cookie
def texUploadView(request):
def uloz_soubory(files, rocnik, cislo):
for filename, f in files:
path = os.path.join(
settings.MEDIA_ROOT,
settings.CISLO_IMG_DIR,
rocnik,
cislo,
filename
)
adresar = os.path.dirname(path)
if not os.path.exists(adresar):
os.makedirs(adresar)
with open(path, "wb+") as fout:
for chunk in f.chunks():
fout.write(chunk)
q = request.POST
# nastavení cookie csrftoken
if not q:
return JsonResponse({"ok": 1})
# Odchytíme všechny výjimky a traceback pošleme v odpovědi
try:
meta = json.loads(q["meta"])
html = q["html"]
if meta["typ"] in ["uloha", "serial", "reseni"]:
# Uložíme soubory
if meta["typ"] != "reseni":
c = meta["cislo"]
else:
# Řešení má nastavené číslo svojí úlohy, ale obrázky jsou
# ukládány do čísla, kde řešení vyšlo
c = meta["cislo_reseni"]
uloz_soubory(request.FILES.items(), meta["rocnik"], c)
# Zjistíme typ ukládaného problému
typy = {
"uloha": Problem.TYP_ULOHA,
"serial": Problem.TYP_SERIAL,
"reseni": Problem.TYP_ULOHA,
}
problem_typ = typy[meta["typ"]]
# Pokud už problém existuje, vytáhneme jej z db a upravíme
# Pokud ročník/číslo ještě neexistuje, vyhodí to výjimku ->
# číslo/ročník se musí založit ručně v adminu
rocnik = Rocnik.objects.get(rocnik=meta["rocnik"])
cislo = Cislo.objects.get(rocnik=rocnik, cislo=meta["cislo"])
existujici = Problem.objects.filter(
typ=problem_typ,
stav=Problem.STAV_ZADANY,
cislo_zadani=cislo,
kod=meta["kod"]
)
problem = None
if existujici:
problem = existujici[0]
# Jinak vytvoříme nový
else:
problem = Problem(
typ=problem_typ,
stav=Problem.STAV_ZADANY,
kod=meta["kod"],
cislo_zadani=cislo
)
if meta["typ"] == "reseni":
problem.text_reseni = html
#při nahrávání řešení už původní zadání atd. neměníme
else:
problem.text_zadani = html
problem.nazev = meta["nazev"]
problem.body = meta["body"]
problem.save()
# Vrátíme id dané úlohy, aby se k ní dala případně připojit pohádka
return JsonResponse({"db_id": problem.id})
elif meta["typ"] == "pohadka":
uloha = Problem.objects.get(typ=Problem.TYP_ULOHA, pk=meta["uloha"])
# Pokud už příslušná pohádka existuje, jen ji upravíme
existujici = Pohadka.objects.filter(uloha=uloha, pred=meta["pred"])
pohadka = None
if existujici:
pohadka = existujici[0]
else:
pohadka = Pohadka(uloha=uloha, pred=meta["pred"])
pohadka.text = q["html"]
pohadka.save()
return JsonResponse({"db_id": pohadka.id})
except Exception, e:
# Pošleme zpátky traceback, ať uživatel ví, v čem je problém
tb = "".join(traceback.format_exception(type(e), e, sys.exc_info()[2]))
return JsonResponse({"error": tb})
def texDownloadView(request, rocnik, cislo):
"""View posílající JSON se zadanými a řešenými problémy pro založení čísla
"""
cislo = Cislo.objects.get(rocnik__rocnik=rocnik, cislo=cislo)
zadane = Problem.objects.filter(
cislo_zadani=cislo,
stav=Problem.STAV_ZADANY
)
resene = Problem.objects.filter(
cislo_reseni=cislo,
stav=Problem.STAV_ZADANY,
typ=Problem.TYP_ULOHA
)
pred_pohadky = Pohadka.objects.filter(uloha__cislo_zadani=cislo, pred=True)
po_pohadky = Pohadka.objects.filter(uloha__cislo_zadani=cislo, pred=False)
response = {
"zadane": [
{
"nazev": p.nazev,
"typ": p.typ,
"kod": p.kod,
"body": p.body,
"zadani": p.text_zadani,
"pred_pohadky": [x.text for x in pred_pohadky.filter(uloha=p)],
"po_pohadky": [x.text for x in po_pohadky.filter(uloha=p)],
} for p in zadane
],
"resene": [
{
"nazev": p.nazev,
"typ": p.typ,
"kod": p.kod,
"body": p.body,
"zadani": p.text_zadani,
"reseni": p.text_reseni,
"cislo_zadani": p.cislo_zadani.cislo,
} for p in resene
],
}
return JsonResponse(response)

Loading…
Cancel
Save