author/title match ordering in api filter-books + fix lektura/audiobook filters
[wolnelektury.git] / src / catalogue / views.py
index fc73c71..267d9b4 100644 (file)
@@ -12,7 +12,7 @@ from django.template.loader import render_to_string
 from django.shortcuts import render_to_response, get_object_or_404, render, redirect
 from django.http import HttpResponse, HttpResponseRedirect, Http404, HttpResponsePermanentRedirect, JsonResponse
 from django.core.urlresolvers import reverse
-from django.db.models import Q
+from django.db.models import Q, QuerySet
 from django.contrib.auth.decorators import login_required, user_passes_test
 from django.utils.http import urlquote_plus
 from django.utils import translation
@@ -29,6 +29,7 @@ from catalogue import forms
 from catalogue.helpers import get_top_level_related_tags
 from catalogue.models import Book, Collection, Tag, Fragment
 from catalogue.utils import split_tags
+from catalogue.models.tag import prefetch_relations
 
 staff_required = user_passes_test(lambda user: user.is_staff)
 
@@ -103,11 +104,19 @@ def object_list(request, objects, fragments=None, related_tags=None, tags=None,
             else:
                 fragments = Fragment.objects.filter(book__in=objects)
         related_tag_lists.append(
-            Tag.objects.usage_for_queryset(fragments, counts=True).filter(category='theme').exclude(pk__in=tag_ids))
+            Tag.objects.usage_for_queryset(fragments, counts=True).filter(category='theme').exclude(pk__in=tag_ids)
+            .only('name', 'sort_key', 'category', 'slug'))
+        if isinstance(objects, QuerySet):
+            objects = prefetch_relations(objects, 'author')
 
     categories = split_tags(*related_tag_lists)
 
     objects = list(objects)
+
+    if not objects and len(tags) == 1 and list_type == 'books':
+        if PictureArea.tagged.with_any(tags).exists() or Picture.tagged.with_any(tags).exists():
+            return redirect('tagged_object_list_gallery', '/'.join(tag.url_chunk for tag in tags))
+
     if len(objects) > 3:
         best = random.sample(objects, 3)
     else:
@@ -133,13 +142,14 @@ def object_list(request, objects, fragments=None, related_tags=None, tags=None,
 def literature(request):
     books = Book.objects.filter(parent=None)
 
-    last_published = Book.objects.exclude(cover_thumb='').filter(parent=None).order_by('-created_at')[:20]
-    most_popular = Book.objects.exclude(cover_thumb='')\
-                       .order_by('-popularity__count', 'sort_key_author', 'sort_key')[:20]
-    return object_list(request, books, related_tags=get_top_level_related_tags([]), extra={
-        'last_published': last_published,
-        'most_popular': most_popular,
-    })
+    # last_published = Book.objects.exclude(cover_thumb='').filter(parent=None).order_by('-created_at')[:20]
+    # most_popular = Book.objects.exclude(cover_thumb='')\
+    #                    .order_by('-popularity__count', 'sort_key_author', 'sort_key')[:20]
+    return object_list(request, books, related_tags=get_top_level_related_tags([]))
+    # extra={
+    #     'last_published': last_published,
+    #     'most_popular': most_popular,
+    # })
 
 
 def gallery(request):
@@ -199,11 +209,8 @@ def theme_list(request, tags, list_type):
         books = Book.tagged.with_all(shelf_tags).order_by()
         fragments = fragments.filter(Q(book__in=books) | Q(book__ancestor__in=books))
 
-    if not fragments and len(tags) == 1:
-        tag = tags[0]
-        if tag.category == 'theme' and (
-                PictureArea.tagged.with_any([tag]).exists() or
-                Picture.tagged.with_any([tag]).exists()):
+    if not fragments and len(tags) == 1 and list_type == 'books':
+        if PictureArea.tagged.with_any(tags).exists() or Picture.tagged.with_any(tags).exists():
             return redirect('tagged_object_list_gallery', '/'.join(tag.url_chunk for tag in tags))
 
     return object_list(request, fragments, tags=tags, list_type=list_type, extra={
@@ -221,7 +228,7 @@ def tagged_object_list(request, tags, list_type):
     if list_type == 'gallery' and any(tag.category == 'set' for tag in tags):
         raise Http404
 
-    if any(tag.category == 'theme' for tag in tags):
+    if any(tag.category in ('theme', 'thing') for tag in tags):
         return theme_list(request, tags, list_type=list_type)
 
     if list_type == 'books':
@@ -261,6 +268,7 @@ def book_fragments(request, slug, theme_slug):
         'book': book,
         'theme': theme,
         'fragments': fragments,
+        'active_menu_item': 'books',
     }, context_instance=RequestContext(request))
 
 
@@ -274,6 +282,7 @@ def book_detail(request, slug):
         'book': book,
         'tags': book.tags.exclude(category__in=('set', 'theme')),
         'book_children': book.children.all().order_by('parent_number', 'sort_key'),
+        'active_menu_item': 'books',
     }, context_instance=RequestContext(request))
 
 
@@ -308,7 +317,7 @@ def get_audiobooks(book):
     return audiobooks, projects, have_oggs
 
 
-# używane tylko do audiobook_tree, które jest używane tylko w snippets/audiobook_list.html, które nie jest używane
+# używane w publicznym interfejsie
 def player(request, slug):
     book = get_object_or_404(Book, slug=slug)
     if not book.has_media('mp3'):
@@ -316,8 +325,6 @@ def player(request, slug):
 
     audiobooks, projects, have_oggs = get_audiobooks(book)
 
-    # extra_info = book.extra_info
-
     return render_to_response('catalogue/player.html', {
         'book': book,
         'audiobook': '',
@@ -331,7 +338,7 @@ def book_text(request, slug):
 
     if not book.has_html_file():
         raise Http404
-    return render_to_response('catalogue/book_text.html', {'book': book,}, context_instance=RequestContext(request))
+    return render_to_response('catalogue/book_text.html', {'book': book}, context_instance=RequestContext(request))
 
 
 # ==========
@@ -351,14 +358,21 @@ def _no_diacritics_regexp(query):
 
     def repl(m):
         l = m.group()
-        return u"(%s)" % '|'.join(names[l])
+        return u"(?:%s)" % '|'.join(names[l])
 
     return re.sub(u'[%s]' % (u''.join(names.keys())), repl, query)
 
 
 def unicode_re_escape(query):
     """ Unicode-friendly version of re.escape """
-    return re.sub(r'(?u)(\W)', r'\\\1', query)
+    s = list(query)
+    for i, c in enumerate(query):
+        if re.match(r'(?u)(\W)', c) and re.match(r'[\x00-\x7e]', c):
+            if c == "\000":
+                s[i] = "\\000"
+            else:
+                s[i] = "\\" + c
+    return query[:0].join(s)
 
 
 def _word_starts_with(name, prefix):
@@ -614,6 +628,7 @@ class CustomPDFFormView(AjaxableFormView):
     form_class = forms.CustomPDFForm
     title = ugettext_lazy('Download custom PDF')
     submit = ugettext_lazy('Download')
+    template = 'catalogue/custom_pdf_form.html'
     honeypot = True
 
     def __call__(self, *args, **kwargs):
@@ -639,13 +654,14 @@ class CustomPDFFormView(AjaxableFormView):
 
 @ssi_included
 def book_mini(request, pk, with_link=True):
-    book = get_object_or_404(Book, pk=pk)
-    author_str = ", ".join(tag.name for tag in book.tags.filter(category='author'))
+    # book = get_object_or_404(Book, pk=pk)
+    try:
+        book = Book.objects.only('cover_thumb', 'title', 'language', 'slug').get(pk=pk)
+    except Book.DoesNotExist:
+        raise Http404
     return render(request, 'catalogue/book_mini_box.html', {
         'book': book,
-        'author_str': author_str,
-        'with_link': with_link,
-        'show_lang': book.language_code() != settings.LANGUAGE_CODE,
+        'no_link': not with_link,
     })
 
 
@@ -727,10 +743,10 @@ def tag_box(request, pk):
 
 @ssi_included
 def collection_box(request, pk):
-    obj = get_object_or_404(Collection, pk=pk)
+    collection = get_object_or_404(Collection, pk=pk)
 
     return render(request, 'catalogue/collection_box.html', {
-        'obj': obj,
+        'collection': collection,
     })
 
 
@@ -769,3 +785,17 @@ def collections(request):
         'objects': objects,
         'best': best,
     })
+
+
+def ridero_cover(request, slug):
+    from librarian.cover import make_cover
+    wldoc = Book.objects.get(slug=slug).wldocument()
+    cover = make_cover(wldoc.book_info, width=980, bleed=20, format='PNG')
+    response = HttpResponse(content_type="image/png")
+    cover.save(response)
+    return response
+
+
+def get_isbn(request, book_format, slug):
+    book = Book.objects.get(slug=slug)
+    return HttpResponse(book.extra_info.get('isbn_%s' % book_format))