Unify public and private gallery views, add author tabs and download
All checks were successful
Docker / build (release) Successful in 8s

This commit is contained in:
krek0 2026-05-07 17:22:06 +02:00
parent 317bad9068
commit 993421f52a
3 changed files with 36 additions and 13 deletions

View file

@ -69,18 +69,26 @@ SPDX-License-Identifier: GPL-3.0-or-later
{% if gallery.description %}<p>{{ gallery.description|linebreaksbr }}</p>{% endif %}
<div class="card">
{% if not guest_mode %}
{% if owners %}
<div class="card-header pb-0 border-bottom-0">
<ul class="nav nav-tabs">
<li class="nav-item">
{% if guest_mode %}
{% url 'photologue:pl-gallery-public' gallery.public_token as url %}
{% else %}
{% url 'photologue:pl-gallery' gallery.slug as url %}
{% endif %}
<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">
{% if guest_mode %}
{% url 'photologue:pl-gallery-public-owner' token=gallery.public_token owner=owner.id as url %}
{% else %}
{% url 'photologue:pl-gallery-owner' slug=gallery.slug owner=owner.id as url %}
{% endif %}
<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>
@ -101,9 +109,12 @@ SPDX-License-Identifier: GPL-3.0-or-later
</a>
{% endfor %}
</div>
{% if not guest_mode %}
<div class="card-footer">
{% if guest_mode %}
<a href="{% url 'photologue:pl-gallery-public-download' gallery.public_token %}" class="btn btn-secondary btn-sm">
{% else %}
<a href="{% url 'photologue:pl-gallery-download' gallery.slug %}" class="btn btn-secondary btn-sm">
{% endif %}
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-download" viewBox="0 0 16 16">
<path d="M.5 9.9a.5.5 0 0 1 .5.5v2.5a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-2.5a.5.5 0 0 1 1 0v2.5a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2v-2.5a.5.5 0 0 1 .5-.5z"/>
<path d="M7.646 11.854a.5.5 0 0 0 .708 0l3-3a.5.5 0 0 0-.708-.708L8.5 10.293V1.5a.5.5 0 0 0-1 0v8.793L5.354 8.146a.5.5 0 1 0-.708.708l3 3z"/>
@ -111,6 +122,5 @@ SPDX-License-Identifier: GPL-3.0-or-later
{% trans 'Download all gallery' %}
</a>
</div>
{% endif %}
</div>
{% endblock %}

View file

@ -9,6 +9,7 @@ from .views import (
GalleryArchiveIndexView,
GalleryDetailView,
GalleryDownload,
GalleryPublicDownload,
GalleryPublicView,
GalleryTokenView,
GalleryUpload,
@ -47,5 +48,7 @@ urlpatterns = [
path("photo/<int:pk>/uncensor/", PhotoUncensorView.as_view(), name="pl-photo-uncensor"),
path("upload/", GalleryUpload.as_view(), name="pl-gallery-upload"),
path("share/<uuid:token>/", GalleryPublicView.as_view(), name="pl-gallery-public"),
path("share/<uuid:token>/<int:owner>/", GalleryPublicView.as_view(), name="pl-gallery-public-owner"),
path("share/<uuid:token>/download/", GalleryPublicDownload.as_view(), name="pl-gallery-public-download"),
path("gallery/<slug:slug>/token/", GalleryTokenView.as_view(), name="pl-gallery-token"),
]

View file

@ -221,29 +221,39 @@ class GalleryDownload(LoginRequiredMixin, DetailView):
# return response
class GalleryPublicView(DetailView):
model = Gallery
template_name = "photologue/gallery_detail.html"
class GalleryPublicView(GalleryDetailView):
def get_object(self):
return get_object_or_404(Gallery, public_token=self.kwargs["token"])
def get(self, request, *args, **kwargs):
def dispatch(self, request, *args, **kwargs):
if request.user.is_authenticated:
gallery = self.get_object()
return redirect("photologue:pl-gallery", slug=gallery.slug)
request.guest_mode = True
return super().get(request, *args, **kwargs)
# Bypass LoginRequiredMixin
return super(LoginRequiredMixin, self).dispatch(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["photos"] = self.object.photos.filter(is_public=True).select_related("owner")
context["owners"] = []
context["guest_mode"] = True
context["photos"].update(view_count=F("view_count") + 1)
context.pop("can_resolve_censorship", None)
context.pop("public_url", None)
return context
class GalleryPublicDownload(View):
def get(self, request, token):
gallery = get_object_or_404(Gallery, public_token=token)
buffer = BytesIO()
with zipfile.ZipFile(buffer, "w") as zf:
for photo in gallery.photos.filter(is_public=True):
filename = os.path.basename(photo.image.name)
zf.write(photo.image.path, filename)
buffer.seek(0)
response = HttpResponse(buffer, content_type="application/zip")
response["Content-Disposition"] = f'attachment; filename="{gallery.slug}.zip"'
return response
class GalleryTokenView(LoginRequiredMixin, View):
def post(self, request, slug):
if not request.user.is_staff: