Browse Source

Merge branch 'data_migrations' of gimli.ms.mff.cuni.cz:/akce/mam/git/mamweb into data_migrations

export_seznamu_prednasek
parent
commit
9e9725497d
  1. 50
      seminar/admin.py
  2. 5
      seminar/migrations/0058_problem_to_uloha_tema_clanek.py
  3. 41
      seminar/models.py
  4. 71
      seminar/old_views.py
  5. 204
      seminar/testutils.py
  6. 4
      seminar/urls.py
  7. 66
      seminar/views.py

50
seminar/admin.py

@ -18,13 +18,13 @@ from autocomplete_light import shortcuts as autocomplete_light
class UserModelChoiceField(forms.ModelChoiceField): class UserModelChoiceField(forms.ModelChoiceField):
u"""Vlastní ModelChoiceField pro uživatele. Zobrazí kromě loginu i jméno. """Vlastní ModelChoiceField pro uživatele. Zobrazí kromě loginu i jméno.
""" """
def label_from_instance(self, obj): def label_from_instance(self, obj):
return u"{} ({})".format(obj.get_full_name(), obj.username) return "{} ({})".format(obj.get_full_name(), obj.username)
def get_form_predvypln_autora(self, request, obj=None, *args, **kwargs): def get_form_predvypln_autora(self, request, obj=None, *args, **kwargs):
u"""get_form fce pro Adminy. Předvyplňí přihlášeného uživatele jako autora. """get_form fce pro Adminy. Předvyplňí přihlášeného uživatele jako autora.
""" """
form = super(self.__class__, self).get_form(request, *args, **kwargs) form = super(self.__class__, self).get_form(request, *args, **kwargs)
form.base_fields['autor'].initial = request.user.id form.base_fields['autor'].initial = request.user.id
@ -32,7 +32,7 @@ def get_form_predvypln_autora(self, request, obj=None, *args, **kwargs):
def make_set_action(atribut, hodnota, nazev): def make_set_action(atribut, hodnota, nazev):
u""" """
Pomocnik pro rychle vytvareni hromadnych admin akci ktere jen nastavuji Pomocnik pro rychle vytvareni hromadnych admin akci ktere jen nastavuji
atribut (dany jako string) na danou hodnotu. atribut (dany jako string) na danou hodnotu.
nazev je krátký popis akce pro admin rozhraní.""" nazev je krátký popis akce pro admin rozhraní."""
@ -214,10 +214,10 @@ class ResitelAdmin(VersionAdmin):
fk_name = 'osoba' fk_name = 'osoba'
fieldsets = [ fieldsets = [
(None, {'fields': ['jmeno', 'prijmeni', 'user']}), (None, {'fields': ['jmeno', 'prijmeni', 'user']}),
(u'Škola', {'fields': ['skola', 'rok_maturity']}), ('Škola', {'fields': ['skola', 'rok_maturity']}),
(u'Seminář', {'fields': ['datum_souhlasu_udaje', 'datum_souhlasu_zasilani', 'datum_prihlaseni', 'zasilat']}), ('Seminář', {'fields': ['datum_souhlasu_udaje', 'datum_souhlasu_zasilani', 'datum_prihlaseni', 'zasilat']}),
(u'Osobní údaje', {'fields': ['pohlavi_muz', 'datum_narozeni', 'email', 'telefon']}), ('Osobní údaje', {'fields': ['pohlavi_muz', 'datum_narozeni', 'email', 'telefon']}),
(u'Adresa', {'fields': ['ulice', 'mesto', 'psc', 'stat']}), ('Adresa', {'fields': ['ulice', 'mesto', 'psc', 'stat']}),
] ]
list_display = ['osoba__jmeno', 'osoba__prijmeni', 'osoba__user', 'osoba__pohlavi_muz', 'skola', 'rok_maturity', 'pocet_reseni'] list_display = ['osoba__jmeno', 'osoba__prijmeni', 'osoba__user', 'osoba__pohlavi_muz', 'skola', 'rok_maturity', 'pocet_reseni']
list_filter = ['osoba__pohlavi_muz', 'rok_maturity', 'zasilat'] list_filter = ['osoba__pohlavi_muz', 'rok_maturity', 'zasilat']
@ -262,8 +262,8 @@ admin.site.register(Resitel, ResitelAdmin)
class SkolaAdmin(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']}), ('Interní ID', {'fields': ['aesop_id', 'izo'], 'classes': ['collapse']}),
(u'Adresa', {'fields': ['ulice', 'mesto', 'psc', 'stat']}), ('Adresa', {'fields': ['ulice', 'mesto', 'psc', 'stat']}),
(None, {'fields': ['poznamka']}), (None, {'fields': ['poznamka']}),
] ]
list_display = ['nazev', 'aesop_id', 'mesto', 'ulice', 'stat', 'je_zs', 'je_ss'] list_display = ['nazev', 'aesop_id', 'mesto', 'ulice', 'stat', 'je_zs', 'je_ss']
@ -328,8 +328,8 @@ class RocnikAdmin(VersionAdmin):
inlines = [CisloInline] inlines = [CisloInline]
view_on_site = Rocnik.verejne_url view_on_site = Rocnik.verejne_url
actions = [ actions = [
make_set_action('exportovat', True, u'Nastavit pro AESOP export'), make_set_action('exportovat', True, 'Nastavit pro AESOP export'),
make_set_action('exportovat', False, u'Skrýt pro AESOP export'), make_set_action('exportovat', False, 'Skrýt pro AESOP export'),
] ]
admin.site.register(Rocnik, RocnikAdmin) admin.site.register(Rocnik, RocnikAdmin)
@ -341,7 +341,7 @@ admin.site.register(Rocnik, RocnikAdmin)
# readonly_fields = ['timestamp', 'reseni'] # readonly_fields = ['timestamp', 'reseni']
# fieldsets = [ # fieldsets = [
# (None, {'fields': ['reseni', 'soubor', 'timestamp']}), # (None, {'fields': ['reseni', 'soubor', 'timestamp']}),
# (u'Poznámky', {'fields': ['poznamka']}), # ('Poznámky', {'fields': ['poznamka']}),
# ] # ]
# list_display = ['reseni', 'soubor', 'timestamp'] # list_display = ['reseni', 'soubor', 'timestamp']
# list_filter = ['reseni', 'timestamp'] # list_filter = ['reseni', 'timestamp']
@ -356,7 +356,7 @@ class ReseniAdmin(VersionAdmin):
#form = autocomplete_light.modelform_factory(Reseni, autocomplete_fields=['problem', 'resitele'], fields=['problem', 'resitele']) #form = autocomplete_light.modelform_factory(Reseni, autocomplete_fields=['problem', 'resitele'], fields=['problem', 'resitele'])
fieldsets = [ fieldsets = [
(None, {'fields': ['problem__set', 'resitele__set', 'forma', 'cas_doruceni']}), (None, {'fields': ['problem__set', 'resitele__set', 'forma', 'cas_doruceni']}),
(u'Poznámky', {'fields': ['poznamka']}), ('Poznámky', {'fields': ['poznamka']}),
] ]
readonly_fields = ['cas_doruceni'] readonly_fields = ['cas_doruceni']
list_display = [ResitelInline, 'forma', 'cas_doruceni'] list_display = [ResitelInline, 'forma', 'cas_doruceni']
@ -400,11 +400,11 @@ class PohadkaAdmin(VersionAdmin):
def get_kod_ulohy(self, obj): def get_kod_ulohy(self, obj):
return obj.uloha.kod_v_rocniku() return obj.uloha.kod_v_rocniku()
get_kod_ulohy.short_description = u'Kód úlohy' get_kod_ulohy.short_description = 'Kód úlohy'
def get_rocnik(self, obj): def get_rocnik(self, obj):
return obj.uloha.cislo_zadani.rocnik.rocnik return obj.uloha.cislo_zadani.rocnik.rocnik
get_rocnik.short_description = u'Ročník' get_rocnik.short_description = 'Ročník'
list_display = [ list_display = [
'__str__', '__str__',
@ -477,7 +477,7 @@ 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']}),
(u'Vydání', {'fields': ['kod', 'cislo_reseni', 'opravovatel',]}), ('Vydání', {'fields': ['kod', 'cislo_reseni', 'opravovatel',]}),
(None, {'fields': ['text_zadani', 'text_reseni', 'text_org',]}), (None, {'fields': ['text_zadani', 'text_reseni', 'text_org',]}),
] ]
list_select_related = True list_select_related = True
@ -506,7 +506,7 @@ class ProblemNavrhAdmin(ProblemAdmin):
#FIXME #FIXME
#create_modeladmin(ProblemNavrhAdmin, Problem, 'ProblemNavrh', verbose_name=u'Problém (návrh)', verbose_name_plural=u'Problémy (návrhy)') #create_modeladmin(ProblemNavrhAdmin, Problem, 'ProblemNavrh', verbose_name='Problém (návrh)', verbose_name_plural='Problémy (návrhy)')
class ProblemZadanyAdmin(ProblemAdmin): class ProblemZadanyAdmin(ProblemAdmin):
@ -531,7 +531,7 @@ class ProblemZadanyAdmin(ProblemAdmin):
reverse("admin:seminar_cislo_change", args=(obj.cislo_zadani.pk,)), reverse("admin:seminar_cislo_change", args=(obj.cislo_zadani.pk,)),
obj.cislo_zadani obj.cislo_zadani
)) ))
cislo_zadani_link.short_description = u'Číslo zadání' cislo_zadani_link.short_description = 'Číslo zadání'
# TODO pokud se budou odkazy v adminu více používat, možná by se hodilo je # TODO pokud se budou odkazy v adminu více používat, možná by se hodilo je
# nějak zjednodušit, např. tímto? # nějak zjednodušit, např. tímto?
@ -543,7 +543,7 @@ class ProblemZadanyAdmin(ProblemAdmin):
reverse("admin:seminar_cislo_change", args=(obj.cislo_reseni.pk,)), reverse("admin:seminar_cislo_change", args=(obj.cislo_reseni.pk,)),
obj.cislo_reseni obj.cislo_reseni
)) ))
cislo_reseni_link.short_description = u'Číslo řešení' cislo_reseni_link.short_description = 'Číslo řešení'
def get_inline_instances(self, request, obj=None): def get_inline_instances(self, request, obj=None):
if obj and obj.typ == Problem.TYP_ULOHA: if obj and obj.typ == Problem.TYP_ULOHA:
@ -560,7 +560,7 @@ class ProblemZadanyAdmin(ProblemAdmin):
get_form = get_form_predvypln_autora get_form = get_form_predvypln_autora
#FIXME #FIXME
#create_modeladmin(ProblemZadanyAdmin, Problem, 'ProblemZadany', verbose_name=u'Problém (zadaný)', verbose_name_plural=u'Problémy (zadané)') #create_modeladmin(ProblemZadanyAdmin, Problem, 'ProblemZadany', verbose_name='Problém (zadaný)', verbose_name_plural='Problémy (zadané)')
#admin.site.register(Problem, ProblemAdmin) #admin.site.register(Problem, ProblemAdmin)
@ -601,10 +601,10 @@ class SoustredeniAdmin(VersionAdmin):
list_filter = ['typ', 'rocnik'] list_filter = ['typ', 'rocnik']
view_on_site = Soustredeni.verejne_url view_on_site = Soustredeni.verejne_url
actions = [ actions = [
make_set_action('verejne_db', True, u'Zveřejnit soustředění'), make_set_action('verejne_db', True, 'Zveřejnit soustředění'),
make_set_action('verejne_db', False, u'Skrýt (zneveřejnit) soustředění'), make_set_action('verejne_db', False, 'Skrýt (zneveřejnit) soustředění'),
make_set_action('exportovat', True, u'Nastavit pro AESOP export'), make_set_action('exportovat', True, 'Nastavit pro AESOP export'),
make_set_action('exportovat', False, u'Skrýt pro AESOP export'), make_set_action('exportovat', False, 'Skrýt pro AESOP export'),
] ]
admin.site.register(Soustredeni, SoustredeniAdmin) admin.site.register(Soustredeni, SoustredeniAdmin)

5
seminar/migrations/0058_problem_to_uloha_tema_clanek.py

@ -91,8 +91,7 @@ def clanek_to_Clanek(apps,schema_editor):
elif cl.cislo_reseni_old == cl.cislo_zadani_old: elif cl.cislo_reseni_old == cl.cislo_zadani_old:
cislo = cl.cislo_zadani_old cislo = cl.cislo_zadani_old
else: else:
cislo = cl.cislo_zadani_old raise ValueError("Různá čísla zadání a řešení u článku! (Článek: {})".format(cl.nazev))
#raise ValueError("Různá čísla zadání a řešení u článku!")
clnew = Clanek.objects.create( clnew = Clanek.objects.create(
problem_ptr = cl, problem_ptr = cl,
@ -132,7 +131,7 @@ def tema_to_Tema(apps, schema_editor):
elif t.cislo_reseni_old.rocnik == t.cislo_zadani_old.rocnik: elif t.cislo_reseni_old.rocnik == t.cislo_zadani_old.rocnik:
rocnik = t.cislo_zadani_old.rocnik rocnik = t.cislo_zadani_old.rocnik
else: else:
raise ValueError("Nelze mít téma přes více ročníků!") raise ValueError("Nelze mít téma přes více ročníků! (Téma: {}".format(t.nazev))
tnew = Tema.objects.create( tnew = Tema.objects.create(
problem_ptr = t, problem_ptr = t,

41
seminar/models.py

@ -115,6 +115,11 @@ class Osoba(SeminarModelBase):
], ],
options={'quality': 95}) options={'quality': 95})
# má OneToOneField nejvýše s:
# Resitel
# Prijemce
# Organizator
def plne_jmeno(self): def plne_jmeno(self):
return '{} {}'.format(self.jmeno, self.prijmeni) return '{} {}'.format(self.jmeno, self.prijmeni)
@ -318,7 +323,11 @@ class Rocnik(SeminarModelBase):
rocnik = models.IntegerField('číslo ročníku', db_index=True, unique=True) rocnik = models.IntegerField('číslo ročníku', db_index=True, unique=True)
exportovat = models.BooleanField('export do AESOPa', db_column='exportovat', default=False, exportovat = models.BooleanField('export do AESOPa', db_column='exportovat', default=False,
help_text='Exportuje se jen podle tohoto flagu (ne veřejnosti), a to jen čísla s veřejnou výsledkovkou') help_text='Exportuje se jen podle tohoto flagu (ne veřejnosti),'
' a to jen čísla s veřejnou výsledkovkou')
# má OneToOneField s:
# RocnikNode
def __str__(self): def __str__(self):
return '{} ({}/{})'.format(self.rocnik, self.prvni_rok, self.prvni_rok+1) return '{} ({}/{})'.format(self.rocnik, self.prvni_rok, self.prvni_rok+1)
@ -414,6 +423,8 @@ class Cislo(SeminarModelBase):
pdf = models.FileField('pdf', upload_to=cislo_pdf_filename, null=True, blank=True, pdf = models.FileField('pdf', upload_to=cislo_pdf_filename, null=True, blank=True,
help_text='Pdf čísla, které si mohou řešitelé stáhnout') help_text='Pdf čísla, které si mohou řešitelé stáhnout')
# má OneToOneField s:
# CisloNode
def kod(self): def kod(self):
return '%s.%s' % (self.rocnik.rocnik, self.cislo) return '%s.%s' % (self.rocnik.rocnik, self.cislo)
@ -567,7 +578,10 @@ class Problem(SeminarModelBase):
class Meta: class Meta:
# Není abstraktní, protože se na něj jinak nedají dělat ForeignKeys. # Není abstraktní, protože se na něj jinak nedají dělat ForeignKeys.
# TODO: Udělat to polymorfní (pomocí django-polymorphic), abychom dostali po těch vazbách přímo tu úlohu/témátko vč. fieldů, které nejsou součástí modelu Problem? # TODO: Udělat to polymorfní (pomocí django-polymorphic), abychom dostali
# po těch vazbách přímo tu úlohu/témátko vč. fieldů, které nejsou součástí
# modelu Problem?
#abstract = True #abstract = True
db_table = 'seminar_problemy' db_table = 'seminar_problemy'
verbose_name = 'Problém' verbose_name = 'Problém'
@ -690,6 +704,10 @@ class Clanek(Problem):
cislo = models.ForeignKey(Cislo, verbose_name='číslo', blank=True, null=True, cislo = models.ForeignKey(Cislo, verbose_name='číslo', blank=True, null=True,
on_delete=models.PROTECT) on_delete=models.PROTECT)
# má OneToOneField s:
# ClanekNode
def kod_v_rocniku(self): def kod_v_rocniku(self):
if self.stav == 'zadany': if self.stav == 'zadany':
# Nemělo by být potřeba # Nemělo by být potřeba
@ -710,9 +728,13 @@ class Text(SeminarModelBase):
do_cisla = models.TextField('text do čísla', blank=True, do_cisla = models.TextField('text do čísla', blank=True,
help_text='Text ke zveřejnění v čísle') help_text='Text ke zveřejnění v čísle')
# má OneToOneField s:
# Reseni (je u něj jako reseni_cele)
# obrázky mají návaznost opačným směrem (vazba z druhé strany) # obrázky mají návaznost opačným směrem (vazba z druhé strany)
class Uloha(Problem): class Uloha(Problem):
class Meta: class Meta:
db_table = 'seminar_ulohy' db_table = 'seminar_ulohy'
@ -733,6 +755,10 @@ class Uloha(Problem):
max_body = models.DecimalField(max_digits=8, decimal_places=1, verbose_name='maximum bodů', max_body = models.DecimalField(max_digits=8, decimal_places=1, verbose_name='maximum bodů',
blank=True, null=True) blank=True, null=True)
# má OneToOneField s:
# UlohaZadaniNode
# UlohaVzorakNode
def kod_v_rocniku(self): def kod_v_rocniku(self):
if self.stav == 'zadany': if self.stav == 'zadany':
name="{}.u{}".format(self.cislo_zadani.cislo,self.kod) name="{}.u{}".format(self.cislo_zadani.cislo,self.kod)
@ -742,7 +768,6 @@ class Uloha(Problem):
return '<Není zadaný>' return '<Není zadaný>'
@reversion.register(ignore_duplicates=True) @reversion.register(ignore_duplicates=True)
class Reseni(SeminarModelBase): class Reseni(SeminarModelBase):
@ -790,6 +815,9 @@ class Reseni(SeminarModelBase):
zverejneno = models.BooleanField('řešení zveřejněno', default=False, zverejneno = models.BooleanField('řešení zveřejněno', default=False,
help_text='Udává, zda je řešení zveřejněno') help_text='Udává, zda je řešení zveřejněno')
# má OneToOneField s:
# Konfera
def __str__(self): def __str__(self):
return "{}: {}".format(self.resitel.osoba.plne_jmeno(), self.problem.nazev) return "{}: {}".format(self.resitel.osoba.plne_jmeno(), self.problem.nazev)
# NOTE: Potenciální DB HOG (bez select_related) # NOTE: Potenciální DB HOG (bez select_related)
@ -913,6 +941,9 @@ class Pohadka(SeminarModelBase):
editable=False editable=False
) )
# má OneToOneField s:
# PohadkaNode
def __str__(self): def __str__(self):
uryvek = self.text if len(self.text) < 50 else self.text[:(50-3)]+"..." uryvek = self.text if len(self.text) < 50 else self.text[:(50-3)]+"..."
return uryvek return uryvek
@ -991,6 +1022,7 @@ class Konfera(models.Model):
organizator = models.ForeignKey(Organizator, verbose_name='organizátor', related_name='konfery', organizator = models.ForeignKey(Organizator, verbose_name='organizátor', related_name='konfery',
on_delete = models.SET_NULL, null=True) on_delete = models.SET_NULL, null=True)
# FIXME: Umíme omezit jen na účastníky daného soustřeďka?
ucastnici = models.ManyToManyField(Resitel, verbose_name='účastníci konfery', ucastnici = models.ManyToManyField(Resitel, verbose_name='účastníci konfery',
help_text='Seznam účastníků konfery', through='Konfery_Ucastnici') help_text='Seznam účastníků konfery', through='Konfery_Ucastnici')
@ -1020,6 +1052,9 @@ class Konfera(models.Model):
help_text = 'Další materiály ke konfeře zabalené do jednoho souboru', help_text = 'Další materiály ke konfeře zabalené do jednoho souboru',
upload_to = generate_filename_konfera, blank=True) upload_to = generate_filename_konfera, blank=True)
# má OneToOneField s:
# KonferaNode
def __str__(self): def __str__(self):
return "{}: ({})".format(self.nazev, self.soustredeni) return "{}: ({})".format(self.nazev, self.soustredeni)

71
seminar/old_views.py

@ -0,0 +1,71 @@
# Tento soubor slouží k odkládání aktuálně nepotřebného kódu, který by
# se však v budoucnu mohl opět hodit.
###################################################################
## Prispevek byl zrusen, mozna ale bude podobny nahled na neco jineho.
#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
####################################################################
## Stvrzenky aktuálně nevydáváme, ale možná časem zase budeme.
#def soustredeniStvrzenkyExportView(request,soustredeni,first_num):
# first_num = int(first_num)
# soustredeni = get_object_or_404(Soustredeni,id = soustredeni)
# ucastnici = Resitel.objects.filter(soustredeni=soustredeni)
# for (idx,u) in enumerate(ucastnici):
# u.cislo_stvrzenky = first_num+idx;
# tex = render(request,'seminar/soustredeni/ucastnici.tex', {'ucastnici': ucastnici, 'datum':soustredeni.datum_zacatku }).content
#
# tempdir = tempfile.mkdtemp()
# with open(tempdir+"/ucastnici.tex","w") as texfile:
# # Pokud TeX chce ISO Latin, tak se da encode nastavit
# texfile.write(tex.decode("utf-8").encode("utf-8"))
# shutil.copy(os.path.join(settings.STATIC_ROOT, 'seminar/stvrzenka.sty'),tempdir)
# shutil.copy(os.path.join(settings.STATIC_ROOT, 'seminar/stvrzenky.tex'),tempdir)
# subprocess.call(["cslatex","stvrzenky.tex"],cwd = tempdir)
# subprocess.call(["dvipdf","stvrzenky.dvi"],cwd = tempdir)
#
# with open(tempdir+"/stvrzenky.pdf","rb") as pdffile:
# response = HttpResponse(pdffile.read(),content_type='application/pdf')
# shutil.rmtree(tempdir)
# return response

204
seminar/testutils.py

@ -59,6 +59,7 @@ def gen_osoby(rnd, size):
datum_registrace = datetime.date(rnd.randint(2019, 2029), datum_registrace = datetime.date(rnd.randint(2019, 2029),
rnd.randint(1, 12), rnd.randint(1, 28)))) rnd.randint(1, 12), rnd.randint(1, 28))))
#TODO pridat foto male a velke. Jak? #TODO pridat foto male a velke. Jak?
# Pavel tvrdí, že to necháme a přidáme až do adminu
return osoby return osoby
@ -206,71 +207,38 @@ def gen_ulohy_do_cisla(rnd, cislo, organizatori, resitele, slovnik_cisel, size):
return return
def gen_soustredeni(): def gen_soustredeni():
# TODO: vice soustredeni a k nim nahodne podmnoziny organizatoru a ucastniku sousy = []
# TODO: pozor, organizatori a ucastnici jsou ManyToManyField, musí se přiřadit for sousi in range(1, size): #FIXME Tu range si změňte jak chcete, nevím, co přesně znamená size (asi Anet?)
# mimo create() a pak dát save() datum_zacatku=datetime.date(randint(2000, 2020), randint(1, 12), radint(1, 28))
sous = Soustredeni.objects.create(rocnik=Rocnik.objects.first(), working_sous = Soustredeni.objects.create(rocnik=Rocnik.objects.order_by('?').first(),
verejne_db=True, verejne_db=rnd.choice([True, False]),
misto=u'Někde', misto=rnd.choice(['Kremrolovice', 'Indiánov', 'U zmzliny', 'Vafláreň', 'Větrník', 'Horní Rakvička', 'Dolní cheesecake']),
datum_zacatku=datetime.date(2000, 11, 23), datum_zacatku=datum_zacatku,
datum_konce=datetime.date(2000, 11, 27) datum_konce=datum_zacatku + datetime.timedelta(weeks=1))
)
for res in rnd.sample(resitele, min(len(resitele), 20)): for res in rnd.sample(resitele, min(len(resitele), 20)):
Soustredeni_Ucastnici.objects.create(resitel=res, soustredeni=sous) Soustredeni_Ucastnici.objects.create(resitel=res, soutredeni=working_sous)
sous.save() for org in rnd.sample(organizatori, min(len(organizatori), 20)):
Soustredeni_Organizatori.objects.create(organizator=org, soutredeni=working_sous)
working_sous.save()
@transaction.atomic sousy.append(working_sous)
def create_test_data(size = 6, rnd = None): return sousy
assert size >= 1
# pevna pseudo-nahodnost def gen_rocniky(last_rocnik, size):
rnd = rnd or random.Random(x=42) rocniky = []
node = None
# static URL stranky
# FIXME: nakopirovat sem vsechny z produkcni databaze
s = Site.objects.filter(name="example.com")
f = FlatPage.objects.create(url="/", title="Seminář M&M",
content = "<p>V&iacute;tejte na str&aacute;nce semin&aacute;ře MaM!</p>")
f.sites.add(s[0])
f.save()
# users
admin = User.objects.create_superuser(username='admin', email='', password='admin')
usernames = ['anet', 'bara', 'cyril', 'david', 'eva', 'filip']
users = []
for usr in usernames[:size]:
u = User.objects.create(username=usr, password=usr)
u.first_name = usr.capitalize()
u.save()
users.append(u)
print(users)
# skoly
skoly = gen_skoly()
# osoby
osoby = gen_osoby(rnd, size)
# resitele a organizatori
last_rocnik = 25
resitele = gen_resitele(rnd, osoby, skoly)
organizatori = gen_organizatori(rnd, osoby, last_rocnik, users)
# prijemci
prijemci = gen_prijemci(rnd, osoby)
global zlinska
zlinska.kontaktni_osoba=rnd.choice(osoby)
zlinska.save()
# rocniky
for ri in range(min(last_rocnik - size, 1), last_rocnik + 1): for ri in range(min(last_rocnik - size, 1), last_rocnik + 1):
r = Rocnik.objects.create(prvni_rok = 1993 + ri, rocnik = ri) rocnik = Rocnik.objects.create(prvni_rok = 1993 + ri, rocnik = ri)
node2 = RocnikNode.objects.create(rocnik = rocnik, succ = node)
# cisla node = node2
cisel = rnd.randint(4, 8) rocniky.append(rocnik)
return rocniky
def gen_cisla(rocniky):
slovnik_rocnik_cisla = {}
for rocnik in rocniky:
slovnik_cisel = {} slovnik_cisel = {}
cisel = rnd.randint(4, 8)
node = None
for ci in range(1, cisel + 1): for ci in range(1, cisel + 1):
# první číslo vydáváme typicky okolo prázdnin # první číslo vydáváme typicky okolo prázdnin
# (ci - 1)*2 zaručuje první číslo v červnu a všechna # (ci - 1)*2 zaručuje první číslo v červnu a všechna
@ -289,20 +257,25 @@ def create_test_data(size = 6, rnd = None):
deadline = None deadline = None
cislo = Cislo.objects.create( cislo = Cislo.objects.create(
rocnik = r, rocnik = rocnik,
cislo = str(ci), cislo = str(ci),
datum_vydani=vydano, datum_vydani=vydano,
datum_deadline=deadline, datum_deadline=deadline,
verejne_db=True verejne_db=True
) )
slovnik_cisel[ci] = cislo node2 = CisloNode.objects.create(cislo = cislo, succ = node)
node = node2
# generovani uloh slovnik_cisel[ci] = cislo
gen_ulohy_do_cisla(rnd, ci, organizatori, resitele, slovnik_cisel, size) slovnik_rocnik_cisla[rocnik] = slovnik_cisel
return slovnik_rocnik_cisla
# generování témat, zatím v prvních třech číslech po jednom
# FIXME: více témat def gen_temata(rocniky, slovnik_rocnik_cisla):
if ci <= 3: slovnik_rocnik_temata = {}
for rocnik in rocniky:
temata = {}
for cislo in slovnik_r[rocnik]
if cislo <= 3:
jake = ["Hravé", "Fyzikální", "Nejlepší", "Totálně masakrální", jake = ["Hravé", "Fyzikální", "Nejlepší", "Totálně masakrální",
"Šokující", "Magnetické", "Modré", "Překvapivé", "Šokující", "Magnetické", "Modré", "Překvapivé",
"Plasmatické", "Novoroční"] "Plasmatické", "Novoroční"]
@ -319,25 +292,30 @@ def create_test_data(size = 6, rnd = None):
garant=rnd.choice(organizatori), garant=rnd.choice(organizatori),
# FIXME: téma má kód podle čísla, až jich bude # FIXME: téma má kód podle čísla, až jich bude
# více, tak udělat kód podle pořadí vygenerování # více, tak udělat kód podle pořadí vygenerování
kod=str(ci), kod=str(cislo),
# atributy třídy Téma # atributy třídy Téma
tema_typ=rnd.choice(Tema.TEMA_CHOICES), tema_typ=rnd.choice(Tema.TEMA_CHOICES),
rocnik=r) rocnik=rocnik)
t.opravovatele=rnd.sample(organizatori, poc_op) t.opravovatele=rnd.sample(organizatori, poc_op)
t.save() t.save()
temata[cislo] = t
# FIXME: nefunguje, protože další čísla v tuhle chvíli ještě slovnik_rocnik_temata[tema] = temata
# nejsou nagenerovaná
# nagenerovat k tématu úlohy a Nody pro vsechna cisla def gen_ulohy_k_tematum(rocniky, slovnik_rocnik_cisla, slovnik_rocnik_temata):
for i in range(ci, cisel-2): for rocnik in rocniky:
# vytvoř úlohu pro každé ze zbývajících čísel slovnik_cisel = slovnik_rocnik_cisla[rocnik]
cisel = len(slovnik_cisel)
slovnik_temat = slovnik_rocnik_temata[rocnik]
for tema in slovnik_temat:
for i in range(tema.
if #TODO
poc_op = rnd.randint(1, 4) poc_op = rnd.randint(1, 4)
poc_oboru = rnd.randint(1, 2) poc_oboru = rnd.randint(1, 2)
p = Uloha.objects.create( p = Uloha.objects.create(
nazev=": ".join([t.nazev, nazev=": ".join([tema.nazev,
"úloha {}.".format(i-ci+1)]), "úloha {}.".format(i-ci+1)]),
nadproblem=t, nadproblem=tema,
stav=Problem.STAV_ZADANY, stav=Problem.STAV_ZADANY,
zamereni=t.zamereni, zamereni=t.zamereni,
autor=t.autor, autor=t.autor,
@ -370,6 +348,72 @@ def create_test_data(size = 6, rnd = None):
# vytvor mezicislo Node # vytvor mezicislo Node
pass pass
@transaction.atomic
def create_test_data(size = 6, rnd = None):
assert size >= 1
# pevna pseudo-nahodnost
rnd = rnd or random.Random(x=42)
# static URL stranky
# FIXME: nakopirovat sem vsechny z produkcni databaze
s = Site.objects.filter(name="example.com")
f = FlatPage.objects.create(url="/", title="Seminář M&M",
content = "<p>V&iacute;tejte na str&aacute;nce semin&aacute;ře MaM!</p>")
f.sites.add(s[0])
f.save()
# users
admin = User.objects.create_superuser(username='admin', email='', password='admin')
usernames = ['anet', 'bara', 'cyril', 'david', 'eva', 'filip']
users = []
for usr in usernames[:size]:
u = User.objects.create(username=usr, password=usr)
u.first_name = usr.capitalize()
u.save()
users.append(u)
print(users)
# skoly
skoly = gen_skoly()
# osoby
osoby = gen_osoby(rnd, size)
# resitele a organizatori
last_rocnik = 25
resitele = gen_resitele(rnd, osoby, skoly)
organizatori = gen_organizatori(rnd, osoby, last_rocnik, users)
# prijemci
prijemci = gen_prijemci(rnd, osoby)
global zlinska
zlinska.kontaktni_osoba=rnd.choice(osoby)
zlinska.save()
# rocniky
rocniky = gen_rocniky(last_rocnik, size)
# cisla
slovnik_rocnik_cisla = gen_cisla(rocniky)
# generování obyčejných úloh do čísel
for rocnik in rocniky:
slovnik_cisel = slovnik_rocnik_cisla[rocnik]
for cislo in slovnik_cisel:
gen_ulohy_do_cisla(rnd, cislo, organizatori, resitele, slovnik_cisel, size)
# generování témat, zatím v prvních třech číslech po jednom
# FIXME: více témat
slovnik_rocnik_temata = gen_temata(rocniky, slovnik_rocnik_cisla)
# generování úloh k tématům ve všech číslech
gen_ulohy_k_tematum(rocniky, slovnik_rocnik_cisla, slovnik_rocnik_temata)
# nagenerovat k tématu úlohy a Nody pro vsechna cisla
# FIXME: misto typu ruzne typy objektu a vnoreni do sebe # FIXME: misto typu ruzne typy objektu a vnoreni do sebe

4
seminar/urls.py

@ -46,10 +46,6 @@ urlpatterns = [
name='maily_ucastniku' name='maily_ucastniku'
), ),
url( url(
'soustredeni/<int:soustredeni>/stvrzenky/<int:first_num>',
staff_member_required(views.soustredeniStvrzenkyExportView),
name='soustredeni_stvrzenky'
),
url( url(
'soustredeni/<int:soustredeni>/export_ucastniku', 'soustredeni/<int:soustredeni>/export_ucastniku',
staff_member_required(views.soustredeniUcastniciExportView), staff_member_required(views.soustredeniUcastniciExportView),

66
seminar/views.py

@ -377,47 +377,6 @@ 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
## Prispevek byl zrusen, mozna ale bude podobny nahled na neco jineho.
#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):
pass pass
@ -465,7 +424,6 @@ class RadekVysledkovky(object):
# #setridi problemy podle typu a poradi zadani # #setridi problemy podle typu a poradi zadani
# problem_index = {} # problem_index = {}
# for i in range(len(problemy)): # for i in range(len(problemy)):
# problem_index[problemy[i].id] = i
# #umoznuje zjistit index podle id problemu # #umoznuje zjistit index podle id problemu
# #
# vysledky_resitele = {} # vysledky_resitele = {}
@ -665,30 +623,6 @@ class SoustredeniUcastniciView(SoustredeniUcastniciBaseView):
model = Soustredeni_Ucastnici model = Soustredeni_Ucastnici
template_name = 'seminar/soustredeni/seznam_ucastniku.html' template_name = 'seminar/soustredeni/seznam_ucastniku.html'
def soustredeniStvrzenkyExportView(request,soustredeni,first_num):
first_num = int(first_num)
soustredeni = get_object_or_404(Soustredeni,id = soustredeni)
ucastnici = Resitel.objects.filter(soustredeni=soustredeni)
for (idx,u) in enumerate(ucastnici):
u.cislo_stvrzenky = first_num+idx;
tex = render(request,'seminar/soustredeni/ucastnici.tex', {'ucastnici': ucastnici, 'datum':soustredeni.datum_zacatku }).content
tempdir = tempfile.mkdtemp()
with open(tempdir+"/ucastnici.tex","w") as texfile:
# Pokud TeX chce ISO Latin, tak se da encode nastavit
texfile.write(tex.decode("utf-8").encode("utf-8"))
shutil.copy(os.path.join(settings.STATIC_ROOT, 'seminar/stvrzenka.sty'),tempdir)
shutil.copy(os.path.join(settings.STATIC_ROOT, 'seminar/stvrzenky.tex'),tempdir)
subprocess.call(["cslatex","stvrzenky.tex"],cwd = tempdir)
subprocess.call(["dvipdf","stvrzenky.dvi"],cwd = tempdir)
with open(tempdir+"/stvrzenky.pdf","rb") as pdffile:
response = HttpResponse(pdffile.read(),content_type='application/pdf')
shutil.rmtree(tempdir)
return response
def soustredeniUcastniciExportView(request,soustredeni): def soustredeniUcastniciExportView(request,soustredeni):
soustredeni = get_object_or_404(Soustredeni,id = soustredeni) soustredeni = get_object_or_404(Soustredeni,id = soustredeni)
ucastnici = Resitel.objects.filter(soustredeni=soustredeni) ucastnici = Resitel.objects.filter(soustredeni=soustredeni)

Loading…
Cancel
Save