+ def get_extra_info_json(self):
+ return json.loads(self.extra_info or '{}')
+
+ def get_initial(self):
+ try:
+ return re.search(r'\w', self.title, re.U).group(0)
+ except AttributeError:
+ return ''
+
+ def authors(self):
+ return self.tags.filter(category='author')
+
+ def epochs(self):
+ return self.tags.filter(category='epoch')
+
+ def genres(self):
+ return self.tags.filter(category='genre')
+
+ def kinds(self):
+ return self.tags.filter(category='kind')
+
+ 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 tags_by_category(self):
+ return split_tags(self.tags.exclude(category__in=('set', 'theme')))
+
+ def author_unicode(self):
+ return self.cached_author
+
+ def kind_unicode(self):
+ return self.tag_unicode('kind')
+
+ def epoch_unicode(self):
+ return self.tag_unicode('epoch')
+
+ def genre_unicode(self):
+ return self.tag_unicode('genre')
+
+ def translators(self):
+ translators = self.get_extra_info_json().get('translators') or []
+ return [
+ '\xa0'.join(reversed(translator.split(', ', 1))) for translator in translators
+ ]
+
+ def translator(self):
+ translators = self.get_extra_info_json().get('translators')
+ if not translators:
+ return None
+ if len(translators) > 3:
+ translators = translators[:2]
+ others = ' i inni'
+ else:
+ others = ''
+ return ', '.join('\xa0'.join(reversed(translator.split(', ', 1))) for translator in translators) + others
+
+ def cover_source(self):
+ return self.get_extra_info_json().get('cover_source', self.parent.cover_source() if self.parent else '')
+
+ @property
+ def isbn_pdf(self):
+ return self.get_extra_info_json().get('isbn_pdf')
+
+ @property
+ def isbn_epub(self):
+ return self.get_extra_info_json().get('isbn_epub')
+
+ @property
+ def isbn_mobi(self):
+ return self.get_extra_info_json().get('isbn_mobi')
+
+