diff --git a/photo21/settings.py b/photo21/settings.py index eaa3a79..0375594 100644 --- a/photo21/settings.py +++ b/photo21/settings.py @@ -42,11 +42,6 @@ ADMINS = [ ("admin", "photos-admin@lists.crans.org"), ] -# Managers receive uploads notification -MANAGERS = [ - ('admin', 'photos-admin@lists.crans.org'), -] - # Use secure cookies in production SESSION_COOKIE_SECURE = not DEBUG CSRF_COOKIE_SECURE = not DEBUG diff --git a/photologue/templates/photologue/gallery_archive.html b/photologue/templates/photologue/gallery_archive.html index 9e58de7..206dd58 100644 --- a/photologue/templates/photologue/gallery_archive.html +++ b/photologue/templates/photologue/gallery_archive.html @@ -9,12 +9,6 @@ SPDX-License-Identifier: GPL-3.0-or-later {% block title %}{% trans "Latest photo galleries" %}{% endblock %} {% block content %} -
-
-

{% trans "Latest photo galleries" %}

-
-
-
-{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/photologue/templates/photologue/gallery_archive_year.html b/photologue/templates/photologue/gallery_archive_year.html index 794fd0d..54cdb95 100644 --- a/photologue/templates/photologue/gallery_archive_year.html +++ b/photologue/templates/photologue/gallery_archive_year.html @@ -9,27 +9,27 @@ SPDX-License-Identifier: GPL-3.0-or-later {% block title %}{% blocktrans with show_year=year|date:"Y" %}Galleries for {{ show_year }}{% endblocktrans %}{% endblock %} {% block content %} -
-
-

{% blocktrans with show_year=year|date:"Y" %}Galleries for {{ show_year }}{% endblocktrans %}

-
-
-
- -
- {% if object_list %} -
- {% for gallery in object_list %} -
- {% include "photologue/includes/gallery_sample.html" %} -
- {% endfor %} +
+ +
+ {% if object_list %} +
+ {% for gallery in object_list %} +
+ {% include "photologue/includes/gallery_sample.html" %}
- {% else %} -

{% trans "No galleries were found." %}

- {% endif %} -
-
-{% endblock %} \ No newline at end of file + {% endfor %} +
+ {% else %} +

{% trans "No galleries were found." %}

+ {% endif %} +
+
+{% endblock %} diff --git a/photologue/views.py b/photologue/views.py index 9bcc837..4914804 100644 --- a/photologue/views.py +++ b/photologue/views.py @@ -9,7 +9,7 @@ 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.core.mail import mail_admins from django.db import IntegrityError from django.http import HttpResponse from django.shortcuts import redirect @@ -27,6 +27,7 @@ from .models import Gallery, Photo, Tag class GalleryDateView(LoginRequiredMixin): model = Gallery date_field = "date_start" + allow_empty = True # Do not 404 if no galleries def get_queryset(self): """Hide galleries with only private photos""" @@ -36,6 +37,12 @@ class GalleryDateView(LoginRequiredMixin): else: return qs.filter(photos__is_public=True).distinct() + def get_context_data(self, **kwargs): + """Always show all years in archive""" + context = super().get_context_data(**kwargs) + context['date_list'] = self.get_queryset().dates(self.date_field, 'year', 'DESC') + return context + class GalleryArchiveIndexView(GalleryDateView, ArchiveIndexView): pass @@ -91,7 +98,7 @@ class PhotoReportView(LoginRequiredMixin, DetailView): url = request.build_absolute_uri(url) # Send mail to managers - mail_managers( + mail_admins( subject=f"Abuse report for photo id {photo.pk}", message=f"{self.request.user.username} reported an abuse for `{photo.title}`: {url}#lg=1&slide={photo.pk}", ) @@ -182,10 +189,15 @@ class GalleryUpload(PermissionRequiredMixin, FormView): # Upload photos # We take files from the request to support multiple upload files = self.request.FILES.getlist("file_field") + + # Get or create gallery gallery = form.get_or_create_gallery() gallery_year = Path(str(gallery.date_start.year)) gallery_dir = gallery_year / gallery.slug - failed_upload = 0 + + # Upload pictures + uploaded_photo_name = [] + already_exists = 0 for photo_file in files: # Check that we have a valid image try: @@ -196,7 +208,6 @@ class GalleryUpload(PermissionRequiredMixin, FormView): 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}" @@ -207,32 +218,32 @@ class GalleryUpload(PermissionRequiredMixin, FormView): 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]) + + # Save to disk after successful database edit + photo.image.save(photo_name, photo_file) except IntegrityError: - messages.error( - self.request, - f"{photo_file.name} was not uploaded. Maybe the photo was already uploaded.", - ) - failed_upload += 1 + already_exists += 1 + continue + + uploaded_photo_name.append(photo_file.name) # Notify user then managers - if not failed_upload: - messages.success(self.request, "All photos has been successfully uploaded.") + n_success = len(uploaded_photo_name) + if already_exists: + messages.success(self.request, f"{n_success} photo(s) uploaded, {already_exists} photo(s) skipped as they already exist in this gallery.") else: - n_success = len(files) - failed_upload - messages.warning( - self.request, f"Only {n_success} photos were successfully uploaded !" + messages.success(self.request, f"{n_success} photo(s) uploaded.") + + # Notify administrators on new uploads + gallery_url = reverse_lazy("photologue:pl-gallery", args=[gallery.slug]) + gallery_url = self.request.build_absolute_uri(gallery_url) + if uploaded_photo_name: + photos = ", ".join(uploaded_photo_name) + mail_admins( + subject=f"New upload from {self.request.user.username}", + message=f"{self.request.user.username} has uploaded in <{gallery_url}>:\n{photos}", ) - 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)