Merge branch 'Galerie'
This commit is contained in:
commit
ef5470bcb6
23 changed files with 807 additions and 6 deletions
24
galerie/TODO
Normal file
24
galerie/TODO
Normal file
|
@ -0,0 +1,24 @@
|
|||
========
|
||||
| TODO |
|
||||
|======|
|
||||
|
||||
Aktualni
|
||||
* do CSS
|
||||
* nahledy
|
||||
* nastylovat tabulku s nahledy
|
||||
* komentare uz na nahledy?
|
||||
* detail
|
||||
* nahledy pred a po
|
||||
* opravit prechodove sipky
|
||||
* vyrobit prechodove sipky ve M&M-stylu
|
||||
|
||||
Dlouhodobe
|
||||
* sipky na prechazeni mezi fotkami
|
||||
* hromadne PRIDANI fotek do jiz existujici galerie
|
||||
|
||||
Fylozoficke
|
||||
* zvolit velikosti velke a male fotky
|
||||
* je potreba i jine razeni nez automaticky podle casu nebo staci podgalerie?
|
||||
* napr. dve hry na dvou ruznych mistech ve stejny cas
|
||||
* fotky od ucastniku ze hry (skupinky se pohybuji ve stejny cas, ale maji sled fotek) -- nestaci to pripadne vrazit do podgalerii?
|
||||
|
0
galerie/__init__.py
Normal file
0
galerie/__init__.py
Normal file
43
galerie/admin.py
Normal file
43
galerie/admin.py
Normal file
|
@ -0,0 +1,43 @@
|
|||
#coding: utf-8
|
||||
|
||||
from galerie.models import Obrazek, Galerie
|
||||
from django.contrib import admin
|
||||
from django.http import HttpResponseRedirect
|
||||
|
||||
# akction
|
||||
|
||||
def zverejnit_fotogalerii(modeladmin, request, queryset):
|
||||
'''zverejni vybranou fotogalerii i jeji vsechny podgalerie'''
|
||||
for galerie in queryset:
|
||||
galerie.zobrazit = 0
|
||||
galerie.save()
|
||||
zverejnit_fotogalerii(modeladmin, request,
|
||||
Galerie.objects.filter(galerie_up = galerie))
|
||||
zverejnit_fotogalerii.short_description = 'Zveřejnit fotogalerie'
|
||||
|
||||
|
||||
def prepnout_fotogalerii_do_org_rezimu(modeladmin, request, queryset):
|
||||
'''zneverjni vybranou fotogalerii i jeji vsechny podgalerie'''
|
||||
for galerie in queryset:
|
||||
galerie.zobrazit = 1
|
||||
galerie.save()
|
||||
prepnout_fotogalerii_do_org_rezimu(modeladmin, request,
|
||||
Galerie.objects.filter(galerie_up = galerie))
|
||||
prepnout_fotogalerii_do_org_rezimu.short_description = \
|
||||
'Přepnout do režimu úprav (zneveřejní galerii)'
|
||||
|
||||
class GalerieInline(admin.TabularInline):
|
||||
model = Obrazek
|
||||
|
||||
class ObrazekAdmin(admin.ModelAdmin):
|
||||
list_display = ('obrazek_velky', 'nazev', 'popis')
|
||||
|
||||
class GalerieAdmin(admin.ModelAdmin):
|
||||
model = Galerie
|
||||
fields = ('zobrazit', 'nazev', 'titulni_obrazek', 'popis', 'galerie_up', 'soustredeni')
|
||||
list_display = ('nazev', 'pk', 'datum_zmeny', 'zobrazit', 'soustredeni')
|
||||
inlines = [GalerieInline]
|
||||
actions = [zverejnit_fotogalerii, prepnout_fotogalerii_do_org_rezimu]
|
||||
|
||||
admin.site.register(Obrazek, ObrazekAdmin)
|
||||
admin.site.register(Galerie, GalerieAdmin)
|
11
galerie/forms.py
Normal file
11
galerie/forms.py
Normal file
|
@ -0,0 +1,11 @@
|
|||
#coding: utf-8
|
||||
|
||||
from django import forms
|
||||
from seminar.models import Soustredeni
|
||||
|
||||
class KomentarForm(forms.Form):
|
||||
komentar = forms.CharField(label = "Komentář:", max_length = 300, required=False)
|
||||
|
||||
class NewGalerieForm(forms.Form):
|
||||
nazev = forms.CharField(label = "Název galerie", max_length = 100)
|
||||
popis = forms.CharField(label = "Popis", required = False, max_length = 2000, widget = forms.Textarea)
|
59
galerie/migrations/0001_initial.py
Normal file
59
galerie/migrations/0001_initial.py
Normal file
|
@ -0,0 +1,59 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('seminar', '0033_organizator_studuje_popisek'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Galerie',
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||
('nazev', models.CharField(max_length=100, verbose_name=b'N\xc3\xa1zev')),
|
||||
('datum_vytvoreni', models.DateTimeField(auto_now_add=True, verbose_name=b'Datum vytvo\xc5\x99en\xc3\xad')),
|
||||
('datum_zmeny', models.DateTimeField(auto_now=True, verbose_name=b'Datum posledn\xc3\xad zm\xc4\x9bny')),
|
||||
('popis', models.TextField(null=True, verbose_name=b'Popis', blank=True)),
|
||||
('zobrazit', models.IntegerField(default=1, verbose_name=b'Zobrazit?', choices=[(0, b'V\xc5\xbedy'), (1, b'Organiz\xc3\xa1tor\xc5\xafm'), (2, b'Nikdy')])),
|
||||
('galerie_up', models.ForeignKey(blank=True, to='galerie.Galerie', null=True)),
|
||||
('soustredeni', models.ForeignKey(blank=True, to='seminar.Soustredeni', null=True)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Galerie',
|
||||
'verbose_name_plural': 'Galerie',
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Obrazek',
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||
('obrazek_velky', models.ImageField(help_text=b'Lze vlo\xc5\xbeit libovoln\xc4\x9b velk\xc3\xbd obr\xc3\xa1zek. Ide\xc3\xa1ln\xc3\xad je, aby alespo\xc5\x88 jeden rozm\xc4\x9br m\xc4\x9bl alespo\xc5\x88 500px.', upload_to=b'Galerie/%Y/%m/%d')),
|
||||
('obrazek_stredni', models.ImageField(upload_to=b'Galerie/%Y/%m/%d/stredni', null=True, editable=False)),
|
||||
('obrazek_maly', models.ImageField(upload_to=b'Galerie/%Y/%m/%d/male', null=True, editable=False)),
|
||||
('nazev', models.CharField(max_length=50, null=True, verbose_name=b'N\xc3\xa1zev', blank=True)),
|
||||
('popis', models.TextField(null=True, verbose_name=b'Popis', blank=True)),
|
||||
('datum_vlozeni', models.DateTimeField(auto_now_add=True, verbose_name=b'Datum vlo\xc5\xbeen\xc3\xad')),
|
||||
('datum', models.DateTimeField(verbose_name=b'Datum po\xc5\x99\xc3\xadzen\xc3\xad fotografie')),
|
||||
('poradi', models.IntegerField(null=True, verbose_name=b'Po\xc5\x99ad\xc3\xad', blank=True)),
|
||||
('galerie', models.ForeignKey(to='galerie.Galerie')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Obr\xe1zek',
|
||||
'verbose_name_plural': 'Obr\xe1zky',
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='galerie',
|
||||
name='titulni_obrazek',
|
||||
field=models.ForeignKey(related_name='+', on_delete=django.db.models.deletion.SET_NULL, to='galerie.Obrazek', null=True),
|
||||
preserve_default=True,
|
||||
),
|
||||
]
|
27
galerie/migrations/0002_auto_20151013_1145.py
Normal file
27
galerie/migrations/0002_auto_20151013_1145.py
Normal file
|
@ -0,0 +1,27 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('galerie', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='galerie',
|
||||
name='titulni_obrazek',
|
||||
field=models.ForeignKey(related_name='+', on_delete=django.db.models.deletion.SET_NULL, blank=True, to='galerie.Obrazek', null=True),
|
||||
preserve_default=True,
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='obrazek',
|
||||
name='datum',
|
||||
field=models.DateTimeField(null=True, verbose_name=b'Datum po\xc5\x99\xc3\xadzen\xc3\xad fotografie', blank=True),
|
||||
preserve_default=True,
|
||||
),
|
||||
]
|
39
galerie/migrations/0003_add_galerie_poradi.py
Normal file
39
galerie/migrations/0003_add_galerie_poradi.py
Normal file
|
@ -0,0 +1,39 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
import galerie.models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('galerie', '0002_auto_20151013_1145'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='galerie',
|
||||
name='poradi',
|
||||
field=models.IntegerField(null=True, verbose_name=b'Po\xc5\x99ad\xc3\xad', blank=True),
|
||||
preserve_default=True,
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='obrazek',
|
||||
name='obrazek_maly',
|
||||
field=models.ImageField(upload_to=galerie.models.obrazek_filename_maly, null=True, editable=False),
|
||||
preserve_default=True,
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='obrazek',
|
||||
name='obrazek_stredni',
|
||||
field=models.ImageField(upload_to=galerie.models.obrazek_filename_stredni, null=True, editable=False),
|
||||
preserve_default=True,
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='obrazek',
|
||||
name='obrazek_velky',
|
||||
field=models.ImageField(help_text=b'Lze vlo\xc5\xbeit libovoln\xc4\x9b velk\xc3\xbd obr\xc3\xa1zek. Ide\xc3\xa1ln\xc3\xad je, aby alespo\xc5\x88 jeden rozm\xc4\x9br m\xc4\x9bl alespo\xc5\x88 500px.', upload_to=galerie.models.obrazek_filename),
|
||||
preserve_default=True,
|
||||
),
|
||||
]
|
0
galerie/migrations/__init__.py
Normal file
0
galerie/migrations/__init__.py
Normal file
178
galerie/models.py
Normal file
178
galerie/models.py
Normal file
|
@ -0,0 +1,178 @@
|
|||
# coding: utf-8
|
||||
|
||||
from django.db import models
|
||||
import seminar.models
|
||||
from django.db.models import Q
|
||||
from django.utils import timezone
|
||||
from django.utils.encoding import force_unicode
|
||||
|
||||
from PIL import Image
|
||||
from PIL.ExifTags import TAGS
|
||||
import os
|
||||
from cStringIO import StringIO
|
||||
from django.core.files.base import ContentFile
|
||||
from datetime import datetime
|
||||
|
||||
from seminar.models import Soustredeni
|
||||
|
||||
VZDY=0
|
||||
ORG=1
|
||||
NIKDY=2
|
||||
VIDITELNOST = (
|
||||
(VZDY, 'Vždy'),
|
||||
(ORG, 'Organizátorům'),
|
||||
(NIKDY, 'Nikdy'),
|
||||
)
|
||||
|
||||
def get_exif(fn):
|
||||
ret = {}
|
||||
info = fn._getexif()
|
||||
for tag, value in info.items():
|
||||
decoded = TAGS.get(tag, tag)
|
||||
ret[decoded] = value
|
||||
return ret
|
||||
|
||||
def flip_horizontal(im): return im.transpose(Image.FLIP_LEFT_RIGHT)
|
||||
def flip_vertical(im): return im.transpose(Image.FLIP_TOP_BOTTOM)
|
||||
def rotate_180(im): return im.transpose(Image.ROTATE_180)
|
||||
def rotate_90(im): return im.transpose(Image.ROTATE_90)
|
||||
def rotate_270(im): return im.transpose(Image.ROTATE_270)
|
||||
def transpose(im): return rotate_90(flip_horizontal(im))
|
||||
def transverse(im): return rotate_90(flip_vertical(im))
|
||||
orientation_funcs = [None,
|
||||
lambda x: x,
|
||||
flip_horizontal,
|
||||
rotate_180,
|
||||
flip_vertical,
|
||||
transpose,
|
||||
rotate_270,
|
||||
transverse,
|
||||
rotate_90
|
||||
]
|
||||
|
||||
|
||||
def obrazek_filename(self, filename):
|
||||
return obrazek_filename_obecny(self, filename, "velky")
|
||||
|
||||
def obrazek_filename_stredni(self, filename):
|
||||
return obrazek_filename_obecny(self, filename, "stredni")
|
||||
|
||||
def obrazek_filename_maly(self, filename):
|
||||
return obrazek_filename_obecny(self, filename, "maly")
|
||||
|
||||
def obrazek_filename_obecny(self, filename, typ):
|
||||
gal = self.galerie
|
||||
cesta = ""
|
||||
while(not gal.soustredeni):
|
||||
cesta = os.path.join(force_unicode(gal.nazev), cesta)
|
||||
gal = gal.galerie_up
|
||||
return os.path.join('Galerie', force_unicode(gal.soustredeni), cesta, typ, force_unicode(self.nazev))
|
||||
|
||||
class Obrazek(models.Model):
|
||||
obrazek_velky = models.ImageField(upload_to=obrazek_filename,
|
||||
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=obrazek_filename_stredni, null = True, editable = False)
|
||||
obrazek_maly = models.ImageField(upload_to=obrazek_filename_maly, 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 = True, null = True)
|
||||
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)
|
||||
# vycteni EXIFu
|
||||
exif = get_exif(original)
|
||||
if exif['Orientation']:
|
||||
f = orientation_funcs[exif['Orientation']]
|
||||
original_otoceny = f(original)
|
||||
original_otoceny.format = original.format
|
||||
original = original_otoceny
|
||||
# datum podle EXIfu
|
||||
if exif['DateTimeOriginal']:
|
||||
datum_string = ":".join(exif['DateTimeOriginal'].split(' ')).split(":")
|
||||
datum_int = []
|
||||
for retezec in datum_string:
|
||||
datum_int.append(int(retezec))
|
||||
self.datum = datetime(datum_int[0], datum_int[1], datum_int[2],
|
||||
datum_int[3], datum_int[4], datum_int[5])
|
||||
jmeno = os.path.basename(self.obrazek_velky.file.name)
|
||||
if not self.obrazek_stredni:
|
||||
Obrazek._vyrobMiniaturu(original, jmeno, 500, self.obrazek_stredni)
|
||||
if not self.obrazek_maly:
|
||||
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 = True, 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)
|
||||
poradi = models.IntegerField('Pořadí', 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 '<a href="/fotogalerie/galerie/%s/">Preview</a>' % 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()
|
2
galerie/static/galerie/.gitignore
vendored
Normal file
2
galerie/static/galerie/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
images
|
||||
lightbox
|
BIN
galerie/static/galerie/prvky/dalsi.png
Normal file
BIN
galerie/static/galerie/prvky/dalsi.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
BIN
galerie/static/galerie/prvky/predchozi.png
Normal file
BIN
galerie/static/galerie/prvky/predchozi.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
6
galerie/templates/galerie/Base.html
Normal file
6
galerie/templates/galerie/Base.html
Normal file
|
@ -0,0 +1,6 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{# TODO predelat pres context processor #}
|
||||
{% block header %}soustredeni{% endblock %}
|
||||
{% block menu_soustredeni %}selected{% endblock %}
|
||||
{% block submenu %}{% include 'seminar/soustredeni/submenu.html' %}{% endblock %}
|
62
galerie/templates/galerie/Galerie.html
Normal file
62
galerie/templates/galerie/Galerie.html
Normal file
|
@ -0,0 +1,62 @@
|
|||
{% extends "galerie/Base.html" %}
|
||||
|
||||
{% block title %}{% block nadpis1a %}
|
||||
{{galerie.nazev}} | Galerie
|
||||
{% endblock %}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1><a title="Zpět na náhled fotek" href="../#obsah">{{galerie.nazev}}</a></h1>
|
||||
<div class="galerie_top" id="obsah">
|
||||
{% for obrazek in obrazky_predchozi %}
|
||||
<a href="../{{obrazek.pk}}#obsah"><img src="{{obrazek.obrazek_maly.url}}" height="100"></a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
|
||||
{# TODO šipky na přecházeni dodelat ve stylech #}
|
||||
<div class="galerie">
|
||||
{% if obrazky_predchozi %}
|
||||
{% with obrazky_predchozi|last as predchozi_obrazek %}
|
||||
<div>
|
||||
<a title="Předchozí" class="predchozi_obrazek" href="../{{predchozi_obrazek.pk}}#obsah"></a>
|
||||
</div>
|
||||
{% endwith %}
|
||||
{% endif%}
|
||||
<img src={{obrazek.obrazek_stredni.url}}
|
||||
height="{{vyska}}"
|
||||
width="{{sirka}}"
|
||||
alt="{{obrazek.popis}}"
|
||||
class="obrazek">
|
||||
{% if obrazky_dalsi %}
|
||||
{% with obrazky_dalsi|first as dalsi_obrazek %}
|
||||
<div>
|
||||
<a title="Další" class="dalsi_obrazek" href="../{{dalsi_obrazek.pk}}#obsah"></a>
|
||||
</div>
|
||||
{% endwith %}
|
||||
{% endif%}
|
||||
</div>
|
||||
|
||||
{# Popisek fotky #}
|
||||
<div class="popis">
|
||||
{% if preview %}
|
||||
<form action=".#obsah" method="post">
|
||||
{% csrf_token %}
|
||||
<table>
|
||||
<tr><td><label>Aktuální komentář:</label></td><td>{{obrazek.popis}}</td>
|
||||
{{form.as_table}}
|
||||
<tr><td></td><td><input name="odeslat" type="submit" value="Změň komentář"></td></tr>
|
||||
</table>
|
||||
</form>
|
||||
{% else %}
|
||||
{% if obrazek.popis %}
|
||||
{{obrazek.popis}}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="galerie_bot">
|
||||
{% for obrazek in obrazky_dalsi %}
|
||||
<a href="../{{obrazek.pk}}#obsah"><img src="{{obrazek.obrazek_maly.url}}" height="100"></a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endblock %}
|
77
galerie/templates/galerie/GalerieNahled.html
Normal file
77
galerie/templates/galerie/GalerieNahled.html
Normal file
|
@ -0,0 +1,77 @@
|
|||
{% extends "galerie/Base.html" %}
|
||||
|
||||
{% block title %}{% block nadpis1a %}
|
||||
{{galerie.nazev}} | Galerie TODO title
|
||||
{% endblock %}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h2>{{galerie.nazev}}</h2>
|
||||
|
||||
{# podgalerie #}
|
||||
{% if podgalerie or galerie.galerie_up %}
|
||||
<h3> PODGALERIE </h3>
|
||||
<ul>
|
||||
{% if galerie.galerie_up %}
|
||||
<li><a href="../{{galerie.galerie_up.pk}}">..</a>
|
||||
{% endif %}
|
||||
{% for galerie in podgalerie %}
|
||||
{% if galerie.zobrazit < 1 or user.is_staff %}
|
||||
<li><a href="../{{galerie.pk}}">{{galerie}}</a>
|
||||
{% if user.is_staff and galerie.zobrazit > 0 %}
|
||||
({{galerie.poradi}})
|
||||
<span class="plus"><a href="plus/{{galerie.pk}}/">+</a></span>
|
||||
<span class="minus"><a href="minus/{{galerie.pk}}/">-</a></span>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% if user.is_staff and galerie.zobrazit > 0 %}
|
||||
<ul>
|
||||
<li><a href="./new">VYTVOŘIT NOVOU PODGALERII </a>
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
{# obrazky v galerii #}
|
||||
{% if obrazky %}
|
||||
<table class="galerie_nahled">
|
||||
{% for obrazek in obrazky %}
|
||||
{% if forloop.counter|add:-1|divisibleby:3 %}
|
||||
<tr>
|
||||
{% endif %}
|
||||
<td class="vystredeno">
|
||||
<a title="Zobrazit tuto fotografii" href="./{{obrazek.pk}}#obsah"
|
||||
class="jednoducha-galerie">
|
||||
<img
|
||||
src="{{obrazek.obrazek_maly.url}}"
|
||||
width={% widthratio obrazek.obrazek_maly.width 200 167 %}
|
||||
height={% widthratio obrazek.obrazek_maly.height 200 167 %} />
|
||||
</a>
|
||||
<!--<a href="{{obrazek.obrazek_velky.url}}"
|
||||
class="javascript-galerie" data-lightbox="galerie" data-title="{{obrazek.popis}}"
|
||||
style="display: none;">
|
||||
<img
|
||||
src="{{obrazek.obrazek_maly.url}}"
|
||||
width={% widthratio obrazek.obrazek_maly.width 200 167 %}
|
||||
height={% widthratio obrazek.obrazek_maly.height 200 167 %} />
|
||||
</a>-->
|
||||
</td>
|
||||
{% if forloop.last %}
|
||||
{% if not forloop.counter|divisibleby:3 %}
|
||||
<td></td>
|
||||
{% endif %}
|
||||
{% if not forloop.counter|divisibleby:2 %}
|
||||
<td></td>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if forloop.counter|divisibleby:3 or forloop.last %}
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% else %}
|
||||
<div class="zadne-vysledky">
|
||||
V galerii nejsou žádné fotky.
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock content %}
|
22
galerie/templates/galerie/GalerieNew.html
Normal file
22
galerie/templates/galerie/GalerieNew.html
Normal file
|
@ -0,0 +1,22 @@
|
|||
{% extends "galerie/Base.html" %}
|
||||
|
||||
{% block title %}{% block nadpis1a %}
|
||||
Vytvářím novou galerii
|
||||
{% endblock %}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<h2> Vytváření nové galerie </h2>
|
||||
|
||||
<h3> Vytvářím galerii k soustředění {{soustredeni}} jako {{galerie_text}}</h3>
|
||||
|
||||
<form enctype="multipart/form-data" action="." method="post">
|
||||
{% csrf_token %}
|
||||
<table>{{form.as_table}}
|
||||
<tr><td><label>Obrázky:</label></td><td><input name="obr" type="file" multiple></td></tr>
|
||||
<tr><td> </td></tr>
|
||||
<tr><td></td><td><input name="odeslat" type="submit" value="Vytvoř galerii"></td></tr>
|
||||
</table>
|
||||
</form>
|
||||
|
||||
{% endblock %}
|
12
galerie/urls.py
Normal file
12
galerie/urls.py
Normal file
|
@ -0,0 +1,12 @@
|
|||
# coding: utf-8
|
||||
|
||||
from django.conf.urls import patterns, include, url
|
||||
|
||||
urlpatterns = patterns('',
|
||||
(r'^(?P<pk>\d+)/$', 'galerie.views.nahled'),
|
||||
(r'^(?P<pk>\d+)/(?P<fotka>\d+)/$', 'galerie.views.detail'),
|
||||
(r'^(?P<galerie>\d+)/new/$', 'galerie.views.new_galerie'),
|
||||
(r'^(?P<galerie>\d+)/plus/(?P<subgalerie>\d+)/$', 'galerie.views.plus_galerie'),
|
||||
(r'^(?P<galerie>\d+)/minus/(?P<subgalerie>\d+)/$', 'galerie.views.minus_galerie'),
|
||||
)
|
||||
|
168
galerie/views.py
Normal file
168
galerie/views.py
Normal file
|
@ -0,0 +1,168 @@
|
|||
# coding: utf-8
|
||||
|
||||
import random
|
||||
|
||||
from django.http import HttpResponse, Http404
|
||||
from django.shortcuts import render, HttpResponseRedirect, get_object_or_404
|
||||
from django.template import RequestContext
|
||||
from datetime import datetime
|
||||
|
||||
from galerie.models import Obrazek, Galerie
|
||||
from seminar.models import Soustredeni
|
||||
from galerie.forms import KomentarForm, NewGalerieForm
|
||||
|
||||
def zobrazit(galerie, request):
|
||||
preview = False
|
||||
if galerie.zobrazit >= 1:
|
||||
if request.user.is_staff:
|
||||
preview = True;
|
||||
else:
|
||||
raise Http404
|
||||
return preview
|
||||
|
||||
def nahled(request, pk, soustredeni):
|
||||
"""Zobrazeni nahledu vsech fotek ve skupine."""
|
||||
galerie = get_object_or_404(Galerie, pk=pk)
|
||||
podgalerie = Galerie.objects.filter(galerie_up = galerie).order_by('poradi')
|
||||
obrazky = Obrazek.objects.filter(galerie = galerie).order_by('datum')
|
||||
preview = zobrazit(galerie, request)
|
||||
return render(request, 'galerie/GalerieNahled.html',
|
||||
{'galerie' : galerie,
|
||||
'podgalerie' : podgalerie,
|
||||
'obrazky' : obrazky,
|
||||
'preview' : preview,
|
||||
})
|
||||
|
||||
def detail(request, pk, fotka, soustredeni):
|
||||
"""Zobrazeni nahledu fotky s id 'fotka'."""
|
||||
MAX_VYSKA = 600
|
||||
MAX_SIRKA = 600
|
||||
MAX_VYSKA_MALA = 100
|
||||
MAX_SIRKA_MALA = 200
|
||||
NAHLEDU = 1
|
||||
|
||||
galerie = get_object_or_404(Galerie, pk=pk)
|
||||
preview = zobrazit(galerie, request)
|
||||
obrazek = get_object_or_404(Obrazek, pk=fotka)
|
||||
obrazky = galerie.obrazek_set.all().order_by('datum')
|
||||
|
||||
# vytvoreni a obslouzeni formulare
|
||||
if request.method == 'POST':
|
||||
form = KomentarForm(request.POST)
|
||||
if form.is_valid():
|
||||
obrazek.popis = form.cleaned_data['komentar']
|
||||
obrazek.save()
|
||||
else:
|
||||
form = KomentarForm({'komentar': obrazek.popis})
|
||||
|
||||
# Poradi aktualniho obrazku v galerii/stitku.
|
||||
for i in range(len(obrazky)):
|
||||
if obrazky[i] == obrazek:
|
||||
znacka = i
|
||||
break
|
||||
else:
|
||||
# Obrazek neni v galerii/stitku.
|
||||
raise Http404
|
||||
|
||||
# Nacteni okolnich obrazku.
|
||||
obrazky_dalsi = obrazky[znacka+1:znacka+NAHLEDU+1]
|
||||
if znacka > NAHLEDU:
|
||||
obrazky_predchozi = obrazky[znacka-NAHLEDU:znacka]
|
||||
else:
|
||||
obrazky_predchozi = obrazky[0:znacka]
|
||||
|
||||
# Preskalovani obrazku do vybraneho prostoru.
|
||||
vyska = obrazek.obrazek_stredni.height
|
||||
sirka = obrazek.obrazek_stredni.width
|
||||
if vyska > MAX_VYSKA:
|
||||
sirka = sirka * MAX_VYSKA / vyska
|
||||
vyska = MAX_VYSKA
|
||||
if sirka > MAX_SIRKA:
|
||||
vyska = vyska * MAX_SIRKA / sirka
|
||||
sirka = MAX_SIRKA
|
||||
|
||||
return render(request, 'galerie/Galerie.html',
|
||||
{'galerie' : galerie,
|
||||
'obrazek' : obrazek,
|
||||
'vyska' : vyska,
|
||||
'sirka' : sirka,
|
||||
'obrazky_predchozi' : obrazky_predchozi,
|
||||
'obrazky_dalsi' : obrazky_dalsi,
|
||||
'preview' : preview,
|
||||
'form' : form,
|
||||
})
|
||||
|
||||
|
||||
def new_galerie(request, galerie, soustredeni):
|
||||
|
||||
# zjistime k jakemu soustredeni se vaze nove vytvarena galerie
|
||||
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:
|
||||
galerie_up = False
|
||||
galerie_text = "Hlavní fotogalerie soustředění"
|
||||
else:
|
||||
galerie_up = get_object_or_404(Galerie, pk = int(galerie))
|
||||
galerie_text = "podgalerii ke galerii " + str(galerie_up)
|
||||
|
||||
# obsluha formulare umoznujiciho multiple nahravani fotek
|
||||
if request.method == 'POST':
|
||||
form = NewGalerieForm(request.POST, request.FILES)
|
||||
if form.is_valid():
|
||||
# vytvoreni nove galerie
|
||||
gal = Galerie()
|
||||
gal.nazev = form.cleaned_data['nazev']
|
||||
gal.popis = form.cleaned_data['popis']
|
||||
gal.zobrazit = 1 # 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 galerie_up:
|
||||
gal.galerie_up = galerie_up
|
||||
else:
|
||||
gal.soustredeni = soustredeni
|
||||
gal.poradi = int(len(gal.galerie_up.galerie_set.all())) + 1
|
||||
gal.save()
|
||||
|
||||
# zpracovani obrazku v galerii
|
||||
for obr in request.FILES.getlist('obr'):
|
||||
o = Obrazek()
|
||||
o.obrazek_velky = obr
|
||||
o.nazev = str(obr)
|
||||
o.galerie = gal
|
||||
o.save()
|
||||
|
||||
# presmerovani na prave vzniklou galerii
|
||||
return HttpResponseRedirect('../../' + str(gal.pk))
|
||||
|
||||
else:
|
||||
form = NewGalerieForm()
|
||||
|
||||
|
||||
return render(request, 'galerie/GalerieNew.html',
|
||||
{
|
||||
'form' : form,
|
||||
'soustredeni' : soustredeni,
|
||||
'galerie_text' : galerie_text,
|
||||
})
|
||||
|
||||
def plus_galerie(request, galerie, soustredeni, subgalerie):
|
||||
galerie = get_object_or_404(Galerie, pk=subgalerie)
|
||||
if galerie.poradi:
|
||||
galerie.poradi += 1
|
||||
else:
|
||||
galerie.poradi = int(len(galerie.galerie_up.galerie_set.all()))
|
||||
galerie.save()
|
||||
return HttpResponseRedirect('../../')
|
||||
|
||||
def minus_galerie(request, galerie, soustredeni, subgalerie):
|
||||
galerie = get_object_or_404(Galerie, pk=subgalerie)
|
||||
if galerie.poradi:
|
||||
galerie.poradi -= 1
|
||||
else:
|
||||
galerie.poradi = 1
|
||||
galerie.save()
|
||||
return HttpResponseRedirect('../../')
|
||||
|
|
@ -113,6 +113,7 @@ INSTALLED_APPS = (
|
|||
# MaMweb
|
||||
'mamweb',
|
||||
'seminar',
|
||||
'galerie',
|
||||
|
||||
# Admin upravy:
|
||||
|
||||
|
|
|
@ -408,3 +408,57 @@ div.zadani_azad_termin {
|
|||
float: none;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* galerie */
|
||||
|
||||
.predchozi_obrazek{
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
width: 33%;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
.predchozi_obrazek:hover{
|
||||
background-image: url("/static/galerie/prvky/predchozi.png");
|
||||
background-position: left center;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
.dalsi_obrazek{
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
width: 33%;
|
||||
height: 100%;
|
||||
left: 67%;
|
||||
top: 0;
|
||||
}
|
||||
.dalsi_obrazek:hover{
|
||||
background-image: url("/static/galerie/prvky/dalsi.png");
|
||||
background-position: right center;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.galerie{
|
||||
position: relative;
|
||||
}
|
||||
.galerie_top{
|
||||
margin: 1em 0;
|
||||
text-align: right;
|
||||
}
|
||||
.galerie_bot{
|
||||
margin: 1em 0;
|
||||
}
|
||||
.galerie_index{
|
||||
width: 100%;
|
||||
}
|
||||
.galerie_index td{
|
||||
width: 50%;
|
||||
}
|
||||
.galerie_nahled{
|
||||
width: 100%;
|
||||
}
|
||||
.galerie_nahled td{
|
||||
width: 33%;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ traitlets==4.0.0
|
|||
|
||||
# Django and modules
|
||||
|
||||
Django==1.7.10 # Updatable to 1.8 (possibly incompatible)
|
||||
Django==1.7.10 # Updatable to 1.9 (possibly incompatible)
|
||||
django-bootstrap-sass==0.0.6a0
|
||||
django-mptt==0.7.3
|
||||
django-reversion==1.9.3
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
<em>
|
||||
Na galeriích ze soustředění a dalších informacích ještě pracujeme.
|
||||
</em><br><br>
|
||||
{#% if user.is_authenticated %#}{# PRACUJE SE STRANKA #}
|
||||
|
||||
|
||||
{# Projdi vsechna soustredeni #}
|
||||
{% for soustredeni in object_list %}
|
||||
|
@ -40,7 +38,25 @@
|
|||
<li>
|
||||
{{soustredeni.datum_zacatku}} – {{soustredeni.datum_konce}}
|
||||
</li>
|
||||
{# Zobrazeni odkazu na galerie #}
|
||||
{% if soustredeni.galerie_set.all %}
|
||||
{% for galerie in soustredeni.galerie_set.all %}
|
||||
{% if galerie.zobrazit == 0 or user.is_staff %}
|
||||
<li>
|
||||
<a href="../{{soustredeni.pk}}/fotogalerie/{{galerie.pk}}">FOTOGALERIE: {{galerie}}</a>
|
||||
{# TODO kdyz je titulni obrazek, tak asi i titulni obrazek #}
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if user.is_staff %}
|
||||
<li>
|
||||
<a href="../{{soustredeni.pk}}/fotogalerie/0/new/"> VYTVOŘIT NOVOU FOTOGALERII </a>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
</ul>
|
||||
|
||||
{% if user.is_authenticated %}
|
||||
{# popis soustredeni #}
|
||||
{% if soustredeni.text %}
|
||||
|
@ -61,7 +77,5 @@
|
|||
Žádná soustředění zatím neproběhla!
|
||||
{% endfor %}
|
||||
|
||||
{#% else %}{% include 'seminar/pracuje_se.html' %}{% endif %#}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from django.conf.urls import * # NOQA
|
||||
from django.conf.urls import patterns, url
|
||||
from . import views, export
|
||||
|
||||
|
@ -15,7 +16,8 @@ urlpatterns = patterns('',
|
|||
|
||||
url(r'^soustredeni/probehlo/$', views.SoustredeniListView.as_view(),
|
||||
name = 'seminar_seznam_soustredeni'),
|
||||
url(r'^soustredeni/(?P<pk>\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'^zadani/aktualni/$', views.AktualniZadaniView, name='seminar_aktualni_zadani'),
|
||||
url(r'^zadani/temata/$', views.ZadaniTemataView, name='seminar_temata'),
|
||||
|
|
Loading…
Reference in a new issue