def set_sets(user, work, sets): """Set tags used for given work by a given user.""" old_sets = list(work.tags.filter(category='set', user=user)) work.tags = sets + list( work.tags.filter(~Q(category='set') | ~Q(user=user))) for shelf in [shelf for shelf in old_sets if shelf not in sets]: touch_tag(shelf) for shelf in [shelf for shelf in sets if shelf not in old_sets]: touch_tag(shelf) # delete empty tags Tag.objects.filter(category='set', user=user, book_count=0).delete()
def _tags_updated_handler(sender, affected_tags, **kwargs): # reset tag global counter # we want Tag.changed_at updated for API to know the tag was touched for tag in affected_tags: tasks.touch_tag(tag) # if book tags changed, reset book tag counter if isinstance(sender, Book) and \ Tag.objects.filter(pk__in=(tag.pk for tag in affected_tags)).\ exclude(category__in=('book', 'theme', 'set')).count(): sender.reset_tag_counter() # if fragment theme changed, reset book theme counter elif isinstance(sender, Fragment) and \ Tag.objects.filter(pk__in=(tag.pk for tag in affected_tags)).\ filter(category='theme').count(): sender.book.reset_theme_counter()
def set_sets(user, work, sets): """Set tags used for given work by a given user.""" old_sets = list(work.tags.filter(category='set', user=user)) work.tags = sets + list( work.tags.filter(~Q(category='set') | ~Q(user=user))) for shelf in [shelf for shelf in old_sets if shelf not in sets]: touch_tag(shelf) for shelf in [shelf for shelf in sets if shelf not in old_sets]: touch_tag(shelf) # delete empty tags Tag.objects.filter(category='set', user=user, items=None).delete() if isinstance(work, Book): work.update_popularity()
def fix_tree_tags(self): """Fixes the l-tags on the book's subtree. Makes sure that: * the book has its parents book-tags, * its fragments have the book's and its parents book-tags, * runs those for every child book too, * touches all relevant tags, * resets tag and theme counter on the book and its ancestry. """ def fix_subtree(book, parent_tags): affected_tags = set(book.tags) book.tags = list(book.tags.exclude(category='book')) + parent_tags sub_parent_tags = parent_tags + [book.book_tag()] for frag in book.fragments.all(): affected_tags.update(frag.tags) frag.tags = list(frag.tags.exclude(category='book') ) + sub_parent_tags for child in book.children.all(): affected_tags.update(fix_subtree(child, sub_parent_tags)) return affected_tags parent_tags = [] parent = self.parent while parent is not None: parent_tags.append(parent.book_tag()) parent = parent.parent affected_tags = fix_subtree(self, parent_tags) for tag in affected_tags: tasks.touch_tag(tag) book = self while book is not None: book.reset_tag_counter() book.reset_theme_counter() book = book.parent
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, search_index_tags=True, search_index_reuse=False): # 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 = [] 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.extra_info = book_info.to_dict() book.save() meta_tags = Tag.tags_from_info(book_info) book.tags = set(meta_tags + book_shelves) book_tag = book.book_tag() for n, child_book in enumerate(children): child_book.parent = book child_book.parent_number = n child_book.save() # Save XML and HTML files book.xml_file.save('%s.xml' % book.slug, raw_file, save=False) # delete old fragments when overwriting book.fragments.all().delete() if book.build_html(): if not settings.NO_BUILD_TXT and build_txt: book.build_txt() book.build_cover(book_info) if not settings.NO_BUILD_EPUB and build_epub: book.build_epub() if not settings.NO_BUILD_PDF and build_pdf: book.build_pdf() if not settings.NO_BUILD_MOBI and build_mobi: book.build_mobi() if not settings.NO_SEARCH_INDEX and search_index: book.search_index(index_tags=search_index_tags, reuse_index=search_index_reuse) #index_book.delay(book.id, book_info) book_descendants = list(book.children.all()) descendants_tags = set() # add l-tag to descendants and their fragments while len(book_descendants) > 0: child_book = book_descendants.pop(0) descendants_tags.update(child_book.tags) child_book.tags = list(child_book.tags) + [book_tag] child_book.save() for fragment in child_book.fragments.all().iterator(): fragment.tags = set(list(fragment.tags) + [book_tag]) book_descendants += list(child_book.children.all()) for tag in descendants_tags: tasks.touch_tag(tag) book.save() # refresh cache book.reset_tag_counter() book.reset_theme_counter() cls.published.send(sender=book) return book