From e9f9c3887d9c9e45401257a78d3182f17a5a8146 Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Thu, 16 Oct 2014 16:38:29 +0200 Subject: [PATCH] Fixes #3211, fixes #3211: related books and pictures bars. --- apps/catalogue/__init__.py | 1 + .../templates/catalogue/related_books.html | 17 ++++++-- apps/catalogue/templatetags/catalogue_tags.py | 40 +++++++++++++++---- apps/catalogue/urls.py | 1 + apps/picture/models.py | 1 + .../templates/picture/picture_detail.html | 9 +++++ .../templates/picture/picture_list_thumb.html | 15 +++---- .../templates/picture/picture_mini_box.html | 22 +++++----- .../templates/picture/picture_wide.html | 2 +- apps/picture/templatetags/picture_tags.py | 21 +++++++++- apps/picture/views.py | 12 ++++++ 11 files changed, 107 insertions(+), 34 deletions(-) diff --git a/apps/catalogue/__init__.py b/apps/catalogue/__init__.py index f3d44e104..eaeb7d468 100644 --- a/apps/catalogue/__init__.py +++ b/apps/catalogue/__init__.py @@ -24,6 +24,7 @@ class Settings(AppSettings): REDAKCJA_URL = "http://redakcja.wolnelektury.pl" GOOD_LICENSES = set([r'CC BY \d\.\d', r'CC BY-SA \d\.\d']) + RELATED_RANDOM_PICTURE_CHANCE = .5 def _more_DONT_BUILD(self, value): for format_ in ['cover', 'pdf', 'epub', 'mobi', 'fb2', 'txt']: diff --git a/apps/catalogue/templates/catalogue/related_books.html b/apps/catalogue/templates/catalogue/related_books.html index 48fb2eeaf..6407d5a04 100755 --- a/apps/catalogue/templates/catalogue/related_books.html +++ b/apps/catalogue/templates/catalogue/related_books.html @@ -1,16 +1,25 @@ {% spaceless %} {% load catalogue_random_book from catalogue_tags %} +{% load picture_random_picture from picture_tags %} {% load ssi_include from ssify %} +{% for pic in pics %} + {% ssi_include 'picture_mini' pk=pic.pk %} +{% endfor %} + {% for book in books %} {% ssi_include 'catalogue_book_mini' pk=book.pk %} {% endfor %} {% if random %} - {% catalogue_random_book random_excluded as random_pk %} - {{ random_pk.if }} - {% ssi_include 'catalogue_book_mini' pk=random_pk %} - {{ random_pk.endif }} + {% catalogue_random_book random_excluded_books as random_book_pk %} + {% picture_random_picture random_excluded_pics unless=random_book_pk as random_pic_pk %} + {{ random_book_pk.if }} + {% ssi_include 'catalogue_book_mini' pk=random_book_pk %} + {{ random_book_pk.endif }} + {{ random_pic_pk.if }} + {% ssi_include 'picture_mini' pk=random_pic_pk %} + {{ random_pic_pk.endif }} {% endif %} {% endspaceless %} \ No newline at end of file diff --git a/apps/catalogue/templatetags/catalogue_tags.py b/apps/catalogue/templatetags/catalogue_tags.py index f9c69ea7d..6e81caec2 100644 --- a/apps/catalogue/templatetags/catalogue_tags.py +++ b/apps/catalogue/templatetags/catalogue_tags.py @@ -2,7 +2,7 @@ # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later. # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. # -from random import randint +from random import randint, random from urlparse import urlparse from django.conf import settings @@ -311,18 +311,39 @@ def work_list(context, object_list): return locals() +# TODO: These are no longer just books. @register.inclusion_tag('catalogue/related_books.html', takes_context=True) -def related_books(context, book, limit=6, random=1, taken=0): +def related_books(context, instance, limit=6, random=1, taken=0): limit = limit - taken - related = Book.tagged.related_to(book, - Book.objects.exclude(common_slug=book.common_slug) - ).exclude(ancestor=book)[:limit-random] - random_excluded = [b.pk for b in related] + [book.pk] + max_books = limit - random + is_picture = isinstance(instance, Picture) + + pics_qs = Picture.objects.all() + if is_picture: + pics_qs = pics_qs.exclude(pk=instance.pk) + pics = Picture.tagged.related_to(instance, pics_qs) + if pics.exists(): + # Reserve one spot for an image. + max_books -= 1 + + books_qs = Book.objects.all() + if not is_picture: + books_qs = books_qs.exclude(common_slug=instance.common_slug).exclude(ancestor=instance) + books = Book.tagged.related_to(instance, books_qs)[:max_books] + + pics = pics[:1 + max_books - books.count()] + + random_excluded_books = [b.pk for b in books] + random_excluded_pics = [p.pk for p in pics] + (random_excluded_pics if is_picture else random_excluded_books).append(instance.pk) + return { 'request': context['request'], - 'books': related, + 'books': books, + 'pics': pics, 'random': random, - 'random_excluded': random_excluded, + 'random_excluded_books': random_excluded_books, + 'random_excluded_pics': random_excluded_pics, } @@ -395,6 +416,9 @@ def source_name(url): @ssi_variable(register, patch_response=[add_never_cache_headers]) def catalogue_random_book(request, exclude_ids): + from .. import app_settings + if random() < app_settings.RELATED_RANDOM_PICTURE_CHANCE: + return None queryset = Book.objects.exclude(pk__in=exclude_ids) count = queryset.count() if count: diff --git a/apps/catalogue/urls.py b/apps/catalogue/urls.py index 05f876607..6e98fb094 100644 --- a/apps/catalogue/urls.py +++ b/apps/catalogue/urls.py @@ -18,6 +18,7 @@ urlpatterns = patterns('picture.views', url(r'^obraz/(?P%s).html$' % SLUG, 'picture_viewer', name='picture_viewer'), url(r'^obraz/(?P%s)/$' % SLUG, 'picture_detail'), + url(r'^p/(?P\d+)/mini\.(?P.+)\.html', 'picture_mini', name='picture_mini'), url(r'^p/(?P\d+)/short\.(?P.+)\.html', 'picture_short', name='picture_short'), url(r'^pa/(?P\d+)/short\.(?P.+)\.html', 'picturearea_short', name='picture_area_short'), ) diff --git a/apps/picture/models.py b/apps/picture/models.py index 120750d7c..97dbd0ec2 100644 --- a/apps/picture/models.py +++ b/apps/picture/models.py @@ -340,6 +340,7 @@ class Picture(models.Model): template % (self.pk, lang) for template in [ '/katalog/p/%d/short.%s.html', + '/katalog/p/%d/mini.%s.html', ] for lang in languages ]) diff --git a/apps/picture/templates/picture/picture_detail.html b/apps/picture/templates/picture/picture_detail.html index 51bd6b98f..514f8c3e8 100644 --- a/apps/picture/templates/picture/picture_detail.html +++ b/apps/picture/templates/picture/picture_detail.html @@ -14,4 +14,13 @@ {% block body %} {% picture_wide picture %} + +{% spaceless %} + +
+

{% trans "See also" %}:

+{% related_books picture %} +
+{% endspaceless %} + {% endblock %} diff --git a/apps/picture/templates/picture/picture_list_thumb.html b/apps/picture/templates/picture/picture_list_thumb.html index 4fce98a68..4c2933c10 100644 --- a/apps/picture/templates/picture/picture_list_thumb.html +++ b/apps/picture/templates/picture/picture_list_thumb.html @@ -1,5 +1,6 @@ {% extends "base.html" %} {% load i18n %} +{% load catalogue_tags %} {% load static %} {% load ssi_include from ssify %} @@ -24,15 +25,11 @@
-
-
    {% spaceless %} -{% for picture in book_list %} -
  1. - {% ssi_include 'picture_short' pk=picture.pk %} -
  2. -{% endfor %} - {% endspaceless %}
-
+ + + +{% work_list book_list %} + diff --git a/apps/picture/templates/picture/picture_mini_box.html b/apps/picture/templates/picture/picture_mini_box.html index 5df989e05..d8ebbf77b 100644 --- a/apps/picture/templates/picture/picture_mini_box.html +++ b/apps/picture/templates/picture/picture_mini_box.html @@ -1,21 +1,23 @@ +{% spaceless %} {% load thumbnail %} +{% endspaceless %} \ No newline at end of file diff --git a/apps/picture/templates/picture/picture_wide.html b/apps/picture/templates/picture/picture_wide.html index 920a9c060..e2fab8cab 100644 --- a/apps/picture/templates/picture/picture_wide.html +++ b/apps/picture/templates/picture/picture_wide.html @@ -7,7 +7,7 @@ {% block picture-view %} -{% thumbnail picture.image_file "535" upscale="false" as thumb %} +{% thumbnail picture.image_file "535" upscale=0 as thumb %} {% endthumbnail %} {% endblock %} diff --git a/apps/picture/templatetags/picture_tags.py b/apps/picture/templatetags/picture_tags.py index 76ae1dece..02d80b005 100644 --- a/apps/picture/templatetags/picture_tags.py +++ b/apps/picture/templatetags/picture_tags.py @@ -2,12 +2,17 @@ # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later. # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. # +import logging +from random import randint from django import template from django.core.urlresolvers import reverse +from django.utils.cache import add_never_cache_headers +import sorl.thumbnail.default +from ssify import ssi_variable from catalogue.utils import split_tags from ..engine import CustomCroppingEngine -import sorl.thumbnail.default -import logging +from ..models import Picture + register = template.Library() @@ -56,3 +61,15 @@ def area_thumbnail_url(area, geometry): sorl.thumbnail.default.engine = _engine return th.url + + +@ssi_variable(register, patch_response=[add_never_cache_headers]) +def picture_random_picture(request, exclude_ids, unless=None): + if unless: + return None + queryset = Picture.objects.exclude(pk__in=exclude_ids).exclude(image_file='') + count = queryset.count() + if count: + return queryset[randint(0, count - 1)].pk + else: + return None diff --git a/apps/picture/views.py b/apps/picture/views.py index 4bc2ab04b..78700d137 100644 --- a/apps/picture/views.py +++ b/apps/picture/views.py @@ -88,6 +88,18 @@ def import_picture(request): return HttpResponse(_("Error importing file: %r") % import_form.errors) +@ssi_included +def picture_mini(request, pk, with_link=True): + picture = get_object_or_404(Picture, pk=pk) + author_str = ", ".join(tag.name + for tag in picture.tags.filter(category='author')) + return render(request, 'picture/picture_mini_box.html', { + 'picture': picture, + 'author_str': author_str, + 'with_link': with_link, + }) + + @ssi_included def picture_short(request, pk): picture = get_object_or_404(Picture, pk=pk) -- 2.20.1