diff --git a/config/settings.py b/config/settings.py index 3765eb6..16c3feb 100644 --- a/config/settings.py +++ b/config/settings.py @@ -15,6 +15,8 @@ ALLOWED_HOSTS = [] INTERNAL_IPS = ['localhost', '127.0.0.1',] +CANONICAL_URL_DOMAIN = "https://nyymix.net" + # Localization LANGUAGES = [ @@ -32,9 +34,6 @@ LOCALE_PATHS = [ BASE_DIR / 'locale', ] -# Hostname for canonical_url -CANONICAL_HOST = "nyymix.net" - # Application definition INSTALLED_APPS = [ @@ -79,7 +78,6 @@ TEMPLATES = [ 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', - 'gallery.context_processors.canonical_url_processor', ], }, }, diff --git a/gallery/context_processors.py b/gallery/context_processors.py deleted file mode 100644 index b24ac55..0000000 --- a/gallery/context_processors.py +++ /dev/null @@ -1,10 +0,0 @@ -from django.conf import settings - - -def canonical_url_processor(request): - if settings.DEBUG: - canonical_url = request.build_absolute_uri() - else: - canonical_host = settings.CANONICAL_HOST - canonical_url = f"{request.scheme}://{canonical_host}{request.get_full_path()}" - return {'canonical_url': canonical_url} diff --git a/gallery/utils.py b/gallery/utils.py new file mode 100644 index 0000000..4ff9f1f --- /dev/null +++ b/gallery/utils.py @@ -0,0 +1,31 @@ +from urllib.parse import urlencode, urlparse, urlunparse + +from django.conf import settings +from django.urls import reverse + + +def build_canonical_url(request, base_url=None, params=None): + + if base_url is None: + base_url = request.path + elif base_url.startswith('/'): + base_url = base_url + else: + parsed = urlparse(base_url) + base_url = parsed.path + ('?' + parsed.query if parsed.query else '') + + filtered_params = { + k: v for k, v in (params or {}).items() + if v not in (None, '', [], {}) and not (k == 'page' and str(v) == '1') + } + + query_string = urlencode(filtered_params) + path = base_url + if query_string: + path += '?' + query_string + + domain = getattr(settings, 'CANONICAL_URL_DOMAIN', None) + if domain: + return domain.rstrip('/') + path + + return request.build_absolute_uri(path) diff --git a/gallery/views/album.py b/gallery/views/album.py index 4c80e1c..b9e3457 100644 --- a/gallery/views/album.py +++ b/gallery/views/album.py @@ -3,13 +3,14 @@ from django.core.cache import cache from django.core.paginator import Paginator from django.db.models import Count, F, Q, Sum from django.http import JsonResponse -from django.shortcuts import get_object_or_404, redirect +from django.shortcuts import get_object_or_404 from django.urls import reverse from django.views import View from django.views.generic import DetailView, ListView, TemplateView from config.cache_durations import * from gallery.cache import cached_or_set +from gallery.utils import build_canonical_url from ..models import Album, Photo, Redir @@ -45,11 +46,11 @@ class AlbumsList(ListView): context = super().get_context_data(**kwargs) page_obj = context.get('page_obj') - page = self.request.GET.get('page') - if page_obj.number > 1: - canonical_url = f"{self.request.build_absolute_uri(reverse('gallery:albums_url'))}?page={page}" - else: - canonical_url = self.request.build_absolute_uri(reverse('gallery:albums_url')) + canonical_url = build_canonical_url( + self.request, + reverse('gallery:albums_url'), + params={'page': page_obj.number} + ) context.update({ 'canonical_url': canonical_url, @@ -75,10 +76,11 @@ class AlbumDetail(DetailView): page_obj = paginator.get_page(self.request.GET.get('page')) # Canonical_url - if page_obj.number > 1: - canonical_url = f"{self.request.build_absolute_uri(self.object.get_absolute_url())}?page={page_obj.number}" - else: - canonical_url = self.request.build_absolute_uri(self.object.get_absolute_url()) + canonical_url = build_canonical_url( + self.request, + self.object.get_absolute_url(), + params={'page': page_obj.number} + ) context.update({ 'photos': page_obj.object_list, @@ -110,12 +112,11 @@ class AlbumSearch(TemplateView): page_obj = paginator.get_page(self.request.GET.get('page')) # Canonical URL - page = self.request.GET.get('page') - base_url = self.request.build_absolute_uri(reverse('gallery:search_url')) - if page_obj.number > 1: - canonical_url = f"{base_url}?page={page}" - else: - canonical_url = base_url + canonical_url = build_canonical_url( + self.request, + reverse('gallery:search_url'), + params={'page': page_obj.number, 'q': query} + ) context.update({ 'results': page_obj.object_list, @@ -124,4 +125,5 @@ class AlbumSearch(TemplateView): 'is_paginated': page_obj.has_other_pages(), 'canonical_url': canonical_url }) + return context diff --git a/gallery/views/main.py b/gallery/views/main.py index 7ace947..2301c46 100644 --- a/gallery/views/main.py +++ b/gallery/views/main.py @@ -11,6 +11,8 @@ from django.urls import reverse from django.views import View from django.views.generic import DetailView, ListView, TemplateView +from gallery.utils import build_canonical_url + from ..models import Album, Photo, Redir @@ -20,8 +22,14 @@ class Main(TemplateView): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context['canonical_url'] = self.request.build_absolute_uri(reverse('gallery:main_url')) - context['latest_albums'] = Album.objects.filter(is_public=True).order_by('-album_date')[:6] + canonical_url = build_canonical_url( + self.request, + reverse('gallery:main_url') + ) + context.update({ + 'canonical_url': canonical_url, + 'latest_albums': Album.objects.filter(is_public=True).order_by('-album_date')[:6], + }) return context @@ -31,7 +39,11 @@ class About(TemplateView): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context['canonical_url'] = self.request.build_absolute_uri(reverse('gallery:about_url')) + canonical_url = build_canonical_url( + self.request, + reverse('gallery:about_url') + ) + context['canonical_url'] = canonical_url return context diff --git a/gallery/views/photo.py b/gallery/views/photo.py index 4a522e6..c73f257 100644 --- a/gallery/views/photo.py +++ b/gallery/views/photo.py @@ -8,6 +8,8 @@ from django.urls import reverse from django.views import View from django.views.generic import DetailView, ListView, TemplateView +from gallery.utils import build_canonical_url + from ..models import Album, Photo, Redir @@ -32,11 +34,11 @@ class PhotosList(ListView): page_obj = context.get('page_obj') # Canonical_url - page = self.request.GET.get('page') - if page_obj.number > 1: - canonical_url = f"{self.request.build_absolute_uri(reverse('gallery:photos_url'))}?page={page}" - else: - canonical_url = self.request.build_absolute_uri(reverse('gallery:photos_url')) + canonical_url = build_canonical_url( + self.request, + reverse('gallery:photos_url'), + params={'page': page_obj.number, 'order': order} + ) context.update({ 'order': self.request.GET.get('order', 'latest'), @@ -54,7 +56,6 @@ class PhotoDetail(DetailView): def get_object(self, queryset=None): album_slug = self.kwargs.get('album_slug') photo_slug = self.kwargs.get('photo_slug') - # photo = get_object_or_404(Photo.objects.select_related('album'), slug=photo_slug, album__slug=album_slug) photo = get_object_or_404(Photo.objects.select_related('album'), slug=photo_slug, album__slug__iexact=album_slug) if photo.slug not in self.request.session: @@ -65,10 +66,16 @@ class PhotoDetail(DetailView): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) + + # Canonical_url + canonical_url = build_canonical_url( + self.request, + self.object.get_absolute_url() + ) context.update({ 'next': self.object.get_next(), 'prev': self.object.get_prev(), - 'canonical_url': self.request.build_absolute_uri(self.object.get_absolute_url()), + 'canonical_url': canonical_url, 'liked': self.request.session.get(f"liked_{self.object.slug}", False) }) return context @@ -131,10 +138,16 @@ class PhotoSlideshow(DetailView): if not next_photo: next_photo = Photo.objects.filter(album=current_photo.album).order_by('taken_at').first() + # Canonical_url + canonical_url = build_canonical_url( + self.request, + current_photo.get_slideshow_url() + ) + context.update({ 'next_photo': next_photo, 'liked': self.request.session.get(f"liked_{current_photo.slug}", False), - 'canonical_url': self.request.build_absolute_uri(current_photo.get_slideshow_url()), + 'canonical_url': canonical_url, }) return context