import random from django.http import HttpResponse, Http404, HttpRequest from django.shortcuts import render, HttpResponseRedirect, get_object_or_404 from django.template import RequestContext from django.urls import reverse from datetime import datetime from galerie.utils import top_galerie from personalni.utils import resitel_uzivatele from galerie.models import Soubor, Galerie from soustredeni.models import Soustredeni from galerie.forms import KomentarForm, NewGalerieForm # Tohle byl import a používá se to tu relativně extensivně, tak asi nedává smysl všude psát prefix `Galerie.Viditelnost.` VZDY = Galerie.Viditelnost.VZDY ORG = Galerie.Viditelnost.ORG UCASTNIK = Galerie.Viditelnost.UCASTNIK import logging logger = logging.getLogger(__name__) def galerie_ke_zobrazeni(soustredeni: Soustredeni | None, request: HttpRequest) -> tuple[Galerie.Viditelnost, ...]: if request.user.is_superuser: return (VZDY, ORG, UCASTNIK) if request.user.je_org: return (VZDY, ORG, UCASTNIK) if request.user.is_anonymous: return (VZDY,) if soustredeni is None: return (VZDY,) if (resitel := resitel_uzivatele(request.user)) is not None: if resitel.soustredeni_set.contains(soustredeni): return (VZDY, UCASTNIK) else: return (VZDY,) logger.warning("Nepodařilo se zjistit, jaké galerie se mají zobrazit!") return (VZDY,) def zobrazit(galerie: Galerie, request: HttpRequest) -> bool: soustredeni = top_galerie(galerie).soustredeni return galerie.zobrazit in galerie_ke_zobrazeni(soustredeni, request) def dovolit_upravy_popisku(galerie: Galerie, request: HttpRequest) -> bool: # FIXME: Dočasné: úpravy jen když je to v org-only stavu. (Odpovídá předchozímu chování) return request.user.je_org and galerie.zobrazit in (ORG,) def cesta_od_korene(g): """Vrátí seznam galerií od kořene ke g""" cesta = [] while g is not None: cesta.append(g) g = g.nadgalerie return reversed(cesta) def galerieView(request, soustredeni:int, galerie: int): """Zobrazení přehledu všech souborů v Galerii.""" galerie: Galerie = get_object_or_404(Galerie, pk=galerie) assert top_galerie(galerie).soustredeni.id == soustredeni soustredeni: Soustredeni | None = top_galerie(galerie).soustredeni # FIXME: přepsat model a použít přímo dolů… podgalerie = Galerie.objects.filter(nadgalerie = galerie).order_by('poradi') podgalerie = podgalerie.filter(zobrazit__in=galerie_ke_zobrazeni(soustredeni, request)) soubory = galerie.soubor_set.all().order_by('poradi', 'nazev') ma_se_zobrazit = zobrazit(galerie, request) if not ma_se_zobrazit: raise Http404("Galerie sice existuje, ale my se tváříme, že ne :-D") sourozenci = [] if galerie.nadgalerie: sourozenci = galerie.nadgalerie.podgalerie.filter(zobrazit__in=galerie_ke_zobrazeni(soustredeni, request)).order_by('poradi') predchozi = None nasledujici = None minuly = None for g in sourozenci: if g.pk == galerie.pk: predchozi = minuly if minuly is not None and minuly.pk == galerie.pk: nasledujici = g break minuly = g cesta = cesta_od_korene(galerie) return render(request, 'galerie/GalerieNahled.html', {'galerie' : galerie, 'podgalerie' : podgalerie, 'soubory' : soubory, 'cesta': cesta, 'sourozenci': sourozenci, 'predchozi': predchozi, 'nasledujici': nasledujici, 'soustredeni': soustredeni, # Jen kvůli reverse urls… 'object': galerie, }) def souborView(request, soustredeni: int, galerie: int, soubor: int): """Zobrazení souboru.""" NAHLEDU = 1 galerie: Galerie = get_object_or_404(Galerie, pk=galerie) assert top_galerie(galerie).soustredeni.id == soustredeni soustredeni: Soustredeni | None = top_galerie(galerie).soustredeni ma_se_zobrazit = zobrazit(galerie, request) if not ma_se_zobrazit: raise Http404("Obrázek neukážu!") soubor = get_object_or_404(Soubor, pk=soubor) # Explicitní pořadí ničemu neuškodí :-) soubory = galerie.soubor_set.all().order_by('poradi', 'nazev') soubory = list(soubory) # Pokud někdo umí z DB rovnou vytáhnout příslušnou sadu obrázků, tak to # bude (teoreticky a asymptoticky) hezčí. Ale pokud neplánujeme mít tisíce # obrázků v jedné galerii, tak je to asi jedno :-D index_souboru = soubory.index(soubor) # Podle mě se nemůže stát, že by volání výš selhalo, kdyžtak shodí web. (původně to byl explicitně ošetřený stav dávající 404) predchozi_soubory = list(reversed(soubory[:index_souboru])) nasledujici_soubory = soubory[index_souboru+1:] # Může jich být hodně… predchozi_soubory = predchozi_soubory[:NAHLEDU] nasledujici_soubory = nasledujici_soubory[:NAHLEDU] # Předchozí obrázky chceme v normálním pořadí predchozi_soubory = list(reversed(predchozi_soubory)) if galerie.nadgalerie is not None: sousedni_galerie = Galerie.objects.filter(nadgalerie=galerie.nadgalerie, zobrazit__in=galerie_ke_zobrazeni(soustredeni, request)).order_by('poradi') sousedni_galerie = list(sousedni_galerie) # Teoreticky se můžeme dívat na galerie.poradi, ale jednak už tenhle pattern stejně je výš a druhak je galerií málo, takže pomalost nevadí. index_galerie = sousedni_galerie.index(galerie) predchozi_galerie = sousedni_galerie[index_galerie-1] if index_galerie > 0 else None nasledujici_galerie = sousedni_galerie[index_galerie+1] if index_galerie < len(sousedni_galerie) - 1 else None else: predchozi_galerie = None nasledujici_galerie = None # Pokud je obrázků dost, tak další galerii nepotřebujeme # (jo, mohli jsme si ušetřit práci, ale takhle je kód imho přehlednější a za pár ušetřených dotazů do DB to nestojí) if len(predchozi_soubory) >= NAHLEDU: predchozi_galerie = None if len(nasledujici_soubory) >= NAHLEDU: nasledujici_galerie = None # vytvoreni a obslouzeni formulare if request.method == 'POST': form = KomentarForm(request.POST) if form.is_valid(): soubor.popisek = form.cleaned_data['popisek'] soubor.save() else: form = KomentarForm({'popisek': soubor.popisek}) return render(request, 'galerie/Galerie.html', {'galerie' : galerie, 'predchozi_galerie' : predchozi_galerie, 'nasledujici_galerie' : nasledujici_galerie, 'soubor' : soubor, 'soubory_predchozi' : predchozi_soubory, 'soubory_dalsi' : nasledujici_soubory, 'upravy_popisku' : dovolit_upravy_popisku(galerie, request), 'form' : form, 'cesta': cesta_od_korene(galerie), 'soustredeni': soustredeni, 'object': soubor, }) def new_galerie(request, galerie: int, soustredeni: int): # zjistime k jakemu soustredeni se vaze nove vytvarena galerie soustredeni: Soustredeni = get_object_or_404(Soustredeni, pk = soustredeni) # pokud je parametr galerie 0, pak jde o hlavni galerii # kdyz je nejaky jiny, pak je pk galerie pod kterou tu dalsi vytvarim if int(galerie) == 0: nadgalerie = False galerie_text = "Hlavní fotogalerie soustředění" else: nadgalerie = get_object_or_404(Galerie, pk = int(galerie)) galerie_text = "podgalerii ke galerii " + str(nadgalerie) # obsluha formulare umoznujiciho multiple nahravani fotek if request.method == 'POST': # Tohle je nějaké zbastlené. NewGalerieForm nežere FILES, ručně zpracováváme ``request.FILES.getlist('obr')``. FIXME. form = NewGalerieForm(request.POST) if form.is_valid(): # vytvoreni nove galerie gal = Galerie() gal.nazev = form.cleaned_data['nazev'] gal.zobrazit = ORG # galerie je v procesu vytvareni ''' pokud je to podgalerie pridej nadrazenou galerii a nadrazene soustredeni nechej volne, pokud je to hlavni galerie, tak nadrazena galerie neexistuje, ale v takovem pripade musi byt nadrazene soustredeni a ne jinak ''' if nadgalerie: gal.nadgalerie = nadgalerie else: gal.soustredeni = soustredeni if gal.nadgalerie: gal.poradi = int(len(gal.nadgalerie.podgalerie.all())) + 1 gal.save() # zpracovani souboru v galerii from galerie.typy import tipniTyp for obr in request.FILES.getlist('obr'): o = Soubor() o.soubor = obr o.typ = tipniTyp(obr) o.nazev = str(obr) o.galerie = gal o.save() # presmerovani na prave vzniklou galerii return HttpResponseRedirect(reverse('galerie_galerie', kwargs={'galerie': gal.pk, 'soustredeni': soustredeni.id})) else: form = NewGalerieForm() return render(request, 'galerie/GalerieNew.html', { 'form' : form, 'soustredeni' : soustredeni, 'galerie_text' : galerie_text, }) # FIXME: Tohle by neměly být GETy, ale POSTy/PATCHe, protože mění stav # (= nejsou safe) a nejsou idempotentní. Ale znamená to mít místo odkazů # `