def tags_from_info(info): from fnpdjango.utils.text.slughifi import slughifi from sortify import sortify meta_tags = [] categories = (('kinds', 'kind'), ('genres', 'genre'), ('authors', 'author'), ('epochs', 'epoch')) for field_name, category in categories: try: tag_names = getattr(info, field_name) except: try: tag_names = [getattr(info, category)] except: # For instance, Pictures do not have 'genre' field. continue for tag_name in tag_names: tag_sort_key = tag_name if category == 'author': tag_sort_key = tag_name.last_name tag_name = tag_name.readable() tag, created = Tag.objects.get_or_create( slug=slughifi(tag_name), category=category) if created: tag.name = tag_name tag.sort_key = sortify(tag_sort_key.lower()) tag.save() meta_tags.append(tag) return meta_tags
def build_notes(book): task_logger.info(book.slug) with transaction.atomic(): book.notesource_set.all().delete() if book.html_file: from librarian import html from librarian.fn_qualifiers import FN_QUALIFIERS for anchor, fn_type, qualifiers, text_str, html_str in \ html.extract_annotations(book.html_file.path): sort_key = sortify(text_str).strip()[:128] language = book.language notes = Note.objects.filter(sort_key=sort_key, fn_type=fn_type, language=language, html=html_str) if notes: note = notes[0] else: note = Note.objects.create(sort_key=sort_key, html=html_str, fn_type=fn_type, language=language) qualifier_objects = [] for qualifier in qualifiers: obj, created = Qualifier.objects.get_or_create( qualifier=qualifier, defaults={'name': FN_QUALIFIERS.get(qualifier, '')}) qualifier_objects.append(obj) note.qualifiers = qualifier_objects note.notesource_set.create(book=book, anchor=anchor) Note.objects.filter(notesource=None).delete()
def add_table_of_themes(root): try: from sortify import sortify except ImportError: def sortify(x): return x book_themes = {} for fragment in root.findall('.//a[@class="theme-begin"]'): if not fragment.text: continue theme_names = [s.strip() for s in fragment.text.split(',')] for theme_name in theme_names: book_themes.setdefault(theme_name, []).append(fragment.get('name')) book_themes = list(book_themes.items()) book_themes.sort(key=lambda s: sortify(s[0])) themes_div = etree.Element('div', id="themes") themes_ol = etree.SubElement(themes_div, 'ol') for theme_name, fragments in book_themes: themes_li = etree.SubElement(themes_ol, 'li') themes_li.text = "%s: " % theme_name for i, fragment in enumerate(fragments): item = etree.SubElement(themes_li, 'a', href="#%s" % fragment) item.text = str(i + 1) item.tail = ' ' root.insert(0, themes_div)
def add_table_of_themes(root): try: from sortify import sortify except ImportError: sortify = lambda x: x book_themes = {} for fragment in root.findall('.//a[@class="theme-begin"]'): if not fragment.text: continue theme_names = [s.strip() for s in fragment.text.split(',')] for theme_name in theme_names: book_themes.setdefault(theme_name, []).append(fragment.get('name')) book_themes = book_themes.items() book_themes.sort(key=lambda s: sortify(s[0])) themes_div = etree.Element('div', id="themes") themes_ol = etree.SubElement(themes_div, 'ol') for theme_name, fragments in book_themes: themes_li = etree.SubElement(themes_ol, 'li') themes_li.text = "%s: " % theme_name for i, fragment in enumerate(fragments): item = etree.SubElement(themes_li, 'a', href="#%s" % fragment) item.text = str(i + 1) item.tail = ' ' root.insert(0, themes_div)
def build_notes(book): task_logger.info(book.slug) with transaction.atomic(): book.notesource_set.all().delete() if book.html_file: from librarian import html from librarian.fn_qualifiers import FN_QUALIFIERS for anchor, fn_type, qualifiers, text_str, html_str in \ html.extract_annotations(book.html_file.path): sort_key = sortify(text_str).strip()[:128] language = book.language notes = Note.objects.filter(sort_key=sort_key, fn_type=fn_type, language=language, html=html_str) if notes: note = notes[0] else: note = Note.objects.create( sort_key=sort_key, html=html_str, fn_type=fn_type, language=language ) qualifier_objects = [] for qualifier in qualifiers: obj, created = Qualifier.objects.get_or_create( qualifier=qualifier, defaults={ 'name': FN_QUALIFIERS.get(qualifier, '') }) qualifier_objects.append(obj) note.qualifiers = qualifier_objects note.notesource_set.create(book=book, anchor=anchor) Note.objects.filter(notesource=None).delete()
def tags_from_info(info): from slughifi import slughifi from sortify import sortify meta_tags = [] categories = (('kinds', 'kind'), ('genres', 'genre'), ('authors', 'author'), ('epochs', 'epoch')) for field_name, category in categories: try: tag_names = getattr(info, field_name) except: try: tag_names = [getattr(info, category)] except: # For instance, Pictures do not have 'genre' field. continue for tag_name in tag_names: tag_sort_key = tag_name if category == 'author': tag_sort_key = tag_name.last_name tag_name = tag_name.readable() tag, created = Tag.objects.get_or_create(slug=slughifi(tag_name), category=category) if created: tag.name = tag_name tag.sort_key = sortify(tag_sort_key.lower()) tag.save() meta_tags.append(tag) return meta_tags
def build_notes(book): Note.objects.filter(book=book).delete() if book.html_file: from librarian import html for anchor, text_str, html_str in html.extract_annotations(book.html_file.path): Note.objects.create(book=book, anchor=anchor, html=html_str, sort_key=sortify(text_str).strip()[:128])
def build_notes(book): Note.objects.filter(book=book).delete() if book.html_file: from librarian import html for anchor, text_str, html_str in html.extract_annotations( book.html_file.path): Note.objects.create(book=book, anchor=anchor, html=html_str, sort_key=sortify(text_str).strip()[:128])
def save(self, force_insert=False, force_update=False, reset_short_html=True, **kwargs): from sortify import sortify self.sort_key = sortify(self.title) ret = super(Book, self).save(force_insert, force_update) if reset_short_html: self.reset_short_html() return ret
def save(self, force_insert=False, force_update=False, reset_short_html=True, **kwargs): from sortify import sortify self.sort_key = sortify(self.title) ret = super(Picture, self).save(force_insert, force_update) if reset_short_html: self.reset_short_html() return ret
def save(self, force_insert=False, force_update=False, **kwargs): from sortify import sortify self.sort_key = sortify(self.title)[:120] try: author = self.authors().first().sort_key except AttributeError: author = u'' self.sort_key_author = author ret = super(Picture, self).save(force_insert, force_update) return ret
def save(self, force_insert=False, force_update=False, **kwargs): from sortify import sortify self.sort_key = sortify(self.title) self.title = unicode(self.title) # ??? try: author = self.tags.filter(category='author')[0].sort_key except IndexError: author = u'' self.sort_key_author = author ret = super(Book, self).save(force_insert, force_update, **kwargs) return ret
def update_sort_keys(apps, schema_editor): Tag = apps.get_model('catalogue', 'Tag') Book = apps.get_model('catalogue', 'Book') Picture = apps.get_model('picture', 'Picture') ContentType = apps.get_model('contenttypes', 'ContentType') for author in Tag.objects.filter(category='author'): name_parts = author.name.split() sort_key = ' '.join([name_parts[-1]] + name_parts[:-1]) author.sort_key = sortify(sort_key.lower()) author.save() for model in Book, Picture: ct = ContentType.objects.get_for_model(model) for obj in model.objects.all(): authors = Tag.objects.filter(category='author', items__content_type=ct, items__object_id=obj.id) author = authors[0] obj.sort_key_author = author.sort_key obj.save()
def save(self, force_insert=False, force_update=False, **kwargs): from sortify import sortify self.sort_key = sortify(self.title)[:120] self.title = str(self.title) # ??? try: author = self.authors().first().sort_key except AttributeError: author = u'' self.sort_key_author = author self.cached_author = self.tag_unicode('author') self.has_audience = 'audience' in self.extra_info ret = super(Book, self).save(force_insert, force_update, **kwargs) return ret
def tags_from_info(info): from slugify import slugify from sortify import sortify meta_tags = [] categories = (('kinds', 'kind'), ('genres', 'genre'), ('authors', 'author'), ('epochs', 'epoch')) for field_name, category in categories: try: tag_names = getattr(info, field_name) except (AttributeError, KeyError): # TODO: shouldn't be KeyError here at all. try: tag_names = [getattr(info, category)] except KeyError: # For instance, Pictures do not have 'genre' field. continue for tag_name in tag_names: lang = getattr(tag_name, 'lang', settings.LANGUAGE_CODE) tag_sort_key = tag_name if category == 'author': tag_sort_key = ' '.join((tag_name.last_name,) + tag_name.first_names) tag_name = tag_name.readable() if lang == settings.LANGUAGE_CODE: # Allow creating new tag, if it's in default language. tag, created = Tag.objects.get_or_create(slug=slugify(tag_name), category=category) if created: tag_name = str(tag_name) tag.name = tag_name setattr(tag, "name_%s" % lang, tag_name) tag.sort_key = sortify(tag_sort_key.lower()) tag.save() meta_tags.append(tag) else: # Ignore unknown tags in non-default languages. try: tag = Tag.objects.get(category=category, **{"name_%s" % lang: tag_name}) except Tag.DoesNotExist: pass else: meta_tags.append(tag) return meta_tags
def tags_from_info(info): from fnpdjango.utils.text.slughifi import slughifi from sortify import sortify meta_tags = [] categories = (('kinds', 'kind'), ('genres', 'genre'), ('authors', 'author'), ('epochs', 'epoch')) for field_name, category in categories: try: tag_names = getattr(info, field_name) except: try: tag_names = [getattr(info, category)] except: # For instance, Pictures do not have 'genre' field. continue for tag_name in tag_names: lang = getattr(tag_name, 'lang', settings.LANGUAGE_CODE) tag_sort_key = tag_name if category == 'author': tag_sort_key = tag_name.last_name tag_name = tag_name.readable() if lang == settings.LANGUAGE_CODE: # Allow creating new tag, if it's in default language. tag, created = Tag.objects.get_or_create(slug=slughifi(tag_name), category=category) if created: tag_name = unicode(tag_name) tag.name = tag_name setattr(tag, "name_%s" % lang, tag_name) tag.sort_key = sortify(tag_sort_key.lower()) tag.save() meta_tags.append(tag) else: # Ignore unknown tags in non-default languages. try: tag = Tag.objects.get(category=category, **{"name_%s" % lang: tag_name}) except Tag.DoesNotExist: pass else: meta_tags.append(tag) return meta_tags
def tags_from_info(info): from fnpdjango.utils.text.slughifi import slughifi from sortify import sortify meta_tags = [] categories = (('kinds', 'kind'), ('genres', 'genre'), ('authors', 'author'), ('epochs', 'epoch')) for field_name, category in categories: try: tag_names = getattr(info, field_name) except KeyError: try: tag_names = [getattr(info, category)] except KeyError: # For instance, Pictures do not have 'genre' field. continue for tag_name in tag_names: lang = getattr(tag_name, 'lang', settings.LANGUAGE_CODE) tag_sort_key = tag_name if category == 'author': tag_sort_key = ' '.join((tag_name.last_name,) + tag_name.first_names) tag_name = tag_name.readable() if lang == settings.LANGUAGE_CODE: # Allow creating new tag, if it's in default language. tag, created = Tag.objects.get_or_create(slug=slughifi(tag_name), category=category) if created: tag_name = unicode(tag_name) tag.name = tag_name setattr(tag, "name_%s" % lang, tag_name) tag.sort_key = sortify(tag_sort_key.lower()) tag.save() meta_tags.append(tag) else: # Ignore unknown tags in non-default languages. try: tag = Tag.objects.get(category=category, **{"name_%s" % lang: tag_name}) except Tag.DoesNotExist: pass else: meta_tags.append(tag) return meta_tags
def from_xml_file(cls, xml_file, image_file=None, image_store=None, overwrite=False): """ Import xml and it's accompanying image file. If image file is missing, it will be fetched by librarian.picture.ImageStore which looks for an image file in the same directory the xml is, with extension matching its mime type. """ from sortify import sortify from django.core.files import File from librarian.picture import WLPicture, ImageStore close_xml_file = False close_image_file = False if image_file is not None and not isinstance(image_file, File): image_file = File(open(image_file)) close_image_file = True if not isinstance(xml_file, File): xml_file = File(open(xml_file)) close_xml_file = True with transaction.atomic(): # use librarian to parse meta-data if image_store is None: image_store = ImageStore(picture_storage.path('images')) picture_xml = WLPicture.from_file(xml_file, image_store=image_store) picture, created = Picture.objects.get_or_create(slug=picture_xml.slug[:120]) if not created and not overwrite: raise Picture.AlreadyExists('Picture %s already exists' % picture_xml.slug) picture.areas.all().delete() picture.title = unicode(picture_xml.picture_info.title) picture.extra_info = picture_xml.picture_info.to_dict() picture_tags = set(catalogue.models.Tag.tags_from_info(picture_xml.picture_info)) motif_tags = set() thing_tags = set() area_data = {'themes': {}, 'things': {}} # Treat all names in picture XML as in default language. lang = settings.LANGUAGE_CODE for part in picture_xml.partiter(): if picture_xml.frame: c = picture_xml.frame[0] part['coords'] = [[p[0] - c[0], p[1] - c[1]] for p in part['coords']] if part.get('object', None) is not None: _tags = set() for objname in part['object'].split(','): objname = objname.strip().capitalize() tag, created = catalogue.models.Tag.objects.get_or_create( slug=slughifi(objname), category='thing') if created: tag.name = objname setattr(tag, 'name_%s' % lang, tag.name) tag.sort_key = sortify(tag.name) tag.save() # thing_tags.add(tag) area_data['things'][tag.slug] = { 'object': objname, 'coords': part['coords'], } _tags.add(tag) area = PictureArea.rectangle(picture, 'thing', part['coords']) area.save() area.tags = _tags else: _tags = set() for motifs in part['themes']: for motif in motifs.split(','): tag, created = catalogue.models.Tag.objects.get_or_create( slug=slughifi(motif), category='theme') if created: tag.name = motif tag.sort_key = sortify(tag.name) tag.save() # motif_tags.add(tag) _tags.add(tag) area_data['themes'][tag.slug] = { 'theme': motif, 'coords': part['coords'] } logging.debug("coords for theme: %s" % part['coords']) area = PictureArea.rectangle(picture, 'theme', part['coords']) area.save() area.tags = _tags.union(picture_tags) picture.tags = picture_tags.union(motif_tags).union(thing_tags) picture.areas_json = area_data if image_file is not None: img = image_file else: img = picture_xml.image_file() modified = cls.crop_to_frame(picture_xml, img) modified = cls.add_source_note(picture_xml, modified) picture.width, picture.height = modified.size modified_file = StringIO() modified.save(modified_file, format='JPEG', quality=95) # FIXME: hardcoded extension - detect from DC format or orginal filename picture.image_file.save(path.basename(picture_xml.image_path), File(modified_file)) picture.xml_file.save("%s.xml" % picture.slug, File(xml_file)) picture.save() tasks.generate_picture_html(picture.id) if close_xml_file: xml_file.close() if close_image_file: image_file.close() return picture
def forwards(self, orm): "Write your forwards methods here." for theme in orm.Tag.objects.filter(category='theme'): theme.sort_key = sortify(theme.sort_key) theme.save()
def from_xml_file(cls, xml_file, image_file=None, overwrite=False): """ Import xml and it's accompanying image file. If image file is missing, it will be fetched by librarian.picture.ImageStore which looks for an image file in the same directory the xml is, with extension matching its mime type. """ from sortify import sortify from django.core.files import File from librarian.picture import WLPicture, ImageStore close_xml_file = False close_image_file = False # class SimpleImageStore(object): # def path(self_, slug, mime_type): # """Returns the image file. Ignores slug ad mime_type.""" # return image_file if image_file is not None and not isinstance(image_file, File): image_file = File(open(image_file)) close_image_file = True if not isinstance(xml_file, File): xml_file = File(open(xml_file)) close_xml_file = True try: # use librarian to parse meta-data picture_xml = WLPicture.from_file( xml_file, image_store=ImageStore(picture_storage.path('images'))) # image_store=SimpleImageStore picture, created = Picture.objects.get_or_create( slug=picture_xml.slug) if not created and not overwrite: raise Picture.AlreadyExists('Picture %s already exists' % picture_xml.slug) picture.title = picture_xml.picture_info.title motif_tags = set() for part in picture_xml.partiter(): for motif in part['themes']: tag, created = catalogue.models.Tag.objects.get_or_create( slug=slughifi(motif), category='theme') if created: tag.name = motif tag.sort_key = sortify(tag.name) tag.save() motif_tags.add(tag) picture.tags = catalogue.models.Tag.tags_from_info(picture_xml.picture_info) + \ list(motif_tags) if image_file is not None: img = image_file else: img = picture_xml.image_file() # FIXME: hardcoded extension picture.image_file.save(path.basename(picture_xml.image_path), File(img)) picture.xml_file.save("%s.xml" % picture.slug, File(xml_file)) picture.save() finally: if close_xml_file: xml_file.close() if close_image_file: image_file.close() return picture
def build(self, fieldfile): from django.core.files.base import ContentFile from fnpdjango.utils.text.slughifi import slughifi from sortify import sortify from librarian import html from catalogue.models import Fragment, Tag book = fieldfile.instance meta_tags = list(book.tags.filter( category__in=('author', 'epoch', 'genre', 'kind'))) book_tag = book.book_tag() html_output = self.transform( book.wldocument(parse_dublincore=False), fieldfile) if html_output: fieldfile.save(None, ContentFile(html_output.get_string()), save=False) type(book).objects.filter(pk=book.pk).update(**{ fieldfile.field.attname: fieldfile }) # get ancestor l-tags for adding to new fragments ancestor_tags = [] p = book.parent while p: ancestor_tags.append(p.book_tag()) p = p.parent # Delete old fragments and create them from scratch book.fragments.all().delete() # Extract fragments closed_fragments, open_fragments = html.extract_fragments(fieldfile.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 = sortify(theme_name.lower()) tag.save() themes.append(tag) if not themes: continue text = fragment.to_string() short_text = truncate_html_words(text, 15) if text == short_text: short_text = '' new_fragment = Fragment.objects.create(anchor=fragment.id, book=book, text=text, short_text=short_text) new_fragment.save() new_fragment.tags = set(meta_tags + themes + [book_tag] + ancestor_tags) book.html_built.send(sender=book) return True return False
def from_xml_file(cls, xml_file, image_file=None, overwrite=False): """ Import xml and it's accompanying image file. If image file is missing, it will be fetched by librarian.picture.ImageStore which looks for an image file in the same directory the xml is, with extension matching its mime type. """ from sortify import sortify from django.core.files import File from librarian.picture import WLPicture, ImageStore close_xml_file = False close_image_file = False # class SimpleImageStore(object): # def path(self_, slug, mime_type): # """Returns the image file. Ignores slug ad mime_type.""" # return image_file if image_file is not None and not isinstance(image_file, File): image_file = File(open(image_file)) close_image_file = True if not isinstance(xml_file, File): xml_file = File(open(xml_file)) close_xml_file = True try: # use librarian to parse meta-data picture_xml = WLPicture.from_file(xml_file, image_store=ImageStore(picture_storage.path("images"))) # image_store=SimpleImageStore picture, created = Picture.objects.get_or_create(slug=picture_xml.slug) if not created and not overwrite: raise Picture.AlreadyExists("Picture %s already exists" % picture_xml.slug) picture.title = picture_xml.picture_info.title motif_tags = set() for part in picture_xml.partiter(): for motif in part["themes"]: tag, created = catalogue.models.Tag.objects.get_or_create(slug=slughifi(motif), category="theme") if created: tag.name = motif tag.sort_key = sortify(tag.name) tag.save() motif_tags.add(tag) picture.tags = catalogue.models.Tag.tags_from_info(picture_xml.picture_info) + list(motif_tags) if image_file is not None: img = image_file else: img = picture_xml.image_file() # FIXME: hardcoded extension picture.image_file.save(path.basename(picture_xml.image_path), File(img)) picture.xml_file.save("%s.xml" % picture.slug, File(xml_file)) picture.save() finally: if close_xml_file: xml_file.close() if close_image_file: image_file.close() return picture
def build(self, fieldfile): from django.core.files.base import ContentFile from fnpdjango.utils.text.slughifi import slughifi from sortify import sortify from librarian import html from catalogue.models import Fragment, Tag book = fieldfile.instance html_output = self.transform(book.wldocument(parse_dublincore=False), fieldfile) # Delete old fragments, create from scratch if necessary. book.fragments.all().delete() if html_output: meta_tags = list( book.tags.filter(category__in=('author', 'epoch', 'genre', 'kind'))) lang = book.language lang = LANGUAGES_3TO2.get(lang, lang) if lang not in [ln[0] for ln in settings.LANGUAGES]: lang = None fieldfile.save(None, ContentFile(html_output.get_string()), save=False) type(book).objects.filter(pk=book.pk).update( **{fieldfile.field.attname: fieldfile}) # Extract fragments closed_fragments, open_fragments = html.extract_fragments( fieldfile.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 if lang == settings.LANGUAGE_CODE: # Allow creating themes if book in default language. tag, created = Tag.objects.get_or_create( slug=slughifi(theme_name), category='theme') if created: tag.name = theme_name setattr(tag, "name_%s" % lang, theme_name) tag.sort_key = sortify(theme_name.lower()) tag.save() themes.append(tag) elif lang is not None: # Don't create unknown themes in non-default languages. try: tag = Tag.objects.get( category='theme', **{"name_%s" % lang: theme_name}) except Tag.DoesNotExist: pass else: themes.append(tag) if not themes: continue text = fragment.to_string() short_text = truncate_html_words(text, 15) if text == short_text: short_text = '' new_fragment = Fragment.objects.create(anchor=fragment.id, book=book, text=text, short_text=short_text) new_fragment.save() new_fragment.tags = set(meta_tags + themes) book.html_built.send(sender=type(self), instance=book) return True return False
def build(self, fieldfile): from django.core.files.base import ContentFile from fnpdjango.utils.text.slughifi import slughifi from sortify import sortify from librarian import html from catalogue.models import Fragment, Tag book = fieldfile.instance html_output = self.transform( book.wldocument(parse_dublincore=False), fieldfile) # Delete old fragments, create from scratch if necessary. book.fragments.all().delete() if html_output: meta_tags = list(book.tags.filter( category__in=('author', 'epoch', 'genre', 'kind'))) lang = book.language lang = LANGUAGES_3TO2.get(lang, lang) if lang not in [ln[0] for ln in settings.LANGUAGES]: lang = None fieldfile.save(None, ContentFile(html_output.get_string()), save=False) type(book).objects.filter(pk=book.pk).update(**{ fieldfile.field.attname: fieldfile }) # Extract fragments closed_fragments, open_fragments = html.extract_fragments(fieldfile.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 if lang == settings.LANGUAGE_CODE: # Allow creating themes if book in default language. tag, created = Tag.objects.get_or_create( slug=slughifi(theme_name), category='theme') if created: tag.name = theme_name setattr(tag, "name_%s" % lang, theme_name) tag.sort_key = sortify(theme_name.lower()) tag.save() themes.append(tag) elif lang is not None: # Don't create unknown themes in non-default languages. try: tag = Tag.objects.get(category='theme', **{"name_%s" % lang: theme_name}) except Tag.DoesNotExist: pass else: themes.append(tag) if not themes: continue text = fragment.to_string() short_text = truncate_html_words(text, 15) if text == short_text: short_text = '' new_fragment = Fragment.objects.create(anchor=fragment.id, book=book, text=text, short_text=short_text) new_fragment.save() new_fragment.tags = set(meta_tags + themes) book.html_built.send(sender=type(self), instance=book) return True return False
def build(self, fieldfile): from django.core.files.base import ContentFile from fnpdjango.utils.text.slughifi import slughifi from sortify import sortify from librarian import html from catalogue.models import Fragment, Tag book = fieldfile.instance meta_tags = list( book.tags.filter(category__in=('author', 'epoch', 'genre', 'kind'))) book_tag = book.book_tag() html_output = self.transform(book.wldocument(parse_dublincore=False), fieldfile) if html_output: fieldfile.save(None, ContentFile(html_output.get_string()), save=False) type(book).objects.filter(pk=book.pk).update( **{fieldfile.field.attname: fieldfile}) # get ancestor l-tags for adding to new fragments ancestor_tags = [] p = book.parent while p: ancestor_tags.append(p.book_tag()) p = p.parent # Delete old fragments and create them from scratch book.fragments.all().delete() # Extract fragments closed_fragments, open_fragments = html.extract_fragments( fieldfile.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 = sortify(theme_name.lower()) tag.save() themes.append(tag) if not themes: continue text = fragment.to_string() short_text = truncate_html_words(text, 15) if text == short_text: short_text = '' new_fragment = Fragment.objects.create(anchor=fragment.id, book=book, text=text, short_text=short_text) new_fragment.save() new_fragment.tags = set(meta_tags + themes + [book_tag] + ancestor_tags) book.html_built.send(sender=book) return True return False