+ if self.parent:
+ # don't need an epub
+ return
+
+ epub_file = StringIO()
+ try:
+ epub.transform(BookImportDocProvider(self), self.slug, output_file=epub_file)
+ self.epub_file.save('%s.epub' % self.slug, ContentFile(epub_file.getvalue()))
+ FileRecord(slug=self.slug, type='epub', sha1=sha1(epub_file.getvalue()).hexdigest()).save()
+ except NoDublinCore:
+ pass
+
+ book_descendants = list(self.children.all())
+ while len(book_descendants) > 0:
+ child_book = book_descendants.pop(0)
+ if remove_descendants and child_book.has_epub_file():
+ child_book.epub_file.delete()
+ # save anyway, to refresh short_html
+ child_book.save()
+ book_descendants += list(child_book.children.all())
+
+ def build_txt(self):
+ from StringIO import StringIO
+ from django.core.files.base import ContentFile
+ from librarian import text
+
+ out = StringIO()
+ text.transform(open(self.xml_file.path), out)
+ self.txt_file.save('%s.txt' % self.slug, ContentFile(out.getvalue()))
+
+
+ def build_html(self):
+ from tempfile import NamedTemporaryFile
+ from markupstring import MarkupString
+
+ meta_tags = list(self.tags.filter(
+ category__in=('author', 'epoch', 'genre', 'kind')))
+ book_tag = self.book_tag()
+
+ html_file = NamedTemporaryFile()
+ if html.transform(self.xml_file.path, html_file, parse_dublincore=False):
+ self.html_file.save('%s.html' % self.slug, File(html_file))
+
+ # get ancestor l-tags for adding to new fragments
+ ancestor_tags = []
+ p = self.parent
+ while p:
+ ancestor_tags.append(p.book_tag())
+ p = p.parent
+
+ # Delete old fragments and create them from scratch
+ self.fragments.all().delete()
+ # Extract fragments
+ closed_fragments, open_fragments = html.extract_fragments(self.html_file.path)
+ for fragment in closed_fragments.values():
+ try:
+ theme_names = [s.strip() for s in fragment.themes.split(',')]
+ except AttributeError:
+ continue
+ themes = []
+ for theme_name in theme_names:
+ if not theme_name:
+ continue
+ tag, created = Tag.objects.get_or_create(slug=slughifi(theme_name), category='theme')
+ if created:
+ tag.name = theme_name
+ tag.sort_key = theme_name.lower()
+ tag.save()
+ themes.append(tag)
+ if not themes:
+ continue
+
+ text = fragment.to_string()
+ short_text = ''
+ if (len(MarkupString(text)) > 240):
+ short_text = unicode(MarkupString(text)[:160])
+ new_fragment = Fragment.objects.create(anchor=fragment.id, book=self,
+ text=text, short_text=short_text)
+
+ new_fragment.save()
+ new_fragment.tags = set(meta_tags + themes + [book_tag] + ancestor_tags)
+ self.save()
+ return True
+ return False
+
+
+ @classmethod
+ def from_xml_file(cls, xml_file, **kwargs):
+ # 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):
+ import re
+
+ # check for parts before we do anything
+ children = []
+ if hasattr(book_info, 'parts'):
+ for part_url in book_info.parts:
+ base, slug = part_url.rsplit('/', 1)
+ try:
+ children.append(Book.objects.get(slug=slug))
+ except Book.DoesNotExist, e:
+ raise Book.DoesNotExist(_('Book with slug = "%s" does not exist.') % slug)
+
+