-python3 fet2020/manage.py create_thumbs
-
-
Erstellt alle Searchindexes neu:
python3 fet2020/manage.py rebuild_index
diff --git a/fet2020/gallery/admin.py b/fet2020/gallery/admin.py
index 691cc4f0..6b4a0beb 100644
--- a/fet2020/gallery/admin.py
+++ b/fet2020/gallery/admin.py
@@ -15,11 +15,7 @@ class AlbumAdmin(admin.ModelAdmin):
"Der Ordner für die Fotos liegt am Server unter '/mnt/save/fotos/www'. "
"Fette Schriften sind Pflichtfelder."
)
- return super().add_view(
- request,
- form_url,
- extra_context=extra_context,
- )
+ return super().add_view(request, form_url, extra_context=extra_context)
def change_view(self, request, object_id, form_url="", extra_context=None):
extra_context = extra_context or {}
@@ -27,12 +23,7 @@ class AlbumAdmin(admin.ModelAdmin):
"Der Ordner für die Fotos liegt am Server unter '/mnt/save/fotos/www'. "
"Fette Schriften sind Pflichtfelder."
)
- return super().change_view(
- request,
- object_id,
- form_url,
- extra_context=extra_context,
- )
+ return super().change_view(request, object_id, form_url, extra_context=extra_context)
def save_model(self, request, obj, form, change):
obj.author = request.user
diff --git a/fet2020/gallery/choices.py b/fet2020/gallery/choices.py
new file mode 100644
index 00000000..d3124a08
--- /dev/null
+++ b/fet2020/gallery/choices.py
@@ -0,0 +1,6 @@
+from django.db import models
+
+
+class Status(models.TextChoices):
+ DRAFT = "10", "DRAFT"
+ PUBLIC = "20", "PUBLIC"
diff --git a/fet2020/gallery/forms.py b/fet2020/gallery/forms.py
index 498b6c5b..472ff581 100644
--- a/fet2020/gallery/forms.py
+++ b/fet2020/gallery/forms.py
@@ -11,11 +11,7 @@ class AlbumAdminForm(forms.ModelForm):
widgets = {"description": CKEditorUploadingWidget(config_name="default")}
- labels = {
- "slug": "Permalink",
- "event_place": "Event Ort",
- "description": "Beschreibung",
- }
+ labels = {"slug": "Permalink", "event_place": "Event Ort", "description": "Beschreibung"}
help_texts = {
"folder_name": "Füge den Ordnername (ohne Pfade) ein.",
diff --git a/fet2020/gallery/management/__init__.py b/fet2020/gallery/management/__init__.py
deleted file mode 100644
index e69de29b..00000000
diff --git a/fet2020/gallery/management/commands/__init__.py b/fet2020/gallery/management/commands/__init__.py
deleted file mode 100644
index e69de29b..00000000
diff --git a/fet2020/gallery/management/commands/create_thumbs.py b/fet2020/gallery/management/commands/create_thumbs.py
deleted file mode 100644
index 8bacdcf9..00000000
--- a/fet2020/gallery/management/commands/create_thumbs.py
+++ /dev/null
@@ -1,16 +0,0 @@
-import logging
-
-from django.core.management.base import BaseCommand
-
-from gallery.utils import create_thumbs, get_folder_list
-
-logger = logging.getLogger(__name__)
-
-
-class Command(BaseCommand):
- def handle(self, *args, **options):
- for folder in get_folder_list():
- logger.info("Folder '%s' in process.", folder)
- create_thumbs(folder)
-
- logger.info("Command 'create thumbs' ended.")
diff --git a/fet2020/gallery/managers.py b/fet2020/gallery/managers.py
new file mode 100644
index 00000000..c58dca14
--- /dev/null
+++ b/fet2020/gallery/managers.py
@@ -0,0 +1,11 @@
+from django.db import models
+
+from .choices import Status
+
+
+class AlbumManager(models.Manager):
+ def get_queryset(self):
+ return super().get_queryset().order_by("-event_date")
+
+ def public(self):
+ return self.get_queryset().filter(status=Status.PUBLIC)
diff --git a/fet2020/gallery/models.py b/fet2020/gallery/models.py
index 09faac43..a83ce945 100644
--- a/fet2020/gallery/models.py
+++ b/fet2020/gallery/models.py
@@ -1,45 +1,44 @@
+import logging
+from random import randint
+
+from django.conf import settings
from django.db import models
from django.urls import reverse
from django.utils import timezone
from django.utils.text import slugify
+from .choices import Status
+from .managers import AlbumManager
from .utils import get_image_list
+logger = logging.getLogger(__name__)
+
class Album(models.Model):
title = models.CharField(verbose_name="Titel", max_length=200)
slug = models.SlugField(unique=True, null=True, blank=True)
folder_name = models.CharField(verbose_name="Ordner Name", max_length=200)
- thumbnail = models.CharField(verbose_name="Thumbnail", max_length=200, null=True, blank=True)
+ thumbnail = models.CharField(verbose_name="Thumbnail", max_length=200, blank=True, default="")
event_date = models.DateField(
- verbose_name="Event Datum",
- null=True,
- blank=True,
- default=timezone.now,
+ verbose_name="Event Datum", null=True, blank=True, default=timezone.now
)
event_place = models.CharField(max_length=200, blank=True)
photographer = models.CharField(
- verbose_name="Fotograph(en)",
- max_length=200,
- null=True,
- blank=True,
+ verbose_name="Fotograph(en)", max_length=200, blank=True, default=""
)
- DRAFT = "10"
- PUBLIC = "20"
- STATUS = (
- (DRAFT, "DRAFT"),
- (PUBLIC, "PUBLIC"),
- )
- status = models.CharField(max_length=2, choices=STATUS, default=DRAFT)
+ # TextChoices
+ Status = Status
- description = models.TextField(null=True, blank=True)
+ status = models.CharField(max_length=2, choices=Status.choices, default=Status.DRAFT)
+
+ description = models.TextField(blank=True, default="")
# Managers
- objects = models.Manager()
+ objects = AlbumManager()
class Meta:
verbose_name = "Album"
@@ -57,14 +56,32 @@ class Album(models.Model):
def get_absolute_url(self):
return reverse("gallery:album", kwargs={"slug": self.slug})
- def get_images(self):
+ def clean(self):
+ if not self.images:
+ logger.info("No thumbnails are generated.")
+
+ @property
+ def images(self) -> list:
return get_image_list(self.folder_name)
def get_images_length_sub_3(self):
- return len(self.get_images()) - 3
+ return len(self.images) - 3
def get_model_name(self):
return self._meta.model_name
- def get_thumbnail(self):
- return None
+ @property
+ def get_album_thumbnail(self):
+ if img_list := self.images:
+ return next(
+ (
+ img["thumb_url"]
+ for img in img_list
+ if self.thumbnail and self.thumbnail in img["title"]
+ ),
+ img_list[randint(0, len(img_list) - 1)]["thumb_url"],
+ )
+
+ self.status = Album.Status.DRAFT
+ logger.info("Album '%s' is empty.", self.title)
+ return settings.STATIC_URL + "img/FET-Logo-2014-quadrat.png"
diff --git a/fet2020/gallery/urls.py b/fet2020/gallery/urls.py
index 9f677242..65a628ed 100644
--- a/fet2020/gallery/urls.py
+++ b/fet2020/gallery/urls.py
@@ -1,11 +1,12 @@
from django.urls import path
from . import apps, views
+from .views import AlbumDetailView, DraftAlbumDetailView
app_name = apps.GalleryConfig.name
urlpatterns = [
path("", views.index, name="index"),
- path("/", views.show_album, name="album"),
- path("draft//", views.show_draft_album, name="album_draft"),
+ path("/", AlbumDetailView.as_view(), name="album"),
+ path("draft//", DraftAlbumDetailView.as_view(), name="album_draft"),
]
diff --git a/fet2020/gallery/utils.py b/fet2020/gallery/utils.py
index 4f19b34b..9c15a72e 100644
--- a/fet2020/gallery/utils.py
+++ b/fet2020/gallery/utils.py
@@ -1,80 +1,56 @@
import logging
import os
+from pathlib import Path
from django.conf import settings
+from django.core.validators import get_available_image_extensions
from PIL import Image, ImageOps
-gallery_path = settings.GALLERY["path"]
-gallery_thumb_path = settings.GALLERY["thumb_path"]
+gallery_path = Path(settings.MEDIA_ROOT) / settings.GALLERY["path"]
+gallery_path_url = Path(settings.MEDIA_URL) / settings.GALLERY["path"]
+gallery_thumb_path = Path(settings.MEDIA_ROOT) / settings.GALLERY["thumb_path"]
+gallery_thumb_path_url = Path(settings.MEDIA_URL) / settings.GALLERY["thumb_path"]
logger = logging.getLogger(__name__)
size = (320, 320)
-valid_images = [".jpg", ".png"]
-def get_image_list(folder_name):
- file_path = os.path.join(settings.MEDIA_ROOT + gallery_path, folder_name)
+def get_image_list(folder_name: str) -> list:
+ image_path = Path(gallery_path) / folder_name
+ thumb_path = Path(gallery_thumb_path) / folder_name
img_list = []
- if os.path.exists(file_path):
- for img in os.listdir(file_path):
- ext = os.path.splitext(img)[1]
- if ext.lower() not in valid_images:
- continue
+ if not Path(image_path).exists():
+ logger.info("Image path '%s' not found.", image_path)
+ return img_list
- thumb_path = os.path.join(settings.MEDIA_ROOT + gallery_thumb_path, folder_name)
- thumb_file_path = os.path.join(thumb_path, f"thumb_{img}")
- if os.path.exists(thumb_file_path):
- thumb_url = os.path.join(
- settings.MEDIA_URL + gallery_thumb_path,
- folder_name + "/" + f"thumb_{img}",
- )
- else:
- thumb_url = None
+ Path(thumb_path).mkdir(exist_ok=True)
- img_dict = {
- "title": img,
- "image_url": os.path.join(
- settings.MEDIA_URL + gallery_path,
- folder_name + "/" + img,
- ),
- "thumb_url": thumb_url,
- }
+ for _file in os.listdir(image_path):
+ if Path(_file).suffix.lower()[1:] not in get_available_image_extensions():
+ continue
- img_list.append(img_dict)
+ thumb_file_path = Path(thumb_path) / f"thumb_{_file}"
+ if not Path(thumb_file_path).exists():
+ with Image.open(Path(image_path) / _file, "r") as im:
+ if im._getexif() is not None:
+ im = ImageOps.exif_transpose(im)
+
+ thumb = ImageOps.fit(im, size, Image.Resampling.LANCZOS)
+ thumb.save(thumb_file_path)
+ logger.info("Save thumb 'thumb_%s'.", _file)
+
+ img_dict = {
+ "title": _file,
+ "image_url": Path(gallery_path_url) / folder_name / _file,
+ "thumb_url": Path(gallery_thumb_path_url) / folder_name / f"thumb_{_file}",
+ }
+ img_list.append(img_dict)
return img_list
def get_folder_list():
- if os.path.exists(settings.MEDIA_ROOT + gallery_path):
- return next(os.walk(settings.MEDIA_ROOT + gallery_path))[1]
+ if Path(gallery_path).exists():
+ return next(os.walk(gallery_path))[1]
return None
-
-
-def create_thumbs(folder_path):
- file_path = os.path.join(settings.MEDIA_ROOT + gallery_path, folder_path)
- thumb_path = os.path.join(settings.MEDIA_ROOT + gallery_thumb_path, folder_path)
-
- if os.path.exists(file_path):
- os.makedirs(thumb_path, exist_ok=True)
-
- for f in os.listdir(file_path):
- ext = os.path.splitext(f)[1]
- if ext.lower() not in valid_images:
- continue
-
- thumb_file_path = os.path.join(thumb_path, f"thumb_{f}")
- if os.path.exists(thumb_file_path):
- continue
-
- image_path = os.path.join(file_path, f)
- logger.info("Edit picture '%s'.", f)
-
- with Image.open(str(image_path), "r") as image:
- if image._getexif() is not None:
- image = ImageOps.exif_transpose(image)
-
- thumb = ImageOps.fit(image, size, Image.ANTIALIAS)
- thumb.save(thumb_file_path)
- logger.info("Save thumb 'thumb_%s'.", f)
diff --git a/fet2020/gallery/views.py b/fet2020/gallery/views.py
index 92d38ee4..4a229cab 100644
--- a/fet2020/gallery/views.py
+++ b/fet2020/gallery/views.py
@@ -1,94 +1,65 @@
+import logging
from collections import deque
-from random import randint
-from django.conf import settings
+from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import Http404
from django.shortcuts import render
from django.utils.text import slugify
-
-from authentications.decorators import authenticated_user
+from django.views.generic.detail import DetailView
from .models import Album
-from .utils import create_thumbs, get_folder_list
+from .utils import get_folder_list
+
+logger = logging.getLogger(__name__)
def index(request):
if request.user.is_authenticated:
- albums = deque(Album.objects.all().order_by("-event_date"))
+ albums = deque(Album.objects.all())
+
+ # Get albums that are in the server but not in the db.
+ for folder in get_folder_list():
+ if not Album.objects.filter(folder_name=folder):
+ albums.append(
+ Album(title=folder, slug=slugify(folder), folder_name=folder, event_date=None)
+ )
- # get albums that are in the server but not in the db.
- folders = get_folder_list()
- if folders:
- for folder in folders:
- if not Album.objects.filter(folder_name=folder):
- albums.append(
- Album(
- title=folder,
- slug=slugify(folder),
- folder_name=folder,
- event_date=None,
- ),
- )
else:
- # show only PUBLIC albums.
- albums = deque(Album.objects.filter(status=Album.PUBLIC).order_by("-event_date"))
+ # Show only PUBLIC albums.
+ albums = Album.objects.public()
- for album in list(albums):
- img_list = album.get_images()
- if img_list:
- if album.thumbnail:
- for img in img_list:
- if album.thumbnail in img["title"]:
- album.thumbnail = img["thumb_url"]
- break
- else:
- value = randint(0, len(img_list) - 1)
- album.thumbnail = img_list[value]["thumb_url"]
- else:
- value = randint(0, len(img_list) - 1)
- album.thumbnail = img_list[value]["thumb_url"]
- else:
- # empty album is temporarily set to DRAFT.
- album.thumbnail = settings.STATIC_URL + "img/FET-Logo-2014-quadrat.png"
- album.status = Album.DRAFT
-
- context = {
- "albums": albums,
- }
+ context = {"albums": albums}
return render(request, "gallery/index.html", context)
-def show_album(request, slug):
- album = Album.objects.filter(slug=slug).first()
- if not album:
- for folder in get_folder_list():
- if slug == slugify(folder):
- album = Album(
- title=folder,
- slug=slugify(folder),
- folder_name=folder,
- event_date=None,
- )
- break
- else:
- raise Http404("wrong album slug")
+class AlbumDetailView(DetailView):
+ model = Album
+ template_name = "gallery/album.html"
- img_list = album.get_images()
- if not img_list:
- # empty album is temporarily set to DRAFT.
- album.status = Album.DRAFT
-
- create_thumbs(album.folder_name)
-
- context = {
- "album": album,
- "images": img_list,
- }
-
- return render(request, "gallery/album.html", context)
+ def get_queryset(self):
+ return (
+ Album.objects.public()
+ if not self.request.user.is_authenticated
+ else Album.objects.all()
+ )
-@authenticated_user
-def show_draft_album(request, slug):
- return show_album(request, slug)
+class DraftAlbumDetailView(LoginRequiredMixin, DetailView):
+ model = Album
+ template_name = "gallery/album.html"
+
+ def get_object(self, queryset=None):
+ slug = self.kwargs.get(self.slug_url_kwarg)
+
+ if not (album := Album.objects.filter(slug=slug).first()):
+ for folder in get_folder_list():
+ if slug == slugify(folder):
+ album = Album(
+ title=folder, slug=slugify(folder), folder_name=folder, event_date=None
+ )
+ break
+ else:
+ raise Http404("Album slug not found.")
+
+ return album
diff --git a/fet2020/templates/gallery/album.html b/fet2020/templates/gallery/album.html
index ffc6f3c9..e2218a01 100644
--- a/fet2020/templates/gallery/album.html
+++ b/fet2020/templates/gallery/album.html
@@ -13,7 +13,7 @@
Fotos
- {% if album.status == album.DRAFT %}
+ {% if album.status == album.Status.DRAFT %}
{{ album.title }}
{% else %}
{{ album.title }}
@@ -34,7 +34,7 @@
{% endif %}
- {% if request.user.is_authenticated %}
+ {% if request.user.is_authenticated and album.id %}
Album bearbeiten
@@ -52,7 +52,7 @@
- {% for image in images %}
+ {% for image in object.images %}
{% if image.thumb_url %}
diff --git a/fet2020/templates/gallery/index.html b/fet2020/templates/gallery/index.html
index c79d644e..1f1c932b 100644
--- a/fet2020/templates/gallery/index.html
+++ b/fet2020/templates/gallery/index.html
@@ -15,15 +15,15 @@
{% for album in albums %}
- {% if request.user.is_authenticated and album.status == album.DRAFT %}
+ {% if request.user.is_authenticated and album.status == album.Status.DRAFT %}
-
+
{{ album.title }}
{{ album.event_date }}
- {% elif album.status == album.PUBLIC %}
+ {% elif album.status == album.Status.PUBLIC %}
-
+
{{ album.title }}
{{ album.event_date }}