From 275630daee7dea2b4b5505241f480327b23205db Mon Sep 17 00:00:00 2001 From: "Bc. Petr Pecha" Date: Sun, 11 Oct 2015 17:31:30 +0200 Subject: [PATCH] Galerie | clone + uprava modelu galerie pecemesrdcem Model upraven pro potreby M&M-miho webu --- galerie/TODO | 7 ++ galerie/__init__.py | 0 galerie/models.py | 114 +++++++++++++++++++++ galerie/static/galerie/prvky/dalsi.png | Bin 0 -> 1180 bytes galerie/static/galerie/prvky/predchozi.png | Bin 0 -> 1256 bytes 5 files changed, 121 insertions(+) create mode 100644 galerie/TODO create mode 100644 galerie/__init__.py create mode 100644 galerie/models.py create mode 100644 galerie/static/galerie/prvky/dalsi.png create mode 100644 galerie/static/galerie/prvky/predchozi.png diff --git a/galerie/TODO b/galerie/TODO new file mode 100644 index 00000000..26918708 --- /dev/null +++ b/galerie/TODO @@ -0,0 +1,7 @@ +======== +| TODO | +|======| + +* zvolit velikosti velke a male fotky +* vycteni EXIFu +* razeni podle casu diff --git a/galerie/__init__.py b/galerie/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/galerie/models.py b/galerie/models.py new file mode 100644 index 00000000..b368415a --- /dev/null +++ b/galerie/models.py @@ -0,0 +1,114 @@ +# coding: utf-8 + +from django.db import models +import seminar.models +from django.db.models import Q +from django.utils import timezone + +from PIL import Image +import os +from cStringIO import StringIO +from django.core.files.base import ContentFile + +from seminar.models import Soustredeni + +VZDY=0 +ORG=1 +NIKDY=2 +VIDITELNOST = ( + (VZDY, 'Vždy'), + (ORG, 'Organizátorům'), + (NIKDY, 'Nikdy'), +) + +class Obrazek(models.Model): + # TODO vkladat do slozek podle soustredeni + obrazek_velky = models.ImageField(upload_to='Galerie/%Y/%m/%d', + help_text = "Lze vložit libovolně velký obrázek. Ideální je, aby alespoň jeden rozměr měl alespoň 500px.") + obrazek_stredni = models.ImageField(upload_to='Galerie/%Y/%m/%d/stredni', null = True, editable = False) + obrazek_maly = models.ImageField(upload_to='Galerie/%Y/%m/%d/male', null = True, editable = False) + nazev = models.CharField('Název', max_length=50, blank = True, null = True) + popis = models.TextField('Popis', blank = True, null = True) + datum_vlozeni = models.DateTimeField('Datum vložení', auto_now_add = True) + datum = models.DateTimeField('Datum pořízení fotografie', blank = False) # TODO zjistit z EXIFU + galerie = models.ForeignKey('Galerie') + poradi = models.IntegerField('Pořadí', blank = True, null = True) + def __unicode__(self): + return self.nazev + " -- " + unicode(self.obrazek_velky.name) + " (" + str(self.datum) + ")" + class Meta: + verbose_name = 'Obrázek' + verbose_name_plural = 'Obrázky' + def save(self): + original = Image.open(self.obrazek_velky) + jmeno = os.path.basename(self.obrazek_velky.file.name) + Obrazek._vyrobMiniaturu(original, jmeno, 500, self.obrazek_stredni) + Obrazek._vyrobMiniaturu(original, jmeno, 200, self.obrazek_maly) + super(Obrazek, self).save() + + @staticmethod + def _vyrobMiniaturu(original, jmeno, maximum, field): + zmensenina = Obrazek._zmensiObrazek(original, maximum) + f = StringIO() + try: + zmensenina.save(f, format=original.format) + data = ContentFile(f.getvalue()) + finally: + f.close() + field.save(jmeno, data, save = False) + + @staticmethod + def _zmensiObrazek(original, maximum): + """Preskaluje obrazek tak, aby byl zachovan pomer stran a zadny rozmer + nepresahoval maxRozmer. Pokud zadny rozmer nepresahuje maxRozmer, tak + vrati puvodni obrazek (tj. nedojde ke zvetseni obrazku).""" + novaVelikost = Obrazek._zmensiVelikost(original.size, maximum) + return original.resize(novaVelikost, Image.ANTIALIAS) + + @staticmethod + def _zmensiVelikost(velikost, maximum): + maximum = float(maximum) + w, h = velikost + soucasneMaximum = max(w, h) + if soucasneMaximum <= maximum: + return velikost + pomer = maximum/soucasneMaximum + return (int(w * pomer), int(h * pomer)) + + +class Galerie(models.Model): + nazev = models.CharField('Název', max_length=100) + datum_vytvoreni = models.DateTimeField('Datum vytvoření', auto_now_add = True) + datum_zmeny = models.DateTimeField('Datum poslední změny', auto_now = True) + popis = models.TextField('Popis', blank = True, null = True) + titulni_obrazek = models.ForeignKey(Obrazek, blank = False, null = True, related_name = "+", on_delete = models.SET_NULL) + zobrazit = models.IntegerField('Zobrazit?', default = ORG, choices = VIDITELNOST) + galerie_up = models.ForeignKey('Galerie', blank = True, null = True) + soustredeni = models.ForeignKey(Soustredeni, blank = True, null = True) + + def __unicode__(self): + return self.nazev + class Meta: + verbose_name = 'Galerie' + verbose_name_plural = 'Galerie' + + #def link_na_preview(self): + #"""Odkaz na galerii, používá se v admin rozhranní. """ + #return 'Preview' % self.id + #link_na_preview.allow_tags = True + #link_na_preview.short_description = 'Zobrazit galerii' +# + #def je_publikovano(self): + #"""Vraci True, pokud je tato galerie publikovana. """ + #if self.zobrazit == VZDY: + #return True + #if self.zobrazit == PODLE_CLANKU: + #for clanek in self.clanek_set.all(): + #if clanek.je_publikovano(): + #return True + #return False +# + #@staticmethod + #def publikovane_galerie(): + #"""Vraci galerie, ktere uz maji byt publikovane.""" + #clanky = Blog.models.Clanek.publikovane_clanky() + #return Galerie.objects.filter(Q(zobrazit=VZDY) | (Q(clanek__in=clanky) & Q(zobrazit=PODLE_CLANKU))).distinct() diff --git a/galerie/static/galerie/prvky/dalsi.png b/galerie/static/galerie/prvky/dalsi.png new file mode 100644 index 0000000000000000000000000000000000000000..37064569ebd92225468203c597325ed203f259ca GIT binary patch literal 1180 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 SFuunC0000