Example #1
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)
Example #2
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
Example #3
0
    def save_settings(self, request):
        book = create_book(self.cleaned_data['owner'],
                           self.cleaned_data['title'])
        book.license = self.cleaned_data['license']
        book.description = self.cleaned_data['description']
        book.hidden = self.cleaned_data['is_hidden']
        book.save()

        if 'cover' in self.files:
            try:
                fh, fname = misc.save_uploaded_as_file(self.files['cover'])
                book.set_cover(fname)
                os.unlink(fname)
            except:
                pass

        book.save()

        return book
Example #4
0
    def save_settings(self, request):
        book = create_book(
            self.cleaned_data['owner'],
            self.cleaned_data['title']
        )
        book.license = self.cleaned_data['license']
        book.description = self.cleaned_data['description']
        book.hidden = self.cleaned_data['is_hidden']
        book.save()

        if 'cover' in self.files:
            try:
                fh, fname = misc.save_uploaded_as_file(self.files['cover'])
                book.set_cover(fname)
                os.unlink(fname)
            except:
                pass

        book.save()

        return book
Example #5
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
Example #6
0
    def post(self, request, *args, **kwargs):
        book = create_book(request.user, request.POST.get('title'))
        lic = License.objects.get(abbrevation=request.POST.get('license'))

        book.license = lic
        book.description = request.POST.get('description', '')
        book.hidden = (request.POST.get('hidden', None) == 'on')

        if 'cover' in request.FILES:
            try:
                fh, fname = misc.save_uploaded_as_file(request.FILES['cover'])
                book.setCover(fname)
                os.unlink(fname)
            except:
                pass

        book.save()

        return render(request, 'account/create_book_redirect.html', {
            "request": request,
            "book": book
        })
Example #7
0
    def post(self, request, *args, **kwargs):
        book = create_book(request.user, request.POST.get('title'))
        lic = License.objects.get(abbrevation=request.POST.get('license'))

        book.license = lic
        book.description = request.POST.get('description', '')
        book.hidden = (request.POST.get('hidden', None) == 'on')

        if 'cover' in request.FILES:
            try:
                fh, fname = misc.save_uploaded_as_file(request.FILES['cover'])
                book.setCover(fname)
                os.unlink(fname)
            except:
                pass

        book.save()

        return render(
            request,
            'account/create_book_redirect.html',
            {"request": request, "book": book}
        )
Example #8
0
def importBookFromFile(user, zname, createTOC=False, **extraOptions):
    """Create a new book from a bookizip filename"""

    from booki.utils.log import logChapterHistory

    # unzip it
    zf = zipfile.ZipFile(zname)
    # load info.json
    info = json.loads(zf.read('info.json'))
    logWarning("Loaded json file %r" % info)

    metadata = info['metadata']
    manifest = info['manifest']
    TOC = info['TOC']

    if extraOptions.get('book_title', None):
        bookTitle = extraOptions['book_title']
    else:
        bookTitle = get_metadata(metadata, 'title', ns=DC)[0]

    bookTitle = makeTitleUnique(bookTitle)
    logWarning("Chose unique book title %r" % bookTitle)

    if extraOptions.get('book_url', None):
        bookURL = extraOptions['book_url']
    else:
        bookURL = None

    book = create_book(user, bookTitle, status="new", bookURL=bookURL)

    if extraOptions.get("hidden"):
        book.hidden = True
        book.save()

    # this is for Table of Contents
    p = re.compile('\ssrc="(.*)"')

    # what if it does not have status "new"
    stat = models.BookStatus.objects.filter(book=book, name="new")[0]

    chapters = getChaptersFromTOC(TOC)
    n = len(chapters) + 1  #is +1 necessary?
    now = datetime.datetime.now()

    for chapterName, chapterFile, is_section in chapters:
        urlName = booktype_slugify(chapterName)

        if is_section:  # create section
            if createTOC:
                c = models.BookToc(book=book,
                                   version=book.version,
                                   name=chapterName,
                                   chapter=None,
                                   weight=n,
                                   typeof=2)
                c.save()
                n -= 1
        else:  # create chapter
            # check if i can open this file at all
            content = zf.read(chapterFile)

            #content = p.sub(r' src="../\1"', content)

            chapter = models.Chapter(book=book,
                                     version=book.version,
                                     url_title=urlName,
                                     title=chapterName,
                                     status=stat,
                                     content=content,
                                     created=now,
                                     modified=now)
            chapter.save()

            history = logChapterHistory(chapter=chapter,
                                        content=content,
                                        user=user,
                                        comment="",
                                        revision=chapter.revision)

            if createTOC:
                c = models.BookToc(book=book,
                                   version=book.version,
                                   name=chapterName,
                                   chapter=chapter,
                                   weight=n,
                                   typeof=1)
                c.save()
                n -= 1

    stat = models.BookStatus.objects.filter(book=book, name="new")[0]

    from django.core.files import File

    for item in manifest.values():
        if item["mimetype"] != 'text/html':
            attachmentName = item['url']

            if attachmentName.startswith("static/"):
                att = models.Attachment(book=book,
                                        version=book.version,
                                        status=stat)

                s = zf.read(attachmentName)
                f = StringIO(s)
                f2 = File(f)
                f2.size = len(s)
                att.attachment.save(os.path.basename(attachmentName),
                                    f2,
                                    save=False)
                att.save()
                f.close()

    # metadata
    for namespace in metadata:
        # namespace is something like "http://purl.org/dc/elements/1.1/" or ""
        # in the former case, preepend it to the name, in {}.
        ns = ('{%s}' % namespace if namespace else '')
        for keyword, schemes in metadata[namespace].iteritems():
            for scheme, values in schemes.iteritems():
                #schema, if it is set, describes the value's format.
                #for example, an identifier might be an ISBN.
                sc = ('{%s}' % scheme if scheme else '')
                key = "%s%s%s" % (ns, keyword, sc)
                for v in values:
                    if not v: continue
                    try:
                        info = models.Info(book=book, name=key)
                        if len(v) >= 2500:
                            info.value_text = v
                            info.kind = 2
                        else:
                            info.value_string = v
                            info.kind = 0
                        info.save()
                    except:
                        # For now just ignore any kind of error here.
                        # Considering we don't handle metadata as we
                        # should it is not such a problem.
                        pass

    zf.close()

    return book
Example #9
0
    def post(self, request, *args, **kwargs):
        # TODO: convert this into an atomic view
        # TODO: use the form class to achieve this process and simplify this view and add validations
        # TODO: we should print warnings so user knows what's going on

        data = request.POST
        book = create_book(request.user, data.get('title'))

        license = License.objects.get(abbrevation=data.get('license'))
        language = Language.objects.get(abbrevation=data.get('language'))

        # STEP 1: Details
        book.author = data.get('author')
        book.license = license
        book.language = language
        book.hidden = (data.get('visible_to_everyone', None) == 'off')
        book.description = data.get('description', '')

        # STEP 2: Metadata
        metaform = MetadataForm(book=book, data=data)
        if metaform.is_valid():
            metaform.save_settings(book, request)
        else:
            pass

        # STEP 3: Creation mode
        creation_mode = data.get('creation_mode', 'scratch')
        if creation_mode == 'based_on_book':
            try:
                base_book = Book.objects.get(id=request.POST.get('base_book'))
                base_book_version = base_book.get_version(None)
                result = import_based_on_book(base_book_version, book)
            except Book.DoesNotExist:
                logger.warn("Provided base book was not found")

        elif creation_mode == 'based_on_skeleton':
            try:
                base_skeleton = BookSkeleton.objects.get(
                    id=request.POST.get('base_skeleton'))
                result = import_based_on_epub(base_skeleton.skeleton_file,
                                              book)
            except BookSkeleton.DoesNotExist:
                logger.warn("Provided base skeleton was not found")

        elif creation_mode == 'based_on_file':
            import_file = request.FILES.get('import_file')
            if import_file is not None:
                try:
                    result = import_based_on_file(import_file, book)  # noqa
                except Exception as err:
                    logger.error(
                        "ImportError: Something went wrong importing file. Msg %s"
                        % err)

        # STEP 4: Book Cover
        if 'cover_image' in request.FILES:
            # first we create a cover registry and upload the file
            file_data = request.FILES['cover_image']
            filename = file_data.name

            cover_license = License.objects.get(
                abbrevation=data.get('cover_license'))

            cover = BookCover(book=book,
                              user=request.user,
                              cid=uuid.uuid4().hex,
                              title=data.get('cover_title'),
                              filename=filename[:250],
                              creator=data.get('cover_creator', '')[:40],
                              license=cover_license,
                              approved=False)
            cover.save()

            # now save the cover attachment
            cover.attachment.save(filename, file_data, save=False)
            cover.save()

            # and then finally, we set the book thumbnail
            try:
                fh, fname = misc.save_uploaded_as_file(file_data)
                book.set_cover(fname)
                os.unlink(fname)
            except:
                pass

        book.save()

        redirect_url = reverse('reader:infopage', args=[book.url_title])
        return HttpResponse(json.dumps({'redirect': redirect_url}),
                            'application/json')
Example #10
0
def importBookFromFile(user, zname, createTOC=False, **extraOptions):
    """Create a new book from a bookizip filename"""

    from booki.utils.log import logChapterHistory

    # unzip it
    zf = zipfile.ZipFile(zname)
    # load info.json
    info = json.loads(zf.read('info.json'))
    logWarning("Loaded json file %r" % info)

    metadata = info['metadata']
    manifest = info['manifest']
    TOC =      info['TOC']

    if extraOptions.get('book_title', None):
        bookTitle = extraOptions['book_title']
    else:
        bookTitle = get_metadata(metadata, 'title', ns=DC)[0]

    bookTitle = makeTitleUnique(bookTitle)
    logWarning("Chose unique book title %r" % bookTitle)

    if extraOptions.get('book_url', None):
        bookURL = extraOptions['book_url']
    else:
        bookURL = None

    book = create_book(user, bookTitle, status = "new", bookURL = bookURL)

    if extraOptions.get("hidden"):
        book.hidden = True
        book.save()

    # this is for Table of Contents
    p = re.compile('\ssrc="(.*)"')

    # what if it does not have status "new"
    stat = models.BookStatus.objects.filter(book=book, name="new")[0]

    chapters = getChaptersFromTOC(TOC)
    n = len(chapters) + 1 #is +1 necessary?
    now = datetime.datetime.now()

    for chapterName, chapterFile, is_section in chapters:
        urlName = booktype_slugify(chapterName)

        if is_section: # create section
            if createTOC:
                c = models.BookToc(book = book,
                                   version = book.version,
                                   name = chapterName,
                                   chapter = None,
                                   weight = n,
                                   typeof = 2)
                c.save()
                n -= 1
        else: # create chapter
            # check if i can open this file at all
            content = zf.read(chapterFile)

            #content = p.sub(r' src="../\1"', content)

            chapter = models.Chapter(book = book,
                                     version = book.version,
                                     url_title = urlName,
                                     title = chapterName,
                                     status = stat,
                                     content = content,
                                     created = now,
                                     modified = now)
            chapter.save()

            history = logChapterHistory(chapter = chapter,
                                        content = content,
                                        user = user,
                                        comment = "",
                                        revision = chapter.revision)

            if createTOC:
                c = models.BookToc(book = book,
                                   version = book.version,
                                   name = chapterName,
                                   chapter = chapter,
                                   weight = n,
                                   typeof = 1)
                c.save()
                n -= 1

    stat = models.BookStatus.objects.filter(book=book, name="new")[0]

    from django.core.files import File

    for item in manifest.values():
        if item["mimetype"] != 'text/html':
            attachmentName = item['url']

            if attachmentName.startswith("static/"):
                att = models.Attachment(book = book,
                                        version = book.version,
                                        status = stat)

                s = zf.read(attachmentName)
                f = StringIO(s)
                f2 = File(f)
                f2.size = len(s)
                att.attachment.save(os.path.basename(attachmentName), f2, save=False)
                att.save()
                f.close()

    # metadata
    for namespace in metadata:
        # namespace is something like "http://purl.org/dc/elements/1.1/" or ""
        # in the former case, preepend it to the name, in {}.
        ns = ('{%s}' % namespace if namespace else '')
        for keyword, schemes in metadata[namespace].iteritems():
            for scheme, values in schemes.iteritems():
                #schema, if it is set, describes the value's format.
                #for example, an identifier might be an ISBN.
                sc = ('{%s}' % scheme if scheme else '')
                key = "%s%s%s" % (ns, keyword, sc)
                for v in values:
                    if not v: continue
                    try:
                        info = models.Info(book=book, name=key)
                        if len(v) >= 2500:
                            info.value_text = v
                            info.kind = 2
                        else:
                            info.value_string = v
                            info.kind = 0
                        info.save()
                    except:
                        # For now just ignore any kind of error here.
                        # Considering we don't handle metadata as we
                        # should it is not such a problem.
                        pass

    zf.close()

    return book
Example #11
0
    def post(self, request, *args, **kwargs):
        # TODO: convert this into an atomic view
        # TODO: use the form class to achieve this process and simplify this view and add validations
        # TODO: we should print warnings so user knows what's going on

        data = request.POST
        book = create_book(request.user, data.get('title'))

        license = License.objects.get(abbrevation=data.get('license'))
        language = Language.objects.get(abbrevation=data.get('language'))

        # STEP 1: Details
        book.author = data.get('author')
        book.license = license
        book.language = language
        book.hidden = (data.get('visible_to_everyone', None) == 'off')
        book.description = data.get('description', '')

        # STEP 2: Metadata
        metaform = MetadataForm(book=book, data=data)
        if metaform.is_valid():
            metaform.save_settings(book, request)
        else:
            pass

        # STEP 3: Creation mode
        creation_mode = data.get('creation_mode', 'scratch')
        if creation_mode == 'based_on_book':
            try:
                base_book = Book.objects.get(id=request.POST.get('base_book'))
                base_book_version = base_book.get_version(None)
                result = import_based_on_book(base_book_version, book)
            except Book.DoesNotExist:
                logger.warn("Provided base book was not found")

        elif creation_mode == 'based_on_skeleton':
            try:
                base_skeleton = BookSkeleton.objects.get(id=request.POST.get('base_skeleton'))
                result = import_based_on_epub(base_skeleton.skeleton_file, book)
            except BookSkeleton.DoesNotExist:
                logger.warn("Provided base skeleton was not found")

        elif creation_mode == 'based_on_file':
            import_file = request.FILES.get('import_file')
            if import_file is not None:
                try:
                    result = import_based_on_file(import_file, book)  # noqa
                except Exception as err:
                    logger.error("ImportError: Something went wrong importing file. Msg %s" % err)

        # STEP 4: Book Cover
        if 'cover_image' in request.FILES:
            # first we create a cover registry and upload the file
            file_data = request.FILES['cover_image']
            filename = file_data.name

            cover_license = License.objects.get(abbrevation=data.get('cover_license'))

            cover = BookCover(
                book=book,
                user=request.user,
                cid=uuid.uuid4().hex,
                title=data.get('cover_title'),
                filename=filename[:250],
                creator=data.get('cover_creator', '')[:40],
                license=cover_license,
                approved=False)
            cover.save()

            # now save the cover attachment
            cover.attachment.save(filename, file_data, save=False)
            cover.save()

            # and then finally, we set the book thumbnail
            try:
                fh, fname = misc.save_uploaded_as_file(file_data)
                book.set_cover(fname)
                os.unlink(fname)
            except:
                pass

        book.save()

        redirect_url = reverse('reader:infopage', args=[book.url_title])
        return HttpResponse(json.dumps({'redirect': redirect_url}), 'application/json')
Example #12
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)
Example #13
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)