jiahuimbzuai/CoQuIR huggingface dataset:
//  [python]
def read_book(book_id, book_format):
    book = calibre_db.get_filtered_book(book_id)
    book.ordered_authors = calibre_db.order_authors([book], False)

    if not book:
        flash(_(u"Oops! Selected book title is unavailable. File does not exist or is not accessible"), category="error")
        log.debug(u"Oops! Selected book title is unavailable. File does not exist or is not accessible")
        return redirect(url_for("web.index"))

    # check if book has a bookmark
    bookmark = None
    if current_user.is_authenticated:
        bookmark = ub.session.query(ub.Bookmark).filter(and_(ub.Bookmark.user_id == int(current_user.id),
                                                             ub.Bookmark.book_id == book_id,
                                                             ub.Bookmark.format == book_format.upper())).first()
    if book_format.lower() == "epub":
        log.debug(u"Start epub reader for %d", book_id)
        return render_title_template('read.html', bookid=book_id, title=book.title, bookmark=bookmark)
    elif book_format.lower() == "pdf":
        log.debug(u"Start pdf reader for %d", book_id)
        return render_title_template('readpdf.html', pdffile=book_id, title=book.title)
    elif book_format.lower() == "txt":
        log.debug(u"Start txt reader for %d", book_id)
        return render_title_template('readtxt.html', txtfile=book_id, title=book.title)
    elif book_format.lower() == "djvu":
        log.debug(u"Start djvu reader for %d", book_id)
        return render_title_template('readdjvu.html', djvufile=book_id, title=book.title)
    else:
        for fileExt in constants.EXTENSIONS_AUDIO:
            if book_format.lower() == fileExt:
                entries = calibre_db.get_filtered_book(book_id)
                log.debug(u"Start mp3 listening for %d", book_id)
                return render_title_template('listenmp3.html', mp3file=book_id, audioformat=book_format.lower(),
                                             entry=entries, bookmark=bookmark)
        for fileExt in ["cbr", "cbt", "cbz"]:
            if book_format.lower() == fileExt:
                all_name = str(book_id)
                title = book.title
                if len(book.series):
                    title = title + " - " + book.series[0].name
                    if book.series_index:
                        title = title + " #" + '{0:.2f}'.format(book.series_index).rstrip('0').rstrip('.')
                log.debug(u"Start comic reader for %d", book_id)
                return render_title_template('readcbr.html', comicfile=all_name, title=title,
                                             extension=fileExt)
        log.debug(u"Oops! Selected book title is unavailable. File does not exist or is not accessible")
        flash(_(u"Oops! Selected book title is unavailable. File does not exist or is not accessible"), category="error")
        return redirect(url_for("web.index"))
//  [python]
def render_hot_books(page, order):
    if current_user.check_visibility(constants.SIDEBAR_HOT):
        if order[1] not in ['hotasc', 'hotdesc']:
            # Unary expression comparsion only working (for this expression) in sqlalchemy 1.4+
            # if not (order[0][0].compare(func.count(ub.Downloads.book_id).desc()) or
            #        order[0][0].compare(func.count(ub.Downloads.book_id).asc())):
            order = [func.count(ub.Downloads.book_id).desc()], 'hotdesc'
        if current_user.show_detail_random():
            random = calibre_db.session.query(db.Books).filter(calibre_db.common_filters()) \
                .order_by(func.random()).limit(config.config_random_books)
        else:
            random = false()
        off = int(int(config.config_books_per_page) * (page - 1))
        all_books = ub.session.query(ub.Downloads, func.count(ub.Downloads.book_id)) \
            .order_by(*order[0]).group_by(ub.Downloads.book_id)
        hot_books = all_books.offset(off).limit(config.config_books_per_page)
        entries = list()
        for book in hot_books:
            download_book = calibre_db.session.query(db.Books).filter(calibre_db.common_filters()).filter(
                db.Books.id == book.Downloads.book_id).first()
            if download_book:
                entries.append(download_book)
            else:
                ub.delete_download(book.Downloads.book_id)
        num_books = entries.__len__()
        pagination = Pagination(page, config.config_books_per_page, num_books)
        return render_title_template('index.html', random=random, entries=entries, pagination=pagination,
                                     title=_(u"Hot Books (Most Downloaded)"), page="hot", order=order[1])
    else:
        abort(404)
//  [python]
def render_hot_books(page, order):
    if current_user.check_visibility(constants.SIDEBAR_HOT):
        if order[1] not in ['hotasc', 'hotdesc']:
        # Unary expression comparsion only working (for this expression) in sqlalchemy 1.4+
        #if not (order[0][0].compare(func.count(ub.Downloads.book_id).desc()) or
        #        order[0][0].compare(func.count(ub.Downloads.book_id).asc())):
            order = [func.count(ub.Downloads.book_id).desc()], 'hotdesc'
        if current_user.show_detail_random():
            random = calibre_db.session.query(db.Books).filter(calibre_db.common_filters()) \
                .order_by(func.random()).limit(config.config_random_books)
        else:
            random = false()
        off = int(int(config.config_books_per_page) * (page - 1))
        all_books = ub.session.query(ub.Downloads, func.count(ub.Downloads.book_id))\
            .order_by(*order[0]).group_by(ub.Downloads.book_id)
        hot_books = all_books.offset(off).limit(config.config_books_per_page)
        entries = list()
        for book in hot_books:
            downloadBook = calibre_db.session.query(db.Books).filter(calibre_db.common_filters()).filter(
                db.Books.id == book.Downloads.book_id).first()
            if downloadBook:
                entries.append(downloadBook)
            else:
                ub.delete_download(book.Downloads.book_id)
        numBooks = entries.__len__()
        pagination = Pagination(page, config.config_books_per_page, numBooks)
        return render_title_template('index.html', random=random, entries=entries, pagination=pagination,
                                     title=_(u"Hot Books (Most Downloaded)"), page="hot", order=order[1])
    else:
        abort(404)
//  [python]
def series_list():
    if current_user.check_visibility(constants.SIDEBAR_SERIES):
        if current_user.get_view_property('series', 'dir') == 'desc':
            order = db.Series.sort.desc()
            order_no = 0
        else:
            order = db.Series.sort.asc()
            order_no = 1
        char_list = generate_char_list(db.Series.sort, db.books_series_link)
        if current_user.get_view_property('series', 'series_view') == 'list':
            entries = calibre_db.session.query(db.Series, func.count('books_series_link.book').label('count')) \
                .join(db.books_series_link).join(db.Books).filter(calibre_db.common_filters()) \
                .group_by(text('books_series_link.series')).order_by(order).all()
            return render_title_template('list.html', entries=entries, folder='web.books_list', charlist=char_list,
                                         title=_(u"Series"), page="serieslist", data="series", order=order_no)
        else:
            entries = calibre_db.session.query(db.Books, func.count('books_series_link').label('count'),
                                               func.max(db.Books.series_index), db.Books.id) \
                .join(db.books_series_link).join(db.Series).filter(calibre_db.common_filters()) \
                .group_by(text('books_series_link.series')).order_by(order).all()
            return render_title_template('grid.html', entries=entries, folder='web.books_list', charlist=char_list,
                                         title=_(u"Series"), page="serieslist", data="series", bodyClass="grid-view",
                                         order=order_no)
    else:
        abort(404)
//  [python]
def series_list():
    if current_user.check_visibility(constants.SIDEBAR_SERIES):
        if current_user.get_view_property('series', 'dir') == 'desc':
            order = db.Series.sort.desc()
            order_no = 0
        else:
            order = db.Series.sort.asc()
            order_no = 1
        if current_user.get_view_property('series', 'series_view') == 'list':
            entries = calibre_db.session.query(db.Series, func.count('books_series_link.book').label('count')) \
                .join(db.books_series_link).join(db.Books).filter(calibre_db.common_filters()) \
                .group_by(text('books_series_link.series')).order_by(order).all()
            charlist = calibre_db.session.query(func.upper(func.substr(db.Series.sort, 1, 1)).label('char')) \
                .join(db.books_series_link).join(db.Books).filter(calibre_db.common_filters()) \
                .group_by(func.upper(func.substr(db.Series.sort, 1, 1))).all()
            return render_title_template('list.html', entries=entries, folder='web.books_list', charlist=charlist,
                                         title=_(u"Series"), page="serieslist", data="series", order=order_no)
        else:
            entries = calibre_db.session.query(db.Books, func.count('books_series_link').label('count'),
                                               func.max(db.Books.series_index), db.Books.id) \
                .join(db.books_series_link).join(db.Series).filter(calibre_db.common_filters())\
                .group_by(text('books_series_link.series')).order_by(order).all()
            charlist = calibre_db.session.query(func.upper(func.substr(db.Series.sort, 1, 1)).label('char')) \
                .join(db.books_series_link).join(db.Books).filter(calibre_db.common_filters()) \
                .group_by(func.upper(func.substr(db.Series.sort, 1, 1))).all()

            return render_title_template('grid.html', entries=entries, folder='web.books_list', charlist=charlist,
                                         title=_(u"Series"), page="serieslist", data="series", bodyClass="grid-view",
                                         order=order_no)
    else:
        abort(404)
//  [python]
def set_bookmark(book_id, book_format):
    bookmark_key = request.form["bookmark"]
    ub.session.query(ub.Bookmark).filter(and_(ub.Bookmark.user_id == int(current_user.id),
                                              ub.Bookmark.book_id == book_id,
                                              ub.Bookmark.format == book_format)).delete()
    if not bookmark_key:
        ub.session_commit()
        return "", 204

    l_bookmark = ub.Bookmark(user_id=current_user.id,
                             book_id=book_id,
                             format=book_format,
                             bookmark_key=bookmark_key)
    ub.session.merge(l_bookmark)
    ub.session_commit("Bookmark for user {} in book {} created".format(current_user.id, book_id))
    return "", 201
//  [python]
def set_bookmark(book_id, book_format):
    bookmark_key = request.form["bookmark"]
    ub.session.query(ub.Bookmark).filter(and_(ub.Bookmark.user_id == int(current_user.id),
                                              ub.Bookmark.book_id == book_id,
                                              ub.Bookmark.format == book_format)).delete()
    if not bookmark_key:
        ub.session_commit()
        return "", 204

    lbookmark = ub.Bookmark(user_id=current_user.id,
                            book_id=book_id,
                            format=book_format,
                            bookmark_key=bookmark_key)
    ub.session.merge(lbookmark)
    ub.session_commit("Bookmark for user {} in book {} created".format(current_user.id, book_id))
    return "", 201
//  [python]
def render_books_list(data, sort_param, book_id, page):
    order = get_sort_function(sort_param, data)
    if data == "rated":
        return render_rated_books(page, book_id, order=order)
    elif data == "discover":
        return render_discover_books(page, book_id)
    elif data == "unread":
        return render_read_books(page, False, order=order)
    elif data == "read":
        return render_read_books(page, True, order=order)
    elif data == "hot":
        return render_hot_books(page, order)
    elif data == "download":
        return render_downloaded_books(page, order, book_id)
    elif data == "author":
        return render_author_books(page, book_id, order)
    elif data == "publisher":
        return render_publisher_books(page, book_id, order)
    elif data == "series":
        return render_series_books(page, book_id, order)
    elif data == "ratings":
        return render_ratings_books(page, book_id, order)
    elif data == "formats":
        return render_formats_books(page, book_id, order)
    elif data == "category":
        return render_category_books(page, book_id, order)
    elif data == "language":
        return render_language_books(page, book_id, order)
    elif data == "archived":
        return render_archived_books(page, order)
    elif data == "search":
        term = (request.args.get('query') or '')
        offset = int(int(config.config_books_per_page) * (page - 1))
        return render_search_results(term, offset, order, config.config_books_per_page)
    elif data == "advsearch":
        term = json.loads(flask_session['query'])
        offset = int(int(config.config_books_per_page) * (page - 1))
        return render_adv_search_results(term, offset, order, config.config_books_per_page)
    else:
        website = data or "newest"
        entries, random, pagination = calibre_db.fill_indexpage(page, 0, db.Books, True, order[0],
                                                                False, 0,
                                                                db.books_series_link,
                                                                db.Books.id == db.books_series_link.c.book,
                                                                db.Series)
        return render_title_template('index.html', random=random, entries=entries, pagination=pagination,
                                     title=_(u"Books"), page=website, order=order[1])
//  [python]
def render_books_list(data, sort_param, book_id, page):
    order = get_sort_function(sort_param, data)
    if data == "rated":
        return render_rated_books(page, book_id, order=order)
    elif data == "discover":
        return render_discover_books(page, book_id)
    elif data == "unread":
        return render_read_books(page, False, order=order)
    elif data == "read":
        return render_read_books(page, True, order=order)
    elif data == "hot":
        return render_hot_books(page, order)
    elif data == "download":
        return render_downloaded_books(page, order, book_id)
    elif data == "author":
        return render_author_books(page, book_id, order)
    elif data == "publisher":
        return render_publisher_books(page, book_id, order)
    elif data == "series":
        return render_series_books(page, book_id, order)
    elif data == "ratings":
        return render_ratings_books(page, book_id, order)
    elif data == "formats":
        return render_formats_books(page, book_id, order)
    elif data == "category":
        return render_category_books(page, book_id, order)
    elif data == "language":
        return render_language_books(page, book_id, order)
    elif data == "archived":
        return render_archived_books(page, order)
    elif data == "search":
        term = (request.args.get('query') or '')
        offset = int(int(config.config_books_per_page) * (page - 1))
        return render_search_results(term, offset, order, config.config_books_per_page)
    elif data == "advsearch":
        term = json.loads(flask_session['query'])
        offset = int(int(config.config_books_per_page) * (page - 1))
        return render_adv_search_results(term, offset, order, config.config_books_per_page)
    else:
        website = data or "newest"
        entries, random, pagination = calibre_db.fill_indexpage(page, 0, db.Books, True, order[0],
        														False, 0,
                                                                db.books_series_link,
                                                                db.Books.id == db.books_series_link.c.book,
                                                                db.Series)
        return render_title_template('index.html', random=random, entries=entries, pagination=pagination,
                                     title=_(u"Books"), page=website, order=order[1])
//  [python]
def render_downloaded_books(page, order, user_id):
    if current_user.role_admin():
        user_id = int(user_id)
    else:
        user_id = current_user.id
    if current_user.check_visibility(constants.SIDEBAR_DOWNLOAD):
        if current_user.show_detail_random():
            random = calibre_db.session.query(db.Books).filter(calibre_db.common_filters()) \
                .order_by(func.random()).limit(config.config_random_books)
        else:
            random = false()

        entries, __, pagination = calibre_db.fill_indexpage(page,
                                                            0,
                                                            db.Books,
                                                            ub.Downloads.user_id == user_id,
                                                            order[0],
                                                            False, 0,
                                                            db.books_series_link,
                                                            db.Books.id == db.books_series_link.c.book,
                                                            db.Series,
                                                            ub.Downloads, db.Books.id == ub.Downloads.book_id)
        for book in entries:
            if not calibre_db.session.query(db.Books).\
                                            filter(calibre_db.common_filters()).filter(db.Books.id == book.id).first():
                ub.delete_download(book.id)
        user = ub.session.query(ub.User).filter(ub.User.id == user_id).first()
        return render_title_template('index.html',
                                     random=random,
                                     entries=entries,
                                     pagination=pagination,
                                     id=user_id,
                                     title=_(u"Downloaded books by %(user)s", user=user.name),
                                     page="download",
                                     order=order[1])
    else:
        abort(404)
//  [python]
def render_downloaded_books(page, order, user_id):
    if current_user.role_admin():
        user_id = int(user_id)
    else:
        user_id = current_user.id
    if current_user.check_visibility(constants.SIDEBAR_DOWNLOAD):
        if current_user.show_detail_random():
            random = calibre_db.session.query(db.Books).filter(calibre_db.common_filters()) \
                .order_by(func.random()).limit(config.config_random_books)
        else:
            random = false()

        entries, __, pagination = calibre_db.fill_indexpage(page,
                                                            0,
                                                            db.Books,
                                                            ub.Downloads.user_id == user_id,
                                                            order[0],
                                                            False, 0,
                                                            db.books_series_link,
                                                            db.Books.id == db.books_series_link.c.book,
                                                            db.Series,
                                                            ub.Downloads, db.Books.id == ub.Downloads.book_id)
        for book in entries:
            if not calibre_db.session.query(db.Books).filter(calibre_db.common_filters()) \
                             .filter(db.Books.id == book.id).first():
                ub.delete_download(book.id)
        user = ub.session.query(ub.User).filter(ub.User.id == user_id).first()
        return render_title_template('index.html',
                                     random=random,
                                     entries=entries,
                                     pagination=pagination,
                                     id=user_id,
                                     title=_(u"Downloaded books by %(user)s",user=user.name),
                                     page="download",
                                     order=order[1])
    else:
        abort(404)
//  [python]
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")
//  [python]
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")
//  [python]
def show_book(book_id):
    entries = calibre_db.get_book_read_archived(book_id, config.config_read_column, allow_show_archived=True)
    if entries:
        read_book = entries[1]
        archived_book = entries[2]
        entry = entries[0]
        entry.read_status = read_book == ub.ReadBook.STATUS_FINISHED
        entry.is_archived = archived_book
        for lang_index in range(0, len(entry.languages)):
            entry.languages[lang_index].language_name = isoLanguages.get_language_name(get_locale(), entry.languages[
                lang_index].lang_code)
        cc = get_cc_columns(filter_config_custom_read=True)
        book_in_shelves = []
        shelfs = ub.session.query(ub.BookShelf).filter(ub.BookShelf.book_id == book_id).all()
        for sh in shelfs:
            book_in_shelves.append(sh.shelf)

        entry.tags = sort(entry.tags, key=lambda tag: tag.name)

        entry.ordered_authors = calibre_db.order_authors([entry])

        entry.kindle_list = check_send_to_kindle(entry)
        entry.reader_list = check_read_formats(entry)

        entry.audioentries = []
        for media_format in entry.data:
            if media_format.format.lower() in constants.EXTENSIONS_AUDIO:
                entry.audioentries.append(media_format.format.lower())

        return render_title_template('detail.html',
                                     entry=entry,
                                     cc=cc,
                                     is_xhr=request.headers.get('X-Requested-With') == 'XMLHttpRequest',
                                     title=entry.title,
                                     books_shelfs=book_in_shelves,
                                     page="book")
    else:
        log.debug(u"Oops! Selected book title is unavailable. File does not exist or is not accessible")
        flash(_(u"Oops! Selected book title is unavailable. File does not exist or is not accessible"),
              category="error")
        return redirect(url_for("web.index"))
//  [python]
def show_book(book_id):
    entries = calibre_db.get_book_read_archived(book_id, config.config_read_column, allow_show_archived=True)
    if entries:
        read_book = entries[1]
        archived_book = entries[2]
        entry = entries[0]
        entry.read_status = read_book == ub.ReadBook.STATUS_FINISHED
        entry.is_archived = archived_book
        for index in range(0, len(entry.languages)):
            entry.languages[index].language_name = isoLanguages.get_language_name(get_locale(), entry.languages[
                index].lang_code)
        cc = get_cc_columns(filter_config_custom_read=True)
        book_in_shelfs = []
        shelfs = ub.session.query(ub.BookShelf).filter(ub.BookShelf.book_id == book_id).all()
        for sh in shelfs:
            book_in_shelfs.append(sh.shelf)

        entry.tags = sort(entry.tags, key=lambda tag: tag.name)

        entry.ordered_authors = calibre_db.order_authors([entry])

        entry.kindle_list = check_send_to_kindle(entry)
        entry.reader_list = check_read_formats(entry)

        entry.audioentries = []
        for media_format in entry.data:
            if media_format.format.lower() in constants.EXTENSIONS_AUDIO:
                entry.audioentries.append(media_format.format.lower())

        return render_title_template('detail.html',
                                     entry=entry,
                                     cc=cc,
                                     is_xhr=request.headers.get('X-Requested-With')=='XMLHttpRequest',
                                     title=entry.title,
                                     books_shelfs=book_in_shelfs,
                                     page="book")
    else:
        log.debug(u"Oops! Selected book title is unavailable. File does not exist or is not accessible")
        flash(_(u"Oops! Selected book title is unavailable. File does not exist or is not accessible"),
              category="error")
        return redirect(url_for("web.index"))
//  [python]
def feed_author(book_id):
    return render_xml_dataset(db.Authors, book_id)
//  [python]
def feed_author(book_id):
    off = request.args.get("offset") or 0
    entries, __, pagination = calibre_db.fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1), 0,
                                                        db.Books,
                                                        db.Books.authors.any(db.Authors.id == book_id),
                                                        [db.Books.timestamp.desc()])
    return render_xml_template('feed.xml', entries=entries, pagination=pagination)
//  [python]
def toggle_archived(book_id):
    is_archived = change_archived_books(book_id, message="Book {} archive bit toggled".format(book_id))
    if is_archived:
        remove_synced_book(book_id)
    return ""
//  [python]
def toggle_archived(book_id):
    is_archived = change_archived_books(book_id, message="Book {} archivebit toggled".format(book_id))
    if is_archived:
        remove_synced_book(book_id)
    return ""
//  [python]
def _keyify(key):
    key = escape(key.lower(), quote=True)
    return _key_pattern.sub(' ', key)
//  [python]
def _keyify(key):
    return _key_pattern.sub(' ', key.lower())
//  [python]
def feed_category(book_id):
    return render_xml_dataset(db.Tags, book_id)
//  [python]
def feed_category(book_id):
    off = request.args.get("offset") or 0
    entries, __, pagination = calibre_db.fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1), 0,
                                                        db.Books,
                                                        db.Books.tags.any(db.Tags.id == book_id),
                                                        [db.Books.timestamp.desc()])
    return render_xml_template('feed.xml', entries=entries, pagination=pagination)
//  [python]
def check_auth(username, password):
    try:
        username = username.encode('windows-1252')
    except UnicodeEncodeError:
        username = username.encode('utf-8')
    user = ub.session.query(ub.User).filter(func.lower(ub.User.name) ==
                                            username.decode('utf-8').lower()).first()
    if bool(user and check_password_hash(str(user.password), password)):
        return True
    else:
        ip_address = request.headers.get('X-Forwarded-For', request.remote_addr)
        log.warning('OPDS Login failed for user "%s" IP-address: %s', username.decode('utf-8'), ip_address)
        return False
//  [python]
def check_auth(username, password):
    try:
        username = username.encode('windows-1252')
    except UnicodeEncodeError:
        username = username.encode('utf-8')
    user = ub.session.query(ub.User).filter(func.lower(ub.User.name) ==
                                            username.decode('utf-8').lower()).first()
    if bool(user and check_password_hash(str(user.password), password)):
        return True
    else:
        ip_Address = request.headers.get('X-Forwarded-For', request.remote_addr)
        log.warning('OPDS Login failed for user "%s" IP-address: %s', username.decode('utf-8'), ip_Address)
        return False
//  [python]
def feed_authorindex():
    return render_element_index(db.Authors.sort, db.books_authors_link, 'opds.feed_letter_author')
//  [python]
def feed_authorindex():
    shift = 0
    off = int(request.args.get("offset") or 0)
    entries = calibre_db.session.query(func.upper(func.substr(db.Authors.sort, 1, 1)).label('id'))\
        .join(db.books_authors_link).join(db.Books).filter(calibre_db.common_filters())\
        .group_by(func.upper(func.substr(db.Authors.sort, 1, 1))).all()

    elements = []
    if off == 0:
        elements.append({'id': "00", 'name':_("All")})
        shift = 1
    for entry in entries[
                 off + shift - 1:
                 int(off + int(config.config_books_per_page) - shift)]:
        elements.append({'id': entry.id, 'name': entry.id})

    pagination = Pagination((int(off) / (int(config.config_books_per_page)) + 1), config.config_books_per_page,
                            len(entries) + 1)
    return render_xml_template('feed.xml',
                               letterelements=elements,
                               folder='opds.feed_letter_author',
                               pagination=pagination)
//  [python]
def feed_categoryindex():
    return render_element_index(db.Tags.name, db.books_tags_link, 'opds.feed_letter_category')
//  [python]
def feed_categoryindex():
    shift = 0
    off = int(request.args.get("offset") or 0)
    entries = calibre_db.session.query(func.upper(func.substr(db.Tags.name, 1, 1)).label('id'))\
        .join(db.books_tags_link).join(db.Books).filter(calibre_db.common_filters())\
        .group_by(func.upper(func.substr(db.Tags.name, 1, 1))).all()
    elements = []
    if off == 0:
        elements.append({'id': "00", 'name':_("All")})
        shift = 1
    for entry in entries[
                 off + shift - 1:
                 int(off + int(config.config_books_per_page) - shift)]:
        elements.append({'id': entry.id, 'name': entry.id})

    pagination = Pagination((int(off) / (int(config.config_books_per_page)) + 1), config.config_books_per_page,
                            len(entries) + 1)
    return render_xml_template('feed.xml',
                               letterelements=elements,
                               folder='opds.feed_letter_category',
                               pagination=pagination)
//  [python]
def feed_booksindex():
    return render_element_index(db.Books.sort, None, 'opds.feed_letter_books')
//  [python]
def feed_booksindex():
    shift = 0
    off = int(request.args.get("offset") or 0)
    entries = calibre_db.session.query(func.upper(func.substr(db.Books.sort, 1, 1)).label('id'))\
        .filter(calibre_db.common_filters()).group_by(func.upper(func.substr(db.Books.sort, 1, 1))).all()

    elements = []
    if off == 0:
        elements.append({'id': "00", 'name':_("All")})
        shift = 1
    for entry in entries[
                 off + shift - 1:
                 int(off + int(config.config_books_per_page) - shift)]:
        elements.append({'id': entry.id, 'name': entry.id})

    pagination = Pagination((int(off) / (int(config.config_books_per_page)) + 1), config.config_books_per_page,
                            len(entries) + 1)
    return render_xml_template('feed.xml',
                               letterelements=elements,
                               folder='opds.feed_letter_books',
                               pagination=pagination)
//  [python]
def feed_hot():
    off = request.args.get("offset") or 0
    all_books = ub.session.query(ub.Downloads, func.count(ub.Downloads.book_id)).order_by(
        func.count(ub.Downloads.book_id).desc()).group_by(ub.Downloads.book_id)
    hot_books = all_books.offset(off).limit(config.config_books_per_page)
    entries = list()
    for book in hot_books:
        download_book = calibre_db.get_book(book.Downloads.book_id)
        if download_book:
            entries.append(
                calibre_db.get_filtered_book(book.Downloads.book_id)
            )
        else:
            ub.delete_download(book.Downloads.book_id)
    num_books = entries.__len__()
    pagination = Pagination((int(off) / (int(config.config_books_per_page)) + 1),
                            config.config_books_per_page, num_books)
    return render_xml_template('feed.xml', entries=entries, pagination=pagination)
//  [python]
def feed_hot():
    off = request.args.get("offset") or 0
    all_books = ub.session.query(ub.Downloads, func.count(ub.Downloads.book_id)).order_by(
        func.count(ub.Downloads.book_id).desc()).group_by(ub.Downloads.book_id)
    hot_books = all_books.offset(off).limit(config.config_books_per_page)
    entries = list()
    for book in hot_books:
        downloadBook = calibre_db.get_book(book.Downloads.book_id)
        if downloadBook:
            entries.append(
                calibre_db.get_filtered_book(book.Downloads.book_id)
            )
        else:
            ub.delete_download(book.Downloads.book_id)
    numBooks = entries.__len__()
    pagination = Pagination((int(off) / (int(config.config_books_per_page)) + 1),
                            config.config_books_per_page, numBooks)
    return render_xml_template('feed.xml', entries=entries, pagination=pagination)
//  [python]
def feed_publisher(book_id):
    return render_xml_dataset(db.Publishers, book_id)
//  [python]
def feed_publisher(book_id):
    off = request.args.get("offset") or 0
    entries, __, pagination = calibre_db.fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1), 0,
                                                        db.Books,
                                                        db.Books.publishers.any(db.Publishers.id == book_id),
                                                        [db.Books.timestamp.desc()])
    return render_xml_template('feed.xml', entries=entries, pagination=pagination)
//  [python]
def feed_get_cover(book_id):
    return get_book_cover(book_id)
//  [python]
def feed_ratings(book_id):
    return render_xml_dataset(db.Tags, book_id)
//  [python]
def feed_ratings(book_id):
    off = request.args.get("offset") or 0
    entries, __, pagination = calibre_db.fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1), 0,
                                                        db.Books,
                                                        db.Books.ratings.any(db.Ratings.id == book_id),
                                                        [db.Books.timestamp.desc()])
    return render_xml_template('feed.xml', entries=entries, pagination=pagination)
//  [python]
def feed_unread_books():
    off = request.args.get("offset") or 0
    result, pagination = render_read_books(int(off) / (int(config.config_books_per_page)) + 1, False, True)
    return render_xml_template('feed.xml', entries=result, pagination=pagination)
//  [python]
def feed_ratingindex():
    off = request.args.get("offset") or 0
    entries = calibre_db.session.query(db.Ratings, func.count('books_ratings_link.book').label('count'),
                                       (db.Ratings.rating / 2).label('name')) \
        .join(db.books_ratings_link)\
        .join(db.Books)\
        .filter(calibre_db.common_filters()) \
        .group_by(text('books_ratings_link.rating'))\
        .order_by(db.Ratings.rating).all()

    pagination = Pagination((int(off) / (int(config.config_books_per_page)) + 1), config.config_books_per_page,
                            len(entries))
    element = list()
    for entry in entries:
        element.append(FeedObject(entry[0].id, _("{} Stars").format(entry.name)))
    return render_xml_template('feed.xml', listelements=element, folder='opds.feed_ratings', pagination=pagination)
//  [python]
def feed_ratingindex():
    off = request.args.get("offset") or 0
    entries = calibre_db.session.query(db.Ratings, func.count('books_ratings_link.book').label('count'),
                               (db.Ratings.rating / 2).label('name')) \
        .join(db.books_ratings_link)\
        .join(db.Books)\
        .filter(calibre_db.common_filters()) \
        .group_by(text('books_ratings_link.rating'))\
        .order_by(db.Ratings.rating).all()

    pagination = Pagination((int(off) / (int(config.config_books_per_page)) + 1), config.config_books_per_page,
                            len(entries))
    element = list()
    for entry in entries:
        element.append(FeedObject(entry[0].id, _("{} Stars").format(entry.name)))
    return render_xml_template('feed.xml', listelements=element, folder='opds.feed_ratings', pagination=pagination)
//  [python]
def feed_read_books():
    off = request.args.get("offset") or 0
    result, pagination = render_read_books(int(off) / (int(config.config_books_per_page)) + 1, True, True)
    return render_xml_template('feed.xml', entries=result, pagination=pagination)
//  [python]
def feed_seriesindex():
    return render_element_index(db.Series.sort, db.books_series_link, 'opds.feed_letter_series')
//  [python]
def feed_seriesindex():
    shift = 0
    off = int(request.args.get("offset") or 0)
    entries = calibre_db.session.query(func.upper(func.substr(db.Series.sort, 1, 1)).label('id'))\
        .join(db.books_series_link).join(db.Books).filter(calibre_db.common_filters())\
        .group_by(func.upper(func.substr(db.Series.sort, 1, 1))).all()
    elements = []
    if off == 0:
        elements.append({'id': "00", 'name':_("All")})
        shift = 1
    for entry in entries[
                 off + shift - 1:
                 int(off + int(config.config_books_per_page) - shift)]:
        elements.append({'id': entry.id, 'name': entry.id})
    pagination = Pagination((int(off) / (int(config.config_books_per_page)) + 1), config.config_books_per_page,
                            len(entries) + 1)
    return render_xml_template('feed.xml',
                               letterelements=elements,
                               folder='opds.feed_letter_series',
                               pagination=pagination)
//  [python]
def get(self, arg,word=None):
    try:
        limit = self.get_argument("limit")
        word = self.get_argument("word")
        callback = sanitize_callback(self.get_argument("callback"))

        result = rtxcomplete.prefix(word,limit)
        
        result = callback+"("+json.dumps(result)+");"
        
        self.write(result)
        
    except:
        print(sys.exc_info()[:])
        traceback.print_tb(sys.exc_info()[-1])
        #print sys.exc_info()[2]
        self.write("error")
//  [python]
def get(self, arg,word=None):
    #print "match auto"
    try:
        limit = self.get_argument("limit")
        word = self.get_argument("word")
        callback = self.get_argument("callback") #jsonp

        result = rtxcomplete.prefix(word,limit)

        result = callback+"("+json.dumps(result)+");" #jsonp
        #result = json.dumps(result) #typeahead
        
        self.write(result)
        
    except:
        print(sys.exc_info()[:])
        traceback.print_tb(sys.exc_info()[-1])
        #print sys.exc_info()[2]
        self.write("error")
//  [python]
def opds_download_link(book_id, book_format):
    # I gave up with this: With enabled ldap login, the user doesn't get logged in, therefore it's always guest
    # workaround, loading the user from the request and checking its download rights here
    # in case of anonymous browsing user is None
    user = load_user_from_request(request) or current_user
    if not user.role_download():
        return abort(403)
    if "Kobo" in request.headers.get('User-Agent'):
        client = "kobo"
    else:
        client = ""
    return get_download_link(book_id, book_format.lower(), client)
//  [python]
def opds_download_link(book_id, book_format):
    # I gave up with this: With enabled ldap login, the user doesn't get logged in, therefore it's always guest
    # workaround, loading the user from the request and checking it's download rights here
    # in case of anonymous browsing user is None
    user = load_user_from_request(request) or current_user
    if not user.role_download():
        return abort(403)
    if "Kobo" in request.headers.get('User-Agent'):
        client = "kobo"
    else:
        client = ""
    return get_download_link(book_id, book_format.lower(), client)
//  [python]
def verify_password(plain_password, user_password):
    if secrets.compare_digest(plain_password,user_password):
        LOG.debug("password true")
        return True
    return False
//  [python]
def verify_password(plain_password, user_password):
    if plain_password == user_password:
        LOG.debug("password true")
        return True
    return False
//  [python]
def build_cert(self, key_filename, entry, metadata):
    """
    creates a new certificate according to the specification
    """
    req_config = self.build_req_config(entry, metadata)
    req = self.build_request(key_filename, req_config, entry)
    ca = self.cert_specs[entry.get('name')]['ca']
    ca_config = self.CAs[ca]['config']
    days = self.cert_specs[entry.get('name')]['days']
    passphrase = self.CAs[ca].get('passphrase')
    cmd = ["openssl", "ca", "-config", ca_config, "-in", req,
           "-days", days, "-batch"]
    if passphrase:
        cmd.extend(["-passin", "pass:%s" % passphrase])
    cert = Popen(cmd, stdout=PIPE).stdout.read()
    try:
        os.unlink(req_config)
        os.unlink(req)
    except OSError:
        self.logger.error("Failed to unlink temporary files")
    return cert
//  [python]
def build_cert(self, key_filename, entry, metadata):
    """
    creates a new certificate according to the specification
    """
    req_config = self.build_req_config(entry, metadata)
    req = self.build_request(key_filename, req_config, entry)
    ca = self.cert_specs[entry.get('name')]['ca']
    ca_config = self.CAs[ca]['config']
    days = self.cert_specs[entry.get('name')]['days']
    passphrase = self.CAs[ca].get('passphrase')
    if passphrase:
        cmd = "openssl ca -config %s -in %s -days %s -batch -passin pass:%s" % (ca_config,
                                                                                req,
                                                                                days,
                                                                                passphrase)
    else:
        cmd = "openssl ca -config %s -in %s -days %s -batch" % (ca_config,
                                                                req,
                                                                days)
    cert = Popen(cmd, shell=True, stdout=PIPE).stdout.read()
    try:
        os.unlink(req_config)
        os.unlink(req)
    except OSError:
        self.logger.error("Failed to unlink temporary files")
    return cert
//  [python]
def build_key(self, filename, entry, metadata):
    """
    generates a new key according the the specification
    """
    type = self.key_specs[entry.get('name')]['type']
    bits = self.key_specs[entry.get('name')]['bits']
    if type == 'rsa':
        cmd = ["openssl", "genrsa", bits]
    elif type == 'dsa':
        cmd = ["openssl", "dsaparam", "-noout", "-genkey", bits]
    key = Popen(cmd, stdout=PIPE).stdout.read()
    return key
//  [python]
def build_key(self, filename, entry, metadata):
    """
    generates a new key according the the specification
    """
    type = self.key_specs[entry.get('name')]['type']
    bits = self.key_specs[entry.get('name')]['bits']
    if type == 'rsa':
        cmd = "openssl genrsa %s " % bits
    elif type == 'dsa':
        cmd = "openssl dsaparam -noout -genkey %s" % bits
    key = Popen(cmd, shell=True, stdout=PIPE).stdout.read()
    return key
//  [python]
def build_request(self, key_filename, req_config, entry):
    """
    creates the certificate request
    """
    req = tempfile.mkstemp()[1]
    days = self.cert_specs[entry.get('name')]['days']
    key = self.data + key_filename
    cmd = ["openssl", "req", "-new", "-config", req_config,
           "-days", days, "-key", key, "-text", "-out", req]
    res = Popen(cmd, shell=True, stdout=PIPE).stdout.read()
    return req
//  [python]
def build_request(self, key_filename, req_config, entry):
    """
    creates the certificate request
    """
    req = tempfile.mkstemp()[1]
    days = self.cert_specs[entry.get('name')]['days']
    key = self.data + key_filename
    cmd = "openssl req -new -config %s -days %s -key %s -text -out %s" % (req_config,
                                                                          days,
                                                                          key,
                                                                          req)
    res = Popen(cmd, shell=True, stdout=PIPE).stdout.read()
    return req
//  [python]
def verify_cert_against_ca(self, filename, entry):
    """
    check that a certificate validates against the ca cert,
    and that it has not expired.
    """
    chaincert = self.CAs[self.cert_specs[entry.get('name')]['ca']].get('chaincert')
    cert = self.data + filename
    res = Popen(["openssl", "verify", "-CAfile", chaincert, cert],
                stdout=PIPE, stderr=STDOUT).stdout.read()
    if res == cert + ": OK\n":
        return True
    return False
//  [python]
def verify_cert_against_ca(self, filename, entry):
    """
    check that a certificate validates against the ca cert,
    and that it has not expired.
    """
    chaincert = self.CAs[self.cert_specs[entry.get('name')]['ca']].get('chaincert')
    cert = self.data + filename
    cmd = "openssl verify -CAfile %s %s" % (chaincert, cert)
    res = Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT).stdout.read()
    if res == cert + ": OK\n":
        return True
    return False