# -*- coding: utf-8 -*- # Generated by Django 1.11.20 on 2019-05-17 17:44 from __future__ import unicode_literals from django.db import migrations, models from django.db.models import Q import django.db.models.deletion def poskladej_strom(apps, rodic, *texty): Text = apps.get_model('seminar', 'Text') TextNode = apps.get_model('seminar', 'TextNode') if not rodic: raise ValueError("Rodič musí být definovaný") uz_ma_deti = False tn = None for txt in texty: if not txt: continue # Přidej do stromu: textobj = Text.objects.create(na_web = txt) textobj.save() textnode = TextNode.objects.create(text = textobj) textnode.save() if not uz_ma_deti: rodic.first_child = textnode rodic.save() tn = rodic.first_child uz_ma_deti = True else: tn.succ = textnode tn.save() tn = tn.succ def uloha_to_Uloha(apps,schema_editor): Problem = apps.get_model('seminar', 'Problem') Uloha = apps.get_model('seminar', 'Uloha') Text = apps.get_model('seminar', 'Text') UlohaZadaniNode = apps.get_model('seminar', 'UlohaZadaniNode') UlohaVzorakNode = apps.get_model('seminar', 'UlohaVzorakNode') TextNode = apps.get_model('seminar', 'TextNode') ulohy = Problem.objects.filter(typ = 'uloha') for uold in ulohy: unew = Uloha.objects.create( # Zakomentované fieldy by se už měly nacházet v příslušném problému problem_ptr = uold, nazev = uold.nazev, stav = uold.stav, zamereni = uold.zamereni, poznamka = uold.poznamka, autor = uold.autor, kod = uold.kod, cislo_zadani = uold.cislo_zadani_old, cislo_reseni = uold.cislo_reseni_old, max_body = uold.body, vytvoreno = uold.vytvoreno, ) uold.save() # DULEZITE!!! Jinak Uloha.objects.create() přepíše všechny atributy Problému unew.opravovatele.add(*uold.opravovatele.all()) # Nody: zadani_node = UlohaZadaniNode.objects.create(uloha = unew) poskladej_strom(apps, zadani_node, uold.text_zadani) zadani_node.save() vzorak_node = UlohaVzorakNode.objects.create(uloha = unew) poskladej_strom(apps, vzorak_node, uold.text_reseni) vzorak_node.save() def konfery_rucne(apps, schema_editor): # Tohle dělat nebudu, máme aktuálně celou jednu. Ale "Errors should never pass silently" Problem = apps.get_model('seminar', 'Problem') pocet_konfer = Problem.objects.filter(typ = 'konfera').count() if pocet_konfer > 0: raise NotImplementedError("Zkonvertuj {} konfer na objekt Konfera ručně, prosím".format(pocet_konfer)) def clanek_to_Clanek(apps,schema_editor): Problem = apps.get_model('seminar', 'Problem') Clanek = apps.get_model('seminar', 'Clanek') ReseniNode = apps.get_model('seminar', 'ReseniNode') Text = apps.get_model('seminar', 'Text') TextNode = apps.get_model('seminar', 'TextNode') # XXX: Org-clanky neexistuji, tak je migrace ani nepodporuje. clanky = Problem.objects.filter(typ='res-clanek') for cl in clanky: # Vybereme vhodné číslo pro článek z čísla zadání a čísla řešení: if cl.cislo_zadani_old is None: cislo = cl.cislo_reseni_old elif cl.cislo_reseni_old is None: cislo = cl.cislo_zadani_old elif cl.cislo_reseni_old == cl.cislo_zadani_old: cislo = cl.cislo_zadani_old else: raise ValueError("Různá čísla zadání a řešení u článku! (Článek: {})".format(cl.nazev)) clnew = Clanek.objects.create( problem_ptr = cl, # Problém by nemělo být potřeba upravovat cislo = cislo, # Body ignorujeme, protože už jsou v hodnocení ) cl.save() # DULEZITE!!! Jinak Clanek.objects.create() přepíše všechny atributy Problému def Clanek_Treenody(apps, schema_editor): Problem = apps.get_model('seminar', 'Problem') Clanek = apps.get_model('seminar', 'Clanek') ReseniNode = apps.get_model('seminar', 'ReseniNode') Text = apps.get_model('seminar', 'Text') TextNode = apps.get_model('seminar', 'TextNode') for cl in Clanek.objects.all(): # Vyrobíme nody: # Clanek nema vlastni node, ma (prave jedno) Reseni a to ma text_cely -- ReseniNode reseni = cl.reseni_set.all() if len(reseni) != 1: raise ValueError(f'Clanek {cl.id} ma vic reseni {len(reseni)} ({reseni})') reseni = reseni[0] resnode = ReseniNode(reseni=reseni) poskladej_strom(apps, resnode, cl.text_zadani, cl.text_reseni) resnode.save() reseni.text_cely = resnode reseni.save() def fix_Clanek_Reseni(apps, schema_editor): Problem = apps.get_model('seminar', 'Problem') Clanek = apps.get_model('seminar', 'Clanek') Reseni = apps.get_model('seminar', 'Reseni') Hodnoceni = apps.get_model('seminar', 'Hodnoceni') Resitel = apps.get_model('seminar', 'Resitel') # Je potreba zajistit, ze clanky budou mit jen jedno reseni -- z pohledu # modelu nic jineho nedava smysl. Ve stavajicim modelu ale naopak nelze # reprezentovat vice resitelu jednoho clanku (coz je ale bezne -- clanky z # konfer) Musime tedy opravit, aby misto nekolika reseni kazdeho resitele # samostatne zustalo jen jedno reseni, spravne obodovane a s vice resiteli # jako autory for cl in Clanek.objects.all(): rr = cl.reseni_set.all() if len(rr) == 1: continue # Vice nez jedno reseni, jdeme je sjednotit. resitele = [] vzor_hodnoceni = rr[0].hodnoceni_set.first() ostatni_hodnoceni = [] for r in rr: # Overime, ze nemame kolizi v datech: h = r.hodnoceni_set.first() if h.cislo_body != vzor_hodnoceni.cislo_body or h.body != vzor_hodnoceni.body: raise ValueError(f'Clanek {cl.id} ma vice nekonzistentnich reseni') if h.id != vzor_hodnoceni.id: ostatni_hodnoceni.append(h) resitele.extend(r.resitele.all()) rr[0].resitele.set(resitele) rr[0].save() vzor_hodnoceni.save() # Ted mame spravne databazi, jeste potrebujeme z databaze smazat po novu nepouzita hodnoceni for h in ostatni_hodnoceni: h.reseni.delete() h.delete() def tema_to_Tema(apps, schema_editor): Problem = apps.get_model('seminar', 'Problem') Tema = apps.get_model('seminar', 'Tema') TemaVCisleNode = apps.get_model('seminar', 'TemaVCisleNode') Text = apps.get_model('seminar', 'Text') TextNode = apps.get_model('seminar', 'TextNode') temata = Problem.objects.filter(Q(typ = 'tema') | Q(typ='serial')) for t in temata: # Vymyslíme správně ročník: if t.cislo_zadani_old is None and t.cislo_reseni_old is None: rocnik = None elif t.cislo_zadani_old is None: rocnik = t.cislo_reseni_old.rocnik elif t.cislo_reseni_old is None: rocnik = t.cislo_zadani_old.rocnik elif t.cislo_reseni_old.rocnik == t.cislo_zadani_old.rocnik: rocnik = t.cislo_zadani_old.rocnik else: raise ValueError("Nelze mít téma přes více ročníků! (Téma: {}".format(t.nazev)) tnew = Tema.objects.create( problem_ptr = t, tema_typ = t.typ, rocnik = rocnik, ) t.save() # DULEZITE!!! Jinak Tema.objects.create() přepíše všechny atributy Problému # Nody: tnode = TemaVCisleNode(tema = tnew) poskladej_strom(apps, tnode, t.text_zadani, t.text_reseni) tnode.save() class Migration(migrations.Migration): dependencies = [ ('seminar', '0087_fix_polymorphism'), ] operations = [ # ashes to Ashes, dust to Dust.... migrations.RunPython(uloha_to_Uloha, migrations.RunPython.noop), migrations.RunPython(tema_to_Tema, migrations.RunPython.noop), migrations.RunPython(clanek_to_Clanek, migrations.RunPython.noop), migrations.RunPython(fix_Clanek_Reseni, migrations.RunPython.noop), migrations.RunPython(Clanek_Treenody, migrations.RunPython.noop), migrations.RunPython(konfery_rucne, migrations.RunPython.noop), ]