book detail page - now with media / custom pdf
[wolnelektury.git] / apps / catalogue / models.py
index f22c9e1..77efe6e 100644 (file)
@@ -23,14 +23,16 @@ from django.conf import settings
 from newtagging.models import TagBase, tags_updated
 from newtagging import managers
 from catalogue.fields import JSONField, OverwritingFileField
 from newtagging.models import TagBase, tags_updated
 from newtagging import managers
 from catalogue.fields import JSONField, OverwritingFileField
-from catalogue.utils import create_zip
-from catalogue.tasks import touch_tag
+from catalogue.utils import create_zip, split_tags
+from catalogue.tasks import touch_tag, index_book
 from shutil import copy
 from glob import glob
 import re
 from os import path
 
 
 from shutil import copy
 from glob import glob
 import re
 from os import path
 
 
+import search
+
 TAG_CATEGORIES = (
     ('author', _('author')),
     ('epoch', _('epoch')),
 TAG_CATEGORIES = (
     ('author', _('author')),
     ('epoch', _('epoch')),
@@ -61,7 +63,6 @@ class Tag(TagBase):
     category = models.CharField(_('category'), max_length=50, blank=False, null=False,
         db_index=True, choices=TAG_CATEGORIES)
     description = models.TextField(_('description'), blank=True)
     category = models.CharField(_('category'), max_length=50, blank=False, null=False,
         db_index=True, choices=TAG_CATEGORIES)
     description = models.TextField(_('description'), blank=True)
-    main_page = models.BooleanField(_('main page'), default=False, db_index=True, help_text=_('Show tag on main page'))
 
     user = models.ForeignKey(User, blank=True, null=True)
     book_count = models.IntegerField(_('book count'), blank=True, null=True)
 
     user = models.ForeignKey(User, blank=True, null=True)
     book_count = models.IntegerField(_('book count'), blank=True, null=True)
@@ -175,7 +176,11 @@ class Tag(TagBase):
             try:
                 tag_names = getattr(info, field_name)
             except:
             try:
                 tag_names = getattr(info, field_name)
             except:
-                tag_names = [getattr(info, category)]
+                try:
+                    tag_names = [getattr(info, category)]
+                except:
+                    # For instance, Pictures do not have 'genre' field.
+                    continue
             for tag_name in tag_names:
                 tag_sort_key = tag_name
                 if category == 'author':
             for tag_name in tag_names:
                 tag_sort_key = tag_name
                 if category == 'author':
@@ -487,6 +492,7 @@ class Book(models.Model):
         cache_key = "Book.short_html/%d/%s"
         for lang, langname in settings.LANGUAGES:
             cache.delete(cache_key % (self.id, lang))
         cache_key = "Book.short_html/%d/%s"
         for lang, langname in settings.LANGUAGES:
             cache.delete(cache_key % (self.id, lang))
+        cache.delete("Book.mini_box/%d" % (self.id, ))
         # Fragment.short_html relies on book's tags, so reset it here too
         for fragm in self.fragments.all():
             fragm.reset_short_html()
         # Fragment.short_html relies on book's tags, so reset it here too
         for fragm in self.fragments.all():
             fragm.reset_short_html()
@@ -501,24 +507,15 @@ class Book(models.Model):
         if short_html is not None:
             return mark_safe(short_html)
         else:
         if short_html is not None:
             return mark_safe(short_html)
         else:
-            tags = self.tags.filter(~Q(category__in=('set', 'theme', 'book')))
-            tags = [mark_safe(u'<a href="%s">%s</a>' % (tag.get_absolute_url(), tag.name)) for tag in tags]
+            tags = self.tags.filter(category__in=('author', 'kind', 'genre', 'epoch'))
+            tags = split_tags(tags)
 
 
-            formats = []
+            formats = {}
             # files generated during publication
             # files generated during publication
-            if self.has_media("html"):
-                formats.append(u'<a href="%s">%s</a>' % (reverse('book_text', args=[self.fileid()]), _('Read online')))
             for ebook_format in self.ebook_formats:
                 if self.has_media(ebook_format):
             for ebook_format in self.ebook_formats:
                 if self.has_media(ebook_format):
-                    formats.append(u'<a href="%s">%s</a>' % (
-                        self.get_media(ebook_format).url,
-                        ebook_format.upper()
-                    ))
-            # other files
-            for m in self.media.order_by('type'):
-                formats.append(u'<a href="%s">%s</a>' % (m.file.url, m.type.upper()))
+                    formats[ebook_format] = self.get_media(ebook_format)
 
 
-            formats = [mark_safe(format) for format in formats]
 
             short_html = unicode(render_to_string('catalogue/book_short.html',
                 {'book': self, 'tags': tags, 'formats': formats}))
 
             short_html = unicode(render_to_string('catalogue/book_short.html',
                 {'book': self, 'tags': tags, 'formats': formats}))
@@ -529,7 +526,7 @@ class Book(models.Model):
 
     def mini_box(self):
         if self.id:
 
     def mini_box(self):
         if self.id:
-            cache_key = "Book.mini_boxs/%d" % (self.id, )
+            cache_key = "Book.mini_box/%d" % (self.id, )
             short_html = cache.get(cache_key)
         else:
             short_html = None
             short_html = cache.get(cache_key)
         else:
             short_html = None
@@ -724,12 +721,25 @@ class Book(models.Model):
                     getattr(settings, "ALL_%s_ZIP" % format_.upper()))
         return result.wait()
 
                     getattr(settings, "ALL_%s_ZIP" % format_.upper()))
         return result.wait()
 
-    def zip_audiobooks(self):
-        bm = BookMedia.objects.filter(book=self, type='mp3')
+    def zip_audiobooks(self, format_):
+        bm = BookMedia.objects.filter(book=self, type=format_)
         paths = map(lambda bm: (None, bm.file.path), bm)
         paths = map(lambda bm: (None, bm.file.path), bm)
-        result = create_zip.delay(paths, self.fileid())
+        result = create_zip.delay(paths, "%s_%s" % (self.fileid(), format_))
         return result.wait()
 
         return result.wait()
 
+    def search_index(self, book_info=None):
+        if settings.CELERY_ALWAYS_EAGER:
+            idx = search.ReusableIndex()
+        else:
+            idx = search.Index()
+            
+        idx.open()
+        try:
+            idx.index_book(self, book_info)
+            idx.index_tags()
+        finally:
+            idx.close()
+
     @classmethod
     def from_xml_file(cls, xml_file, **kwargs):
         from django.core.files import File
     @classmethod
     def from_xml_file(cls, xml_file, **kwargs):
         from django.core.files import File
@@ -748,7 +758,8 @@ class Book(models.Model):
 
     @classmethod
     def from_text_and_meta(cls, raw_file, book_info, overwrite=False,
 
     @classmethod
     def from_text_and_meta(cls, raw_file, book_info, overwrite=False,
-            build_epub=True, build_txt=True, build_pdf=True, build_mobi=True):
+            build_epub=True, build_txt=True, build_pdf=True, build_mobi=True,
+            search_index=True):
         import re
         from sortify import sortify
 
         import re
         from sortify import sortify
 
@@ -816,6 +827,9 @@ class Book(models.Model):
         if not settings.NO_BUILD_MOBI and build_mobi:
             book.build_mobi()
 
         if not settings.NO_BUILD_MOBI and build_mobi:
             book.build_mobi()
 
+        if not settings.NO_SEARCH_INDEX and search_index:
+            index_book.delay(book.id, book_info)
+
         book_descendants = list(book.children.all())
         descendants_tags = set()
         # add l-tag to descendants and their fragments
         book_descendants = list(book.children.all())
         descendants_tags = set()
         # add l-tag to descendants and their fragments
@@ -1017,7 +1031,7 @@ class Fragment(models.Model):
         verbose_name_plural = _('fragments')
 
     def get_absolute_url(self):
         verbose_name_plural = _('fragments')
 
     def get_absolute_url(self):
-        return '%s#m%s' % (self.book.get_html_url(), self.anchor)
+        return '%s#m%s' % (reverse('book_text', args=[self.book.slug]), self.anchor)
 
     def reset_short_html(self):
         if self.id is None:
 
     def reset_short_html(self):
         if self.id is None: