X-Git-Url: https://git.mdrn.pl/wolnelektury.git/blobdiff_plain/429d452d276b0767debec6a83e4c5d200d244bc0..ac05eb781dae22cef8d2d08f5b039e18b3274344:/src/catalogue/models/book.py?ds=sidebyside diff --git a/src/catalogue/models/book.py b/src/catalogue/models/book.py index a4017fbb9..00921b899 100644 --- a/src/catalogue/models/book.py +++ b/src/catalogue/models/book.py @@ -13,7 +13,7 @@ from django.db.models import permalink import django.dispatch from django.contrib.contenttypes.fields import GenericRelation from django.core.urlresolvers import reverse -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import ugettext_lazy as _, get_language import jsonfield from fnpdjango.storage import BofhFileSystemStorage from ssify import flush_ssi_includes @@ -22,6 +22,7 @@ from catalogue import constants from catalogue.fields import EbookField from catalogue.models import Tag, Fragment, BookMedia from catalogue.utils import create_zip, gallery_url, gallery_path +from catalogue.models.tag import prefetched_relations from catalogue import app_settings from catalogue import tasks from wolnelektury.utils import makedirs @@ -59,6 +60,8 @@ class Book(models.Model): extra_info = jsonfield.JSONField(_('extra information'), default={}) gazeta_link = models.CharField(blank=True, max_length=240) wiki_link = models.CharField(blank=True, max_length=240) + print_on_demand = models.BooleanField(_('print on demand'), default=False) + recommended = models.BooleanField(_('recommended'), default=False) # files generated during publication cover = EbookField( @@ -78,6 +81,9 @@ class Book(models.Model): parent = models.ForeignKey('self', blank=True, null=True, related_name='children') ancestor = models.ManyToManyField('self', blank=True, editable=False, related_name='descendant', symmetrical=False) + cached_author = models.CharField(blank=True, max_length=240, db_index=True) + has_audience = models.BooleanField(default=False) + objects = models.Manager() tagged = managers.ModelTaggedItemManager(Tag) tags = managers.TagDescriptor(Tag) @@ -92,7 +98,7 @@ class Book(models.Model): pass class Meta: - ordering = ('sort_key',) + ordering = ('sort_key_author', 'sort_key') verbose_name = _('book') verbose_name_plural = _('books') app_label = 'catalogue' @@ -106,8 +112,32 @@ class Book(models.Model): except AttributeError: return '' - def author_str(self): - return ", ".join(str(t) for t in self.tags.filter(category='author')) + def authors(self): + return self.tags.filter(category='author') + + def tag_unicode(self, category): + relations = prefetched_relations(self, category) + if relations: + return ', '.join(rel.tag.name for rel in relations) + else: + return ', '.join(self.tags.filter(category=category).values_list('name', flat=True)) + + def author_unicode(self): + return self.cached_author + + def translator(self): + translators = self.extra_info.get('translators') + if not translators: + return None + if len(translators) > 3: + translators = translators[:2] + others = ' i inni' + else: + others = '' + return ', '.join(u'\xa0'.join(reversed(translator.split(', ', 1))) for translator in translators) + others + + def cover_source(self): + return self.extra_info.get('cover_source', self.parent.cover_source() if self.parent else '') def save(self, force_insert=False, force_update=False, **kwargs): from sortify import sortify @@ -116,11 +146,14 @@ class Book(models.Model): self.title = unicode(self.title) # ??? try: - author = self.tags.filter(category='author')[0].sort_key - except IndexError: + author = self.authors().first().sort_key + except AttributeError: author = u'' self.sort_key_author = author + self.cached_author = self.tag_unicode('author') + self.has_audience = 'audience' in self.extra_info + ret = super(Book, self).save(force_insert, force_update, **kwargs) return ret @@ -150,6 +183,9 @@ class Book(models.Model): def language_name(self): return dict(settings.LANGUAGES).get(self.language_code(), "") + def is_foreign(self): + return self.language_code() != settings.LANGUAGE_CODE + def has_media(self, type_): if type_ in Book.formats: return bool(getattr(self, "%s_file" % type_)) @@ -248,9 +284,10 @@ class Book(models.Model): def download_pictures(self, remote_gallery_url): gallery_path = self.gallery_path() # delete previous files, so we don't include old files in ebooks - for filename in os.listdir(gallery_path): - file_path = os.path.join(gallery_path, filename) - os.unlink(file_path) + if os.path.isdir(gallery_path): + for filename in os.listdir(gallery_path): + file_path = os.path.join(gallery_path, filename) + os.unlink(file_path) ilustr_elements = list(self.wldocument().edoc.findall('//ilustr')) if ilustr_elements: makedirs(gallery_path) @@ -371,6 +408,7 @@ class Book(models.Model): for child in notify_cover_changed: child.parent_cover_changed() + book.save() # update sort_key_author cls.published.send(sender=cls, instance=book) return book @@ -474,7 +512,7 @@ class Book(models.Model): return books def pretty_title(self, html_links=False): - names = [(tag.name, tag.get_absolute_url()) for tag in self.tags.filter(category='author')] + names = [(tag.name, tag.get_absolute_url()) for tag in self.authors().only('name', 'category', 'slug')] books = self.parents() + [self] names.extend([(b.title, b.get_absolute_url()) for b in books]) @@ -484,6 +522,13 @@ class Book(models.Model): names = [tag[0] for tag in names] return ', '.join(names) + def publisher(self): + publisher = self.extra_info['publisher'] + if isinstance(publisher, basestring): + return publisher + elif isinstance(publisher, list): + return ', '.join(publisher) + @classmethod def tagged_top_level(cls, tags): """ Returns top-level books tagged with `tags`. @@ -504,8 +549,7 @@ class Book(models.Model): """ books_by_parent = {} - books = cls.objects.all().order_by('parent_number', 'sort_key').only( - 'title', 'parent', 'slug') + books = cls.objects.order_by('parent_number', 'sort_key').only('title', 'parent', 'slug') if book_filter: books = books.filter(book_filter).distinct() @@ -525,7 +569,7 @@ class Book(models.Model): books_by_author[tag] = [] for book in books_by_parent.get(None, ()): - authors = list(book.tags.filter(category='author')) + authors = list(book.authors().only('pk')) if authors: for author in authors: books_by_author[author].append(book) @@ -538,6 +582,7 @@ class Book(models.Model): "SP": (1, u"szkoła podstawowa"), "SP1": (1, u"szkoła podstawowa"), "SP2": (1, u"szkoła podstawowa"), + "SP3": (1, u"szkoła podstawowa"), "P": (1, u"szkoła podstawowa"), "G": (2, u"gimnazjum"), "L": (3, u"liceum"), @@ -570,6 +615,25 @@ class Book(models.Model): else: return None + def fragment_data(self): + fragment = self.choose_fragment() + if fragment: + return {'title': fragment.book.pretty_title(), 'html': fragment.get_short_text()} + else: + return None + + def update_popularity(self): + count = self.tags.filter(category='set').values('user').order_by('user').distinct().count() + try: + pop = self.popularity + pop.count = count + pop.save() + except BookPopularity.DoesNotExist: + BookPopularity.objects.create(book=self, count=count) + + def ridero_link(self): + return 'https://ridero.eu/%s/books/wl_%s/' % (get_language(), self.slug.replace('-', '_')) + def add_file_fields(): for format_ in Book.formats: @@ -589,3 +653,8 @@ def add_file_fields(): ).contribute_to_class(Book, field_name) add_file_fields() + + +class BookPopularity(models.Model): + book = models.OneToOneField(Book, related_name='popularity') + count = models.IntegerField(default=0)