X-Git-Url: https://git.mdrn.pl/wolnelektury.git/blobdiff_plain/f906193db2ec44590f57beae2e8ee2df76117b7b..6c071c6cbb739209e9d8488ff7080f8ad7c7d2d0:/apps/catalogue/models.py?ds=inline diff --git a/apps/catalogue/models.py b/apps/catalogue/models.py index 2b33964c2..f92ebd38b 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 @@ -24,7 +23,8 @@ 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 +from catalogue.utils import create_zip, split_tags +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): @@ -178,12 +174,16 @@ class Tag(TagBase): 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': tag_sort_key = tag_name.last_name - tag_name = ' '.join(tag_name.first_names) + ' ' + 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 @@ -359,6 +359,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'] @@ -488,6 +490,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.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() @@ -502,22 +505,17 @@ class Book(models.Model): 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'%s' % (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 = [] # files generated during publication - if self.has_media("html"): - formats.append(u'%s' % (reverse('book_text', args=[self.fileid()]), _('Read online'))) for ebook_format in self.ebook_formats: if self.has_media(ebook_format): formats.append(u'%s' % ( self.get_media(ebook_format).url, ebook_format.upper() )) - # other files - for m in self.media.order_by('type'): - formats.append(u'%s' % (m.file.url, m.type.upper())) formats = [mark_safe(format) for format in formats] @@ -530,7 +528,7 @@ class Book(models.Model): 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 @@ -574,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. @@ -792,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() @@ -802,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 @@ -1034,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 \