X-Git-Url: https://git.mdrn.pl/wolnelektury.git/blobdiff_plain/142cf364fb3fc7cd95df709126ada97b6944c128..06ae2ba67e697b8fa06229fc3117d4b081db1130:/apps/catalogue/models.py diff --git a/apps/catalogue/models.py b/apps/catalogue/models.py index 3fd80ef8a..8b65d4bbb 100644 --- a/apps/catalogue/models.py +++ b/apps/catalogue/models.py @@ -3,7 +3,6 @@ # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. # from collections import namedtuple -from datetime import datetime from django.db import models from django.db.models import permalink, Q @@ -25,6 +24,7 @@ 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 shutil import copy from glob import glob import re @@ -61,7 +61,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) - 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) @@ -106,25 +105,22 @@ class Tag(TagBase): has_description.boolean = True def get_count(self): - """ returns global book count for book tags, fragment count for themes """ - - if self.book_count is None: - if self.category == 'book': - # never used - objects = Book.objects.none() - elif self.category == 'theme': - objects = Fragment.tagged.with_all((self,)) - else: - objects = Book.tagged.with_all((self,)).order_by() - if self.category != 'set': - # eliminate descendants - l_tags = Tag.objects.filter(slug__in=[book.book_tag_slug() for book in objects]) - descendants_keys = [book.pk for book in Book.tagged.with_any(l_tags)] - if descendants_keys: - objects = objects.exclude(pk__in=descendants_keys) - self.book_count = objects.count() - self.save() - return self.book_count + """Returns global book count for book tags, fragment count for themes.""" + + if self.category == 'book': + # never used + objects = Book.objects.none() + elif self.category == 'theme': + objects = Fragment.tagged.with_all((self,)) + else: + objects = Book.tagged.with_all((self,)).order_by() + if self.category != 'set': + # eliminate descendants + l_tags = Tag.objects.filter(slug__in=[book.book_tag_slug() for book in objects]) + descendants_keys = [book.pk for book in Book.tagged.with_any(l_tags)] + if descendants_keys: + objects = objects.exclude(pk__in=descendants_keys) + return objects.count() @staticmethod def get_tag_list(tags): @@ -168,6 +164,31 @@ class Tag(TagBase): def url_chunk(self): return '/'.join((Tag.categories_dict[self.category], self.slug)) + @staticmethod + def tags_from_info(info): + from slughifi import slughifi + from sortify import sortify + meta_tags = [] + categories = (('kinds', 'kind'), ('genres', 'genre'), ('authors', 'author'), ('epochs', 'epoch')) + for field_name, category in categories: + try: + tag_names = getattr(info, field_name) + except: + tag_names = [getattr(info, category)] + for tag_name in tag_names: + tag_sort_key = tag_name + if category == 'author': + tag_sort_key = tag_name.last_name + tag_name = tag_name.readable() + tag, created = Tag.objects.get_or_create(slug=slughifi(tag_name), category=category) + if created: + tag.name = tag_name + tag.sort_key = sortify(tag_sort_key.lower()) + tag.save() + meta_tags.append(tag) + return meta_tags + + def get_dynamic_path(media, filename, ext=None, maxlen=100): from slughifi import slughifi @@ -334,6 +355,8 @@ class Book(models.Model): wiki_link = models.CharField(blank=True, max_length=240) # files generated during publication + cover = models.FileField(_('cover'), upload_to=book_upload_path('png'), + null=True, blank=True) ebook_formats = ['pdf', 'epub', 'mobi', 'txt'] formats = ebook_formats + ['html', 'xml'] @@ -549,6 +572,20 @@ class Book(models.Model): provider=ORMDocProvider(self), parse_dublincore=parse_dublincore) + def build_cover(self, book_info=None): + """(Re)builds the cover image.""" + from StringIO import StringIO + from django.core.files.base import ContentFile + from librarian.cover import WLCover + + if book_info is None: + book_info = self.wldocument().book_info + + cover = WLCover(book_info).image() + imgstr = StringIO() + cover.save(imgstr, 'png') + self.cover.save(None, ContentFile(imgstr.getvalue())) + def build_pdf(self, customizations=None, file_name=None): """ (Re)builds the pdf file. customizations - customizations which are passed to LaTeX class file. @@ -712,7 +749,6 @@ class Book(models.Model): def from_text_and_meta(cls, raw_file, book_info, overwrite=False, build_epub=True, build_txt=True, build_pdf=True, build_mobi=True): import re - from slughifi import slughifi from sortify import sortify # check for parts before we do anything @@ -747,24 +783,7 @@ class Book(models.Model): book.set_extra_info_value(book_info.to_dict()) book.save() - meta_tags = [] - categories = (('kinds', 'kind'), ('genres', 'genre'), ('authors', 'author'), ('epochs', 'epoch')) - for field_name, category in categories: - try: - tag_names = getattr(book_info, field_name) - except: - tag_names = [getattr(book_info, category)] - for tag_name in tag_names: - tag_sort_key = tag_name - if category == 'author': - tag_sort_key = tag_name.last_name - tag_name = ' '.join(tag_name.first_names) + ' ' + tag_name.last_name - tag, created = Tag.objects.get_or_create(slug=slughifi(tag_name), category=category) - if created: - tag.name = tag_name - tag.sort_key = sortify(tag_sort_key.lower()) - tag.save() - meta_tags.append(tag) + meta_tags = Tag.tags_from_info(book_info) book.tags = set(meta_tags + book_shelves) @@ -785,6 +804,8 @@ class Book(models.Model): if not settings.NO_BUILD_TXT and build_txt: book.build_txt() + book.build_cover(book_info) + if not settings.NO_BUILD_EPUB and build_epub: book.build_epub() @@ -795,15 +816,20 @@ class Book(models.Model): book.build_mobi() book_descendants = list(book.children.all()) + descendants_tags = set() # add l-tag to descendants and their fragments while len(book_descendants) > 0: child_book = book_descendants.pop(0) + descendants_tags.update(child_book.tags) child_book.tags = list(child_book.tags) + [book_tag] child_book.save() for fragment in child_book.fragments.all(): fragment.tags = set(list(fragment.tags) + [book_tag]) book_descendants += list(child_book.children.all()) + for tag in descendants_tags: + touch_tag.delay(tag) + book.save() # refresh cache @@ -1027,7 +1053,8 @@ class Fragment(models.Model): 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 - Tag.objects.filter(pk__in=[tag.pk for tag in affected_tags]).update(book_count=None, changed_at=datetime.now()) + for tag in affected_tags: + touch_tag.delay(tag) # if book tags changed, reset book tag counter if isinstance(sender, Book) and \