X-Git-Url: https://git.mdrn.pl/wolnelektury.git/blobdiff_plain/3badd77f743883992829a1174eef7c8d5e851766..ad9d29909733d402b8c197cb7c5d46afe887fa15:/apps/catalogue/models.py diff --git a/apps/catalogue/models.py b/apps/catalogue/models.py index 1f6210d20..cace1a596 100644 --- a/apps/catalogue/models.py +++ b/apps/catalogue/models.py @@ -16,7 +16,7 @@ from django.utils.datastructures import SortedDict from django.utils.safestring import mark_safe from django.utils.translation import get_language from django.core.urlresolvers import reverse -from django.db.models.signals import post_save, m2m_changed, pre_delete +from django.db.models.signals import post_save, m2m_changed, pre_delete, post_delete import jsonfield from django.conf import settings @@ -24,7 +24,7 @@ from django.conf import settings from newtagging.models import TagBase, tags_updated from newtagging import managers from catalogue.fields import JSONField, OverwritingFileField -from catalogue.utils import create_zip, split_tags +from catalogue.utils import create_zip, split_tags, truncate_html_words from catalogue.tasks import touch_tag, index_book from shutil import copy from glob import glob @@ -565,7 +565,6 @@ class Book(models.Model): def build_html(self): - from markupstring import MarkupString from django.core.files.base import ContentFile from slughifi import slughifi from librarian import html @@ -609,9 +608,9 @@ class Book(models.Model): continue text = fragment.to_string() - short_text = '' - if (len(MarkupString(text)) > 240): - short_text = unicode(MarkupString(text)[:160]) + short_text = truncate_html_words(text, 15) + if text == short_text: + short_text = '' new_fragment = Fragment.objects.create(anchor=fragment.id, book=self, text=text, short_text=short_text) @@ -644,7 +643,7 @@ class Book(models.Model): result = create_zip.delay(paths, "%s_%s" % (self.slug, format_)) return result.wait() - def search_index(self, book_info=None, reuse_index=False): + def search_index(self, book_info=None, reuse_index=False, index_tags=True): if reuse_index: idx = search.ReusableIndex() else: @@ -653,7 +652,8 @@ class Book(models.Model): idx.open() try: idx.index_book(self, book_info) - idx.index_tags() + if index_tags: + idx.index_tags() finally: idx.close() @@ -676,7 +676,7 @@ class Book(models.Model): @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, - search_index=True): + search_index=True, search_index_tags=True, search_index_reuse=False): import re from sortify import sortify @@ -748,7 +748,8 @@ class Book(models.Model): book.build_mobi() if not settings.NO_SEARCH_INDEX and search_index: - index_book.delay(book.id, book_info) + book.search_index(index_tags=search_index_tags, reuse_index=search_index_reuse) + #index_book.delay(book.id, book_info) book_descendants = list(book.children.all()) descendants_tags = set() @@ -763,7 +764,7 @@ class Book(models.Model): book_descendants += list(child_book.children.all()) for tag in descendants_tags: - touch_tag.delay(tag) + touch_tag(tag) book.save() @@ -780,14 +781,26 @@ class Book(models.Model): return self._related_info else: rel = {'tags': {}, 'media': {}} + tags = self.tags.filter(category__in=( 'author', 'kind', 'genre', 'epoch')) tags = split_tags(tags) for category in tags: rel['tags'][category] = [ - (t.name, t.get_absolute_url()) for t in tags[category]] + (t.name, t.slug) for t in tags[category]] + for media_format in BookMedia.formats: rel['media'][media_format] = self.has_media(media_format) + + book = self + parents = [] + while book.parent: + parents.append((book.parent.title, book.parent.slug)) + book = book.parent + parents = parents[::-1] + if parents: + rel['parents'] = parents + if self.pk: type(self).objects.filter(pk=self.pk).update(_related_info=rel) return rel @@ -934,6 +947,16 @@ class Book(models.Model): audiences = sorted(set([self._audiences_pl[a] for a in audiences])) return [a[1] for a in audiences] + def choose_fragment(self): + tag = self.book_tag() + fragments = Fragment.tagged.with_any([tag]) + if fragments.exists(): + return fragments.order_by('?')[0] + elif self.parent: + return self.parent.choose_fragment() + else: + return None + def _has_factory(ftype): has = lambda self: bool(getattr(self, "%s_file" % ftype)) @@ -979,6 +1002,10 @@ class Fragment(models.Model): for lang, langname in settings.LANGUAGES: permanent_cache.delete(cache_key % (self.id, lang)) + def get_short_text(self): + """Returns short version of the fragment.""" + return self.short_text if self.short_text else self.text + def short_html(self): if self.id: cache_key = "Fragment.short_html/%d/%s" % (self.id, get_language()) @@ -1025,7 +1052,7 @@ def _tags_updated_handler(sender, affected_tags, **kwargs): # reset tag global counter # we want Tag.changed_at updated for API to know the tag was touched for tag in affected_tags: - touch_tag.delay(tag) + touch_tag(tag) # if book tags changed, reset book tag counter if isinstance(sender, Book) and \ @@ -1046,8 +1073,20 @@ def _pre_delete_handler(sender, instance, **kwargs): instance.book.save() pre_delete.connect(_pre_delete_handler) + def _post_save_handler(sender, instance, **kwargs): """ refresh all the short_html stuff on BookMedia update """ if sender == BookMedia: instance.book.save() post_save.connect(_post_save_handler) + + +@django.dispatch.receiver(post_delete, sender=Book) +def _remove_book_from_index_handler(sender, instance, **kwargs): + """ remove the book from search index, when it is deleted.""" + idx = search.Index() + idx.open(timeout=10000) # 10 seconds timeout. + try: + idx.remove_book(instance) + finally: + idx.close()