+ new_fragment.tags = set(meta_tags + themes + [book_tag] + ancestor_tags)
+ self.save()
+ self.html_built.send(sender=self)
+ return True
+ return False
+
+ @staticmethod
+ def zip_format(format_):
+ def pretty_file_name(book):
+ return "%s/%s.%s" % (
+ b.get_extra_info_value()['author'],
+ b.slug,
+ format_)
+
+ field_name = "%s_file" % format_
+ books = Book.objects.filter(parent=None).exclude(**{field_name: ""})
+ paths = [(pretty_file_name(b), getattr(b, field_name).path)
+ for b in books]
+ result = create_zip.delay(paths,
+ getattr(settings, "ALL_%s_ZIP" % format_.upper()))
+ return result.wait()
+
+ def zip_audiobooks(self, format_):
+ bm = BookMedia.objects.filter(book=self, type=format_)
+ paths = map(lambda bm: (None, bm.file.path), bm)
+ result = create_zip.delay(paths, "%s_%s" % (self.slug, format_))
+ return result.wait()
+
+ def search_index(self, book_info=None):
+ if settings.CELERY_ALWAYS_EAGER:
+ idx = search.ReusableIndex()
+ else:
+ idx = search.Index()
+
+ idx.open()
+ try:
+ idx.index_book(self, book_info)
+ idx.index_tags()
+ finally:
+ idx.close()
+
+ @classmethod
+ def from_xml_file(cls, xml_file, **kwargs):
+ from django.core.files import File
+ from librarian import dcparser
+
+ # use librarian to parse meta-data
+ book_info = dcparser.parse(xml_file)
+
+ if not isinstance(xml_file, File):
+ xml_file = File(open(xml_file))
+
+ try:
+ return cls.from_text_and_meta(xml_file, book_info, **kwargs)
+ finally:
+ xml_file.close()
+
+ @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):
+ import re
+ from sortify import sortify
+
+ # check for parts before we do anything
+ children = []
+ if hasattr(book_info, 'parts'):
+ for part_url in book_info.parts:
+ try:
+ children.append(Book.objects.get(slug=part_url.slug))
+ except Book.DoesNotExist, e:
+ raise Book.DoesNotExist(_('Book "%s" does not exist.') %
+ part_url.slug)
+
+
+ # Read book metadata
+ book_slug = book_info.url.slug
+ if re.search(r'[^a-z0-9-]', book_slug):
+ raise ValueError('Invalid characters in slug')
+ book, created = Book.objects.get_or_create(slug=book_slug)
+
+ if created:
+ book_shelves = []
+ else:
+ if not overwrite:
+ raise Book.AlreadyExists(_('Book %s already exists') % (
+ book_slug))
+ # Save shelves for this book
+ book_shelves = list(book.tags.filter(category='set'))
+
+ book.language = book_info.language
+ book.title = book_info.title
+ if book_info.variant_of:
+ book.common_slug = book_info.variant_of.slug
+ else:
+ book.common_slug = book.slug
+ book.set_extra_info_value(book_info.to_dict())
+ book.save()
+
+ meta_tags = Tag.tags_from_info(book_info)