def from_text_and_meta(cls, raw_file, book_info, overwrite=False, dont_build=None, search_index=True, search_index_tags=True, remote_gallery_url=None): if dont_build is None: dont_build = set() dont_build = set.union(set(dont_build), set(app_settings.DONT_BUILD)) # 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: 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 = [] old_cover = None 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')) old_cover = book.cover_info() # Save XML file book.xml_file.save('%s.xml' % book.slug, raw_file, save=False) 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.extra_info = book_info.to_dict() book.save() meta_tags = Tag.tags_from_info(book_info) book.tags = set(meta_tags + book_shelves) cover_changed = old_cover != book.cover_info() obsolete_children = set(b for b in book.children.all() if b not in children) notify_cover_changed = [] for n, child_book in enumerate(children): new_child = child_book.parent != book child_book.parent = book child_book.parent_number = n child_book.save() if new_child or cover_changed: notify_cover_changed.append(child_book) # Disown unfaithful children and let them cope on their own. for child in obsolete_children: child.parent = None child.parent_number = 0 child.save() if old_cover: notify_cover_changed.append(child) cls.repopulate_ancestors() tasks.update_counters.delay() if remote_gallery_url: book.download_pictures(remote_gallery_url) # No saves beyond this point. # Build cover. if 'cover' not in dont_build: book.cover.build_delay() book.cover_thumb.build_delay() # Build HTML and ebooks. book.html_file.build_delay() if not children: for format_ in constants.EBOOK_FORMATS_WITHOUT_CHILDREN: if format_ not in dont_build: getattr(book, '%s_file' % format_).build_delay() for format_ in constants.EBOOK_FORMATS_WITH_CHILDREN: if format_ not in dont_build: getattr(book, '%s_file' % format_).build_delay() if not settings.NO_SEARCH_INDEX and search_index: tasks.index_book.delay(book.id, book_info=book_info, index_tags=search_index_tags) 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