Merge photologue_custom into photologue
This commit is contained in:
parent
8beedb3626
commit
d865a6eb1f
36 changed files with 549 additions and 566 deletions
100
photologue/forms.py
Normal file
100
photologue/forms.py
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
import datetime
|
||||
|
||||
from crispy_forms.helper import FormHelper
|
||||
from crispy_forms.layout import Div, Layout, Submit
|
||||
from django import forms
|
||||
from django.utils.text import slugify
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from .models import Gallery, Tag
|
||||
|
||||
|
||||
class UploadForm(forms.Form):
|
||||
file_field = forms.FileField(
|
||||
label="",
|
||||
widget=forms.FileInput(attrs={
|
||||
'accept': 'image/*',
|
||||
'multiple': True,
|
||||
'class': 'mb-3',
|
||||
}),
|
||||
)
|
||||
gallery = forms.ModelChoiceField(
|
||||
Gallery.objects.all(),
|
||||
label=_('Gallery'),
|
||||
required=False,
|
||||
empty_label=_('-- Create a new gallery --'),
|
||||
help_text=_('Select a gallery to add these images to. Leave this empty to '
|
||||
'create a new gallery from the supplied title.')
|
||||
)
|
||||
new_gallery_title = forms.CharField(
|
||||
label=_('New gallery title'),
|
||||
max_length=250,
|
||||
required=False,
|
||||
)
|
||||
new_gallery_date_start = forms.DateField(
|
||||
label=_('New gallery event start date'),
|
||||
initial=datetime.date.today,
|
||||
required=False,
|
||||
)
|
||||
new_gallery_date_end = forms.DateField(
|
||||
label=_('New gallery event end date'),
|
||||
initial=datetime.date.today,
|
||||
required=False,
|
||||
)
|
||||
new_gallery_tags = forms.ModelMultipleChoiceField(
|
||||
Tag.objects.all(),
|
||||
label=_('New gallery tags'),
|
||||
required=False,
|
||||
help_text=_('Hold down "Control", or "Command" on a Mac, to select more than one.')
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.helper = FormHelper()
|
||||
self.helper.use_custom_control = False
|
||||
self.helper.layout = Layout(
|
||||
'file_field',
|
||||
'gallery',
|
||||
'new_gallery_title',
|
||||
Div(
|
||||
Div('new_gallery_date_start', css_class='col'),
|
||||
Div('new_gallery_date_end', css_class='col'),
|
||||
css_class='row'
|
||||
),
|
||||
'new_gallery_tags',
|
||||
Submit('submit', _('Upload'), css_class='btn btn-success mt-2')
|
||||
)
|
||||
|
||||
def clean_new_gallery_title(self):
|
||||
title = self.cleaned_data['new_gallery_title']
|
||||
if title and Gallery.objects.filter(title=title).exists():
|
||||
raise forms.ValidationError(_('A gallery with that title already exists.'))
|
||||
return title
|
||||
|
||||
def clean(self):
|
||||
cleaned_data = super().clean()
|
||||
|
||||
# Check that either an existing gallery is chosen, or new_gallery_title is filled
|
||||
if not (bool(cleaned_data['gallery']) ^ bool(cleaned_data.get('new_gallery_title', None))):
|
||||
raise forms.ValidationError(
|
||||
_('Select an existing gallery, or enter a title for a new gallery.'))
|
||||
|
||||
return cleaned_data
|
||||
|
||||
def get_or_create_gallery(self):
|
||||
"""
|
||||
Get or create gallery
|
||||
"""
|
||||
gallery = self.cleaned_data['gallery']
|
||||
if not gallery:
|
||||
# Create new gallery
|
||||
title = self.cleaned_data.get('new_gallery_title')
|
||||
gallery = Gallery.objects.create(
|
||||
title=title,
|
||||
slug=slugify(title),
|
||||
date_start=self.cleaned_data['new_gallery_date_start'],
|
||||
date_end=self.cleaned_data['new_gallery_date_end'],
|
||||
)
|
||||
for tag in self.cleaned_data['new_gallery_tags']:
|
||||
gallery.tags.add(tag)
|
||||
return gallery
|
||||
|
|
@ -11,7 +11,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: Photologue\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2022-01-30 07:09+0000\n"
|
||||
"POT-Creation-Date: 2022-01-30 09:55+0000\n"
|
||||
"PO-Revision-Date: 2017-12-03 14:47+0000\n"
|
||||
"Last-Translator: Richard Barran <richard@arbee-design.co.uk>\n"
|
||||
"Language-Team: German (http://www.transifex.com/richardbarran/django-"
|
||||
|
|
@ -22,75 +22,79 @@ msgstr ""
|
|||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: photologue/models.py:86
|
||||
#: photologue/admin.py:30 photologue/models.py:499
|
||||
msgid "owner"
|
||||
msgstr ""
|
||||
|
||||
#: photologue/models.py:84
|
||||
msgid "Very Low"
|
||||
msgstr "Sehr niedrig"
|
||||
|
||||
#: photologue/models.py:87
|
||||
#: photologue/models.py:85
|
||||
msgid "Low"
|
||||
msgstr "Niedrig"
|
||||
|
||||
#: photologue/models.py:88
|
||||
#: photologue/models.py:86
|
||||
msgid "Medium-Low"
|
||||
msgstr "Mittel-niedrig"
|
||||
|
||||
#: photologue/models.py:89
|
||||
#: photologue/models.py:87
|
||||
msgid "Medium"
|
||||
msgstr "Mittel"
|
||||
|
||||
#: photologue/models.py:90
|
||||
#: photologue/models.py:88
|
||||
msgid "Medium-High"
|
||||
msgstr "Mittel-hoch"
|
||||
|
||||
#: photologue/models.py:91
|
||||
#: photologue/models.py:89
|
||||
msgid "High"
|
||||
msgstr "Hoch"
|
||||
|
||||
#: photologue/models.py:92
|
||||
#: photologue/models.py:90
|
||||
msgid "Very High"
|
||||
msgstr "Sehr hoch"
|
||||
|
||||
#: photologue/models.py:97
|
||||
#: photologue/models.py:95
|
||||
msgid "Top"
|
||||
msgstr "Oben"
|
||||
|
||||
#: photologue/models.py:98
|
||||
#: photologue/models.py:96
|
||||
msgid "Right"
|
||||
msgstr "Rechts"
|
||||
|
||||
#: photologue/models.py:99
|
||||
#: photologue/models.py:97
|
||||
msgid "Bottom"
|
||||
msgstr "Unten"
|
||||
|
||||
#: photologue/models.py:100
|
||||
#: photologue/models.py:98
|
||||
msgid "Left"
|
||||
msgstr "Links"
|
||||
|
||||
#: photologue/models.py:101
|
||||
#: photologue/models.py:99
|
||||
msgid "Center (Default)"
|
||||
msgstr "Mitte (Standard)"
|
||||
|
||||
#: photologue/models.py:105
|
||||
#: photologue/models.py:103
|
||||
msgid "Flip left to right"
|
||||
msgstr "Horizontal spiegeln"
|
||||
|
||||
#: photologue/models.py:106
|
||||
#: photologue/models.py:104
|
||||
msgid "Flip top to bottom"
|
||||
msgstr "Vertikal spiegeln"
|
||||
|
||||
#: photologue/models.py:107
|
||||
#: photologue/models.py:105
|
||||
msgid "Rotate 90 degrees counter-clockwise"
|
||||
msgstr "Um 90° nach links drehen"
|
||||
|
||||
#: photologue/models.py:108
|
||||
#: photologue/models.py:106
|
||||
msgid "Rotate 90 degrees clockwise"
|
||||
msgstr "Um 90° nach rechts drehen"
|
||||
|
||||
#: photologue/models.py:109
|
||||
#: photologue/models.py:107
|
||||
msgid "Rotate 180 degrees"
|
||||
msgstr "Um 180° drehen"
|
||||
|
||||
#: photologue/models.py:119
|
||||
#: photologue/models.py:117
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Chain multiple filters using the following pattern \"FILTER_ONE->FILTER_TWO-"
|
||||
|
|
@ -101,106 +105,122 @@ msgstr ""
|
|||
"\". Bildfilter werden nach der Reihe angewendet. Folgende Filter sind "
|
||||
"verfügbar: %s."
|
||||
|
||||
#: photologue/models.py:141
|
||||
#: photologue/models.py:139
|
||||
msgid "date published"
|
||||
msgstr "Veröffentlichungsdatum"
|
||||
|
||||
#: photologue/models.py:143 photologue/models.py:474
|
||||
#: photologue/models.py:141 photologue/models.py:485
|
||||
msgid "title"
|
||||
msgstr "Titel"
|
||||
|
||||
#: photologue/models.py:146
|
||||
#: photologue/models.py:144
|
||||
msgid "title slug"
|
||||
msgstr "Kurztitel"
|
||||
|
||||
#: photologue/models.py:149 photologue/models.py:480
|
||||
#: photologue/models.py:147 photologue/models.py:491 photologue/models.py:697
|
||||
msgid "A \"slug\" is a unique URL-friendly title for an object."
|
||||
msgstr ""
|
||||
"Ein Kurztitel (\"slug\") ist ein eindeutiger, URL-geeigneter Titel für ein "
|
||||
"Objekt."
|
||||
|
||||
#: photologue/models.py:150
|
||||
msgid "start date"
|
||||
msgstr ""
|
||||
|
||||
#: photologue/models.py:155
|
||||
msgid "end date"
|
||||
msgstr ""
|
||||
|
||||
#: photologue/models.py:157
|
||||
msgid "description"
|
||||
msgstr "Beschreibung"
|
||||
|
||||
#: photologue/models.py:152 photologue/models.py:485
|
||||
#: photologue/models.py:162 photologue/models.py:703
|
||||
msgid "tags"
|
||||
msgstr ""
|
||||
|
||||
#: photologue/models.py:165 photologue/models.py:506
|
||||
msgid "is public"
|
||||
msgstr "ist öffentlich"
|
||||
|
||||
#: photologue/models.py:154
|
||||
#: photologue/models.py:167
|
||||
msgid "Public galleries will be displayed in the default views."
|
||||
msgstr "Öffentliche Galerien werden in den Standard-Views angezeigt."
|
||||
|
||||
#: photologue/models.py:158 photologue/models.py:495
|
||||
#: photologue/models.py:171 photologue/models.py:514
|
||||
msgid "photos"
|
||||
msgstr "Fotos"
|
||||
|
||||
#: photologue/models.py:166
|
||||
#: photologue/models.py:177
|
||||
msgid "gallery"
|
||||
msgstr "Galerie"
|
||||
|
||||
#: photologue/models.py:167
|
||||
#: photologue/models.py:178
|
||||
msgid "galleries"
|
||||
msgstr "Galerien"
|
||||
|
||||
#: photologue/models.py:202
|
||||
#: photologue/models.py:213
|
||||
msgid "count"
|
||||
msgstr "Anzahl"
|
||||
|
||||
#: photologue/models.py:210
|
||||
#: photologue/models.py:221
|
||||
msgid "image"
|
||||
msgstr "Bild"
|
||||
|
||||
#: photologue/models.py:213
|
||||
#: photologue/models.py:224
|
||||
msgid "date taken"
|
||||
msgstr "Aufnahmedatum"
|
||||
|
||||
#: photologue/models.py:216
|
||||
#: photologue/models.py:227
|
||||
msgid "Date image was taken; is obtained from the image EXIF data."
|
||||
msgstr ""
|
||||
"Datum, an dem das Foto geschossen wurde; ausgelesen aus den EXIF-Daten."
|
||||
|
||||
#: photologue/models.py:217
|
||||
#: photologue/models.py:228
|
||||
msgid "view count"
|
||||
msgstr "Anzahl an Aufrufen"
|
||||
|
||||
#: photologue/models.py:220
|
||||
#: photologue/models.py:231
|
||||
msgid "crop from"
|
||||
msgstr "Beschneiden von"
|
||||
|
||||
#: photologue/models.py:243
|
||||
#: photologue/models.py:254
|
||||
msgid "An \"admin_thumbnail\" photo size has not been defined."
|
||||
msgstr "Es ist keine Fotogröße \"admin_thumbnail\" definiert."
|
||||
|
||||
#: photologue/models.py:250
|
||||
#: photologue/models.py:261
|
||||
msgid "Thumbnail"
|
||||
msgstr "Vorschaubild"
|
||||
|
||||
#: photologue/models.py:477
|
||||
#: photologue/models.py:488 photologue/models.py:696
|
||||
msgid "slug"
|
||||
msgstr "Kurztitel"
|
||||
|
||||
#: photologue/models.py:481
|
||||
#: photologue/models.py:492
|
||||
msgid "caption"
|
||||
msgstr "Bildunterschrift"
|
||||
|
||||
#: photologue/models.py:483
|
||||
#: photologue/models.py:494
|
||||
msgid "date added"
|
||||
msgstr "Datum des Eintrags"
|
||||
|
||||
#: photologue/models.py:487
|
||||
#: photologue/models.py:504
|
||||
msgid "license"
|
||||
msgstr ""
|
||||
|
||||
#: photologue/models.py:508
|
||||
msgid "Public photographs will be displayed in the default views."
|
||||
msgstr "Öffentliche Fotos werden in den Standard-Views angezeigt."
|
||||
|
||||
#: photologue/models.py:494
|
||||
#: photologue/models.py:513
|
||||
msgid "photo"
|
||||
msgstr "Foto"
|
||||
|
||||
#: photologue/models.py:556
|
||||
#: photologue/models.py:575 photologue/models.py:691
|
||||
msgid "name"
|
||||
msgstr "Name"
|
||||
|
||||
#: photologue/models.py:560
|
||||
#: photologue/models.py:579
|
||||
msgid ""
|
||||
"Photo size name should contain only letters, numbers and underscores. "
|
||||
"Examples: \"thumbnail\", \"display\", \"small\", \"main_page_widget\"."
|
||||
|
|
@ -209,41 +229,41 @@ msgstr ""
|
|||
"enthalten. Beispiele: \"thumbnail\", \"display\", \"small\", "
|
||||
"\"main_page_widget\"."
|
||||
|
||||
#: photologue/models.py:567
|
||||
#: photologue/models.py:586
|
||||
msgid "width"
|
||||
msgstr "Breite"
|
||||
|
||||
#: photologue/models.py:570
|
||||
#: photologue/models.py:589
|
||||
msgid ""
|
||||
"If width is set to \"0\" the image will be scaled to the supplied height."
|
||||
msgstr ""
|
||||
"Wenn die Breite auf \"0\" gesetzt ist, wird das Bild proportional auf die "
|
||||
"angebene Höhe skaliert."
|
||||
|
||||
#: photologue/models.py:571
|
||||
#: photologue/models.py:590
|
||||
msgid "height"
|
||||
msgstr "Höhe"
|
||||
|
||||
#: photologue/models.py:574
|
||||
#: photologue/models.py:593
|
||||
msgid ""
|
||||
"If height is set to \"0\" the image will be scaled to the supplied width"
|
||||
msgstr ""
|
||||
"Wenn die Höhe auf \"0\" gesetzt ist, wird das Bild proportional auf die "
|
||||
"angebene Breite skaliert."
|
||||
|
||||
#: photologue/models.py:575
|
||||
#: photologue/models.py:594
|
||||
msgid "quality"
|
||||
msgstr "Qualität"
|
||||
|
||||
#: photologue/models.py:578
|
||||
#: photologue/models.py:597
|
||||
msgid "JPEG image quality."
|
||||
msgstr "JPEG-Bildqualität"
|
||||
|
||||
#: photologue/models.py:579
|
||||
#: photologue/models.py:598
|
||||
msgid "upscale images?"
|
||||
msgstr "Bilder hochskalieren?"
|
||||
|
||||
#: photologue/models.py:581
|
||||
#: photologue/models.py:600
|
||||
msgid ""
|
||||
"If selected the image will be scaled up if necessary to fit the supplied "
|
||||
"dimensions. Cropped sizes will be upscaled regardless of this setting."
|
||||
|
|
@ -252,32 +272,32 @@ msgstr ""
|
|||
"Beschnittene Größen werden unabhängig von dieser Einstellung bei Bedarf "
|
||||
"hochskaliert."
|
||||
|
||||
#: photologue/models.py:585
|
||||
#: photologue/models.py:604
|
||||
msgid "crop to fit?"
|
||||
msgstr "Zuschneiden?"
|
||||
|
||||
#: photologue/models.py:587
|
||||
#: photologue/models.py:606
|
||||
msgid ""
|
||||
"If selected the image will be scaled and cropped to fit the supplied "
|
||||
"dimensions."
|
||||
msgstr ""
|
||||
"Soll das Bild auf das angegebene Format skaliert und beschnitten werden?"
|
||||
|
||||
#: photologue/models.py:589
|
||||
#: photologue/models.py:608
|
||||
msgid "pre-cache?"
|
||||
msgstr "Vorausspeichern?"
|
||||
|
||||
#: photologue/models.py:591
|
||||
#: photologue/models.py:610
|
||||
msgid "If selected this photo size will be pre-cached as photos are added."
|
||||
msgstr ""
|
||||
"Soll diese Bildgröße im Voraus gespeichert (pre-cached) werden, wenn Fotos "
|
||||
"hinzugefügt werden?"
|
||||
|
||||
#: photologue/models.py:592
|
||||
#: photologue/models.py:611
|
||||
msgid "increment view count?"
|
||||
msgstr "Bildzähler?"
|
||||
|
||||
#: photologue/models.py:594
|
||||
#: photologue/models.py:613
|
||||
msgid ""
|
||||
"If selected the image's \"view_count\" will be incremented when this photo "
|
||||
"size is displayed."
|
||||
|
|
@ -285,32 +305,32 @@ msgstr ""
|
|||
"Soll der Ansichts-Zähler (view-count) hochgezählt werden, wenn ein Foto "
|
||||
"dieser Größe angezeigt wird?"
|
||||
|
||||
#: photologue/models.py:599
|
||||
#: photologue/models.py:618
|
||||
msgid "photo size"
|
||||
msgstr "Foto-Größe"
|
||||
|
||||
#: photologue/models.py:600
|
||||
#: photologue/models.py:619
|
||||
msgid "photo sizes"
|
||||
msgstr "Foto-Größen"
|
||||
|
||||
#: photologue/models.py:617
|
||||
#: photologue/models.py:636
|
||||
msgid "Can only crop photos if both width and height dimensions are set."
|
||||
msgstr ""
|
||||
"Fotos können nur zugeschnitten werden, wenn Breite und Höhe angegeben sind."
|
||||
|
||||
#: photologue_custom/admin.py:43 photologue_custom/models.py:51
|
||||
msgid "owner"
|
||||
#: photologue/models.py:702
|
||||
msgid "tag"
|
||||
msgstr ""
|
||||
|
||||
#: photologue_custom/forms.py:34
|
||||
#: photologue_custom/forms.py:22
|
||||
msgid "Gallery"
|
||||
msgstr "Galerie"
|
||||
|
||||
#: photologue_custom/forms.py:36
|
||||
#: photologue_custom/forms.py:24
|
||||
msgid "-- Create a new gallery --"
|
||||
msgstr ""
|
||||
|
||||
#: photologue_custom/forms.py:37
|
||||
#: photologue_custom/forms.py:25
|
||||
msgid ""
|
||||
"Select a gallery to add these images to. Leave this empty to create a new "
|
||||
"gallery from the supplied title."
|
||||
|
|
@ -318,59 +338,43 @@ msgstr ""
|
|||
"Wähle eine Galerie aus, zu der diese Bilder hinzugefügt werden sollen. Lasse "
|
||||
"dieses Feld leer, um eine neue Galerie mit dem angegeben Titel zu erzeugen."
|
||||
|
||||
#: photologue_custom/forms.py:41
|
||||
#, fuzzy
|
||||
#| msgid "View all galleries"
|
||||
#: photologue_custom/forms.py:29
|
||||
msgid "New gallery title"
|
||||
msgstr "Zeige alle Galerien."
|
||||
msgstr ""
|
||||
|
||||
#: photologue_custom/forms.py:46
|
||||
#: photologue_custom/forms.py:34
|
||||
msgid "New gallery event start date"
|
||||
msgstr ""
|
||||
|
||||
#: photologue_custom/forms.py:51
|
||||
#: photologue_custom/forms.py:39
|
||||
msgid "New gallery event end date"
|
||||
msgstr ""
|
||||
|
||||
#: photologue_custom/forms.py:57
|
||||
#, fuzzy
|
||||
#| msgid "gallery"
|
||||
#: photologue_custom/forms.py:45
|
||||
msgid "New gallery tags"
|
||||
msgstr "Galerie"
|
||||
msgstr ""
|
||||
|
||||
#: photologue_custom/forms.py:59
|
||||
#: photologue_custom/forms.py:47
|
||||
msgid ""
|
||||
"Hold down \"Control\", or \"Command\" on a Mac, to select more than one."
|
||||
msgstr ""
|
||||
|
||||
#: photologue_custom/forms.py:76
|
||||
#: photologue_custom/forms.py:64
|
||||
#: photologue_custom/templates/photologue/upload.html:6
|
||||
#: photologue_custom/templates/photologue/upload.html:73
|
||||
msgid "Upload"
|
||||
msgstr "Hochladen"
|
||||
|
||||
#: photologue_custom/forms.py:82
|
||||
#: photologue_custom/forms.py:70
|
||||
msgid "A gallery with that title already exists."
|
||||
msgstr "Es existiert bereits eine Gallerie mit diesem Titel."
|
||||
|
||||
#: photologue_custom/forms.py:91
|
||||
#: photologue_custom/forms.py:79
|
||||
msgid "Select an existing gallery, or enter a title for a new gallery."
|
||||
msgstr ""
|
||||
"Wähle eine existierende Galerie aus oder gib einen Titel für eine neue "
|
||||
"Galerie ein."
|
||||
|
||||
#: photologue_custom/models.py:23
|
||||
msgid "start date"
|
||||
msgstr ""
|
||||
|
||||
#: photologue_custom/models.py:28
|
||||
msgid "end date"
|
||||
msgstr ""
|
||||
|
||||
#: photologue_custom/models.py:56
|
||||
msgid "license"
|
||||
msgstr ""
|
||||
|
||||
#: photologue_custom/templates/photologue/gallery_archive.html:7
|
||||
#: photologue_custom/templates/photologue/gallery_archive.html:12
|
||||
msgid "Latest photo galleries"
|
||||
|
|
@ -403,16 +407,12 @@ msgid "to"
|
|||
msgstr ""
|
||||
|
||||
#: photologue_custom/templates/photologue/gallery_detail.html:57
|
||||
#, fuzzy
|
||||
#| msgid "All photos"
|
||||
msgid "All pictures"
|
||||
msgstr "Alle Fotos"
|
||||
msgstr ""
|
||||
|
||||
#: photologue_custom/templates/photologue/gallery_detail.html:78
|
||||
#, fuzzy
|
||||
#| msgid "View all galleries"
|
||||
msgid "Download all gallery"
|
||||
msgstr "Zeige alle Galerien."
|
||||
msgstr ""
|
||||
|
||||
#: photologue_custom/templates/photologue/photo_detail.html:13
|
||||
msgid "Published"
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: Photologue\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2022-01-30 07:09+0000\n"
|
||||
"POT-Creation-Date: 2022-01-30 09:55+0000\n"
|
||||
"PO-Revision-Date: 2017-12-03 14:46+0000\n"
|
||||
"Last-Translator: Richard Barran <richard@arbee-design.co.uk>\n"
|
||||
"Language-Team: Spanish (Spain) (http://www.transifex.com/richardbarran/"
|
||||
|
|
@ -23,75 +23,79 @@ msgstr ""
|
|||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: photologue/models.py:86
|
||||
#: photologue/admin.py:30 photologue/models.py:499
|
||||
msgid "owner"
|
||||
msgstr ""
|
||||
|
||||
#: photologue/models.py:84
|
||||
msgid "Very Low"
|
||||
msgstr "Muy bajo"
|
||||
|
||||
#: photologue/models.py:87
|
||||
#: photologue/models.py:85
|
||||
msgid "Low"
|
||||
msgstr "Bajo"
|
||||
|
||||
#: photologue/models.py:88
|
||||
#: photologue/models.py:86
|
||||
msgid "Medium-Low"
|
||||
msgstr "Medio-bajo"
|
||||
|
||||
#: photologue/models.py:89
|
||||
#: photologue/models.py:87
|
||||
msgid "Medium"
|
||||
msgstr "Medio"
|
||||
|
||||
#: photologue/models.py:90
|
||||
#: photologue/models.py:88
|
||||
msgid "Medium-High"
|
||||
msgstr "Medio-alto"
|
||||
|
||||
#: photologue/models.py:91
|
||||
#: photologue/models.py:89
|
||||
msgid "High"
|
||||
msgstr "Alto"
|
||||
|
||||
#: photologue/models.py:92
|
||||
#: photologue/models.py:90
|
||||
msgid "Very High"
|
||||
msgstr "Muy alto"
|
||||
|
||||
#: photologue/models.py:97
|
||||
#: photologue/models.py:95
|
||||
msgid "Top"
|
||||
msgstr "Arriba"
|
||||
|
||||
#: photologue/models.py:98
|
||||
#: photologue/models.py:96
|
||||
msgid "Right"
|
||||
msgstr "Derecha"
|
||||
|
||||
#: photologue/models.py:99
|
||||
#: photologue/models.py:97
|
||||
msgid "Bottom"
|
||||
msgstr "Abajo"
|
||||
|
||||
#: photologue/models.py:100
|
||||
#: photologue/models.py:98
|
||||
msgid "Left"
|
||||
msgstr "Izquierda"
|
||||
|
||||
#: photologue/models.py:101
|
||||
#: photologue/models.py:99
|
||||
msgid "Center (Default)"
|
||||
msgstr "Centro (por defecto)"
|
||||
|
||||
#: photologue/models.py:105
|
||||
#: photologue/models.py:103
|
||||
msgid "Flip left to right"
|
||||
msgstr "Voltear de izquerda a derecha"
|
||||
|
||||
#: photologue/models.py:106
|
||||
#: photologue/models.py:104
|
||||
msgid "Flip top to bottom"
|
||||
msgstr "Voltear de arriba a abajo"
|
||||
|
||||
#: photologue/models.py:107
|
||||
#: photologue/models.py:105
|
||||
msgid "Rotate 90 degrees counter-clockwise"
|
||||
msgstr "Rotar 90 grados en sentido horario"
|
||||
|
||||
#: photologue/models.py:108
|
||||
#: photologue/models.py:106
|
||||
msgid "Rotate 90 degrees clockwise"
|
||||
msgstr "Rotar 90 grados en sentido antihorario"
|
||||
|
||||
#: photologue/models.py:109
|
||||
#: photologue/models.py:107
|
||||
msgid "Rotate 180 degrees"
|
||||
msgstr "Rotar 180 grados"
|
||||
|
||||
#: photologue/models.py:119
|
||||
#: photologue/models.py:117
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Chain multiple filters using the following pattern \"FILTER_ONE->FILTER_TWO-"
|
||||
|
|
@ -102,103 +106,119 @@ msgstr ""
|
|||
">FILTRO_DOS->FILTRO_TRES\". Los filtros de imagen se aplicarán en orden. Los "
|
||||
"siguientes filtros están disponibles: %s."
|
||||
|
||||
#: photologue/models.py:141
|
||||
#: photologue/models.py:139
|
||||
msgid "date published"
|
||||
msgstr "fecha de publicación"
|
||||
|
||||
#: photologue/models.py:143 photologue/models.py:474
|
||||
#: photologue/models.py:141 photologue/models.py:485
|
||||
msgid "title"
|
||||
msgstr "título"
|
||||
|
||||
#: photologue/models.py:146
|
||||
#: photologue/models.py:144
|
||||
msgid "title slug"
|
||||
msgstr "título slug"
|
||||
|
||||
#: photologue/models.py:149 photologue/models.py:480
|
||||
#: photologue/models.py:147 photologue/models.py:491 photologue/models.py:697
|
||||
msgid "A \"slug\" is a unique URL-friendly title for an object."
|
||||
msgstr "Un \"slug\" es un único título URL-amigable para un objeto."
|
||||
|
||||
#: photologue/models.py:150
|
||||
msgid "start date"
|
||||
msgstr ""
|
||||
|
||||
#: photologue/models.py:155
|
||||
msgid "end date"
|
||||
msgstr ""
|
||||
|
||||
#: photologue/models.py:157
|
||||
msgid "description"
|
||||
msgstr "descripción"
|
||||
|
||||
#: photologue/models.py:152 photologue/models.py:485
|
||||
#: photologue/models.py:162 photologue/models.py:703
|
||||
msgid "tags"
|
||||
msgstr ""
|
||||
|
||||
#: photologue/models.py:165 photologue/models.py:506
|
||||
msgid "is public"
|
||||
msgstr "es público"
|
||||
|
||||
#: photologue/models.py:154
|
||||
#: photologue/models.py:167
|
||||
msgid "Public galleries will be displayed in the default views."
|
||||
msgstr "Las galerías públicas serán mostradas en las vistas por defecto."
|
||||
|
||||
#: photologue/models.py:158 photologue/models.py:495
|
||||
#: photologue/models.py:171 photologue/models.py:514
|
||||
msgid "photos"
|
||||
msgstr "fotos"
|
||||
|
||||
#: photologue/models.py:166
|
||||
#: photologue/models.py:177
|
||||
msgid "gallery"
|
||||
msgstr "galería"
|
||||
|
||||
#: photologue/models.py:167
|
||||
#: photologue/models.py:178
|
||||
msgid "galleries"
|
||||
msgstr "galerías"
|
||||
|
||||
#: photologue/models.py:202
|
||||
#: photologue/models.py:213
|
||||
msgid "count"
|
||||
msgstr "contar"
|
||||
|
||||
#: photologue/models.py:210
|
||||
#: photologue/models.py:221
|
||||
msgid "image"
|
||||
msgstr "imagen"
|
||||
|
||||
#: photologue/models.py:213
|
||||
#: photologue/models.py:224
|
||||
msgid "date taken"
|
||||
msgstr "fecha en la que se tomó"
|
||||
|
||||
#: photologue/models.py:216
|
||||
#: photologue/models.py:227
|
||||
msgid "Date image was taken; is obtained from the image EXIF data."
|
||||
msgstr "La fecha de la imagen fue obtenida por información EXIF de la imagen."
|
||||
|
||||
#: photologue/models.py:217
|
||||
#: photologue/models.py:228
|
||||
msgid "view count"
|
||||
msgstr "Contador de visitas"
|
||||
|
||||
#: photologue/models.py:220
|
||||
#: photologue/models.py:231
|
||||
msgid "crop from"
|
||||
msgstr "Recortar desde"
|
||||
|
||||
#: photologue/models.py:243
|
||||
#: photologue/models.py:254
|
||||
msgid "An \"admin_thumbnail\" photo size has not been defined."
|
||||
msgstr "El tamaño de foto de \"miniatura de admin\" no ha sido definido."
|
||||
|
||||
#: photologue/models.py:250
|
||||
#: photologue/models.py:261
|
||||
msgid "Thumbnail"
|
||||
msgstr "Miniatura"
|
||||
|
||||
#: photologue/models.py:477
|
||||
#: photologue/models.py:488 photologue/models.py:696
|
||||
msgid "slug"
|
||||
msgstr "slug"
|
||||
|
||||
#: photologue/models.py:481
|
||||
#: photologue/models.py:492
|
||||
msgid "caption"
|
||||
msgstr "pie de foto"
|
||||
|
||||
#: photologue/models.py:483
|
||||
#: photologue/models.py:494
|
||||
msgid "date added"
|
||||
msgstr "fecha añadida"
|
||||
|
||||
#: photologue/models.py:487
|
||||
#: photologue/models.py:504
|
||||
msgid "license"
|
||||
msgstr ""
|
||||
|
||||
#: photologue/models.py:508
|
||||
msgid "Public photographs will be displayed in the default views."
|
||||
msgstr "Las fotos públicas serán mostradas en las vistas por defecto."
|
||||
|
||||
#: photologue/models.py:494
|
||||
#: photologue/models.py:513
|
||||
msgid "photo"
|
||||
msgstr "foto"
|
||||
|
||||
#: photologue/models.py:556
|
||||
#: photologue/models.py:575 photologue/models.py:691
|
||||
msgid "name"
|
||||
msgstr "nombre"
|
||||
|
||||
#: photologue/models.py:560
|
||||
#: photologue/models.py:579
|
||||
msgid ""
|
||||
"Photo size name should contain only letters, numbers and underscores. "
|
||||
"Examples: \"thumbnail\", \"display\", \"small\", \"main_page_widget\"."
|
||||
|
|
@ -206,41 +226,41 @@ msgstr ""
|
|||
"El nombre del tamaño solo puede contener letras, números y subrayados. Por "
|
||||
"ejemplo:\"miniaturas\", \"muestra\", \"muestra_principal\"."
|
||||
|
||||
#: photologue/models.py:567
|
||||
#: photologue/models.py:586
|
||||
msgid "width"
|
||||
msgstr "anchura"
|
||||
|
||||
#: photologue/models.py:570
|
||||
#: photologue/models.py:589
|
||||
msgid ""
|
||||
"If width is set to \"0\" the image will be scaled to the supplied height."
|
||||
msgstr ""
|
||||
"Si la anchura se establece a \"0\" la imagen será escalada hasta la altura "
|
||||
"proporcionada"
|
||||
|
||||
#: photologue/models.py:571
|
||||
#: photologue/models.py:590
|
||||
msgid "height"
|
||||
msgstr "altura"
|
||||
|
||||
#: photologue/models.py:574
|
||||
#: photologue/models.py:593
|
||||
msgid ""
|
||||
"If height is set to \"0\" the image will be scaled to the supplied width"
|
||||
msgstr ""
|
||||
"Si la altura se establece a \"0\" la imagen será escalada hasta la anchura "
|
||||
"proporcionada"
|
||||
|
||||
#: photologue/models.py:575
|
||||
#: photologue/models.py:594
|
||||
msgid "quality"
|
||||
msgstr "calidad"
|
||||
|
||||
#: photologue/models.py:578
|
||||
#: photologue/models.py:597
|
||||
msgid "JPEG image quality."
|
||||
msgstr "Calidad de imagen JPEG."
|
||||
|
||||
#: photologue/models.py:579
|
||||
#: photologue/models.py:598
|
||||
msgid "upscale images?"
|
||||
msgstr "¿Aumentar imágenes?"
|
||||
|
||||
#: photologue/models.py:581
|
||||
#: photologue/models.py:600
|
||||
msgid ""
|
||||
"If selected the image will be scaled up if necessary to fit the supplied "
|
||||
"dimensions. Cropped sizes will be upscaled regardless of this setting."
|
||||
|
|
@ -249,11 +269,11 @@ msgstr ""
|
|||
"las dimensiones proporcionadas. Los tamaños recortados serán aumentados de "
|
||||
"acuerdo a esta opción."
|
||||
|
||||
#: photologue/models.py:585
|
||||
#: photologue/models.py:604
|
||||
msgid "crop to fit?"
|
||||
msgstr "¿Recortar hasta ajustar?"
|
||||
|
||||
#: photologue/models.py:587
|
||||
#: photologue/models.py:606
|
||||
msgid ""
|
||||
"If selected the image will be scaled and cropped to fit the supplied "
|
||||
"dimensions."
|
||||
|
|
@ -261,21 +281,21 @@ msgstr ""
|
|||
"Si se selecciona la imagen será escalada y recortada para ajustarse a las "
|
||||
"dimensiones proporcionadas."
|
||||
|
||||
#: photologue/models.py:589
|
||||
#: photologue/models.py:608
|
||||
msgid "pre-cache?"
|
||||
msgstr "¿pre-cachear?"
|
||||
|
||||
#: photologue/models.py:591
|
||||
#: photologue/models.py:610
|
||||
msgid "If selected this photo size will be pre-cached as photos are added."
|
||||
msgstr ""
|
||||
"Si se selecciona, este tamaño de foto será pre-cacheado cuando se añadan "
|
||||
"nuevas fotos."
|
||||
|
||||
#: photologue/models.py:592
|
||||
#: photologue/models.py:611
|
||||
msgid "increment view count?"
|
||||
msgstr "¿incrementar contador de visualizaciones?"
|
||||
|
||||
#: photologue/models.py:594
|
||||
#: photologue/models.py:613
|
||||
msgid ""
|
||||
"If selected the image's \"view_count\" will be incremented when this photo "
|
||||
"size is displayed."
|
||||
|
|
@ -283,31 +303,31 @@ msgstr ""
|
|||
"Si se selecciona el \"contador de visualizaciones\" se incrementará cuando "
|
||||
"esta foto sea visualizada."
|
||||
|
||||
#: photologue/models.py:599
|
||||
#: photologue/models.py:618
|
||||
msgid "photo size"
|
||||
msgstr "tamaño de foto"
|
||||
|
||||
#: photologue/models.py:600
|
||||
#: photologue/models.py:619
|
||||
msgid "photo sizes"
|
||||
msgstr "tamaños de foto"
|
||||
|
||||
#: photologue/models.py:617
|
||||
#: photologue/models.py:636
|
||||
msgid "Can only crop photos if both width and height dimensions are set."
|
||||
msgstr "Solo puede recortar las fotos si ancho y alto están establecidos."
|
||||
|
||||
#: photologue_custom/admin.py:43 photologue_custom/models.py:51
|
||||
msgid "owner"
|
||||
#: photologue/models.py:702
|
||||
msgid "tag"
|
||||
msgstr ""
|
||||
|
||||
#: photologue_custom/forms.py:34
|
||||
#: photologue_custom/forms.py:22
|
||||
msgid "Gallery"
|
||||
msgstr "Galería"
|
||||
|
||||
#: photologue_custom/forms.py:36
|
||||
#: photologue_custom/forms.py:24
|
||||
msgid "-- Create a new gallery --"
|
||||
msgstr ""
|
||||
|
||||
#: photologue_custom/forms.py:37
|
||||
#: photologue_custom/forms.py:25
|
||||
msgid ""
|
||||
"Select a gallery to add these images to. Leave this empty to create a new "
|
||||
"gallery from the supplied title."
|
||||
|
|
@ -315,58 +335,42 @@ msgstr ""
|
|||
"Seleccione una galería para agregarle estas imágenes. Déjelo vacío para "
|
||||
"crear una nueva galería a partir de este título."
|
||||
|
||||
#: photologue_custom/forms.py:41
|
||||
#, fuzzy
|
||||
#| msgid "View all galleries"
|
||||
#: photologue_custom/forms.py:29
|
||||
msgid "New gallery title"
|
||||
msgstr "Ver todas las galerías"
|
||||
msgstr ""
|
||||
|
||||
#: photologue_custom/forms.py:46
|
||||
#: photologue_custom/forms.py:34
|
||||
msgid "New gallery event start date"
|
||||
msgstr ""
|
||||
|
||||
#: photologue_custom/forms.py:51
|
||||
#: photologue_custom/forms.py:39
|
||||
msgid "New gallery event end date"
|
||||
msgstr ""
|
||||
|
||||
#: photologue_custom/forms.py:57
|
||||
#, fuzzy
|
||||
#| msgid "gallery"
|
||||
#: photologue_custom/forms.py:45
|
||||
msgid "New gallery tags"
|
||||
msgstr "galería"
|
||||
msgstr ""
|
||||
|
||||
#: photologue_custom/forms.py:59
|
||||
#: photologue_custom/forms.py:47
|
||||
msgid ""
|
||||
"Hold down \"Control\", or \"Command\" on a Mac, to select more than one."
|
||||
msgstr ""
|
||||
|
||||
#: photologue_custom/forms.py:76
|
||||
#: photologue_custom/forms.py:64
|
||||
#: photologue_custom/templates/photologue/upload.html:6
|
||||
#: photologue_custom/templates/photologue/upload.html:73
|
||||
msgid "Upload"
|
||||
msgstr "Subir"
|
||||
|
||||
#: photologue_custom/forms.py:82
|
||||
#: photologue_custom/forms.py:70
|
||||
msgid "A gallery with that title already exists."
|
||||
msgstr "Ya existe una galería con ese título."
|
||||
|
||||
#: photologue_custom/forms.py:91
|
||||
#: photologue_custom/forms.py:79
|
||||
msgid "Select an existing gallery, or enter a title for a new gallery."
|
||||
msgstr ""
|
||||
"Seleccione una galería existente o ingrese un nuevo nombre para la galería."
|
||||
|
||||
#: photologue_custom/models.py:23
|
||||
msgid "start date"
|
||||
msgstr ""
|
||||
|
||||
#: photologue_custom/models.py:28
|
||||
msgid "end date"
|
||||
msgstr ""
|
||||
|
||||
#: photologue_custom/models.py:56
|
||||
msgid "license"
|
||||
msgstr ""
|
||||
|
||||
#: photologue_custom/templates/photologue/gallery_archive.html:7
|
||||
#: photologue_custom/templates/photologue/gallery_archive.html:12
|
||||
msgid "Latest photo galleries"
|
||||
|
|
@ -399,16 +403,12 @@ msgid "to"
|
|||
msgstr ""
|
||||
|
||||
#: photologue_custom/templates/photologue/gallery_detail.html:57
|
||||
#, fuzzy
|
||||
#| msgid "All photos"
|
||||
msgid "All pictures"
|
||||
msgstr "Todas las fotos"
|
||||
msgstr ""
|
||||
|
||||
#: photologue_custom/templates/photologue/gallery_detail.html:78
|
||||
#, fuzzy
|
||||
#| msgid "View all galleries"
|
||||
msgid "Download all gallery"
|
||||
msgstr "Ver todas las galerías"
|
||||
msgstr ""
|
||||
|
||||
#: photologue_custom/templates/photologue/photo_detail.html:13
|
||||
msgid "Published"
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: Photologue\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2022-01-30 07:09+0000\n"
|
||||
"POT-Creation-Date: 2022-01-30 10:06+0000\n"
|
||||
"PO-Revision-Date: 2017-12-03 14:47+0000\n"
|
||||
"Last-Translator: Richard Barran <richard@arbee-design.co.uk>\n"
|
||||
"Language-Team: French (http://www.transifex.com/richardbarran/django-"
|
||||
|
|
@ -21,75 +21,131 @@ msgstr ""
|
|||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
|
||||
#: photologue/models.py:86
|
||||
#: photologue/admin.py:30 photologue/models.py:499
|
||||
msgid "owner"
|
||||
msgstr "propriétaire"
|
||||
|
||||
#: photologue/forms.py:23
|
||||
msgid "Gallery"
|
||||
msgstr "Galerie"
|
||||
|
||||
#: photologue/forms.py:25
|
||||
msgid "-- Create a new gallery --"
|
||||
msgstr "-- Créer une nouvelle galerie --"
|
||||
|
||||
#: photologue/forms.py:26
|
||||
msgid ""
|
||||
"Select a gallery to add these images to. Leave this empty to create a new "
|
||||
"gallery from the supplied title."
|
||||
msgstr ""
|
||||
"Sélectionner une galerie à laquelle ajouter ces images. Laisser ce champ "
|
||||
"vide pour créer une nouvelle galerie à partir du titre indiqué."
|
||||
|
||||
#: photologue/forms.py:30
|
||||
msgid "New gallery title"
|
||||
msgstr "Titre de la nouvelle galerie"
|
||||
|
||||
#: photologue/forms.py:35
|
||||
msgid "New gallery event start date"
|
||||
msgstr "Date de début de l'évènement de la nouvelle galerie"
|
||||
|
||||
#: photologue/forms.py:40
|
||||
msgid "New gallery event end date"
|
||||
msgstr "Date de fin de l'évènement de la nouvelle galerie"
|
||||
|
||||
#: photologue/forms.py:46
|
||||
msgid "New gallery tags"
|
||||
msgstr "Balises de la nouvelle galerie"
|
||||
|
||||
#: photologue/forms.py:48
|
||||
msgid ""
|
||||
"Hold down \"Control\", or \"Command\" on a Mac, to select more than one."
|
||||
msgstr ""
|
||||
|
||||
#: photologue/forms.py:65 photologue/templates/photologue/upload.html:6
|
||||
#: photologue/templates/photologue/upload.html:73
|
||||
msgid "Upload"
|
||||
msgstr "Télécharger"
|
||||
|
||||
#: photologue/forms.py:71
|
||||
msgid "A gallery with that title already exists."
|
||||
msgstr "Une galerie portant ce nom existe déjà."
|
||||
|
||||
#: photologue/forms.py:80
|
||||
msgid "Select an existing gallery, or enter a title for a new gallery."
|
||||
msgstr ""
|
||||
"Sélectionner une galerie existante ou entrer un titre pour une nouvelle "
|
||||
"galerie."
|
||||
|
||||
#: photologue/models.py:84
|
||||
msgid "Very Low"
|
||||
msgstr "Très Bas"
|
||||
|
||||
#: photologue/models.py:87
|
||||
#: photologue/models.py:85
|
||||
msgid "Low"
|
||||
msgstr "Bas"
|
||||
|
||||
#: photologue/models.py:88
|
||||
#: photologue/models.py:86
|
||||
msgid "Medium-Low"
|
||||
msgstr "Moyen-Bas"
|
||||
|
||||
#: photologue/models.py:89
|
||||
#: photologue/models.py:87
|
||||
msgid "Medium"
|
||||
msgstr "Moyen"
|
||||
|
||||
#: photologue/models.py:90
|
||||
#: photologue/models.py:88
|
||||
msgid "Medium-High"
|
||||
msgstr "Moyen-Haut"
|
||||
|
||||
#: photologue/models.py:91
|
||||
#: photologue/models.py:89
|
||||
msgid "High"
|
||||
msgstr "Haut"
|
||||
|
||||
#: photologue/models.py:92
|
||||
#: photologue/models.py:90
|
||||
msgid "Very High"
|
||||
msgstr "Très Haut"
|
||||
|
||||
#: photologue/models.py:97
|
||||
#: photologue/models.py:95
|
||||
msgid "Top"
|
||||
msgstr "Sommet"
|
||||
|
||||
#: photologue/models.py:98
|
||||
#: photologue/models.py:96
|
||||
msgid "Right"
|
||||
msgstr "Droite"
|
||||
|
||||
#: photologue/models.py:99
|
||||
#: photologue/models.py:97
|
||||
msgid "Bottom"
|
||||
msgstr "Bas"
|
||||
|
||||
#: photologue/models.py:100
|
||||
#: photologue/models.py:98
|
||||
msgid "Left"
|
||||
msgstr "Gauche"
|
||||
|
||||
#: photologue/models.py:101
|
||||
#: photologue/models.py:99
|
||||
msgid "Center (Default)"
|
||||
msgstr "Centré (par défaut)"
|
||||
|
||||
#: photologue/models.py:105
|
||||
#: photologue/models.py:103
|
||||
msgid "Flip left to right"
|
||||
msgstr "Inversion de gauche à droite"
|
||||
|
||||
#: photologue/models.py:106
|
||||
#: photologue/models.py:104
|
||||
msgid "Flip top to bottom"
|
||||
msgstr "Inversion de haut en bas"
|
||||
|
||||
#: photologue/models.py:107
|
||||
#: photologue/models.py:105
|
||||
msgid "Rotate 90 degrees counter-clockwise"
|
||||
msgstr "Rotation de 90 degrés dans le sens anti-horloger"
|
||||
|
||||
#: photologue/models.py:108
|
||||
#: photologue/models.py:106
|
||||
msgid "Rotate 90 degrees clockwise"
|
||||
msgstr "Rotation de 90 degrés dans le sens horloger"
|
||||
|
||||
#: photologue/models.py:109
|
||||
#: photologue/models.py:107
|
||||
msgid "Rotate 180 degrees"
|
||||
msgstr "Rotation de 180 degrés"
|
||||
|
||||
#: photologue/models.py:119
|
||||
#: photologue/models.py:117
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Chain multiple filters using the following pattern \"FILTER_ONE->FILTER_TWO-"
|
||||
|
|
@ -100,107 +156,123 @@ msgstr ""
|
|||
">FILTRE_DEUX->FILTRE_TROIS\". Les filtres d'image seront appliqués dans "
|
||||
"l'ordre. Les filtres suivants sont disponibles: %s."
|
||||
|
||||
#: photologue/models.py:141
|
||||
#: photologue/models.py:139
|
||||
msgid "date published"
|
||||
msgstr "date de publication"
|
||||
|
||||
#: photologue/models.py:143 photologue/models.py:474
|
||||
#: photologue/models.py:141 photologue/models.py:485
|
||||
msgid "title"
|
||||
msgstr "titre"
|
||||
|
||||
#: photologue/models.py:146
|
||||
#: photologue/models.py:144
|
||||
msgid "title slug"
|
||||
msgstr "version abrégée du titre"
|
||||
|
||||
#: photologue/models.py:149 photologue/models.py:480
|
||||
#: photologue/models.py:147 photologue/models.py:491 photologue/models.py:697
|
||||
msgid "A \"slug\" is a unique URL-friendly title for an object."
|
||||
msgstr ""
|
||||
"Un \"slug\" est un titre abrégé et unique, compatible avec les URL, pour un "
|
||||
"objet."
|
||||
|
||||
#: photologue/models.py:150
|
||||
msgid "start date"
|
||||
msgstr "date de début"
|
||||
|
||||
#: photologue/models.py:155
|
||||
msgid "end date"
|
||||
msgstr "date de fin"
|
||||
|
||||
#: photologue/models.py:157
|
||||
msgid "description"
|
||||
msgstr "description"
|
||||
|
||||
#: photologue/models.py:152 photologue/models.py:485
|
||||
#: photologue/models.py:162 photologue/models.py:703
|
||||
msgid "tags"
|
||||
msgstr "balises"
|
||||
|
||||
#: photologue/models.py:165 photologue/models.py:506
|
||||
msgid "is public"
|
||||
msgstr "est public"
|
||||
|
||||
#: photologue/models.py:154
|
||||
#: photologue/models.py:167
|
||||
msgid "Public galleries will be displayed in the default views."
|
||||
msgstr "Les galeries publiques seront affichée dans les vues par défaut."
|
||||
|
||||
#: photologue/models.py:158 photologue/models.py:495
|
||||
#: photologue/models.py:171 photologue/models.py:514
|
||||
msgid "photos"
|
||||
msgstr "photos"
|
||||
|
||||
#: photologue/models.py:166
|
||||
#: photologue/models.py:177
|
||||
msgid "gallery"
|
||||
msgstr "galerie"
|
||||
|
||||
#: photologue/models.py:167
|
||||
#: photologue/models.py:178
|
||||
msgid "galleries"
|
||||
msgstr "galleries"
|
||||
|
||||
#: photologue/models.py:202
|
||||
#: photologue/models.py:213
|
||||
msgid "count"
|
||||
msgstr "nombre"
|
||||
|
||||
#: photologue/models.py:210
|
||||
#: photologue/models.py:221
|
||||
msgid "image"
|
||||
msgstr "image"
|
||||
|
||||
#: photologue/models.py:213
|
||||
#: photologue/models.py:224
|
||||
msgid "date taken"
|
||||
msgstr "date de prise de vue"
|
||||
|
||||
#: photologue/models.py:216
|
||||
#: photologue/models.py:227
|
||||
msgid "Date image was taken; is obtained from the image EXIF data."
|
||||
msgstr ""
|
||||
"La date à laquelle l'image a été prise ; obtenue à partir des données EXIF "
|
||||
"de l'image."
|
||||
|
||||
#: photologue/models.py:217
|
||||
#: photologue/models.py:228
|
||||
msgid "view count"
|
||||
msgstr "nombre"
|
||||
|
||||
#: photologue/models.py:220
|
||||
#: photologue/models.py:231
|
||||
msgid "crop from"
|
||||
msgstr "découper à partir de"
|
||||
|
||||
#: photologue/models.py:243
|
||||
#: photologue/models.py:254
|
||||
msgid "An \"admin_thumbnail\" photo size has not been defined."
|
||||
msgstr "Une taille de photo \"admin_thumbnail\" n'a pas encore été définie."
|
||||
|
||||
#: photologue/models.py:250
|
||||
#: photologue/models.py:261
|
||||
msgid "Thumbnail"
|
||||
msgstr "Miniature"
|
||||
|
||||
#: photologue/models.py:477
|
||||
#: photologue/models.py:488 photologue/models.py:696
|
||||
msgid "slug"
|
||||
msgstr "libellé court"
|
||||
|
||||
#: photologue/models.py:481
|
||||
#: photologue/models.py:492
|
||||
msgid "caption"
|
||||
msgstr "légende"
|
||||
|
||||
#: photologue/models.py:483
|
||||
#: photologue/models.py:494
|
||||
msgid "date added"
|
||||
msgstr "date d'ajout"
|
||||
|
||||
#: photologue/models.py:487
|
||||
#: photologue/models.py:504
|
||||
msgid "license"
|
||||
msgstr "licence"
|
||||
|
||||
#: photologue/models.py:508
|
||||
msgid "Public photographs will be displayed in the default views."
|
||||
msgstr "Les photographies publique seront affichées dans les vues par défaut."
|
||||
|
||||
#: photologue/models.py:494
|
||||
#: photologue/models.py:513
|
||||
msgid "photo"
|
||||
msgstr "photo"
|
||||
|
||||
#: photologue/models.py:556
|
||||
#: photologue/models.py:575 photologue/models.py:691
|
||||
msgid "name"
|
||||
msgstr "nom"
|
||||
|
||||
#: photologue/models.py:560
|
||||
#: photologue/models.py:579
|
||||
msgid ""
|
||||
"Photo size name should contain only letters, numbers and underscores. "
|
||||
"Examples: \"thumbnail\", \"display\", \"small\", \"main_page_widget\"."
|
||||
|
|
@ -209,41 +281,41 @@ msgstr ""
|
|||
"chiffres et des caractères de soulignement. Exemples: \"miniature\", "
|
||||
"\"affichage\", \"petit\", \"widget_page_principale\"."
|
||||
|
||||
#: photologue/models.py:567
|
||||
#: photologue/models.py:586
|
||||
msgid "width"
|
||||
msgstr "largeur"
|
||||
|
||||
#: photologue/models.py:570
|
||||
#: photologue/models.py:589
|
||||
msgid ""
|
||||
"If width is set to \"0\" the image will be scaled to the supplied height."
|
||||
msgstr ""
|
||||
"Si la largeur est réglée à \"0\" l l'image sera redimensionnée par rapport à "
|
||||
"la hauteur fournie."
|
||||
|
||||
#: photologue/models.py:571
|
||||
#: photologue/models.py:590
|
||||
msgid "height"
|
||||
msgstr "hauteur"
|
||||
|
||||
#: photologue/models.py:574
|
||||
#: photologue/models.py:593
|
||||
msgid ""
|
||||
"If height is set to \"0\" the image will be scaled to the supplied width"
|
||||
msgstr ""
|
||||
"Si la hauteur est réglée à \"0\" l l'image sera redimensionnée par rapport à "
|
||||
"la largeur fournie."
|
||||
|
||||
#: photologue/models.py:575
|
||||
#: photologue/models.py:594
|
||||
msgid "quality"
|
||||
msgstr "qualité"
|
||||
|
||||
#: photologue/models.py:578
|
||||
#: photologue/models.py:597
|
||||
msgid "JPEG image quality."
|
||||
msgstr "Qualité JPEG de l'image."
|
||||
|
||||
#: photologue/models.py:579
|
||||
#: photologue/models.py:598
|
||||
msgid "upscale images?"
|
||||
msgstr "agrandir les images ?"
|
||||
|
||||
#: photologue/models.py:581
|
||||
#: photologue/models.py:600
|
||||
msgid ""
|
||||
"If selected the image will be scaled up if necessary to fit the supplied "
|
||||
"dimensions. Cropped sizes will be upscaled regardless of this setting."
|
||||
|
|
@ -252,11 +324,11 @@ msgstr ""
|
|||
"dimensions fournies. Les dimensions ajustées seront agrandies sans prendre "
|
||||
"en compte ce paramètre."
|
||||
|
||||
#: photologue/models.py:585
|
||||
#: photologue/models.py:604
|
||||
msgid "crop to fit?"
|
||||
msgstr "découper pour adapter à la taille ?"
|
||||
|
||||
#: photologue/models.py:587
|
||||
#: photologue/models.py:606
|
||||
msgid ""
|
||||
"If selected the image will be scaled and cropped to fit the supplied "
|
||||
"dimensions."
|
||||
|
|
@ -264,21 +336,21 @@ msgstr ""
|
|||
"Si sélectionné l'image sera redimensionnée et recadrée pour coïncider avec "
|
||||
"les dimensions fournies."
|
||||
|
||||
#: photologue/models.py:589
|
||||
#: photologue/models.py:608
|
||||
msgid "pre-cache?"
|
||||
msgstr "mise en cache ?"
|
||||
|
||||
#: photologue/models.py:591
|
||||
#: photologue/models.py:610
|
||||
msgid "If selected this photo size will be pre-cached as photos are added."
|
||||
msgstr ""
|
||||
"Si sélectionné cette taille de photo sera mise en cache au moment au les "
|
||||
"photos sont ajoutées."
|
||||
|
||||
#: photologue/models.py:592
|
||||
#: photologue/models.py:611
|
||||
msgid "increment view count?"
|
||||
msgstr "incrémenter le nombre d'affichages ?"
|
||||
|
||||
#: photologue/models.py:594
|
||||
#: photologue/models.py:613
|
||||
msgid ""
|
||||
"If selected the image's \"view_count\" will be incremented when this photo "
|
||||
"size is displayed."
|
||||
|
|
@ -286,148 +358,75 @@ msgstr ""
|
|||
"Si sélectionné le \"view_count\" (nombre d'affichage) de l'image sera "
|
||||
"incrémenté quand cette taille de photo sera affichée."
|
||||
|
||||
#: photologue/models.py:599
|
||||
#: photologue/models.py:618
|
||||
msgid "photo size"
|
||||
msgstr "taille de la photo"
|
||||
|
||||
#: photologue/models.py:600
|
||||
#: photologue/models.py:619
|
||||
msgid "photo sizes"
|
||||
msgstr "tailles des photos"
|
||||
|
||||
#: photologue/models.py:617
|
||||
#: photologue/models.py:636
|
||||
msgid "Can only crop photos if both width and height dimensions are set."
|
||||
msgstr ""
|
||||
"La hauteur et la largeur doivent être toutes les deux définies pour "
|
||||
"retailler des photos."
|
||||
|
||||
#: photologue_custom/admin.py:43 photologue_custom/models.py:51
|
||||
msgid "owner"
|
||||
#: photologue/models.py:702
|
||||
msgid "tag"
|
||||
msgstr ""
|
||||
|
||||
#: photologue_custom/forms.py:34
|
||||
msgid "Gallery"
|
||||
msgstr "Galerie"
|
||||
|
||||
#: photologue_custom/forms.py:36
|
||||
msgid "-- Create a new gallery --"
|
||||
msgstr ""
|
||||
|
||||
#: photologue_custom/forms.py:37
|
||||
msgid ""
|
||||
"Select a gallery to add these images to. Leave this empty to create a new "
|
||||
"gallery from the supplied title."
|
||||
msgstr ""
|
||||
"Sélectionner une galerie à laquelle ajouter ces images. Laisser ce champ "
|
||||
"vide pour créer une nouvelle galerie à partir du titre indiqué."
|
||||
|
||||
#: photologue_custom/forms.py:41
|
||||
#, fuzzy
|
||||
#| msgid "View all galleries"
|
||||
msgid "New gallery title"
|
||||
msgstr "Afficher toutes les galeries"
|
||||
|
||||
#: photologue_custom/forms.py:46
|
||||
msgid "New gallery event start date"
|
||||
msgstr ""
|
||||
|
||||
#: photologue_custom/forms.py:51
|
||||
msgid "New gallery event end date"
|
||||
msgstr ""
|
||||
|
||||
#: photologue_custom/forms.py:57
|
||||
#, fuzzy
|
||||
#| msgid "gallery uploads"
|
||||
msgid "New gallery tags"
|
||||
msgstr "gallery uploads"
|
||||
|
||||
#: photologue_custom/forms.py:59
|
||||
msgid ""
|
||||
"Hold down \"Control\", or \"Command\" on a Mac, to select more than one."
|
||||
msgstr ""
|
||||
|
||||
#: photologue_custom/forms.py:76
|
||||
#: photologue_custom/templates/photologue/upload.html:6
|
||||
#: photologue_custom/templates/photologue/upload.html:73
|
||||
msgid "Upload"
|
||||
msgstr "Télécharger"
|
||||
|
||||
#: photologue_custom/forms.py:82
|
||||
msgid "A gallery with that title already exists."
|
||||
msgstr "Une galerie portant ce nom existe déjà."
|
||||
|
||||
#: photologue_custom/forms.py:91
|
||||
msgid "Select an existing gallery, or enter a title for a new gallery."
|
||||
msgstr ""
|
||||
"Sélectionner une galerie existante ou entrer un titre pour une nouvelle "
|
||||
"galerie."
|
||||
|
||||
#: photologue_custom/models.py:23
|
||||
msgid "start date"
|
||||
msgstr ""
|
||||
|
||||
#: photologue_custom/models.py:28
|
||||
msgid "end date"
|
||||
msgstr ""
|
||||
|
||||
#: photologue_custom/models.py:56
|
||||
msgid "license"
|
||||
msgstr ""
|
||||
|
||||
#: photologue_custom/templates/photologue/gallery_archive.html:7
|
||||
#: photologue_custom/templates/photologue/gallery_archive.html:12
|
||||
#: photologue/templates/photologue/gallery_archive.html:7
|
||||
#: photologue/templates/photologue/gallery_archive.html:12
|
||||
msgid "Latest photo galleries"
|
||||
msgstr "Dernières galeries de photos"
|
||||
|
||||
#: photologue_custom/templates/photologue/gallery_archive.html:18
|
||||
#: photologue/templates/photologue/gallery_archive.html:18
|
||||
msgid "Filter by year"
|
||||
msgstr "Filtrer par année"
|
||||
|
||||
#: photologue_custom/templates/photologue/gallery_archive.html:35
|
||||
#: photologue/templates/photologue/gallery_archive.html:35
|
||||
msgid "No galleries were found"
|
||||
msgstr "Aucune galerie trouvée"
|
||||
|
||||
#: photologue_custom/templates/photologue/gallery_archive_year.html:7
|
||||
#: photologue_custom/templates/photologue/gallery_archive_year.html:12
|
||||
#: photologue/templates/photologue/gallery_archive_year.html:7
|
||||
#: photologue/templates/photologue/gallery_archive_year.html:12
|
||||
#, python-format
|
||||
msgid "Galleries for %(show_year)s"
|
||||
msgstr "Galeries de %(show_year)s"
|
||||
|
||||
#: photologue_custom/templates/photologue/gallery_archive_year.html:17
|
||||
#: photologue/templates/photologue/gallery_archive_year.html:17
|
||||
msgid "View all galleries"
|
||||
msgstr "Afficher toutes les galeries"
|
||||
|
||||
#: photologue_custom/templates/photologue/gallery_archive_year.html:29
|
||||
#: photologue/templates/photologue/gallery_archive_year.html:29
|
||||
msgid "No galleries were found."
|
||||
msgstr "Aucune galerie trouvée."
|
||||
|
||||
#: photologue_custom/templates/photologue/gallery_detail.html:41
|
||||
#: photologue/templates/photologue/gallery_detail.html:41
|
||||
msgid "to"
|
||||
msgstr ""
|
||||
msgstr "au"
|
||||
|
||||
#: photologue_custom/templates/photologue/gallery_detail.html:57
|
||||
#, fuzzy
|
||||
#| msgid "All photos"
|
||||
#: photologue/templates/photologue/gallery_detail.html:57
|
||||
msgid "All pictures"
|
||||
msgstr "Toutes les photos"
|
||||
|
||||
#: photologue_custom/templates/photologue/gallery_detail.html:78
|
||||
#, fuzzy
|
||||
#| msgid "View all galleries"
|
||||
#: photologue/templates/photologue/gallery_detail.html:78
|
||||
msgid "Download all gallery"
|
||||
msgstr "Afficher toutes les galeries"
|
||||
msgstr "Télécharger toute la galerie"
|
||||
|
||||
#: photologue_custom/templates/photologue/photo_detail.html:13
|
||||
#: photologue/templates/photologue/photo_detail.html:13
|
||||
msgid "Published"
|
||||
msgstr "Publiée le"
|
||||
|
||||
#: photologue_custom/templates/photologue/photo_detail.html:25
|
||||
#: photologue/templates/photologue/photo_detail.html:25
|
||||
msgid "This photo is found in the following galleries"
|
||||
msgstr "Cette photo se trouve dans les galeries suivantes"
|
||||
|
||||
#: photologue_custom/templates/photologue/upload.html:78
|
||||
#: photologue/templates/photologue/upload.html:78
|
||||
msgid "Drag and drop photos here"
|
||||
msgstr ""
|
||||
msgstr "Glissez et déposez les photos ici"
|
||||
|
||||
#: photologue_custom/templates/photologue/upload.html:82
|
||||
#: photologue/templates/photologue/upload.html:82
|
||||
msgid "Owner will be"
|
||||
msgstr ""
|
||||
msgstr "Le propriétaire sera"
|
||||
|
|
|
|||
71
photologue/management/commands/duplicate.py
Normal file
71
photologue/management/commands/duplicate.py
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
import hashlib
|
||||
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
from photologue.models import Gallery
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = 'List all duplicate for chosen galleries'
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument(
|
||||
'--slugs', nargs='+', help='Try to find duplicate in the selected galleries', default=[])
|
||||
parser.add_argument('-a', '--all', action='store_true',
|
||||
help='Try to find duplicate in all galleries, overide any slugs given')
|
||||
parser.add_argument('-d', '--delete', action='store_true')
|
||||
|
||||
def handle(self, *args, **options):
|
||||
# Collect all required galleries
|
||||
if options['all']:
|
||||
galleries = Gallery.objects.all()
|
||||
else:
|
||||
galleries = []
|
||||
for slug in options['slugs']:
|
||||
gallery_query = Gallery.objects.filter(slug=slug)
|
||||
if not gallery_query:
|
||||
raise CommandError(f"Slug {slug} does not correspond to a "
|
||||
"gallery in the database.")
|
||||
galleries += gallery_query
|
||||
|
||||
# Find duplicates in all galleries
|
||||
for gallery in galleries:
|
||||
duplicates = find_duplicate(gallery)
|
||||
self.stdout.write(f"Gallery {gallery.slug}:")
|
||||
for original, copies in duplicates:
|
||||
self.stdout.write(f" {original.slug} is duplicated:", ending='')
|
||||
for copy in copies:
|
||||
self.stdout.write(f" {copy.slug}")
|
||||
|
||||
# Delete them if --delete
|
||||
if options['delete']:
|
||||
self.stdout.write(
|
||||
' Deleting duplicate in {} :'.format(gallery.slug))
|
||||
for (_original, copies) in duplicates:
|
||||
for copy in copies:
|
||||
self.stdout.write(
|
||||
' Deleting {}...'.format(copy.slug))
|
||||
copy.delete()
|
||||
|
||||
|
||||
def find_duplicate(gallery):
|
||||
# Dict of all already checked photos
|
||||
non_duplicate = {}
|
||||
# Dict of all found duplicate {h0 : (original:[duplicates])}
|
||||
duplicate = {}
|
||||
|
||||
for photo in gallery.photos.all():
|
||||
with photo.image.open("rb") as f:
|
||||
h0 = hashlib.sha256(f.read()).digest()
|
||||
if h0 not in non_duplicate:
|
||||
# Photo is not a duplicate
|
||||
non_duplicate[h0] = photo
|
||||
elif h0 in duplicate:
|
||||
if len(photo.slug) > len(duplicate[h0][0].slug):
|
||||
duplicate[h0][1] += [photo]
|
||||
else:
|
||||
duplicate[h0][1] += [duplicate[h0][0]]
|
||||
duplicate[h0][0] = photo
|
||||
else:
|
||||
duplicate[h0] = [non_duplicate[h0], [photo]]
|
||||
# Return only value because hash aren't usefull
|
||||
return duplicate.values()
|
||||
37
photologue/management/commands/rename_media.py
Normal file
37
photologue/management/commands/rename_media.py
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from django.conf import settings
|
||||
from django.core.management.base import BaseCommand
|
||||
from photologue.models import Gallery
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = 'Rename uploaded media file to match gallery and photo names'
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('--apply', action='store_true')
|
||||
|
||||
def handle(self, *args, **options):
|
||||
media_dir = Path(settings.MEDIA_ROOT)
|
||||
for gallery in Gallery.objects.all():
|
||||
# Create gallery directory
|
||||
gallery_year = str(gallery.date_start.year)
|
||||
gallery_dir = Path('photos') / gallery_year / gallery.slug
|
||||
gallery_path = media_dir / gallery_dir
|
||||
if not gallery_path.exists():
|
||||
self.stdout.write(f"Creating {gallery_dir}")
|
||||
if options["apply"]:
|
||||
gallery_path.mkdir(parents=True)
|
||||
|
||||
# Move photos in gallery folder
|
||||
for photo in gallery.photos.all():
|
||||
photo_name = str(gallery_dir / photo.image.name.split("/")[-1])
|
||||
if photo.image.name == photo_name:
|
||||
continue
|
||||
self.stdout.write(f" Moving {photo.image.name} -> {photo_name}")
|
||||
if options["apply"]:
|
||||
if not (media_dir / photo_name).exists():
|
||||
os.rename(photo.image.path, media_dir / photo_name)
|
||||
photo.image.name = photo_name
|
||||
photo.save()
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
# Generated by Django 3.2.11 on 2022-01-30 08:32
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import django.utils.timezone
|
||||
import taggit.managers
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.db import migrations, models
|
||||
from django.template.defaultfilters import slugify
|
||||
|
||||
numens = User.objects.get(username="Numens").id
|
||||
|
|
|
|||
108
photologue/static/lightgallery/css/lg-thumbnail.css
Normal file
108
photologue/static/lightgallery/css/lg-thumbnail.css
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
.lg-outer .lg-thumb-outer {
|
||||
background-color: #0d0a0a;
|
||||
width: 100%;
|
||||
max-height: 350px;
|
||||
overflow: hidden;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.lg-outer .lg-thumb-outer.lg-grab .lg-thumb-item {
|
||||
cursor: -webkit-grab;
|
||||
cursor: -moz-grab;
|
||||
cursor: -o-grab;
|
||||
cursor: -ms-grab;
|
||||
cursor: grab;
|
||||
}
|
||||
|
||||
.lg-outer .lg-thumb-outer.lg-grabbing .lg-thumb-item {
|
||||
cursor: move;
|
||||
cursor: -webkit-grabbing;
|
||||
cursor: -moz-grabbing;
|
||||
cursor: -o-grabbing;
|
||||
cursor: -ms-grabbing;
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
.lg-outer .lg-thumb-outer.lg-dragging .lg-thumb {
|
||||
-webkit-transition-duration: 0s !important;
|
||||
transition-duration: 0s !important;
|
||||
}
|
||||
|
||||
.lg-outer .lg-thumb-outer.lg-rebuilding-thumbnails .lg-thumb {
|
||||
-webkit-transition-duration: 0s !important;
|
||||
transition-duration: 0s !important;
|
||||
}
|
||||
|
||||
.lg-outer .lg-thumb-outer.lg-thumb-align-middle {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.lg-outer .lg-thumb-outer.lg-thumb-align-left {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.lg-outer .lg-thumb-outer.lg-thumb-align-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.lg-outer.lg-single-item .lg-thumb-outer {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.lg-outer .lg-thumb {
|
||||
padding: 5px 0;
|
||||
height: 100%;
|
||||
margin-bottom: -5px;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.lg-outer .lg-thumb {
|
||||
padding: 10px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.lg-outer .lg-thumb-item {
|
||||
cursor: pointer;
|
||||
float: left;
|
||||
overflow: hidden;
|
||||
height: 100%;
|
||||
border-radius: 2px;
|
||||
margin-bottom: 5px;
|
||||
will-change: border-color;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.lg-outer .lg-thumb-item {
|
||||
border-radius: 4px;
|
||||
border: 2px solid #fff;
|
||||
-webkit-transition: border-color 0.25s ease;
|
||||
-o-transition: border-color 0.25s ease;
|
||||
transition: border-color 0.25s ease;
|
||||
}
|
||||
}
|
||||
|
||||
.lg-outer .lg-thumb-item.active, .lg-outer .lg-thumb-item:hover {
|
||||
border-color: #a90707;
|
||||
}
|
||||
|
||||
.lg-outer .lg-thumb-item img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.lg-outer.lg-can-toggle .lg-item {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.lg-outer .lg-toggle-thumb:after {
|
||||
content: '\e1ff';
|
||||
}
|
||||
|
||||
.lg-outer.lg-animate-thumb .lg-thumb {
|
||||
-webkit-transition-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
|
||||
transition-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
|
||||
}
|
||||
84
photologue/static/lightgallery/css/lg-zoom.css
Normal file
84
photologue/static/lightgallery/css/lg-zoom.css
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
.lg-outer.lg-css3.lg-zoom-dragging .lg-item.lg-complete.lg-zoomable .lg-img-wrap,
|
||||
.lg-outer.lg-css3.lg-zoom-dragging .lg-item.lg-complete.lg-zoomable .lg-image {
|
||||
-webkit-transition-duration: 0ms !important;
|
||||
transition-duration: 0ms !important;
|
||||
}
|
||||
|
||||
.lg-outer.lg-use-transition-for-zoom .lg-item.lg-complete.lg-zoomable .lg-img-wrap {
|
||||
will-change: transform;
|
||||
-webkit-transition: -webkit-transform 0.5s cubic-bezier(0.12, 0.415, 0.01, 1.19) 0s;
|
||||
-moz-transition: -moz-transform 0.5s cubic-bezier(0.12, 0.415, 0.01, 1.19) 0s;
|
||||
-o-transition: -o-transform 0.5s cubic-bezier(0.12, 0.415, 0.01, 1.19) 0s;
|
||||
transition: transform 0.5s cubic-bezier(0.12, 0.415, 0.01, 1.19) 0s;
|
||||
}
|
||||
|
||||
.lg-outer.lg-use-transition-for-zoom.lg-zoom-drag-transition .lg-item.lg-complete.lg-zoomable .lg-img-wrap {
|
||||
will-change: transform;
|
||||
-webkit-transition: -webkit-transform 0.8s cubic-bezier(0, 0, 0.25, 1) 0s;
|
||||
-moz-transition: -moz-transform 0.8s cubic-bezier(0, 0, 0.25, 1) 0s;
|
||||
-o-transition: -o-transform 0.8s cubic-bezier(0, 0, 0.25, 1) 0s;
|
||||
transition: transform 0.8s cubic-bezier(0, 0, 0.25, 1) 0s;
|
||||
}
|
||||
|
||||
.lg-outer .lg-item.lg-complete.lg-zoomable .lg-img-wrap {
|
||||
-webkit-transform: translate3d(0, 0, 0);
|
||||
transform: translate3d(0, 0, 0);
|
||||
-webkit-backface-visibility: hidden;
|
||||
-moz-backface-visibility: hidden;
|
||||
backface-visibility: hidden;
|
||||
}
|
||||
|
||||
.lg-outer .lg-item.lg-complete.lg-zoomable .lg-image,
|
||||
.lg-outer .lg-item.lg-complete.lg-zoomable .lg-dummy-img {
|
||||
-webkit-transform: scale3d(1, 1, 1);
|
||||
transform: scale3d(1, 1, 1);
|
||||
will-change: opacity, transform;
|
||||
-webkit-transition: -webkit-transform 0.5s cubic-bezier(0.12, 0.415, 0.01, 1.19) 0s, opacity 0.15s !important;
|
||||
-moz-transition: -moz-transform 0.5s cubic-bezier(0.12, 0.415, 0.01, 1.19) 0s, opacity 0.15s !important;
|
||||
-o-transition: -o-transform 0.5s cubic-bezier(0.12, 0.415, 0.01, 1.19) 0s, opacity 0.15s !important;
|
||||
transition: transform 0.5s cubic-bezier(0.12, 0.415, 0.01, 1.19) 0s, opacity 0.15s !important;
|
||||
-webkit-transform-origin: 0 0;
|
||||
-moz-transform-origin: 0 0;
|
||||
-ms-transform-origin: 0 0;
|
||||
transform-origin: 0 0;
|
||||
-webkit-backface-visibility: hidden;
|
||||
-moz-backface-visibility: hidden;
|
||||
backface-visibility: hidden;
|
||||
}
|
||||
|
||||
.lg-icon.lg-zoom-in:after {
|
||||
content: '\e311';
|
||||
}
|
||||
|
||||
.lg-icon.lg-actual-size {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.lg-icon.lg-actual-size:after {
|
||||
content: '\e033';
|
||||
}
|
||||
|
||||
.lg-icon.lg-zoom-out {
|
||||
opacity: 0.5;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.lg-icon.lg-zoom-out:after {
|
||||
content: '\e312';
|
||||
}
|
||||
|
||||
.lg-zoomed .lg-icon.lg-zoom-out {
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.lg-outer[data-lg-slide-type='video'] .lg-zoom-in,
|
||||
.lg-outer[data-lg-slide-type='video'] .lg-actual-size,
|
||||
.lg-outer[data-lg-slide-type='video'] .lg-zoom-out, .lg-outer[data-lg-slide-type='iframe'] .lg-zoom-in,
|
||||
.lg-outer[data-lg-slide-type='iframe'] .lg-actual-size,
|
||||
.lg-outer[data-lg-slide-type='iframe'] .lg-zoom-out, .lg-outer.lg-first-slide-loading .lg-zoom-in,
|
||||
.lg-outer.lg-first-slide-loading .lg-actual-size,
|
||||
.lg-outer.lg-first-slide-loading .lg-zoom-out {
|
||||
opacity: 0.75;
|
||||
pointer-events: none;
|
||||
}
|
||||
721
photologue/static/lightgallery/css/lightgallery.css
Normal file
721
photologue/static/lightgallery/css/lightgallery.css
Normal file
|
|
@ -0,0 +1,721 @@
|
|||
@font-face {
|
||||
font-family: 'lg';
|
||||
src: url("../fonts/lg.woff2?io9a6k") format("woff2"), url("../fonts/lg.ttf?io9a6k") format("truetype"), url("../fonts/lg.woff?io9a6k") format("woff"), url("../fonts/lg.svg?io9a6k#lg") format("svg");
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-display: block;
|
||||
}
|
||||
|
||||
.lg-icon {
|
||||
/* use !important to prevent issues with browser extensions that change fonts */
|
||||
font-family: 'lg' !important;
|
||||
speak: never;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
font-variant: normal;
|
||||
text-transform: none;
|
||||
line-height: 1;
|
||||
/* Better Font Rendering =========== */
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.lg-container {
|
||||
font-family: system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', 'Liberation Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
|
||||
}
|
||||
|
||||
.lg-next,
|
||||
.lg-prev {
|
||||
background-color: rgba(0, 0, 0, 0.45);
|
||||
border-radius: 2px;
|
||||
color: #999;
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
font-size: 22px;
|
||||
margin-top: -10px;
|
||||
padding: 8px 10px 9px;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
z-index: 1080;
|
||||
outline: none;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.lg-next.disabled,
|
||||
.lg-prev.disabled {
|
||||
opacity: 0 !important;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.lg-next:hover:not(.disabled),
|
||||
.lg-prev:hover:not(.disabled) {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.lg-single-item .lg-next, .lg-single-item
|
||||
.lg-prev {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.lg-next {
|
||||
right: 20px;
|
||||
}
|
||||
|
||||
.lg-next:before {
|
||||
content: '\e095';
|
||||
}
|
||||
|
||||
.lg-prev {
|
||||
left: 20px;
|
||||
}
|
||||
|
||||
.lg-prev:after {
|
||||
content: '\e094';
|
||||
}
|
||||
|
||||
@-webkit-keyframes lg-right-end {
|
||||
0% {
|
||||
left: 0;
|
||||
}
|
||||
50% {
|
||||
left: -30px;
|
||||
}
|
||||
100% {
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@-moz-keyframes lg-right-end {
|
||||
0% {
|
||||
left: 0;
|
||||
}
|
||||
50% {
|
||||
left: -30px;
|
||||
}
|
||||
100% {
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@-ms-keyframes lg-right-end {
|
||||
0% {
|
||||
left: 0;
|
||||
}
|
||||
50% {
|
||||
left: -30px;
|
||||
}
|
||||
100% {
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes lg-right-end {
|
||||
0% {
|
||||
left: 0;
|
||||
}
|
||||
50% {
|
||||
left: -30px;
|
||||
}
|
||||
100% {
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes lg-left-end {
|
||||
0% {
|
||||
left: 0;
|
||||
}
|
||||
50% {
|
||||
left: 30px;
|
||||
}
|
||||
100% {
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@-moz-keyframes lg-left-end {
|
||||
0% {
|
||||
left: 0;
|
||||
}
|
||||
50% {
|
||||
left: 30px;
|
||||
}
|
||||
100% {
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@-ms-keyframes lg-left-end {
|
||||
0% {
|
||||
left: 0;
|
||||
}
|
||||
50% {
|
||||
left: 30px;
|
||||
}
|
||||
100% {
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes lg-left-end {
|
||||
0% {
|
||||
left: 0;
|
||||
}
|
||||
50% {
|
||||
left: 30px;
|
||||
}
|
||||
100% {
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.lg-outer.lg-right-end .lg-object {
|
||||
-webkit-animation: lg-right-end 0.3s;
|
||||
-o-animation: lg-right-end 0.3s;
|
||||
animation: lg-right-end 0.3s;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.lg-outer.lg-left-end .lg-object {
|
||||
-webkit-animation: lg-left-end 0.3s;
|
||||
-o-animation: lg-left-end 0.3s;
|
||||
animation: lg-left-end 0.3s;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.lg-toolbar {
|
||||
z-index: 1082;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.lg-media-overlap .lg-toolbar {
|
||||
background-image: linear-gradient(0deg, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.4));
|
||||
}
|
||||
|
||||
.lg-toolbar .lg-icon {
|
||||
color: #999;
|
||||
cursor: pointer;
|
||||
float: right;
|
||||
font-size: 24px;
|
||||
height: 47px;
|
||||
line-height: 27px;
|
||||
padding: 10px 0;
|
||||
text-align: center;
|
||||
width: 50px;
|
||||
text-decoration: none !important;
|
||||
outline: medium none;
|
||||
will-change: color;
|
||||
-webkit-transition: color 0.2s linear;
|
||||
-o-transition: color 0.2s linear;
|
||||
transition: color 0.2s linear;
|
||||
background: none;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.lg-toolbar .lg-icon.lg-icon-18 {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.lg-toolbar .lg-icon:hover {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.lg-toolbar .lg-close:after {
|
||||
content: '\e070';
|
||||
}
|
||||
|
||||
.lg-toolbar .lg-maximize {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
.lg-toolbar .lg-maximize:after {
|
||||
content: '\e90a';
|
||||
}
|
||||
|
||||
.lg-toolbar .lg-download:after {
|
||||
content: '\e0f2';
|
||||
}
|
||||
|
||||
.lg-sub-html {
|
||||
color: #eee;
|
||||
font-size: 16px;
|
||||
padding: 10px 40px;
|
||||
text-align: center;
|
||||
z-index: 1080;
|
||||
opacity: 0;
|
||||
-webkit-transition: opacity 0.2s ease-out 0s;
|
||||
-o-transition: opacity 0.2s ease-out 0s;
|
||||
transition: opacity 0.2s ease-out 0s;
|
||||
}
|
||||
|
||||
.lg-sub-html h4 {
|
||||
margin: 0;
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.lg-sub-html p {
|
||||
font-size: 12px;
|
||||
margin: 5px 0 0;
|
||||
}
|
||||
|
||||
.lg-sub-html a {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.lg-sub-html a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.lg-media-overlap .lg-sub-html {
|
||||
background-image: linear-gradient(180deg, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.6));
|
||||
}
|
||||
|
||||
.lg-item .lg-sub-html {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.lg-error-msg {
|
||||
font-size: 14px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.lg-counter {
|
||||
color: #999;
|
||||
display: inline-block;
|
||||
font-size: 16px;
|
||||
padding-left: 20px;
|
||||
padding-top: 12px;
|
||||
height: 47px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.lg-closing .lg-toolbar,
|
||||
.lg-closing .lg-prev,
|
||||
.lg-closing .lg-next,
|
||||
.lg-closing .lg-sub-html {
|
||||
opacity: 0;
|
||||
-webkit-transition: -webkit-transform 0.08 cubic-bezier(0, 0, 0.25, 1) 0s, opacity 0.08 cubic-bezier(0, 0, 0.25, 1) 0s, color 0.08 linear;
|
||||
-moz-transition: -moz-transform 0.08 cubic-bezier(0, 0, 0.25, 1) 0s, opacity 0.08 cubic-bezier(0, 0, 0.25, 1) 0s, color 0.08 linear;
|
||||
-o-transition: -o-transform 0.08 cubic-bezier(0, 0, 0.25, 1) 0s, opacity 0.08 cubic-bezier(0, 0, 0.25, 1) 0s, color 0.08 linear;
|
||||
transition: transform 0.08 cubic-bezier(0, 0, 0.25, 1) 0s, opacity 0.08 cubic-bezier(0, 0, 0.25, 1) 0s, color 0.08 linear;
|
||||
}
|
||||
|
||||
body:not(.lg-from-hash) .lg-outer.lg-start-zoom .lg-object {
|
||||
opacity: 0;
|
||||
will-change: opacity;
|
||||
-webkit-transition: opacity 250ms cubic-bezier(0, 0, 0.25, 1) !important;
|
||||
-moz-transition: opacity 250ms cubic-bezier(0, 0, 0.25, 1) !important;
|
||||
-o-transition: opacity 250ms cubic-bezier(0, 0, 0.25, 1) !important;
|
||||
transition: opacity 250ms cubic-bezier(0, 0, 0.25, 1) !important;
|
||||
}
|
||||
|
||||
body:not(.lg-from-hash) .lg-outer.lg-start-zoom .lg-item.lg-complete .lg-object {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.lg-group:after {
|
||||
content: '';
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.lg-container {
|
||||
display: none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.lg-container.lg-show {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.lg-on {
|
||||
scroll-behavior: unset;
|
||||
}
|
||||
|
||||
.lg-toolbar,
|
||||
.lg-prev,
|
||||
.lg-next,
|
||||
.lg-pager-outer,
|
||||
.lg-hide-sub-html .lg-sub-html {
|
||||
opacity: 0;
|
||||
will-change: transform, opacity;
|
||||
-webkit-transition: -webkit-transform 0.25s cubic-bezier(0, 0, 0.25, 1) 0s, opacity 0.25s cubic-bezier(0, 0, 0.25, 1) 0s;
|
||||
-moz-transition: -moz-transform 0.25s cubic-bezier(0, 0, 0.25, 1) 0s, opacity 0.25s cubic-bezier(0, 0, 0.25, 1) 0s;
|
||||
-o-transition: -o-transform 0.25s cubic-bezier(0, 0, 0.25, 1) 0s, opacity 0.25s cubic-bezier(0, 0, 0.25, 1) 0s;
|
||||
transition: transform 0.25s cubic-bezier(0, 0, 0.25, 1) 0s, opacity 0.25s cubic-bezier(0, 0, 0.25, 1) 0s;
|
||||
}
|
||||
|
||||
.lg-show-in .lg-toolbar,
|
||||
.lg-show-in .lg-prev,
|
||||
.lg-show-in .lg-next,
|
||||
.lg-show-in .lg-pager-outer {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.lg-show-in.lg-hide-sub-html .lg-sub-html {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.lg-show-in .lg-hide-items .lg-prev {
|
||||
opacity: 0;
|
||||
-webkit-transform: translate3d(-10px, 0, 0);
|
||||
transform: translate3d(-10px, 0, 0);
|
||||
}
|
||||
|
||||
.lg-show-in .lg-hide-items .lg-next {
|
||||
opacity: 0;
|
||||
-webkit-transform: translate3d(10px, 0, 0);
|
||||
transform: translate3d(10px, 0, 0);
|
||||
}
|
||||
|
||||
.lg-show-in .lg-hide-items .lg-toolbar {
|
||||
opacity: 0;
|
||||
-webkit-transform: translate3d(0, -10px, 0);
|
||||
transform: translate3d(0, -10px, 0);
|
||||
}
|
||||
|
||||
.lg-show-in .lg-hide-items.lg-hide-sub-html .lg-sub-html {
|
||||
opacity: 0;
|
||||
-webkit-transform: translate3d(0, 20px, 0);
|
||||
transform: translate3d(0, 20px, 0);
|
||||
}
|
||||
|
||||
.lg-outer {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 1050;
|
||||
text-align: left;
|
||||
opacity: 0.001;
|
||||
outline: none;
|
||||
will-change: auto;
|
||||
overflow: hidden;
|
||||
-webkit-transition: opacity 0.15s ease 0s;
|
||||
-o-transition: opacity 0.15s ease 0s;
|
||||
transition: opacity 0.15s ease 0s;
|
||||
}
|
||||
|
||||
.lg-outer * {
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.lg-outer.lg-zoom-from-image {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.lg-outer.lg-visible {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.lg-outer.lg-css3 .lg-item:not(.lg-start-end-progress).lg-prev-slide, .lg-outer.lg-css3 .lg-item:not(.lg-start-end-progress).lg-next-slide, .lg-outer.lg-css3 .lg-item:not(.lg-start-end-progress).lg-current {
|
||||
-webkit-transition-duration: inherit !important;
|
||||
transition-duration: inherit !important;
|
||||
-webkit-transition-timing-function: inherit !important;
|
||||
transition-timing-function: inherit !important;
|
||||
}
|
||||
|
||||
.lg-outer.lg-css3.lg-dragging .lg-item.lg-prev-slide, .lg-outer.lg-css3.lg-dragging .lg-item.lg-next-slide, .lg-outer.lg-css3.lg-dragging .lg-item.lg-current {
|
||||
-webkit-transition-duration: 0s !important;
|
||||
transition-duration: 0s !important;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.lg-outer.lg-grab img.lg-object {
|
||||
cursor: -webkit-grab;
|
||||
cursor: -moz-grab;
|
||||
cursor: -o-grab;
|
||||
cursor: -ms-grab;
|
||||
cursor: grab;
|
||||
}
|
||||
|
||||
.lg-outer.lg-grabbing img.lg-object {
|
||||
cursor: move;
|
||||
cursor: -webkit-grabbing;
|
||||
cursor: -moz-grabbing;
|
||||
cursor: -o-grabbing;
|
||||
cursor: -ms-grabbing;
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
.lg-outer .lg-content {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.lg-outer .lg-inner {
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
-webkit-transition: opacity 0s;
|
||||
-o-transition: opacity 0s;
|
||||
transition: opacity 0s;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.lg-outer .lg-item {
|
||||
will-change: transform, opacity;
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.lg-outer .lg-item:not(.lg-start-end-progress) {
|
||||
background: url("../images/loading.gif") no-repeat scroll center center transparent;
|
||||
}
|
||||
|
||||
.lg-outer.lg-css3 .lg-prev-slide,
|
||||
.lg-outer.lg-css3 .lg-current,
|
||||
.lg-outer.lg-css3 .lg-next-slide {
|
||||
display: inline-block !important;
|
||||
}
|
||||
|
||||
.lg-outer.lg-css .lg-current {
|
||||
display: inline-block !important;
|
||||
}
|
||||
|
||||
.lg-outer .lg-item,
|
||||
.lg-outer .lg-img-wrap {
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.lg-outer .lg-item:before,
|
||||
.lg-outer .lg-img-wrap:before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.lg-outer .lg-img-wrap {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
white-space: nowrap;
|
||||
font-size: 0;
|
||||
}
|
||||
|
||||
.lg-outer .lg-item.lg-complete {
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
.lg-outer .lg-item.lg-current {
|
||||
z-index: 1060;
|
||||
}
|
||||
|
||||
.lg-outer .lg-object {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
width: auto;
|
||||
height: auto;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.lg-outer.lg-show-after-load .lg-item .lg-object,
|
||||
.lg-outer.lg-show-after-load .lg-item .lg-video-play-button {
|
||||
opacity: 0;
|
||||
will-change: opacity;
|
||||
-webkit-transition: opacity 0.15s ease 0s;
|
||||
-o-transition: opacity 0.15s ease 0s;
|
||||
transition: opacity 0.15s ease 0s;
|
||||
}
|
||||
|
||||
.lg-outer.lg-show-after-load .lg-item.lg-zoom-from-image .lg-object,
|
||||
.lg-outer.lg-show-after-load .lg-item.lg-zoom-from-image .lg-video-play-button {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.lg-outer.lg-show-after-load .lg-item.lg-complete .lg-object,
|
||||
.lg-outer.lg-show-after-load .lg-item.lg-complete .lg-video-play-button {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.lg-outer .lg-empty-html.lg-sub-html,
|
||||
.lg-outer .lg-empty-html .lg-sub-html {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.lg-outer.lg-hide-download .lg-download {
|
||||
opacity: 0.75;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.lg-outer .lg-first-slide .lg-dummy-img {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
}
|
||||
|
||||
.lg-outer.lg-components-open:not(.lg-zoomed) .lg-components {
|
||||
-webkit-transform: translate3d(0, 0%, 0);
|
||||
transform: translate3d(0, 0%, 0);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.lg-outer.lg-components-open:not(.lg-zoomed) .lg-sub-html {
|
||||
opacity: 1;
|
||||
transition: opacity 0.2s ease-out 0.15s;
|
||||
}
|
||||
|
||||
.lg-backdrop {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 1040;
|
||||
background-color: #000;
|
||||
opacity: 0;
|
||||
will-change: auto;
|
||||
-webkit-transition: opacity 333ms ease-in 0s;
|
||||
-o-transition: opacity 333ms ease-in 0s;
|
||||
transition: opacity 333ms ease-in 0s;
|
||||
}
|
||||
|
||||
.lg-backdrop.in {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.lg-css3.lg-no-trans .lg-prev-slide,
|
||||
.lg-css3.lg-no-trans .lg-next-slide,
|
||||
.lg-css3.lg-no-trans .lg-current {
|
||||
-webkit-transition: none 0s ease 0s !important;
|
||||
-moz-transition: none 0s ease 0s !important;
|
||||
-o-transition: none 0s ease 0s !important;
|
||||
transition: none 0s ease 0s !important;
|
||||
}
|
||||
|
||||
.lg-css3.lg-use-css3 .lg-item {
|
||||
-webkit-backface-visibility: hidden;
|
||||
-moz-backface-visibility: hidden;
|
||||
backface-visibility: hidden;
|
||||
}
|
||||
|
||||
.lg-css3.lg-fade .lg-item {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.lg-css3.lg-fade .lg-item.lg-current {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.lg-css3.lg-fade .lg-item.lg-prev-slide, .lg-css3.lg-fade .lg-item.lg-next-slide, .lg-css3.lg-fade .lg-item.lg-current {
|
||||
-webkit-transition: opacity 0.1s ease 0s;
|
||||
-moz-transition: opacity 0.1s ease 0s;
|
||||
-o-transition: opacity 0.1s ease 0s;
|
||||
transition: opacity 0.1s ease 0s;
|
||||
}
|
||||
|
||||
.lg-css3.lg-use-css3 .lg-item.lg-start-progress {
|
||||
-webkit-transition: -webkit-transform 1s cubic-bezier(0.175, 0.885, 0.32, 1.275) 0s;
|
||||
-moz-transition: -moz-transform 1s cubic-bezier(0.175, 0.885, 0.32, 1.275) 0s;
|
||||
-o-transition: -o-transform 1s cubic-bezier(0.175, 0.885, 0.32, 1.275) 0s;
|
||||
transition: transform 1s cubic-bezier(0.175, 0.885, 0.32, 1.275) 0s;
|
||||
}
|
||||
|
||||
.lg-css3.lg-use-css3 .lg-item.lg-start-end-progress {
|
||||
-webkit-transition: -webkit-transform 1s cubic-bezier(0, 0, 0.25, 1) 0s;
|
||||
-moz-transition: -moz-transform 1s cubic-bezier(0, 0, 0.25, 1) 0s;
|
||||
-o-transition: -o-transform 1s cubic-bezier(0, 0, 0.25, 1) 0s;
|
||||
transition: transform 1s cubic-bezier(0, 0, 0.25, 1) 0s;
|
||||
}
|
||||
|
||||
.lg-css3.lg-slide.lg-use-css3 .lg-item {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.lg-css3.lg-slide.lg-use-css3 .lg-item.lg-prev-slide {
|
||||
-webkit-transform: translate3d(-100%, 0, 0);
|
||||
transform: translate3d(-100%, 0, 0);
|
||||
}
|
||||
|
||||
.lg-css3.lg-slide.lg-use-css3 .lg-item.lg-next-slide {
|
||||
-webkit-transform: translate3d(100%, 0, 0);
|
||||
transform: translate3d(100%, 0, 0);
|
||||
}
|
||||
|
||||
.lg-css3.lg-slide.lg-use-css3 .lg-item.lg-current {
|
||||
-webkit-transform: translate3d(0, 0, 0);
|
||||
transform: translate3d(0, 0, 0);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.lg-css3.lg-slide.lg-use-css3 .lg-item.lg-prev-slide, .lg-css3.lg-slide.lg-use-css3 .lg-item.lg-next-slide, .lg-css3.lg-slide.lg-use-css3 .lg-item.lg-current {
|
||||
-webkit-transition: -webkit-transform 1s cubic-bezier(0, 0, 0.25, 1) 0s, opacity 0.1s ease 0s;
|
||||
-moz-transition: -moz-transform 1s cubic-bezier(0, 0, 0.25, 1) 0s, opacity 0.1s ease 0s;
|
||||
-o-transition: -o-transform 1s cubic-bezier(0, 0, 0.25, 1) 0s, opacity 0.1s ease 0s;
|
||||
transition: transform 1s cubic-bezier(0, 0, 0.25, 1) 0s, opacity 0.1s ease 0s;
|
||||
}
|
||||
|
||||
.lg-container {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.lg-container.lg-show {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.lg-container.lg-dragging-vertical .lg-backdrop {
|
||||
-webkit-transition-duration: 0s !important;
|
||||
transition-duration: 0s !important;
|
||||
}
|
||||
|
||||
.lg-container.lg-dragging-vertical .lg-css3 .lg-item.lg-current {
|
||||
-webkit-transition-duration: 0s !important;
|
||||
transition-duration: 0s !important;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.lg-inline .lg-backdrop,
|
||||
.lg-inline .lg-outer {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.lg-inline .lg-backdrop {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.lg-inline .lg-outer {
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.lg-inline .lg-maximize:after {
|
||||
content: '\e909';
|
||||
}
|
||||
|
||||
.lg-components {
|
||||
-webkit-transform: translate3d(0, 100%, 0);
|
||||
transform: translate3d(0, 100%, 0);
|
||||
will-change: transform;
|
||||
-webkit-transition: -webkit-transform 0.35s ease-out 0s;
|
||||
-moz-transition: -moz-transform 0.35s ease-out 0s;
|
||||
-o-transition: -o-transform 0.35s ease-out 0s;
|
||||
transition: transform 0.35s ease-out 0s;
|
||||
z-index: 1080;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
}
|
||||
54
photologue/static/lightgallery/fonts/lg.svg
Normal file
54
photologue/static/lightgallery/fonts/lg.svg
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<metadata>
|
||||
<json>
|
||||
<![CDATA[
|
||||
{
|
||||
"fontFamily": "lg",
|
||||
"majorVersion": 2,
|
||||
"minorVersion": 0,
|
||||
"fontURL": "",
|
||||
"copyright": "",
|
||||
"license": "",
|
||||
"licenseURL": "",
|
||||
"description": "Font generated by IcoMoon.",
|
||||
"version": "Version 2.0",
|
||||
"fontId": "lg",
|
||||
"psName": "lg",
|
||||
"subFamily": "Regular",
|
||||
"fullName": "lg"
|
||||
}
|
||||
]]>
|
||||
</json>
|
||||
</metadata>
|
||||
<defs>
|
||||
<font id="lg" horiz-adv-x="1024">
|
||||
<font-face units-per-em="1024" ascent="960" descent="-64" />
|
||||
<missing-glyph horiz-adv-x="1024" />
|
||||
<glyph unicode=" " horiz-adv-x="512" d="" />
|
||||
<glyph unicode="" glyph-name="pause_circle_outline" data-tags="pause_circle_outline" d="M554 256.667v340h86v-340h-86zM512 84.667q140 0 241 101t101 241-101 241-241 101-241-101-101-241 101-241 241-101zM512 852.667q176 0 301-125t125-301-125-301-301-125-301 125-125 301 125 301 301 125zM384 256.667v340h86v-340h-86z" />
|
||||
<glyph unicode="" glyph-name="play_circle_outline" data-tags="play_circle_outline" d="M512 84.667q140 0 241 101t101 241-101 241-241 101-241-101-101-241 101-241 241-101zM512 852.667q176 0 301-125t125-301-125-301-301-125-301 125-125 301 125 301 301 125zM426 234.667v384l256-192z" />
|
||||
<glyph unicode="" glyph-name="stack-2" data-tags="stack-2" d="M384 853.334h426.667q53 0 90.5-37.5t37.5-90.5v-426.667q0-53-37.5-90.5t-90.5-37.5h-426.667q-53 0-90.5 37.5t-37.5 90.5v426.667q0 53 37.5 90.5t90.5 37.5zM170.667 675.334v-547.333q0-17.667 12.5-30.167t30.167-12.5h547.333q-13.333-37.667-46.333-61.5t-74.333-23.833h-426.667q-53 0-90.5 37.5t-37.5 90.5v426.667q0 41.333 23.833 74.333t61.5 46.333zM810.667 768h-426.667q-17.667 0-30.167-12.5t-12.5-30.167v-426.667q0-17.667 12.5-30.167t30.167-12.5h426.667q17.667 0 30.167 12.5t12.5 30.167v426.667q0 17.667-12.5 30.167t-30.167 12.5z" />
|
||||
<glyph unicode="" glyph-name="clear" data-tags="clear" d="M810 664.667l-238-238 238-238-60-60-238 238-238-238-60 60 238 238-238 238 60 60 238-238 238 238z" />
|
||||
<glyph unicode="" glyph-name="arrow-left" data-tags="arrow-left" d="M426.667 768q17.667 0 30.167-12.5t12.5-30.167q0-18-12.667-30.333l-225.667-225.667h665q17.667 0 30.167-12.5t12.5-30.167-12.5-30.167-30.167-12.5h-665l225.667-225.667q12.667-12.333 12.667-30.333 0-17.667-12.5-30.167t-30.167-12.5q-18 0-30.333 12.333l-298.667 298.667q-12.333 13-12.333 30.333t12.333 30.333l298.667 298.667q12.667 12.333 30.333 12.333z" />
|
||||
<glyph unicode="" glyph-name="arrow-right" data-tags="arrow-right" d="M597.333 768q18 0 30.333-12.333l298.667-298.667q12.333-12.333 12.333-30.333t-12.333-30.333l-298.667-298.667q-12.333-12.333-30.333-12.333-18.333 0-30.5 12.167t-12.167 30.5q0 18 12.333 30.333l226 225.667h-665q-17.667 0-30.167 12.5t-12.5 30.167 12.5 30.167 30.167 12.5h665l-226 225.667q-12.333 12.333-12.333 30.333 0 18.333 12.167 30.5t30.5 12.167z" />
|
||||
<glyph unicode="" glyph-name="vertical_align_bottom" data-tags="vertical_align_bottom" d="M170 128.667h684v-86h-684v86zM682 384.667l-170-172-170 172h128v426h84v-426h128z" />
|
||||
<glyph unicode="" glyph-name="apps" data-tags="apps" d="M682 84.667v172h172v-172h-172zM682 340.667v172h172v-172h-172zM426 596.667v172h172v-172h-172zM682 768.667h172v-172h-172v172zM426 340.667v172h172v-172h-172zM170 340.667v172h172v-172h-172zM170 84.667v172h172v-172h-172zM426 84.667v172h172v-172h-172zM170 596.667v172h172v-172h-172z" />
|
||||
<glyph unicode="" glyph-name="fullscreen" data-tags="fullscreen" d="M598 724.667h212v-212h-84v128h-128v84zM726 212.667v128h84v-212h-212v84h128zM214 512.667v212h212v-84h-128v-128h-84zM298 340.667v-128h128v-84h-212v212h84z" />
|
||||
<glyph unicode="" glyph-name="fullscreen_exit" data-tags="fullscreen_exit" d="M682 596.667h128v-84h-212v212h84v-128zM598 128.667v212h212v-84h-128v-128h-84zM342 596.667v128h84v-212h-212v84h128zM214 256.667v84h212v-212h-84v128h-128z" />
|
||||
<glyph unicode="" glyph-name="zoom_in" data-tags="zoom_in" d="M512 512.667h-86v-86h-42v86h-86v42h86v86h42v-86h86v-42zM406 340.667q80 0 136 56t56 136-56 136-136 56-136-56-56-136 56-136 136-56zM662 340.667l212-212-64-64-212 212v34l-12 12q-76-66-180-66-116 0-197 80t-81 196 81 197 197 81 196-81 80-197q0-104-66-180l12-12h34z" />
|
||||
<glyph unicode="" glyph-name="zoom_out" data-tags="zoom_out" d="M298 554.667h214v-42h-214v42zM406 340.667q80 0 136 56t56 136-56 136-136 56-136-56-56-136 56-136 136-56zM662 340.667l212-212-64-64-212 212v34l-12 12q-76-66-180-66-116 0-197 80t-81 196 81 197 197 81 196-81 80-197q0-104-66-180l12-12h34z" />
|
||||
<glyph unicode="" glyph-name="share" data-tags="share" d="M768 252.667c68 0 124-56 124-124s-56-126-124-126-124 58-124 126c0 10 0 20 2 28l-302 176c-24-22-54-34-88-34-70 0-128 58-128 128s58 128 128 128c34 0 64-12 88-34l300 174c-2 10-4 20-4 30 0 70 58 128 128 128s128-58 128-128-58-128-128-128c-34 0-64 14-88 36l-300-176c2-10 4-20 4-30s-2-20-4-30l304-176c22 20 52 32 84 32z" />
|
||||
<glyph unicode="" glyph-name="rotate_left" data-tags="rotate_left" d="M554 764.667q126-16 213-112t87-226-87-226-213-112v86q92 16 153 87t61 165-61 165-153 87v-166l-194 190 194 194v-132zM302 156.667l62 62q46-34 106-44v-86q-96 12-168 68zM260 384.667q10-58 42-106l-60-60q-56 74-68 166h86zM304 574.667q-36-52-44-106h-86q12 90 70 166z" />
|
||||
<glyph unicode="" glyph-name="rotate_right" data-tags="rotate_right" d="M720 278.667q34 46 44 106h86q-12-92-68-166zM554 174.667q60 10 106 44l62-62q-72-56-168-68v86zM850 468.667h-86q-10 60-44 106l62 60q58-72 68-166zM664 702.667l-194-190v166q-92-16-153-87t-61-165 61-165 153-87v-86q-126 16-213 112t-87 226 87 226 213 112v132z" />
|
||||
<glyph unicode="" glyph-name="swap_horiz" data-tags="swap_horiz" d="M896 554.667l-170-170v128h-300v84h300v128zM298 468.667v-128h300v-84h-300v-128l-170 170z" />
|
||||
<glyph unicode="" glyph-name="swap_vert" data-tags="swap_vert" d="M384 810.667l170-170h-128v-300h-84v300h-128zM682 212.667h128l-170-170-170 170h128v300h84v-300z" />
|
||||
<glyph unicode="" glyph-name="facebook-with-circle" data-tags="facebook-with-circle" d="M512 952.32c-271.462 0-491.52-220.058-491.52-491.52s220.058-491.52 491.52-491.52 491.52 220.058 491.52 491.52-220.058 491.52-491.52 491.52zM628.429 612.659h-73.882c-8.755 0-18.483-11.52-18.483-26.829v-53.35h92.416l-13.978-76.083h-78.438v-228.403h-87.194v228.403h-79.104v76.083h79.104v44.749c0 64.205 44.544 116.378 105.677 116.378h73.882v-80.947z" />
|
||||
<glyph unicode="" glyph-name="google-with-circle" data-tags="google+-with-circle" d="M512 952.32c-271.462 0-491.52-220.058-491.52-491.52s220.058-491.52 491.52-491.52 491.52 220.058 491.52 491.52-220.058 491.52-491.52 491.52zM483.686 249.805c-30.874-15.002-64.102-16.589-76.954-16.589-2.458 0-3.84 0-3.84 0s-1.178 0-2.765 0c-20.070 0-119.962 4.608-119.962 95.59 0 89.395 108.8 96.41 142.131 96.41h0.87c-19.251 25.702-15.258 51.61-15.258 51.61-1.69-0.102-4.147-0.205-7.168-0.205-12.544 0-36.762 1.997-57.549 15.411-25.498 16.384-38.4 44.288-38.4 82.893 0 109.107 119.142 113.51 120.32 113.613h118.989v-2.611c0-13.312-23.91-15.923-40.192-18.125-5.53-0.819-16.64-1.894-19.763-3.482 30.157-16.128 35.021-41.421 35.021-79.104 0-42.906-16.794-65.587-34.611-81.51-11.059-9.882-19.712-17.613-19.712-28.006 0-10.189 11.878-20.582 25.702-32.717 22.579-19.917 53.555-47.002 53.555-92.723 0-47.258-20.326-81.050-60.416-100.454zM742.4 460.8h-76.8v-76.8h-51.2v76.8h-76.8v51.2h76.8v76.8h51.2v-76.8h76.8v-51.2zM421.018 401.92c-2.662 0-5.325-0.102-8.038-0.307-22.733-1.69-43.725-10.189-58.88-24.013-15.053-13.619-22.733-30.822-21.658-48.179 2.304-36.403 41.37-57.702 88.832-54.323 46.694 3.379 77.824 30.31 75.571 66.714-2.15 34.202-31.898 60.109-75.827 60.109zM465.766 599.808c-12.39 43.52-32.358 56.422-63.386 56.422-3.328 0-6.707-0.512-9.933-1.382-13.466-3.84-24.166-15.053-30.106-31.744-6.093-16.896-6.451-34.509-1.229-54.579 9.472-35.891 34.97-61.901 60.672-61.901 3.379 0 6.758 0.41 9.933 1.382 28.109 7.885 45.722 50.79 34.048 91.802z" />
|
||||
<glyph unicode="" glyph-name="pinterest-with-circle" data-tags="pinterest-with-circle" d="M512 952.32c-271.462 0-491.52-220.058-491.52-491.52s220.058-491.52 491.52-491.52 491.52 220.058 491.52 491.52-220.058 491.52-491.52 491.52zM545.638 344.32c-31.539 2.406-44.749 18.022-69.427 32.973-13.568-71.219-30.157-139.52-79.309-175.206-15.206 107.725 22.221 188.518 39.629 274.381-29.645 49.92 3.533 150.323 66.099 125.645 76.954-30.515-66.662-185.6 29.747-205.005 100.659-20.173 141.773 174.694 79.36 237.978-90.214 91.494-262.502 2.099-241.306-128.87 5.12-32 38.246-41.728 13.21-85.914-57.702 12.8-74.957 58.317-72.704 118.989 3.533 99.328 89.242 168.909 175.155 178.483 108.698 12.083 210.688-39.885 224.819-142.182 15.821-115.405-49.101-240.282-165.274-231.27z" />
|
||||
<glyph unicode="" glyph-name="twitter-with-circle" data-tags="twitter-with-circle" d="M512 952.32c-271.462 0-491.52-220.058-491.52-491.52s220.058-491.52 491.52-491.52 491.52 220.058 491.52 491.52-220.058 491.52-491.52 491.52zM711.936 549.683c0.205-4.198 0.256-8.397 0.256-12.493 0-128-97.331-275.507-275.405-275.507-54.682 0-105.574 15.974-148.378 43.52 7.526-0.922 15.258-1.28 23.091-1.28 45.363 0 87.091 15.411 120.218 41.421-42.342 0.819-78.080 28.774-90.419 67.174 5.888-1.075 11.93-1.69 18.176-1.69 8.806 0 17.408 1.178 25.498 3.379-44.288 8.909-77.67 48.026-77.67 94.925v1.178c13.056-7.219 28.006-11.622 43.878-12.134-26.010 17.408-43.059 47.002-43.059 80.64 0 17.715 4.762 34.406 13.107 48.691 47.77-58.573 119.040-97.075 199.526-101.222-1.69 7.117-2.509 14.49-2.509 22.118 0 53.402 43.315 96.819 96.819 96.819 27.802 0 52.992-11.776 70.656-30.618 22.067 4.403 42.752 12.39 61.44 23.501-7.219-22.579-22.528-41.574-42.547-53.606 19.61 2.406 38.246 7.578 55.603 15.309-12.954-19.405-29.389-36.506-48.282-50.125z" />
|
||||
<glyph unicode="" glyph-name="message-circle" data-tags="message-circle" d="M938.667 448.128v21.205c0 0.725-0.043 1.621-0.085 2.475-5.803 99.755-47.488 190.336-112.725 258.176-68.352 71.125-162.731 117.419-268.843 123.264-0.683 0.043-1.536 0.085-2.347 0.085h-20.864c-59.947 0.683-122.965-13.227-181.931-43.008-52.181-26.496-97.749-63.488-133.931-108.16-56.405-69.717-89.899-158.080-89.941-253.696-0.597-54.4 10.795-111.36 35.157-165.419l-75.605-226.859c-2.816-8.363-3.072-17.835 0-26.965 7.467-22.357 31.616-34.432 53.973-26.965l226.731 75.563c49.493-22.485 105.984-35.243 165.376-35.115 58.539 0.384 115.797 13.141 168.149 36.949 81.579 37.163 151.040 101.248 193.749 186.667 27.477 53.291 43.307 115.84 43.136 181.803zM853.333 447.872c0.128-52.267-12.459-101.333-33.664-142.464-34.176-68.352-88.832-118.827-153.259-148.139-41.387-18.859-86.827-28.971-133.376-29.269-52.096-0.128-101.163 12.459-142.293 33.664-10.624 5.504-22.528 6.059-33.067 2.56l-162.261-54.101 54.101 162.261c3.755 11.221 2.56 22.912-2.389 32.725-23.552 46.677-34.304 96.171-33.792 142.421 0.043 76.331 26.411 145.92 70.955 200.917 28.629 35.371 64.768 64.725 106.24 85.76 46.592 23.552 96.085 34.304 142.336 33.792h19.456c83.712-4.565 158.037-41.003 212.011-97.152 51.285-53.376 84.139-124.416 89.003-202.795z" />
|
||||
<glyph unicode="" glyph-name="maximize-2" data-tags="maximize-2" d="M793.003 768l-225.835-225.835c-16.683-16.683-16.683-43.691 0-60.331s43.691-16.683 60.331 0l225.835 225.835v-153.003c0-23.552 19.115-42.667 42.667-42.667s42.667 19.115 42.667 42.667v256c0 5.803-1.152 11.307-3.243 16.341s-5.163 9.728-9.216 13.781c-0.043 0.043-0.043 0.043-0.085 0.085-3.925 3.925-8.619 7.083-13.781 9.216-5.035 2.091-10.539 3.243-16.341 3.243h-256c-23.552 0-42.667-19.115-42.667-42.667s19.115-42.667 42.667-42.667zM230.997 85.334l225.835 225.835c16.683 16.683 16.683 43.691 0 60.331s-43.691 16.683-60.331 0l-225.835-225.835v153.003c0 23.552-19.115 42.667-42.667 42.667s-42.667-19.115-42.667-42.667v-256c0-23.552 19.115-42.667 42.667-42.667h256c23.552 0 42.667 19.115 42.667 42.667s-19.115 42.667-42.667 42.667z" />
|
||||
<glyph unicode="" glyph-name="minimize-2" data-tags="minimize-2" d="M700.331 554.667l225.835 225.835c16.683 16.683 16.683 43.691 0 60.331s-43.691 16.683-60.331 0l-225.835-225.835v153.003c0 23.552-19.115 42.667-42.667 42.667s-42.667-19.115-42.667-42.667v-256c0-5.803 1.152-11.307 3.243-16.341s5.163-9.728 9.216-13.781c0.043-0.043 0.043-0.043 0.085-0.085 3.925-3.925 8.619-7.083 13.781-9.216 5.035-2.091 10.539-3.243 16.341-3.243h256c23.552 0 42.667 19.115 42.667 42.667s-19.115 42.667-42.667 42.667zM158.165 12.502l225.835 225.835v-153.003c0-23.552 19.115-42.667 42.667-42.667s42.667 19.115 42.667 42.667v256c0 5.803-1.152 11.307-3.243 16.341s-5.163 9.728-9.216 13.781c-0.043 0.043-0.043 0.043-0.085 0.085-4.096 4.053-8.789 7.125-13.781 9.216-5.035 2.091-10.539 3.243-16.341 3.243h-256c-23.552 0-42.667-19.115-42.667-42.667s19.115-42.667 42.667-42.667h153.003l-225.835-225.835c-16.683-16.683-16.683-43.691 0-60.331s43.691-16.683 60.331 0z" />
|
||||
</font></defs></svg>
|
||||
|
After Width: | Height: | Size: 12 KiB |
BIN
photologue/static/lightgallery/fonts/lg.ttf
Normal file
BIN
photologue/static/lightgallery/fonts/lg.ttf
Normal file
Binary file not shown.
BIN
photologue/static/lightgallery/fonts/lg.woff
Normal file
BIN
photologue/static/lightgallery/fonts/lg.woff
Normal file
Binary file not shown.
BIN
photologue/static/lightgallery/fonts/lg.woff2
Normal file
BIN
photologue/static/lightgallery/fonts/lg.woff2
Normal file
Binary file not shown.
BIN
photologue/static/lightgallery/images/loading.gif
Normal file
BIN
photologue/static/lightgallery/images/loading.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.1 KiB |
8
photologue/static/lightgallery/lightgallery.min.js
vendored
Normal file
8
photologue/static/lightgallery/lightgallery.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
26
photologue/static/lightgallery/plugins/admin/lg-admin.js
Normal file
26
photologue/static/lightgallery/plugins/admin/lg-admin.js
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Custom LightGallery plugin to add some buttons for administration
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
class lgAdmin {
|
||||
constructor(instance, $LG) {
|
||||
this.core = instance;
|
||||
this.$LG = $LG;
|
||||
return this;
|
||||
}
|
||||
|
||||
init() {
|
||||
this.core.$toolbar.append("<a href=\"#\" id=\"lg-admin\" class=\"lg-icon\">\uE033</a>");
|
||||
this.core.LGel.on("lgAfterSlide.admin", this.onAfterSlide.bind(this));
|
||||
}
|
||||
|
||||
onAfterSlide(event) {
|
||||
const photoId = this.core.galleryItems[event.detail.index].slideName;
|
||||
document.getElementById("lg-admin").href = `https://photos.crans.org/admin/photologue/photo/${photoId}/change/`;
|
||||
}
|
||||
|
||||
// Admin must have destroy prototype
|
||||
destroy() { }
|
||||
}
|
||||
8
photologue/static/lightgallery/plugins/hash/lg-hash.min.js
vendored
Normal file
8
photologue/static/lightgallery/plugins/hash/lg-hash.min.js
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
/**
|
||||
* lightgallery | 2.2.1 | September 4th 2021
|
||||
* http://www.lightgalleryjs.com/
|
||||
* Copyright (c) 2020 Sachin Neravath;
|
||||
* @license GPLv3
|
||||
*/
|
||||
|
||||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).lgHash=e()}(this,(function(){"use strict";var t=function(){return(t=Object.assign||function(t){for(var e,i=1,o=arguments.length;i<o;i++)for(var s in e=arguments[i])Object.prototype.hasOwnProperty.call(e,s)&&(t[s]=e[s]);return t}).apply(this,arguments)},e="lgAfterSlide",i="lgAfterClose",o={hash:!0,galleryId:"1",customSlideName:!1};return function(){function s(e,i){return this.core=e,this.$LG=i,this.settings=t(t({},o),this.core.settings),this}return s.prototype.init=function(){var t=this;this.settings.hash&&(this.oldHash=window.location.hash,setTimeout((function(){t.buildFromHash()}),100),this.core.LGel.on(e+".hash",this.onAfterSlide.bind(this)),this.core.LGel.on(i+".hash",this.onCloseAfter.bind(this)),this.$LG(window).on("hashchange.lg.hash.global"+this.core.lgId,this.onHashchange.bind(this)))},s.prototype.onAfterSlide=function(t){var e=this.core.galleryItems[t.detail.index].slideName;e=this.settings.customSlideName&&e||t.detail.index,history.replaceState?history.replaceState(null,"",window.location.pathname+window.location.search+"#lg="+this.settings.galleryId+"&slide="+e):window.location.hash="lg="+this.settings.galleryId+"&slide="+e},s.prototype.getIndexFromUrl=function(t){void 0===t&&(t=window.location.hash);var e=t.split("&slide=")[1],i=0;if(this.settings.customSlideName)for(var o=0;o<this.core.galleryItems.length;o++){if(this.core.galleryItems[o].slideName===e){i=o;break}}else i=parseInt(e,10);return isNaN(i)?0:i},s.prototype.buildFromHash=function(){var t=window.location.hash;if(t.indexOf("lg="+this.settings.galleryId)>0){this.$LG(document.body).addClass("lg-from-hash");var e=this.getIndexFromUrl(t);return this.core.openGallery(e),!0}},s.prototype.onCloseAfter=function(){this.oldHash&&this.oldHash.indexOf("lg="+this.settings.galleryId)<0?history.replaceState?history.replaceState(null,"",this.oldHash):window.location.hash=this.oldHash:history.replaceState?history.replaceState(null,document.title,window.location.pathname+window.location.search):window.location.hash=""},s.prototype.onHashchange=function(){if(this.core.lgOpened){var t=window.location.hash,e=this.getIndexFromUrl(t);t.indexOf("lg="+this.settings.galleryId)>-1?this.core.slide(e,!1,!1):this.core.lGalleryOn&&this.core.closeGallery()}},s.prototype.closeGallery=function(){this.settings.hash&&this.$LG(document.body).removeClass("lg-from-hash")},s.prototype.destroy=function(){this.core.LGel.off(".lg.hash"),this.core.LGel.off(".hash"),this.$LG(window).off("hashchange.lg.hash.global"+this.core.lgId)},s}()}));
|
||||
8
photologue/static/lightgallery/plugins/thumbnail/lg-thumbnail.min.js
vendored
Normal file
8
photologue/static/lightgallery/plugins/thumbnail/lg-thumbnail.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
8
photologue/static/lightgallery/plugins/zoom/lg-zoom.min.js
vendored
Normal file
8
photologue/static/lightgallery/plugins/zoom/lg-zoom.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,3 @@
|
|||
{% extends "admin/change_list.html" %}
|
||||
{% load i18n %}
|
||||
{# Hide upload as zip #}
|
||||
39
photologue/templates/photologue/gallery_archive.html
Normal file
39
photologue/templates/photologue/gallery_archive.html
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
{% extends "base.html" %}
|
||||
{% comment %}
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
{% endcomment %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}{% trans "Latest photo galleries" %}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<h1>{% trans "Latest photo galleries" %}</h1>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<aside class="col-md-2">
|
||||
<h5>{% trans "Filter by year" %}</h5>
|
||||
<div class="list-group">
|
||||
{% for date in date_list %}
|
||||
<a class="list-group-item list-group-item-action" href="{% url 'photologue:pl-gallery-archive-year' date.year %}">{{ date|date:"Y" }}</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</aside>
|
||||
<main class="col-md-10">
|
||||
{% if latest %}
|
||||
<div class="row mb-2">
|
||||
{% for gallery in latest|slice:":32" %}
|
||||
<div class="col-6 col-md-3 mb-2">
|
||||
{% include "photologue/includes/gallery_sample.html" %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
<p>{% trans "No galleries were found" %}.</p>
|
||||
{% endif %}
|
||||
</main>
|
||||
</div>
|
||||
{% endblock %}
|
||||
33
photologue/templates/photologue/gallery_archive_year.html
Normal file
33
photologue/templates/photologue/gallery_archive_year.html
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
{% extends "base.html" %}
|
||||
{% comment %}
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
{% endcomment %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}{% blocktrans with show_year=year|date:"Y" %}Galleries for {{ show_year }}{% endblocktrans %}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<h1>{% blocktrans with show_year=year|date:"Y" %}Galleries for {{ show_year }}{% endblocktrans %}</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<aside class="col-md-2">
|
||||
<a href="{% url 'photologue:pl-gallery-archive' %}">⬅ {% trans "View all galleries" %}</a>
|
||||
</aside>
|
||||
<main class="col-md-10">
|
||||
{% if object_list %}
|
||||
<div class="row mb-2">
|
||||
{% for gallery in object_list %}
|
||||
<div class="col-6 col-md-3 mb-2">
|
||||
{% include "photologue/includes/gallery_sample.html" %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
<p>{% trans "No galleries were found." %}</p>
|
||||
{% endif %}
|
||||
</main>
|
||||
</div>
|
||||
{% endblock %}
|
||||
81
photologue/templates/photologue/gallery_detail.html
Normal file
81
photologue/templates/photologue/gallery_detail.html
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
{% extends "base.html" %}
|
||||
{% comment %}
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
{% endcomment %}
|
||||
{% load static i18n %}
|
||||
|
||||
{% block title %}{{ gallery.title }}{% endblock %}
|
||||
|
||||
{% block extracss %}
|
||||
<link rel="stylesheet" href="{% static 'lightgallery/css/lightgallery.css' %}" />
|
||||
<link rel="stylesheet" href="{% static 'lightgallery/css/lg-zoom.css' %}" />
|
||||
<link rel="stylesheet" href="{% static 'lightgallery/css/lg-thumbnail.css' %}" />
|
||||
{% endblock %}
|
||||
|
||||
{% block extrajs %}
|
||||
<script src="{% static 'lightgallery/lightgallery.min.js' %}"></script>
|
||||
<script src="{% static 'lightgallery/plugins/admin/lg-admin.js' %}"></script>
|
||||
<script src="{% static 'lightgallery/plugins/hash/lg-hash.min.js' %}"></script>
|
||||
<script src="{% static 'lightgallery/plugins/thumbnail/lg-thumbnail.min.js' %}"></script>
|
||||
<script src="{% static 'lightgallery/plugins/zoom/lg-zoom.min.js' %}"></script>
|
||||
<script>
|
||||
lightGallery(document.getElementById('lightgallery'), {
|
||||
plugins: [{% if request.user.is_staff %}lgAdmin, {% endif %}lgHash, lgThumbnail, lgZoom],
|
||||
customSlideName: true,
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>
|
||||
{{ gallery.title }}
|
||||
{% if request.user.is_staff and perms.photologue.change_gallery %}
|
||||
<a href="{% url 'admin:photologue_gallery_change' gallery.id %}">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="#555" class="bi bi-gear" viewBox="0 0 16 18">
|
||||
<path d="M8 4.754a3.246 3.246 0 1 0 0 6.492 3.246 3.246 0 0 0 0-6.492zM5.754 8a2.246 2.246 0 1 1 4.492 0 2.246 2.246 0 0 1-4.492 0z"/>
|
||||
<path d="M9.796 1.343c-.527-1.79-3.065-1.79-3.592 0l-.094.319a.873.873 0 0 1-1.255.52l-.292-.16c-1.64-.892-3.433.902-2.54 2.541l.159.292a.873.873 0 0 1-.52 1.255l-.319.094c-1.79.527-1.79 3.065 0 3.592l.319.094a.873.873 0 0 1 .52 1.255l-.16.292c-.892 1.64.901 3.434 2.541 2.54l.292-.159a.873.873 0 0 1 1.255.52l.094.319c.527 1.79 3.065 1.79 3.592 0l.094-.319a.873.873 0 0 1 1.255-.52l.292.16c1.64.893 3.434-.902 2.54-2.541l-.159-.292a.873.873 0 0 1 .52-1.255l.319-.094c1.79-.527 1.79-3.065 0-3.592l-.319-.094a.873.873 0 0 1-.52-1.255l.16-.292c.893-1.64-.902-3.433-2.541-2.54l-.292.159a.873.873 0 0 1-1.255-.52l-.094-.319zm-2.633.283c.246-.835 1.428-.835 1.674 0l.094.319a1.873 1.873 0 0 0 2.693 1.115l.291-.16c.764-.415 1.6.42 1.184 1.185l-.159.292a1.873 1.873 0 0 0 1.116 2.692l.318.094c.835.246.835 1.428 0 1.674l-.319.094a1.873 1.873 0 0 0-1.115 2.693l.16.291c.415.764-.42 1.6-1.185 1.184l-.291-.159a1.873 1.873 0 0 0-2.693 1.116l-.094.318c-.246.835-1.428.835-1.674 0l-.094-.319a1.873 1.873 0 0 0-2.692-1.115l-.292.16c-.764.415-1.6-.42-1.184-1.185l.159-.291A1.873 1.873 0 0 0 1.945 8.93l-.319-.094c-.835-.246-.835-1.428 0-1.674l.319-.094A1.873 1.873 0 0 0 3.06 4.377l-.16-.292c-.415-.764.42-1.6 1.185-1.184l.292.159a1.873 1.873 0 0 0 2.692-1.115l.094-.319z"/>
|
||||
</svg>
|
||||
</a>
|
||||
{% endif %}
|
||||
</h1>
|
||||
{% if gallery.date_start %}<p class="text-muted small">{{ gallery.date_start }}{% if gallery.date_end and gallery.date_end != gallery.date_start %} {% trans "to" %} {{ gallery.date_end }}{% endif %}</p>{% endif %}
|
||||
{% if gallery.tags.all %}
|
||||
<p class="text-muted">
|
||||
Tags : {% for tag in gallery.tags.all %}
|
||||
<a class="badge rounded-pill bg-dark text-decoration-none" href="{% url 'photologue:tag-detail' tag.slug %}">{{ tag }}</a>
|
||||
{% endfor %}
|
||||
</p>
|
||||
{% endif %}
|
||||
{% if gallery.description %}<p>{{ gallery.description|safe }}</p>{% endif %}
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header pb-0 border-bottom-0">
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="nav-item">
|
||||
{% url 'photologue:pl-gallery' gallery.slug as url %}
|
||||
<a class="nav-link {% if request.path_info == url %}active{% endif %}" href="{{ url }}">
|
||||
{% trans "All pictures" %}
|
||||
</a>
|
||||
</li>
|
||||
{% for owner in owners %}
|
||||
<li class="nav-item">
|
||||
{% url 'photologue:pl-gallery-owner' slug=gallery.slug owner=owner.id as url %}
|
||||
<a class="nav-link {% if request.path_info == url %}active{% endif %}" href="{{ url }}">
|
||||
{% if owner.get_full_name %}{{ owner.get_full_name }}{% else %}{{ owner.username }}{% endif %}
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
<div class="card-body row" id="lightgallery">
|
||||
{% for photo in photos %}
|
||||
<a class="col-6 col-md-3 mb-2 text-center" href="{{ photo.get_absolute_url }}" data-src="{{ photo.get_display_url }}" data-download-url="{{ photo.image.url }}" data-slide-name="{{ photo.id }}">
|
||||
<img src="{{ photo.get_thumbnail_url }}" loading="lazy" class="img-thumbnail p-0" alt="{{ photo.title }}{% if photo.date_taken %} - {{ photo.date_taken|date }} {{ photo.date_taken|time }}{% endif %} - {{ photo.owner.get_full_name }}{% if photo.license %} - {{ photo.license }}{% endif %}">
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<a href="{% url 'photologue:pl-gallery-download' gallery.slug %}" class="btn btn-secondary btn-sm">{% trans 'Download all gallery' %}</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
12
photologue/templates/photologue/includes/gallery_sample.html
Normal file
12
photologue/templates/photologue/includes/gallery_sample.html
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{% load i18n %}
|
||||
|
||||
<div class="card text-white bg-dark">
|
||||
{% for photo in gallery.sample %}
|
||||
<img src="{{ photo.get_thumbnail_url }}" class="card-img-top" alt="{{ photo.title }}">
|
||||
{% endfor %}
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">{{ gallery.title }}</h5>
|
||||
{% if gallery.date_start %}<p class="card-text text-muted small mb-0">{{ gallery.date_start }}{% if gallery.date_end and gallery.date_end != gallery.date_start %} - {{ gallery.date_end }}{% endif %}</p>{% endif %}
|
||||
<a href="{{ gallery.get_absolute_url }}" class="stretched-link"></a>
|
||||
</div>
|
||||
</div>
|
||||
34
photologue/templates/photologue/photo_detail.html
Normal file
34
photologue/templates/photologue/photo_detail.html
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
{% extends "base.html" %}
|
||||
{% comment %}
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
{% endcomment %}
|
||||
{% load photologue_tags i18n %}
|
||||
|
||||
{% block title %}{{ object.title }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<h1>{{ object.title }}</h1>
|
||||
<p class="text-muted small">{% trans "Published" %} {{ object.date_added }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
{% if object.caption %}<p>{{ object.caption|safe }}</p>{% endif %}
|
||||
<a href="{{ object.image.url }}">
|
||||
<img src="{{ object.get_display_url }}" class="img-thumbnail" alt="{{ object.title }}">
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
{% if object.public_galleries %}
|
||||
<p>{% trans "This photo is found in the following galleries" %}:</p>
|
||||
<ul>
|
||||
{% for gallery in object.public_galleries %}
|
||||
<li><a href="{{ gallery.get_absolute_url }}">{{ gallery.title }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
16
photologue/templates/photologue/tag_detail.html
Normal file
16
photologue/templates/photologue/tag_detail.html
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
{% extends "base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}{{ object.name }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Tag : {{ object.name }}</h1>
|
||||
|
||||
<div class="row mb-2">
|
||||
{% for gallery in galleries %}
|
||||
<div class="col-6 col-md-3 mb-2">
|
||||
{% include "photologue/includes/gallery_sample.html" %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
87
photologue/templates/photologue/upload.html
Normal file
87
photologue/templates/photologue/upload.html
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
{% extends "base.html" %}
|
||||
{% comment %}
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
{% endcomment %}
|
||||
{% load i18n crispy_forms_tags %}
|
||||
{% block title %}{% trans "Upload" %}{% endblock %}
|
||||
|
||||
{% block extracss %}
|
||||
<style>
|
||||
.upload-drop-zone {
|
||||
height: 10em;
|
||||
line-height: 10em;
|
||||
border-width: 2px;
|
||||
color: #a3a3a3;
|
||||
border-style: dashed;
|
||||
border-color: #a3a3a3;
|
||||
border-radius: 0.5em;
|
||||
text-align: center;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
.upload-drop-zone.drop {
|
||||
color: #222;
|
||||
border-color: #222;
|
||||
background-color: rgba(163, 163, 163, 0.274);
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block extrajs %}
|
||||
<script>
|
||||
// When user drags files, register them in the file field
|
||||
const dropZone = document.getElementById('drop-zone');
|
||||
const uploadInput = document.getElementById('id_file_field');
|
||||
|
||||
dropZone.ondrop = function(e) {
|
||||
e.preventDefault();
|
||||
this.className = 'upload-drop-zone';
|
||||
console.log(e.dataTransfer.files)
|
||||
uploadInput.files = e.dataTransfer.files;
|
||||
}
|
||||
|
||||
dropZone.ondragover = function() {
|
||||
this.className = 'upload-drop-zone drop';
|
||||
return false;
|
||||
}
|
||||
|
||||
dropZone.ondragleave = function() {
|
||||
this.className = 'upload-drop-zone';
|
||||
return false;
|
||||
}
|
||||
|
||||
// When user selects an existing gallery, disable new gallery fields
|
||||
const gallerySelect = document.getElementById('id_gallery')
|
||||
gallerySelectUpdate = () => {
|
||||
const useGallery = (gallerySelect.value !== "");
|
||||
document.getElementById('id_new_gallery_title').disabled = useGallery;
|
||||
document.getElementById('id_new_gallery_date_start').disabled = useGallery;
|
||||
document.getElementById('id_new_gallery_date_end').disabled = useGallery;
|
||||
document.getElementById('id_new_gallery_tags').disabled = useGallery;
|
||||
}
|
||||
gallerySelect.addEventListener('change', gallerySelectUpdate);
|
||||
gallerySelectUpdate();
|
||||
|
||||
// On submit, show a message to make user wait
|
||||
document.getElementById('upload_form').addEventListener('submit', (e) => {
|
||||
document.getElementById('submit-id-submit').disabled = true;
|
||||
document.getElementById('submit-id-submit').value = "Please be patient";
|
||||
})
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>{% trans "Upload" %}</h1>
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<form method="post" enctype="multipart/form-data" id="upload_form">{% csrf_token %}
|
||||
<div class="upload-drop-zone" id="drop-zone">
|
||||
{% trans "Drag and drop photos here" %}
|
||||
</div>
|
||||
{% crispy form %}
|
||||
<p class="mt-3">
|
||||
{% trans "Owner will be" %} <code>{{ request.user.get_full_name }} ({{ request.user.username}})</code>.
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
from django.urls import path, re_path
|
||||
from photologue_custom.views import CustomGalleryDetailView, GalleryDownload, GalleryUpload, TagDetail
|
||||
|
||||
from .views import GalleryArchiveIndexView, GalleryYearArchiveView, PhotoDetailView
|
||||
from .views import (CustomGalleryDetailView, GalleryArchiveIndexView,
|
||||
GalleryDownload, GalleryUpload, GalleryYearArchiveView,
|
||||
PhotoDetailView, TagDetail)
|
||||
|
||||
app_name = 'photologue'
|
||||
urlpatterns = [
|
||||
|
|
|
|||
|
|
@ -1,8 +1,26 @@
|
|||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
# Copyright (C) 2021 by BDE ENS Paris-Saclay
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
import os
|
||||
import zipfile
|
||||
from io import BytesIO
|
||||
from pathlib import Path
|
||||
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth.mixins import (LoginRequiredMixin,
|
||||
PermissionRequiredMixin)
|
||||
from django.core.mail import mail_managers
|
||||
from django.db import IntegrityError
|
||||
from django.http import HttpResponse
|
||||
from django.urls import reverse_lazy
|
||||
from django.utils.text import slugify
|
||||
from django.views.generic.dates import ArchiveIndexView, YearArchiveView
|
||||
from django.views.generic.detail import DetailView
|
||||
from django.views.generic.edit import FormView
|
||||
from PIL import Image
|
||||
|
||||
from .models import Gallery, Photo
|
||||
from .forms import UploadForm
|
||||
from .models import Gallery, Photo, Tag
|
||||
|
||||
|
||||
class GalleryDateView(LoginRequiredMixin):
|
||||
|
|
@ -22,3 +40,125 @@ class GalleryYearArchiveView(GalleryDateView, YearArchiveView):
|
|||
|
||||
class PhotoDetailView(LoginRequiredMixin, DetailView):
|
||||
queryset = Photo.objects.filter(is_public=True)
|
||||
|
||||
|
||||
class TagDetail(LoginRequiredMixin, DetailView):
|
||||
model = Tag
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
"""
|
||||
Insert the single object into the context dict.
|
||||
"""
|
||||
current_tag = self.get_object().slug
|
||||
context = super().get_context_data(**kwargs)
|
||||
context['galleries'] = Gallery.objects.filter(is_public=True) \
|
||||
.filter(tags__slug=current_tag) \
|
||||
.order_by('-date_start')
|
||||
return context
|
||||
|
||||
|
||||
class CustomGalleryDetailView(LoginRequiredMixin, DetailView):
|
||||
"""
|
||||
Custom gallery detail view to filter on photo owner
|
||||
"""
|
||||
queryset = Gallery.objects.filter(is_public=True)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
|
||||
# Query with owner to reduce database lag
|
||||
context['photos'] = self.object.public().select_related('owner')
|
||||
|
||||
# List owners
|
||||
context['owners'] = []
|
||||
for photo in context['photos']:
|
||||
if photo.owner not in context['owners']:
|
||||
context['owners'].append(photo.owner)
|
||||
|
||||
# Filter on owner
|
||||
if 'owner' in self.kwargs:
|
||||
context['photos'] = context['photos'].filter(owner__id=self.kwargs['owner'])
|
||||
|
||||
return context
|
||||
|
||||
|
||||
class GalleryDownload(LoginRequiredMixin, DetailView):
|
||||
model = Gallery
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
"""
|
||||
Download a zip file of the gallery on GET request.
|
||||
"""
|
||||
# Create zip file with pictures
|
||||
gallery = self.get_object()
|
||||
byte_data = BytesIO()
|
||||
zip_file = zipfile.ZipFile(byte_data, "w")
|
||||
for photo in gallery.public():
|
||||
filename = os.path.basename(os.path.normpath(photo.image.path))
|
||||
zip_file.write(photo.image.path, filename)
|
||||
zip_file.close()
|
||||
|
||||
# Return zip file
|
||||
response = HttpResponse(byte_data.getvalue(), content_type='application/x-zip-compressed')
|
||||
response['Content-Disposition'] = f"attachment; filename={gallery.slug}.zip"
|
||||
return response
|
||||
|
||||
|
||||
class GalleryUpload(PermissionRequiredMixin, FormView):
|
||||
"""
|
||||
Form to upload new photos in a gallery
|
||||
"""
|
||||
form_class = UploadForm
|
||||
template_name = "photologue/upload.html"
|
||||
success_url = reverse_lazy("photologue:pl-gallery-upload")
|
||||
permission_required = 'photologue.add_gallery'
|
||||
|
||||
def form_valid(self, form):
|
||||
# Upload photos
|
||||
# We take files from the request to support multiple upload
|
||||
files = self.request.FILES.getlist('file_field')
|
||||
gallery = form.get_or_create_gallery()
|
||||
gallery_year = Path(str(gallery.date_start.year))
|
||||
gallery_dir = gallery_year / gallery.slug
|
||||
failed_upload = 0
|
||||
for photo_file in files:
|
||||
# Check that we have a valid image
|
||||
try:
|
||||
opened = Image.open(photo_file)
|
||||
opened.verify()
|
||||
except Exception:
|
||||
# Pillow doesn't recognize it as an image, skip it
|
||||
messages.error(self.request, f"{photo_file.name} was not recognized as an image")
|
||||
failed_upload += 1
|
||||
continue
|
||||
|
||||
title = f"{gallery.title} - {photo_file.name}"
|
||||
try:
|
||||
photo = Photo(
|
||||
title=title,
|
||||
slug=slugify(title),
|
||||
owner=self.request.user,
|
||||
)
|
||||
photo_name = str(gallery_dir / photo_file.name)
|
||||
photo.image.save(photo_name, photo_file)
|
||||
photo.save()
|
||||
photo.galleries.set([gallery])
|
||||
except IntegrityError:
|
||||
messages.error(self.request, f"{photo_file.name} was not uploaded. Maybe the photo was already uploaded.")
|
||||
failed_upload += 1
|
||||
|
||||
# Notify user then managers
|
||||
if not failed_upload:
|
||||
messages.success(self.request, "All photos has been successfully uploaded.")
|
||||
else:
|
||||
n_success = len(files) - failed_upload
|
||||
messages.warning(self.request, f"Only {n_success} photos were successfully uploaded !")
|
||||
|
||||
gallery_title = form.cleaned_data['gallery'] or form.cleaned_data.get('new_gallery_title', '')
|
||||
photos = ", ".join(f.name for f in files)
|
||||
mail_managers(
|
||||
subject="New photos upload",
|
||||
message=f"{self.request.user.username} has uploaded in `{gallery_title}`: {photos}",
|
||||
)
|
||||
|
||||
return super().form_valid(form)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue