Exemple #1
0
    def common_filters(self, allow_show_archived=False):
        if not allow_show_archived:
            archived_books = (
                ub.session.query(ub.ArchivedBook)
                    .filter(ub.ArchivedBook.user_id == int(current_user.id))
                    .filter(ub.ArchivedBook.is_archived == True)
                    .all()
            )
            archived_book_ids = [archived_book.book_id for archived_book in archived_books]
            archived_filter = Books.id.notin_(archived_book_ids)
        else:
            archived_filter = true()

        if current_user.filter_language() != "all":
            lang_filter = Books.languages.any(Languages.lang_code == current_user.filter_language())
        else:
            lang_filter = true()
        negtags_list = current_user.list_denied_tags()
        postags_list = current_user.list_allowed_tags()
        neg_content_tags_filter = false() if negtags_list == [''] else Books.tags.any(Tags.name.in_(negtags_list))
        pos_content_tags_filter = true() if postags_list == [''] else Books.tags.any(Tags.name.in_(postags_list))
        if self.config.config_restricted_column:
            pos_cc_list = current_user.allowed_column_value.split(',')
            pos_content_cc_filter = true() if pos_cc_list == [''] else \
                getattr(Books, 'custom_column_' + str(self.config.config_restricted_column)). \
                    any(cc_classes[self.config.config_restricted_column].value.in_(pos_cc_list))
            neg_cc_list = current_user.denied_column_value.split(',')
            neg_content_cc_filter = false() if neg_cc_list == [''] else \
                getattr(Books, 'custom_column_' + str(self.config.config_restricted_column)). \
                    any(cc_classes[self.config.config_restricted_column].value.in_(neg_cc_list))
        else:
            pos_content_cc_filter = true()
            neg_content_cc_filter = false()
        return and_(lang_filter, pos_content_tags_filter, ~neg_content_tags_filter,
                    pos_content_cc_filter, ~neg_content_cc_filter, archived_filter)
Exemple #2
0
def common_filters():
    if current_user.filter_language() != "all":
        lang_filter = db.Books.languages.any(
            db.Languages.lang_code == current_user.filter_language())
    else:
        lang_filter = true()
    negtags_list = current_user.list_denied_tags()
    postags_list = current_user.list_allowed_tags()
    neg_content_tags_filter = false() if negtags_list == [
        ''
    ] else db.Books.tags.any(db.Tags.name.in_(negtags_list))
    pos_content_tags_filter = true() if postags_list == [
        ''
    ] else db.Books.tags.any(db.Tags.name.in_(postags_list))
    if config.config_restricted_column:
        pos_cc_list = current_user.allowed_column_value.split(',')
        pos_content_cc_filter = true() if pos_cc_list == [''] else \
            getattr(db.Books, 'custom_column_' + str(config.config_restricted_column)).\
                any(db.cc_classes[config.config_restricted_column].value.in_(pos_cc_list))
        neg_cc_list = current_user.denied_column_value.split(',')
        neg_content_cc_filter = false() if neg_cc_list == [''] else \
            getattr(db.Books, 'custom_column_' + str(config.config_restricted_column)).\
                any(db.cc_classes[config.config_restricted_column].value.in_(neg_cc_list))
    else:
        pos_content_cc_filter = true()
        neg_content_cc_filter = false()
    return and_(lang_filter, pos_content_tags_filter, ~neg_content_tags_filter,
                pos_content_cc_filter, ~neg_content_cc_filter)
Exemple #3
0
def edit_book_languages(languages, book, upload=False):
    input_languages = languages.split(',')
    unknown_languages = []
    if not upload:
        input_l = isoLanguages.get_language_codes(get_locale(),
                                                  input_languages,
                                                  unknown_languages)
    else:
        input_l = isoLanguages.get_valid_language_codes(
            get_locale(), input_languages, unknown_languages)
    for l in unknown_languages:
        log.error('%s is not a valid language', l)
        flash(_(u"%(langname)s is not a valid language", langname=l),
              category="warning")
    # ToDo: Not working correct
    if upload and len(input_l) == 1:
        # If the language of the file is excluded from the users view, it's not imported, to allow the user to view
        # the book it's language is set to the filter language
        if input_l[0] != current_user.filter_language(
        ) and current_user.filter_language() != "all":
            input_l[0] = calibre_db.session.query(db.Languages). \
                filter(db.Languages.lang_code == current_user.filter_language()).first()
    # Remove duplicates
    input_l = helper.uniq(input_l)
    return modify_database_object(input_l, book.languages, db.Languages,
                                  calibre_db.session, 'languages')
Exemple #4
0
def common_filters():
    if current_user.filter_language() != "all":
        lang_filter = db.Books.languages.any(db.Languages.lang_code == current_user.filter_language())
    else:
        lang_filter = true()
    content_rating_filter = false() if current_user.mature_content else \
        db.Books.tags.any(db.Tags.name.in_(config.mature_content_tags()))
    return and_(lang_filter, ~content_rating_filter)
Exemple #5
0
    def common_filters(self,
                       allow_show_archived=False,
                       return_all_languages=False):
        if not allow_show_archived:
            archived_books = (ub.session.query(ub.ArchivedBook).filter(
                ub.ArchivedBook.user_id == int(current_user.id)).filter(
                    ub.ArchivedBook.is_archived == True).all())
            archived_book_ids = [
                archived_book.book_id for archived_book in archived_books
            ]
            archived_filter = Books.id.notin_(archived_book_ids)
        else:
            archived_filter = true()

        if current_user.filter_language() == "all" or return_all_languages:
            lang_filter = true()
        else:
            lang_filter = Books.languages.any(
                Languages.lang_code == current_user.filter_language())
        negtags_list = current_user.list_denied_tags()
        postags_list = current_user.list_allowed_tags()
        neg_content_tags_filter = false() if negtags_list == [
            ''
        ] else Books.tags.any(Tags.name.in_(negtags_list))
        pos_content_tags_filter = true() if postags_list == [
            ''
        ] else Books.tags.any(Tags.name.in_(postags_list))
        if self.config.config_restricted_column:
            try:
                pos_cc_list = current_user.allowed_column_value.split(',')
                pos_content_cc_filter = true() if pos_cc_list == [''] else \
                    getattr(Books, 'custom_column_' + str(self.config.config_restricted_column)). \
                        any(cc_classes[self.config.config_restricted_column].value.in_(pos_cc_list))
                neg_cc_list = current_user.denied_column_value.split(',')
                neg_content_cc_filter = false() if neg_cc_list == [''] else \
                    getattr(Books, 'custom_column_' + str(self.config.config_restricted_column)). \
                        any(cc_classes[self.config.config_restricted_column].value.in_(neg_cc_list))
            except (KeyError, AttributeError):
                pos_content_cc_filter = false()
                neg_content_cc_filter = true()
                log.error(
                    u"Custom Column No.%d is not existing in calibre database",
                    self.config.config_restricted_column)
                flash(_(
                    "Custom Column No.%(column)d is not existing in calibre database",
                    column=self.config.config_restricted_column),
                      category="error")

        else:
            pos_content_cc_filter = true()
            neg_content_cc_filter = false()
        return and_(lang_filter, pos_content_tags_filter,
                    ~neg_content_tags_filter, pos_content_cc_filter,
                    ~neg_content_cc_filter, archived_filter)
Exemple #6
0
def feed_languagesindex():
    off = request.args.get("offset") or 0
    if current_user.filter_language() == u"all":
        languages = calibre_db.speaking_language()
    else:
        languages = calibre_db.session.query(db.Languages).filter(
            db.Languages.lang_code == current_user.filter_language()).all()
        languages[0].name = isoLanguages.get_language_name(get_locale(), languages[0].lang_code)
    pagination = Pagination((int(off) / (int(config.config_books_per_page)) + 1), config.config_books_per_page,
                            len(languages))
    return render_xml_template('feed.xml', listelements=languages, folder='opds.feed_languages', pagination=pagination)
Exemple #7
0
def adv_search_language(q, include_languages_inputs, exclude_languages_inputs):
    if current_user.filter_language() != "all":
        q = q.filter(
            db.Books.languages.any(
                db.Languages.lang_code == current_user.filter_language()))
    else:
        for language in include_languages_inputs:
            q = q.filter(db.Books.languages.any(db.Languages.id == language))
        for language in exclude_languages_inputs:
            q = q.filter(not_(
                db.Books.series.any(db.Languages.id == language)))
    return q
Exemple #8
0
def feed_languagesindex():
    off = request.args.get("offset") or 0
    if current_user.filter_language() == u"all":
        languages = speaking_language()
    else:
        try:
            cur_l = LC.parse(current_user.filter_language())
        except UnknownLocaleError:
            cur_l = None
        languages = db.session.query(db.Languages).filter(
            db.Languages.lang_code == current_user.filter_language()).all()
        if cur_l:
            languages[0].name = cur_l.get_language_name(get_locale())
        else:
            languages[0].name = _(isoLanguages.get(part3=languages[0].lang_code).name)
    pagination = Pagination((int(off) / (int(config.config_books_per_page)) + 1), config.config_books_per_page,
                            len(languages))
    return render_xml_template('feed.xml', listelements=languages, folder='opds.feed_languages', pagination=pagination)
Exemple #9
0
def render_prepare_search_form(cc):
    # prepare data for search-form
    tags = calibre_db.session.query(db.Tags)\
        .join(db.books_tags_link)\
        .join(db.Books)\
        .filter(calibre_db.common_filters()) \
        .group_by(text('books_tags_link.tag'))\
        .order_by(db.Tags.name).all()
    series = calibre_db.session.query(db.Series)\
        .join(db.books_series_link)\
        .join(db.Books)\
        .filter(calibre_db.common_filters()) \
        .group_by(text('books_series_link.series'))\
        .order_by(db.Series.name)\
        .filter(calibre_db.common_filters()).all()
    shelves = ub.session.query(ub.Shelf)\
        .filter(or_(ub.Shelf.is_public == 1, ub.Shelf.user_id == int(current_user.id)))\
        .order_by(ub.Shelf.name).all()
    extensions = calibre_db.session.query(db.Data)\
        .join(db.Books)\
        .filter(calibre_db.common_filters()) \
        .group_by(db.Data.format)\
        .order_by(db.Data.format).all()
    if current_user.filter_language() == u"all":
        languages = calibre_db.speaking_language()
    else:
        languages = None
    return render_title_template('search_form.html',
                                 tags=tags,
                                 languages=languages,
                                 extensions=extensions,
                                 series=series,
                                 shelves=shelves,
                                 title=_(u"Advanced Search"),
                                 cc=cc,
                                 page="advsearch")
Exemple #10
0
def upload():
    if not config.config_uploading:
        abort(404)
    if request.method == 'POST' and 'btn-upload' in request.files:
        for requested_file in request.files.getlist("btn-upload"):
            # create the function for sorting...
            db.update_title_sort(config)
            db.session.connection().connection.connection.create_function(
                'uuid4', 0, lambda: str(uuid4()))

            # check if file extension is correct
            if '.' in requested_file.filename:
                file_ext = requested_file.filename.rsplit('.', 1)[-1].lower()
                if file_ext not in constants.EXTENSIONS_UPLOAD:
                    flash(_(
                        "File extension '%(ext)s' is not allowed to be uploaded to this server",
                        ext=file_ext),
                          category="error")
                    return Response(json.dumps(
                        {"location": url_for("web.index")}),
                                    mimetype='application/json')
            else:
                flash(_('File to be uploaded must have an extension'),
                      category="error")
                return Response(json.dumps({"location": url_for("web.index")}),
                                mimetype='application/json')

            # extract metadata from file
            try:
                meta = uploader.upload(requested_file)
            except (IOError, OSError):
                log.error("File %s could not saved to temp dir",
                          requested_file.filename)
                flash(_(u"File %(filename)s could not saved to temp dir",
                        filename=requested_file.filename),
                      category="error")
                return Response(json.dumps({"location": url_for("web.index")}),
                                mimetype='application/json')
            title = meta.title
            authr = meta.author
            tags = meta.tags
            series = meta.series
            series_index = meta.series_id
            title_dir = helper.get_valid_filename(title)
            author_dir = helper.get_valid_filename(authr)
            filepath = os.path.join(config.config_calibre_dir, author_dir,
                                    title_dir)
            saved_filename = os.path.join(filepath,
                                          title_dir + meta.extension.lower())

            if title != _(u'Unknown') and authr != _(u'Unknown'):
                entry = helper.check_exists_book(authr, title)
                if entry:
                    log.info("Uploaded book probably exists in library")
                    flash(_(
                        u"Uploaded book probably exists in the library, consider to change before upload new: "
                    ) + Markup(
                        render_title_template('book_exists_flash.html',
                                              entry=entry)),
                          category="warning")

            # check if file path exists, otherwise create it, copy file to calibre path and delete temp file
            if not os.path.exists(filepath):
                try:
                    os.makedirs(filepath)
                except OSError:
                    log.error("Failed to create path %s (Permission denied)",
                              filepath)
                    flash(_(
                        u"Failed to create path %(path)s (Permission denied).",
                        path=filepath),
                          category="error")
                    return Response(json.dumps(
                        {"location": url_for("web.index")}),
                                    mimetype='application/json')
            try:
                copyfile(meta.file_path, saved_filename)
            except OSError:
                log.error("Failed to store file %s (Permission denied)",
                          saved_filename)
                flash(_(u"Failed to store file %(file)s (Permission denied).",
                        file=saved_filename),
                      category="error")
                return Response(json.dumps({"location": url_for("web.index")}),
                                mimetype='application/json')
            try:
                os.unlink(meta.file_path)
            except OSError:
                log.error("Failed to delete file %(file)s (Permission denied)",
                          meta.file_path)
                flash(_(u"Failed to delete file %(file)s (Permission denied).",
                        file=meta.file_path),
                      category="warning")

            if meta.cover is None:
                has_cover = 0
                copyfile(
                    os.path.join(constants.STATIC_DIR, 'generic_cover.jpg'),
                    os.path.join(filepath, "cover.jpg"))
            else:
                has_cover = 1
                move(meta.cover, os.path.join(filepath, "cover.jpg"))

            # handle authors
            is_author = db.session.query(
                db.Authors).filter(db.Authors.name == authr).first()
            if is_author:
                db_author = is_author
            else:
                db_author = db.Authors(authr, helper.get_sorted_author(authr),
                                       "")
                db.session.add(db_author)

            # handle series
            db_series = None
            is_series = db.session.query(
                db.Series).filter(db.Series.name == series).first()
            if is_series:
                db_series = is_series
            elif series != '':
                db_series = db.Series(series, "")
                db.session.add(db_series)

            # add language actually one value in list
            input_language = meta.languages
            db_language = None
            if input_language != "":
                input_language = isoLanguages.get(name=input_language).part3
                hasLanguage = db.session.query(db.Languages).filter(
                    db.Languages.lang_code == input_language).first()
                if hasLanguage:
                    db_language = hasLanguage
                else:
                    db_language = db.Languages(input_language)
                    db.session.add(db_language)

            # If the language of the file is excluded from the users view, it's not imported, to allow the user to view
            # the book it's language is set to the filter language
            if db_language != current_user.filter_language(
            ) and current_user.filter_language() != "all":
                db_language = db.session.query(db.Languages).\
                    filter(db.Languages.lang_code == current_user.filter_language()).first()

            # combine path and normalize path from windows systems
            path = os.path.join(author_dir, title_dir).replace('\\', '/')
            db_book = db.Books(title, "", db_author.sort,
                               datetime.datetime.now(),
                               datetime.datetime(101, 1, 1), series_index,
                               datetime.datetime.now(), path, has_cover,
                               db_author, [], db_language)
            db_book.authors.append(db_author)
            if db_series:
                db_book.series.append(db_series)
            if db_language is not None:
                db_book.languages.append(db_language)
            file_size = os.path.getsize(saved_filename)
            db_data = db.Data(db_book,
                              meta.extension.upper()[1:], file_size, title_dir)

            # handle tags
            input_tags = tags.split(',')
            input_tags = list(map(lambda it: it.strip(), input_tags))
            if input_tags[0] != "":
                modify_database_object(input_tags, db_book.tags, db.Tags,
                                       db.session, 'tags')

            # flush content, get db_book.id available
            db_book.data.append(db_data)
            db.session.add(db_book)
            db.session.flush()

            # add comment
            book_id = db_book.id
            upload_comment = Markup(meta.description).unescape()
            if upload_comment != "":
                db.session.add(db.Comments(upload_comment, book_id))

            # save data to database, reread data
            db.session.commit()
            db.update_title_sort(config)
            # Reread book. It's important not to filter the result, as it could have language which hide it from
            # current users view (tags are not stored/extracted from metadata and could also be limited)
            book = db.session.query(
                db.Books).filter(db.Books.id == book_id).first()
            # upload book to gdrive if nesseccary and add "(bookid)" to folder name
            if config.config_use_google_drive:
                gdriveutils.updateGdriveCalibreFromLocal()
            error = helper.update_dir_stucture(book.id,
                                               config.config_calibre_dir)
            db.session.commit()
            if config.config_use_google_drive:
                gdriveutils.updateGdriveCalibreFromLocal()
            if error:
                flash(error, category="error")
            uploadText = _(u"File %(file)s uploaded", file=book.title)
            worker.add_upload(
                current_user.nickname,
                "<a href=\"" + url_for('web.show_book', book_id=book.id) +
                "\">" + uploadText + "</a>")

            # create data for displaying display Full language name instead of iso639.part3language
            if db_language is not None:
                book.languages[0].language_name = _(meta.languages)
            author_names = []
            for author in db_book.authors:
                author_names.append(author.name)
            if len(request.files.getlist("btn-upload")) < 2:
                if current_user.role_edit() or current_user.role_admin():
                    resp = {
                        "location":
                        url_for('editbook.edit_book', book_id=db_book.id)
                    }
                    return Response(json.dumps(resp),
                                    mimetype='application/json')
                else:
                    resp = {
                        "location": url_for('web.show_book',
                                            book_id=db_book.id)
                    }
                    return Response(json.dumps(resp),
                                    mimetype='application/json')
        return Response(json.dumps({"location": url_for("web.index")}),
                        mimetype='application/json')