Beispiel #1
0
    def __init__(self,
                 book=None,
                 chapter=None,
                 serialize_options=SERIALIZE_OPTIONS,
                 **kwargs):
        """
        Args:
            - book (`booki.editor.models.Book`) Booktype model instance of book
            - chapter (`booki.editor.models.Chapter`) Booktype model instance of chapter
            - serialize_options (`dict`) A dictionary with options to be passed to ooxml library

            kwargs: Some keyword arguments might be:
                - delegate (`importer.delegate.Delegate`) Delegate instance
                - notifier (`importer.notifier.CollectNotifier`) Notifier instance

        """

        self.book = book
        self.chapter = chapter
        self.is_chapter_mode = (chapter is not None)

        self._serialize_options = serialize_options

        self.notifier = kwargs.get('notifier', CollectNotifier())
        self.delegate = kwargs.get('delegate', Delegate())

        # Attachment objects indexed by image file name
        self._attachments = {}

        # Chapter objects indexed by document file name
        self._chapters = {}
Beispiel #2
0
    def form_valid(self, form):
        """
        If the form is valid, redirect to the supplied URL.
        """
        chapter = self.chapter
        book = self.object
        chapter_file = form.cleaned_data.get('chapter_file')
        process_mode = form.cleaned_data.get('import_mode')

        # this are used to get information messages about import process
        notifier, delegate = CollectNotifier(), Delegate()
        response = {}

        # allow getting custom importer class if any
        docx = get_importer_class()(
            book, chapter, notifier=notifier, delegate=delegate, user=self.request.user)

        try:
            docx.import_file(chapter_file, **{'process_mode': process_mode})
            response['url'] = self.get_success_url()
            response['new_content'] = chapter.content
        except Exception as e:
            logger.error('ImporterToChapter::Unexpected error while importing file')
            logger.exception(e)
            notifier.errors.append(str(e))

        response['infos'] = notifier.infos
        response['warnings'] = notifier.warnings
        response['errors'] = notifier.errors

        response_data = json.dumps(response, cls=LazyEncoder)

        return HttpResponse(response_data, content_type="application/json")
Beispiel #3
0
    def form_valid(self, form):
        logger.debug('ImporterView::form_valid')

        book_file = form.cleaned_data.get('book_file')
        ext = get_file_extension(book_file.name)

        logger.debug('ImporterView::Importing file extension is "{}".'.format(ext.encode('utf8')))

        default_book_title = self.get_default_title(book_file, ext)
        book_title = form.cleaned_data.get('book_title', default_book_title)

        logger.debug('ImporterView::book_title="{}" default_book_title="{}".'.format(
            book_title.encode('utf8'), default_book_title.encode('utf8')))

        # in case book title in form is empty string
        if len(book_title) == 0:
            book_title = default_book_title

        if not check_book_availability(book_title):
            registered = Book.objects.filter(title__startswith=book_title).count()
            book_title = '%s %s' % (book_title, registered)
            logger.debug('ImporterView::Checking book availability: "{}".'.format(book_title.encode('utf8')))

        book_url = booktype_slugify(book_title)
        book = create_book(self.request.user, book_title, book_url=book_url)
        logger.debug('ImporterView::Book created with url title="{}".'.format(book_url))

        # check if book will be hidden and set to book
        book.hidden = form.cleaned_data.get('hidden')
        book.save()

        notifier = CollectNotifier()
        delegate = Delegate()
        response = {}

        try:
            book_importer = importer_utils.get_importer_module(ext)
        except KeyError:
            logger.error('ImporterView::No importer for this extension')
            response_data = dict(errors=[ugettext('Extension not supported!')])
            return self.render_json_response(response_data)

        try:
            book_importer(
                book_file, book, notifier=notifier, delegate=delegate)
            logger.debug('ImporterView::Book imported.')
            response['url'] = reverse('reader:infopage', args=[book.url_title])
        except Exception as e:
            logger.error('ImporterView::Some kind of error while importing book.')
            logger.exception(e)
            notifier.errors.append(str(e))

        response['infos'] = notifier.infos
        response['warnings'] = notifier.warnings
        response['errors'] = notifier.errors

        return self.render_json_response(response)
Beispiel #4
0
    def __init__(self):
        self.notifier = Notifier()
        self.delegate = Delegate()

        # Attachment objects indexed by image file name
        self._attachments = {}
        # Chapter objects indexed by document file name
        self._chapters = {}

        self.endnotes = {}
        self.footnotes = {}
Beispiel #5
0
def import_based_on_epub(epub_file, book_dest):
    """
    It will import an epub file into a existent book on the system.
    This will also try to import sections settings and stuff

    Keyword arguments:
        epub_file -- EPUB file to be imported into book_dest
        book_dest -- Destiny book

    TODO: add docstrings of return info
    """

    notifier = CollectNotifier()
    delegate = Delegate()

    epub_importer = EpubImporter()
    epub_importer.notifier = notifier
    epub_importer.delegate = delegate

    result = {}

    try:
        epub_book = epub_importer.import_file(epub_file, book_dest)
    except Exception as e:
        epub_book = None
        logger.error('ImporterView::Some kind of error while importing book.')
        logger.exception(e)
        notifier.errors.append(str(e))

    # let's try to save sections settings
    if epub_book is not None:
        settings_dict = get_sections_settings(epub_book)
        book_dest_version = book_dest.get_version(None)
        sec_count = 1

        for toc_item in book_dest_version.get_toc():
            if toc_item.is_section():
                url_title = booktype_slugify(toc_item.name)
                section_key = SectionsSettingsPlugin.build_section_key(
                    url_title, sec_count)
                section_settings = settings_dict.get(section_key, None)

                if section_settings is not None:
                    toc_item.settings = section_settings
                    toc_item.save()

                    sec_count += 1

    result['infos'] = notifier.infos
    result['warnings'] = notifier.warnings
    result['errors'] = notifier.errors

    return result
Beispiel #6
0
    def create(self, validated_data):
        n = Book.objects.count()
        book_title = validated_data['title']
        owner = validated_data['owner']
        url_title = '%s-%s' % (n, booktype_slugify(book_title))

        book = create_book(owner, book_title, book_url=url_title)
        book.language = validated_data.get('language', None)
        book.save()

        import_book_url = validated_data.get('import_book_url')
        import_format = validated_data.get('import_book_format')

        if import_book_url:
            book_file = self._get_book_file(import_book_url)
            try:
                book_importer = importer_utils.get_importer_module(
                    import_format)
            except Exception as err:
                error = "Wrong importer format {}".format(err)
                logger.warn('BookCreateSerializer create: {}'.format(error))
                raise serializers.ValidationError(error)

            delegate = Delegate()
            notifier = CollectNotifier()

            try:
                book_importer(book_file,
                              book,
                              notifier=notifier,
                              delegate=delegate)
            except Exception as err:
                error_msg = "Unexpected error while importing the file {}".format(
                    err)
                logger.warn(
                    'BookCreateSerializer create: {}'.format(error_msg))
                raise APIException(error_msg)

            if len(notifier.errors) > 0:
                err = "\n".join(notifier.errors)
                error_msg = "Something went wrong: {}".format(err)
                logger.warn(
                    'BookCreateSerializer create: {}'.format(error_msg))
                raise APIException(error_msg)

        return book
Beispiel #7
0
def import_based_on_file(import_file, book_dest):
    """
    It will import the content from a given file (docx or epub for now) into a existent
    book on the system. Note that this is not going to import section settings

    Keyword arguments:
        import_file -- EPUB/DOCX file to be imported into book_dest
        book_dest -- Destiny book
    """

    ext = get_file_extension(import_file.name)

    notifier = CollectNotifier()
    delegate = Delegate()
    result = {}

    try:
        book_importer = importer_utils.get_importer_module(ext)
    except KeyError:
        logger.error('ImporterView::No importer for this extension')
        raise NotImplementedError('Extension not supported!')

    try:
        book_importer(import_file,
                      book_dest,
                      notifier=notifier,
                      delegate=delegate)
        logger.debug('ImporterView::Book imported.')
    except Exception as e:
        logger.error('ImporterView::Some kind of error while importing book.')
        logger.exception(e)
        notifier.errors.append(str(e))

    result['infos'] = notifier.infos
    result['warnings'] = notifier.warnings
    result['errors'] = notifier.errors

    return result
Beispiel #8
0
    def form_valid(self, form):
        logger.debug('ImporterView::form_valid')

        book_file = self.request.FILES['book_file']
        ext = self.file_extension(book_file.name)

        logger.debug('ImporterView::Importing file extension is "{}".'.format(
            ext.encode('utf8')))

        temp_file = tempfile.NamedTemporaryFile(prefix='importing-',
                                                suffix='%s' % ext,
                                                delete=False)
        temp_file = open(temp_file.name, 'wb+')

        logger.debug('ImporterView::Saving temporary file {}.'.format(
            temp_file.name.encode('utf8')))

        for chunk in book_file.chunks():
            temp_file.write(chunk)
        temp_file.close()
        temp_file = temp_file.name

        default_book_title = self.get_default_title(temp_file, ext)
        book_title = form.cleaned_data.get('book_title', default_book_title)
        logger.debug(
            'ImporterView::book_title="{}"" default_book_title="{}".'.format(
                book_title.encode('utf8'), default_book_title.encode('utf8')))

        # in case book title in form is empty string
        if len(book_title) == 0:
            book_title = default_book_title

        if not check_book_availability(book_title):
            registered = Book.objects.filter(
                title__startswith=book_title).count()
            book_title = '%s %s' % (book_title, registered)
            logger.debug(
                'ImporterView::Checking book availability: "{}".'.format(
                    book_title.encode('utf8')))

        book_url = booktype_slugify(book_title)
        book = create_book(self.request.user, book_title, book_url=book_url)
        logger.debug(
            'ImporterView::Book created with url title="{}".'.format(book_url))

        # check if book will be hidden and set to book
        book_hidden = form.cleaned_data.get('hidden')
        if book_hidden:
            book.hidden = book_hidden
            book.save()
            logger.debug('ImporterView::Setting book hidden.')
        else:
            logger.debug('ImporterView::Setting book visible.')

        notifier = CollectNotifier()
        delegate = Delegate()
        response = {}

        try:
            book_importer = self.get_importer(ext)
        except KeyError:
            logger.error('ImporterView::No importer for this extension')

            response_data = {
                'errors': [_('Extension not supported!')],
            }
            return self.render_json_response(response_data)

        try:
            book_importer(temp_file,
                          book,
                          notifier=notifier,
                          delegate=delegate)
            logger.debug('ImporterView::Book imported.')
            response['url'] = reverse('reader:infopage', args=[book.url_title])
        except Exception as e:
            logger.error(
                'ImporterView::Some kind of error while importing book.')
            logger.exception(e)
            notifier.errors.append(str(e))

        response['infos'] = notifier.infos
        response['warnings'] = notifier.warnings
        response['errors'] = notifier.errors

        return self.render_json_response(response)