mirror of
https://github.com/janeczku/calibre-web
synced 2024-12-25 01:20:32 +00:00
Refactored helper.py and db.py
This commit is contained in:
parent
ec3a3a73ef
commit
5f0660a4e5
@ -37,8 +37,6 @@ from . import config_sql, logger, cache_buster, cli, ub, db
|
||||
from .reverseproxy import ReverseProxied
|
||||
from .server import WebServer
|
||||
|
||||
# import queue
|
||||
# queue = queue.Queue()
|
||||
|
||||
mimetypes.init()
|
||||
mimetypes.add_type('application/xhtml+xml', '.xhtml')
|
||||
|
12
cps/admin.py
12
cps/admin.py
@ -39,7 +39,7 @@ from sqlalchemy.sql.expression import func
|
||||
|
||||
from . import constants, logger, helper, services
|
||||
from . import db, calibre_db, ub, web_server, get_locale, config, updater_thread, babel, gdriveutils
|
||||
from .helper import speaking_language, check_valid_domain, send_test_mail, reset_password, generate_password_hash
|
||||
from .helper import check_valid_domain, send_test_mail, reset_password, generate_password_hash
|
||||
from .gdriveutils import is_gdrive_ready, gdrive_support
|
||||
from .web import admin_required, render_title_template, before_request, unconfigured, login_required_if_no_ano
|
||||
|
||||
@ -149,9 +149,9 @@ def configuration():
|
||||
@admin_required
|
||||
def view_configuration():
|
||||
readColumn = calibre_db.session.query(db.Custom_Columns)\
|
||||
.filter(and_(db.Custom_Columns.datatype == 'bool',db.Custom_Columns.mark_for_delete == 0)).all()
|
||||
.filter(and_(db.Custom_Columns.datatype == 'bool', db.Custom_Columns.mark_for_delete == 0)).all()
|
||||
restrictColumns= calibre_db.session.query(db.Custom_Columns)\
|
||||
.filter(and_(db.Custom_Columns.datatype == 'text',db.Custom_Columns.mark_for_delete == 0)).all()
|
||||
.filter(and_(db.Custom_Columns.datatype == 'text', db.Custom_Columns.mark_for_delete == 0)).all()
|
||||
return render_title_template("config_view_edit.html", conf=config, readColumns=readColumn,
|
||||
restrictColumns=restrictColumns,
|
||||
title=_(u"UI Configuration"), page="uiconfig")
|
||||
@ -878,7 +878,7 @@ def _handle_edit_user(to_save, content,languages, translations, kobo_support, do
|
||||
@admin_required
|
||||
def new_user():
|
||||
content = ub.User()
|
||||
languages = speaking_language()
|
||||
languages = calibre_db.speaking_language()
|
||||
translations = [LC('en')] + babel.list_translations()
|
||||
kobo_support = feature_support['kobo'] and config.config_kobo_sync
|
||||
if request.method == "POST":
|
||||
@ -942,11 +942,11 @@ def edit_user(user_id):
|
||||
flash(_(u"User not found"), category="error")
|
||||
return redirect(url_for('admin.admin'))
|
||||
downloads = list()
|
||||
languages = speaking_language()
|
||||
languages = calibre_db.speaking_language()
|
||||
translations = babel.list_translations() + [LC('en')]
|
||||
kobo_support = feature_support['kobo'] and config.config_kobo_sync
|
||||
for book in content.downloads:
|
||||
downloadbook = calibre_db.session.query(db.Books).filter(db.Books.id == book.book_id).first()
|
||||
downloadbook = calibre_db.get_book(book.book_id)
|
||||
if downloadbook:
|
||||
downloads.append(downloadbook)
|
||||
else:
|
||||
|
173
cps/db.py
173
cps/db.py
@ -22,10 +22,9 @@ import sys
|
||||
import os
|
||||
import re
|
||||
import ast
|
||||
import json
|
||||
from datetime import datetime
|
||||
import threading
|
||||
import time
|
||||
import queue
|
||||
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy import Table, Column, ForeignKey, CheckConstraint
|
||||
@ -33,12 +32,24 @@ from sqlalchemy import String, Integer, Boolean, TIMESTAMP, Float
|
||||
from sqlalchemy.orm import relationship, sessionmaker, scoped_session
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
from sqlalchemy.exc import OperationalError
|
||||
from flask_login import current_user
|
||||
from sqlalchemy.sql.expression import and_, true, false, text, func, or_
|
||||
from babel import Locale as LC
|
||||
from babel.core import UnknownLocaleError
|
||||
from flask_babel import gettext as _
|
||||
|
||||
from . import logger, ub, isoLanguages
|
||||
from .pagination import Pagination
|
||||
|
||||
try:
|
||||
import unidecode
|
||||
use_unidecode = True
|
||||
except ImportError:
|
||||
use_unidecode = False
|
||||
|
||||
|
||||
from . import logger
|
||||
# session = None
|
||||
cc_exceptions = ['datetime', 'comments', 'composite', 'series']
|
||||
cc_classes = {}
|
||||
# engine = None
|
||||
|
||||
Base = declarative_base()
|
||||
|
||||
@ -327,6 +338,7 @@ class CalibreDB(threading.Thread):
|
||||
self.session = None
|
||||
self.queue = None
|
||||
self.log = None
|
||||
self.config = None
|
||||
|
||||
def add_queue(self,queue):
|
||||
self.queue = queue
|
||||
@ -356,6 +368,7 @@ class CalibreDB(threading.Thread):
|
||||
self.queue.put('dummy')
|
||||
|
||||
def setup_db(self, config, app_db_path):
|
||||
self.config = config
|
||||
self.dispose()
|
||||
# global engine
|
||||
|
||||
@ -441,6 +454,149 @@ class CalibreDB(threading.Thread):
|
||||
self.session = Session()
|
||||
return True
|
||||
|
||||
def get_book(self, book_id):
|
||||
return self.session.query(Books).filter(Books.id == book_id).first()
|
||||
|
||||
def get_filtered_book(self, book_id, allow_show_archived=False):
|
||||
return self.session.query(Books).filter(Books.id == book_id).\
|
||||
filter(self.common_filters(allow_show_archived)).first()
|
||||
|
||||
def get_book_by_uuid(self, book_uuid):
|
||||
return self.session.query(Books).filter(Books.uuid == book_uuid).first()
|
||||
|
||||
def get_book_format(self, book_id, format):
|
||||
return self.session.query(Data).filter(Data.book == book_id).filter(Data.format == format).first()
|
||||
|
||||
# Language and content filters for displaying in the UI
|
||||
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)
|
||||
|
||||
# Fill indexpage with all requested data from database
|
||||
def fill_indexpage(self, page, database, db_filter, order, *join):
|
||||
return self.fill_indexpage_with_archived_books(page, database, db_filter, order, False, *join)
|
||||
|
||||
def fill_indexpage_with_archived_books(self, page, database, db_filter, order, allow_show_archived, *join):
|
||||
if current_user.show_detail_random():
|
||||
randm = self.session.query(Books) \
|
||||
.filter(self.common_filters(allow_show_archived)) \
|
||||
.order_by(func.random()) \
|
||||
.limit(self.config.config_random_books)
|
||||
else:
|
||||
randm = false()
|
||||
off = int(int(self.config.config_books_per_page) * (page - 1))
|
||||
query = self.session.query(database) \
|
||||
.join(*join, isouter=True) \
|
||||
.filter(db_filter) \
|
||||
.filter(self.common_filters(allow_show_archived))
|
||||
pagination = Pagination(page, self.config.config_books_per_page,
|
||||
len(query.all()))
|
||||
entries = query.order_by(*order).offset(off).limit(self.config.config_books_per_page).all()
|
||||
for book in entries:
|
||||
book = self.order_authors(book)
|
||||
return entries, randm, pagination
|
||||
|
||||
# Orders all Authors in the list according to authors sort
|
||||
def order_authors(self, entry):
|
||||
sort_authors = entry.author_sort.split('&')
|
||||
authors_ordered = list()
|
||||
error = False
|
||||
for auth in sort_authors:
|
||||
# ToDo: How to handle not found authorname
|
||||
result = self.session.query(Authors).filter(Authors.sort == auth.lstrip().strip()).first()
|
||||
if not result:
|
||||
error = True
|
||||
break
|
||||
authors_ordered.append(result)
|
||||
if not error:
|
||||
entry.authors = authors_ordered
|
||||
return entry
|
||||
|
||||
def get_typeahead(self, database, query, replace=('', ''), tag_filter=true()):
|
||||
query = query or ''
|
||||
self.session.connection().connection.connection.create_function("lower", 1, self.lcase)
|
||||
entries = self.session.query(database).filter(tag_filter). \
|
||||
filter(func.lower(database.name).ilike("%" + query + "%")).all()
|
||||
json_dumps = json.dumps([dict(name=r.name.replace(*replace)) for r in entries])
|
||||
return json_dumps
|
||||
|
||||
def check_exists_book(self, authr, title):
|
||||
self.session.connection().connection.connection.create_function("lower", 1, self.lcase)
|
||||
q = list()
|
||||
authorterms = re.split(r'\s*&\s*', authr)
|
||||
for authorterm in authorterms:
|
||||
q.append(Books.authors.any(func.lower(Authors.name).ilike("%" + authorterm + "%")))
|
||||
|
||||
return self.session.query(Books)\
|
||||
.filter(and_(Books.authors.any(and_(*q)), func.lower(Books.title).ilike("%" + title + "%"))).first()
|
||||
|
||||
# read search results from calibre-database and return it (function is used for feed and simple search
|
||||
def get_search_results(self, term):
|
||||
term.strip().lower()
|
||||
self.session.connection().connection.connection.create_function("lower", 1, self.lcase)
|
||||
q = list()
|
||||
authorterms = re.split("[, ]+", term)
|
||||
for authorterm in authorterms:
|
||||
q.append(Books.authors.any(func.lower(Authors.name).ilike("%" + authorterm + "%")))
|
||||
|
||||
return self.session.query(Books).filter(self.common_filters()).filter(
|
||||
or_(Books.tags.any(func.lower(Tags.name).ilike("%" + term + "%")),
|
||||
Books.series.any(func.lower(Series.name).ilike("%" + term + "%")),
|
||||
Books.authors.any(and_(*q)),
|
||||
Books.publishers.any(func.lower(Publishers.name).ilike("%" + term + "%")),
|
||||
func.lower(Books.title).ilike("%" + term + "%")
|
||||
)).order_by(Books.sort).all()
|
||||
|
||||
# Creates for all stored languages a translated speaking name in the array for the UI
|
||||
def speaking_language(self, languages=None):
|
||||
from . import get_locale
|
||||
|
||||
if not languages:
|
||||
languages = self.session.query(Languages) \
|
||||
.join(books_languages_link) \
|
||||
.join(Books) \
|
||||
.filter(self.common_filters()) \
|
||||
.group_by(text('books_languages_link.lang_code')).all()
|
||||
for lang in languages:
|
||||
try:
|
||||
cur_l = LC.parse(lang.lang_code)
|
||||
lang.name = cur_l.get_language_name(get_locale())
|
||||
except UnknownLocaleError:
|
||||
lang.name = _(isoLanguages.get(part3=lang.lang_code).name)
|
||||
return languages
|
||||
|
||||
def update_title_sort(self, config, conn=None):
|
||||
# user defined sort function for calibre databases (Series, etc.)
|
||||
def _title_sort(title):
|
||||
@ -481,8 +637,13 @@ class CalibreDB(threading.Thread):
|
||||
if table is not None:
|
||||
Base.metadata.remove(table)
|
||||
|
||||
|
||||
def reconnect_db(self, config, app_db_path):
|
||||
self.session.close()
|
||||
self.engine.dispose()
|
||||
self.setup_db(config, app_db_path)
|
||||
|
||||
def lcase(self, s):
|
||||
try:
|
||||
return unidecode.unidecode(s.lower())
|
||||
except Exception as e:
|
||||
self.log.exception(e)
|
||||
|
@ -35,7 +35,6 @@ from sqlalchemy.exc import OperationalError
|
||||
from . import constants, logger, isoLanguages, gdriveutils, uploader, helper
|
||||
from . import config, get_locale, ub, worker, db
|
||||
from . import calibre_db
|
||||
from .helper import order_authors, common_filters
|
||||
from .web import login_required_if_no_ano, render_title_template, edit_required, upload_required
|
||||
|
||||
|
||||
@ -176,7 +175,7 @@ def modify_identifiers(input_identifiers, db_identifiers, db_session):
|
||||
@login_required
|
||||
def delete_book(book_id, book_format):
|
||||
if current_user.role_delete_books():
|
||||
book = calibre_db.session.query(db.Books).filter(db.Books.id == book_id).first()
|
||||
book = calibre_db.get_book(book_id)
|
||||
if book:
|
||||
try:
|
||||
result, error = helper.delete_book(book, config.config_calibre_dir, book_format=book_format.upper())
|
||||
@ -250,9 +249,7 @@ def delete_book(book_id, book_format):
|
||||
def render_edit_book(book_id):
|
||||
calibre_db.update_title_sort(config)
|
||||
cc = calibre_db.session.query(db.Custom_Columns).filter(db.Custom_Columns.datatype.notin_(db.cc_exceptions)).all()
|
||||
book = calibre_db.session.query(db.Books)\
|
||||
.filter(db.Books.id == book_id).filter(common_filters()).first()
|
||||
|
||||
book = calibre_db.get_filtered_book(book_id)
|
||||
if not book:
|
||||
flash(_(u"Error opening eBook. File does not exist or file is not accessible"), category="error")
|
||||
return redirect(url_for("web.index"))
|
||||
@ -260,7 +257,7 @@ def render_edit_book(book_id):
|
||||
for lang in book.languages:
|
||||
lang.language_name = isoLanguages.get_language_name(get_locale(), lang.lang_code)
|
||||
|
||||
book = order_authors(book)
|
||||
book = calibre_db.order_authors(book)
|
||||
|
||||
author_names = []
|
||||
for authr in book.authors:
|
||||
@ -447,8 +444,7 @@ def upload_single_file(request, book, book_id):
|
||||
return redirect(url_for('web.show_book', book_id=book.id))
|
||||
|
||||
file_size = os.path.getsize(saved_filename)
|
||||
is_format = calibre_db.session.query(db.Data).filter(db.Data.book == book_id).\
|
||||
filter(db.Data.format == file_ext.upper()).first()
|
||||
is_format = calibre_db.get_book_format(book_id, file_ext.upper())
|
||||
|
||||
# Format entry already exists, no need to update the database
|
||||
if is_format:
|
||||
@ -500,8 +496,7 @@ def edit_book(book_id):
|
||||
|
||||
# create the function for sorting...
|
||||
calibre_db.update_title_sort(config)
|
||||
book = calibre_db.session.query(db.Books)\
|
||||
.filter(db.Books.id == book_id).filter(common_filters()).first()
|
||||
book = calibre_db.get_filtered_book(book_id)
|
||||
|
||||
# Book not found
|
||||
if not book:
|
||||
@ -702,7 +697,7 @@ def upload():
|
||||
series_index = meta.series_id
|
||||
|
||||
if title != _(u'Unknown') and authr != _(u'Unknown'):
|
||||
entry = helper.check_exists_book(authr, title)
|
||||
entry = calibre_db.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: ")
|
||||
@ -807,7 +802,7 @@ def upload():
|
||||
calibre_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 = calibre_db.session.query(db.Books).filter(db.Books.id == book_id).first()
|
||||
book = calibre_db.get_book(book_id)
|
||||
# upload book to gdrive if nesseccary and add "(bookid)" to folder name
|
||||
if config.config_use_google_drive:
|
||||
gdriveutils.updateGdriveCalibreFromLocal()
|
||||
|
169
cps/helper.py
169
cps/helper.py
@ -74,8 +74,8 @@ log = logger.create()
|
||||
|
||||
# Convert existing book entry to new format
|
||||
def convert_book_format(book_id, calibrepath, old_book_format, new_book_format, user_id, kindle_mail=None):
|
||||
book = calibre_db.session.query(db.Books).filter(db.Books.id == book_id).first()
|
||||
data = calibre_db.session.query(db.Data).filter(db.Data.book == book.id).filter(db.Data.format == old_book_format).first()
|
||||
book = calibre_db.get_book(book_id)
|
||||
data = calibre_db.get_book_format(book.id, old_book_format)
|
||||
if not data:
|
||||
error_message = _(u"%(format)s format not found for book id: %(book)d", format=old_book_format, book=book_id)
|
||||
log.error("convert_book_format: %s", error_message)
|
||||
@ -212,7 +212,7 @@ def check_read_formats(entry):
|
||||
# 3: If Pdf file is existing, it's directly send to kindle email
|
||||
def send_mail(book_id, book_format, convert, kindle_mail, calibrepath, user_id):
|
||||
"""Send email with attachments"""
|
||||
book = calibre_db.session.query(db.Books).filter(db.Books.id == book_id).first()
|
||||
book = calibre_db.get_book(book_id)
|
||||
|
||||
if convert == 1:
|
||||
# returns None if success, otherwise errormessage
|
||||
@ -324,7 +324,7 @@ def delete_book_file(book, calibrepath, book_format=None):
|
||||
|
||||
|
||||
def update_dir_structure_file(book_id, calibrepath, first_author):
|
||||
localbook = calibre_db.session.query(db.Books).filter(db.Books.id == book_id).first()
|
||||
localbook = calibre_db.get_book(book_id)
|
||||
path = os.path.join(calibrepath, localbook.path)
|
||||
|
||||
authordir = localbook.path.split('/')[0]
|
||||
@ -383,7 +383,7 @@ def update_dir_structure_file(book_id, calibrepath, first_author):
|
||||
|
||||
def update_dir_structure_gdrive(book_id, first_author):
|
||||
error = False
|
||||
book = calibre_db.session.query(db.Books).filter(db.Books.id == book_id).first()
|
||||
book = calibre_db.get_book(book_id)
|
||||
path = book.path
|
||||
|
||||
authordir = book.path.split('/')[0]
|
||||
@ -494,18 +494,17 @@ def get_cover_on_failure(use_generic_cover):
|
||||
|
||||
|
||||
def get_book_cover(book_id):
|
||||
book = calibre_db.session.query(db.Books).filter(db.Books.id == book_id).filter(common_filters(allow_show_archived=True)).first()
|
||||
book = calibre_db.get_filtered_book(book_id, allow_show_archived=True)
|
||||
return get_book_cover_internal(book, use_generic_cover_on_failure=True)
|
||||
|
||||
|
||||
def get_book_cover_with_uuid(book_uuid,
|
||||
use_generic_cover_on_failure=True):
|
||||
book = calibre_db.session.query(db.Books).filter(db.Books.uuid == book_uuid).first()
|
||||
book = calibre_db.get_book_by_uuid(book_uuid)
|
||||
return get_book_cover_internal(book, use_generic_cover_on_failure)
|
||||
|
||||
|
||||
def get_book_cover_internal(book,
|
||||
use_generic_cover_on_failure):
|
||||
def get_book_cover_internal(book, use_generic_cover_on_failure):
|
||||
if book and book.has_cover:
|
||||
if config.config_use_google_drive:
|
||||
try:
|
||||
@ -725,66 +724,12 @@ def render_task_status(tasklist):
|
||||
return renderedtasklist
|
||||
|
||||
|
||||
# Language and content filters for displaying in the UI
|
||||
def common_filters(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 = db.Books.id.notin_(archived_book_ids)
|
||||
else:
|
||||
archived_filter = true()
|
||||
|
||||
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, archived_filter)
|
||||
|
||||
|
||||
def tags_filters():
|
||||
negtags_list = current_user.list_denied_tags()
|
||||
postags_list = current_user.list_allowed_tags()
|
||||
neg_content_tags_filter = false() if negtags_list == [''] else db.Tags.name.in_(negtags_list)
|
||||
pos_content_tags_filter = true() if postags_list == [''] else db.Tags.name.in_(postags_list)
|
||||
return and_(pos_content_tags_filter, ~neg_content_tags_filter)
|
||||
# return ~(false()) if postags_list == [''] else db.Tags.in_(postags_list)
|
||||
|
||||
|
||||
# Creates for all stored languages a translated speaking name in the array for the UI
|
||||
def speaking_language(languages=None):
|
||||
if not languages:
|
||||
languages = calibre_db.session.query(db.Languages).join(db.books_languages_link).join(db.Books)\
|
||||
.filter(common_filters())\
|
||||
.group_by(text('books_languages_link.lang_code')).all()
|
||||
for lang in languages:
|
||||
try:
|
||||
cur_l = LC.parse(lang.lang_code)
|
||||
lang.name = cur_l.get_language_name(get_locale())
|
||||
except UnknownLocaleError:
|
||||
lang.name = _(isoLanguages.get(part3=lang.lang_code).name)
|
||||
return languages
|
||||
|
||||
|
||||
# checks if domain is in database (including wildcards)
|
||||
@ -801,76 +746,9 @@ def check_valid_domain(domain_text):
|
||||
return not len(result)
|
||||
|
||||
|
||||
# Orders all Authors in the list according to authors sort
|
||||
def order_authors(entry):
|
||||
sort_authors = entry.author_sort.split('&')
|
||||
authors_ordered = list()
|
||||
error = False
|
||||
for auth in sort_authors:
|
||||
# ToDo: How to handle not found authorname
|
||||
result = calibre_db.session.query(db.Authors).filter(db.Authors.sort == auth.lstrip().strip()).first()
|
||||
if not result:
|
||||
error = True
|
||||
break
|
||||
authors_ordered.append(result)
|
||||
if not error:
|
||||
entry.authors = authors_ordered
|
||||
return entry
|
||||
|
||||
|
||||
# Fill indexpage with all requested data from database
|
||||
def fill_indexpage(page, database, db_filter, order, *join):
|
||||
return fill_indexpage_with_archived_books(page, database, db_filter, order, False, *join)
|
||||
|
||||
|
||||
def fill_indexpage_with_archived_books(page, database, db_filter, order, allow_show_archived, *join):
|
||||
if current_user.show_detail_random():
|
||||
randm = calibre_db.session.query(db.Books).filter(common_filters(allow_show_archived))\
|
||||
.order_by(func.random()).limit(config.config_random_books)
|
||||
else:
|
||||
randm = false()
|
||||
off = int(int(config.config_books_per_page) * (page - 1))
|
||||
query = calibre_db.session.query(database).join(*join, isouter=True).\
|
||||
filter(db_filter).\
|
||||
filter(common_filters(allow_show_archived))
|
||||
pagination = Pagination(page, config.config_books_per_page,
|
||||
len(query.all()))
|
||||
entries = query.order_by(*order).offset(off).limit(config.config_books_per_page).all()
|
||||
for book in entries:
|
||||
book = order_authors(book)
|
||||
return entries, randm, pagination
|
||||
|
||||
|
||||
def get_typeahead(database, query, replace=('', ''), tag_filter=true()):
|
||||
query = query or ''
|
||||
calibre_db.session.connection().connection.connection.create_function("lower", 1, lcase)
|
||||
entries = calibre_db.session.query(database).filter(tag_filter).\
|
||||
filter(func.lower(database.name).ilike("%" + query + "%")).all()
|
||||
json_dumps = json.dumps([dict(name=r.name.replace(*replace)) for r in entries])
|
||||
return json_dumps
|
||||
|
||||
|
||||
# read search results from calibre-database and return it (function is used for feed and simple search
|
||||
def get_search_results(term):
|
||||
calibre_db.session.connection().connection.connection.create_function("lower", 1, lcase)
|
||||
q = list()
|
||||
authorterms = re.split("[, ]+", term)
|
||||
for authorterm in authorterms:
|
||||
q.append(db.Books.authors.any(func.lower(db.Authors.name).ilike("%" + authorterm + "%")))
|
||||
|
||||
db.Books.authors.any(func.lower(db.Authors.name).ilike("%" + term + "%"))
|
||||
|
||||
return calibre_db.session.query(db.Books).filter(common_filters()).filter(
|
||||
or_(db.Books.tags.any(func.lower(db.Tags.name).ilike("%" + term + "%")),
|
||||
db.Books.series.any(func.lower(db.Series.name).ilike("%" + term + "%")),
|
||||
db.Books.authors.any(and_(*q)),
|
||||
db.Books.publishers.any(func.lower(db.Publishers.name).ilike("%" + term + "%")),
|
||||
func.lower(db.Books.title).ilike("%" + term + "%")
|
||||
)).order_by(db.Books.sort).all()
|
||||
|
||||
|
||||
def get_cc_columns(filter_config_custom_read=False):
|
||||
tmpcc = calibre_db.session.query(db.Custom_Columns).filter(db.Custom_Columns.datatype.notin_(db.cc_exceptions)).all()
|
||||
tmpcc = calibre_db.session.query(db.Custom_Columns)\
|
||||
.filter(db.Custom_Columns.datatype.notin_(db.cc_exceptions)).all()
|
||||
cc = []
|
||||
r = None
|
||||
if config.config_columns_to_ignore:
|
||||
@ -887,10 +765,9 @@ def get_cc_columns(filter_config_custom_read=False):
|
||||
|
||||
def get_download_link(book_id, book_format, client):
|
||||
book_format = book_format.split(".")[0]
|
||||
book = calibre_db.session.query(db.Books).filter(db.Books.id == book_id).filter(common_filters()).first()
|
||||
book = calibre_db.get_filtered_book(book_id)
|
||||
if book:
|
||||
data1 = calibre_db.session.query(db.Data).filter(db.Data.book == book.id)\
|
||||
.filter(db.Data.format == book_format.upper()).first()
|
||||
data1 = data = calibre_db.get_book_format(book.id, book_format.upper())
|
||||
else:
|
||||
abort(404)
|
||||
if data1:
|
||||
@ -908,25 +785,3 @@ def get_download_link(book_id, book_format, client):
|
||||
return do_download_file(book, book_format, client, data1, headers)
|
||||
else:
|
||||
abort(404)
|
||||
|
||||
|
||||
def check_exists_book(authr, title):
|
||||
calibre_db.session.connection().connection.connection.create_function("lower", 1, lcase)
|
||||
q = list()
|
||||
authorterms = re.split(r'\s*&\s*', authr)
|
||||
for authorterm in authorterms:
|
||||
q.append(db.Books.authors.any(func.lower(db.Authors.name).ilike("%" + authorterm + "%")))
|
||||
|
||||
return calibre_db.session.query(db.Books).filter(
|
||||
and_(db.Books.authors.any(and_(*q)),
|
||||
func.lower(db.Books.title).ilike("%" + title + "%")
|
||||
)).first()
|
||||
|
||||
############### Database Helper functions
|
||||
|
||||
|
||||
def lcase(s):
|
||||
try:
|
||||
return unidecode.unidecode(s.lower())
|
||||
except Exception as e:
|
||||
log.exception(e)
|
||||
|
@ -111,10 +111,3 @@ def timestamptodate(date, fmt=None):
|
||||
@jinjia.app_template_filter('yesno')
|
||||
def yesno(value, yes, no):
|
||||
return yes if value else no
|
||||
|
||||
|
||||
'''@jinjia.app_template_filter('canread')
|
||||
def canread(ext):
|
||||
if isinstance(ext, db.Data):
|
||||
ext = ext.format
|
||||
return ext.lower() in EXTENSIONS_READER'''
|
||||
|
12
cps/kobo.py
12
cps/kobo.py
@ -256,7 +256,7 @@ def HandleMetadataRequest(book_uuid):
|
||||
if not current_app.wsgi_app.is_proxied:
|
||||
log.debug('Kobo: Received unproxied request, changed request port to server port')
|
||||
log.info("Kobo library metadata request received for book %s" % book_uuid)
|
||||
book = calibre_db.session.query(db.Books).filter(db.Books.uuid == book_uuid).first()
|
||||
book = calibre_db.get_book_by_uuid(book_uuid)
|
||||
if not book or not book.data:
|
||||
log.info(u"Book %s not found in database", book_uuid)
|
||||
return redirect_or_proxy_request()
|
||||
@ -474,7 +474,7 @@ def add_items_to_shelf(items, shelf):
|
||||
items_unknown_to_calibre.append(item)
|
||||
continue
|
||||
|
||||
book = calibre_db.session.query(db.Books).filter(db.Books.uuid == item["RevisionId"]).one_or_none()
|
||||
book = calibre_db.get_book_by_uuid(item["RevisionId"])
|
||||
if not book:
|
||||
items_unknown_to_calibre.append(item)
|
||||
continue
|
||||
@ -545,7 +545,7 @@ def HandleTagRemoveItem(tag_id):
|
||||
items_unknown_to_calibre.append(item)
|
||||
continue
|
||||
|
||||
book = calibre_db.session.query(db.Books).filter(db.Books.uuid == item["RevisionId"]).one_or_none()
|
||||
book = calibre_db.get_book_by_uuid(item["RevisionId"])
|
||||
if not book:
|
||||
items_unknown_to_calibre.append(item)
|
||||
continue
|
||||
@ -613,7 +613,7 @@ def create_kobo_tag(shelf):
|
||||
"Type": "UserTag"
|
||||
}
|
||||
for book_shelf in shelf.books:
|
||||
book = calibre_db.session.query(db.Books).filter(db.Books.id == book_shelf.book_id).one_or_none()
|
||||
book = calibre_db.get_book_by_uuid(book_shelf.book_id)
|
||||
if not book:
|
||||
log.info(u"Book (id: %s) in BookShelf (id: %s) not found in book database", book_shelf.book_id, shelf.id)
|
||||
continue
|
||||
@ -629,7 +629,7 @@ def create_kobo_tag(shelf):
|
||||
@kobo.route("/v1/library/<book_uuid>/state", methods=["GET", "PUT"])
|
||||
@login_required
|
||||
def HandleStateRequest(book_uuid):
|
||||
book = calibre_db.session.query(db.Books).filter(db.Books.uuid == book_uuid).first()
|
||||
book = calibre_db.get_book_by_uuid(book_uuid)
|
||||
if not book or not book.data:
|
||||
log.info(u"Book %s not found in database", book_uuid)
|
||||
return redirect_or_proxy_request()
|
||||
@ -804,7 +804,7 @@ def TopLevelEndpoint():
|
||||
@login_required
|
||||
def HandleBookDeletionRequest(book_uuid):
|
||||
log.info("Kobo book deletion request received for book %s" % book_uuid)
|
||||
book = calibre_db.session.query(db.Books).filter(db.Books.uuid == book_uuid).first()
|
||||
book = calibre_db.get_book_by_uuid(book_uuid)
|
||||
if not book:
|
||||
log.info(u"Book %s not found in database", book_uuid)
|
||||
return redirect_or_proxy_request()
|
||||
|
131
cps/opds.py
131
cps/opds.py
@ -31,9 +31,9 @@ from sqlalchemy.sql.expression import func, text, or_, and_
|
||||
from werkzeug.security import check_password_hash
|
||||
|
||||
from . import constants, logger, config, db, calibre_db, ub, services, get_locale, isoLanguages
|
||||
from .helper import fill_indexpage, get_download_link, get_book_cover, speaking_language
|
||||
from .helper import get_download_link, get_book_cover
|
||||
from .pagination import Pagination
|
||||
from .web import common_filters, get_search_results, render_read_books, download_required
|
||||
from .web import render_read_books, download_required
|
||||
from flask_babel import gettext as _
|
||||
from babel import Locale as LC
|
||||
from babel.core import UnknownLocaleError
|
||||
@ -100,15 +100,15 @@ def feed_normal_search():
|
||||
@requires_basic_auth_if_no_ano
|
||||
def feed_new():
|
||||
off = request.args.get("offset") or 0
|
||||
entries, __, pagination = fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1),
|
||||
db.Books, True, [db.Books.timestamp.desc()])
|
||||
entries, __, pagination = calibre_db.fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1),
|
||||
db.Books, True, [db.Books.timestamp.desc()])
|
||||
return render_xml_template('feed.xml', entries=entries, pagination=pagination)
|
||||
|
||||
|
||||
@opds.route("/opds/discover")
|
||||
@requires_basic_auth_if_no_ano
|
||||
def feed_discover():
|
||||
entries = calibre_db.session.query(db.Books).filter(common_filters()).order_by(func.random())\
|
||||
entries = calibre_db.session.query(db.Books).filter(calibre_db.common_filters()).order_by(func.random())\
|
||||
.limit(config.config_books_per_page)
|
||||
pagination = Pagination(1, config.config_books_per_page, int(config.config_books_per_page))
|
||||
return render_xml_template('feed.xml', entries=entries, pagination=pagination)
|
||||
@ -118,9 +118,9 @@ def feed_discover():
|
||||
@requires_basic_auth_if_no_ano
|
||||
def feed_best_rated():
|
||||
off = request.args.get("offset") or 0
|
||||
entries, __, pagination = fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1),
|
||||
db.Books, db.Books.ratings.any(db.Ratings.rating > 9),
|
||||
[db.Books.timestamp.desc()])
|
||||
entries, __, pagination = calibre_db.fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1),
|
||||
db.Books, db.Books.ratings.any(db.Ratings.rating > 9),
|
||||
[db.Books.timestamp.desc()])
|
||||
return render_xml_template('feed.xml', entries=entries, pagination=pagination)
|
||||
|
||||
|
||||
@ -133,16 +133,13 @@ def feed_hot():
|
||||
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(db.Books.id == book.Downloads.book_id).first()
|
||||
downloadBook = calibre_db.get_book(book.Downloads.book_id)
|
||||
if downloadBook:
|
||||
entries.append(
|
||||
calibre_db.session.query(db.Books).filter(common_filters())
|
||||
.filter(db.Books.id == book.Downloads.book_id).first()
|
||||
calibre_db.get_filtered_book(book.Downloads.book_id)
|
||||
)
|
||||
else:
|
||||
ub.delete_download(book.Downloads.book_id)
|
||||
# ub.session.query(ub.Downloads).filter(book.Downloads.book_id == ub.Downloads.book_id).delete()
|
||||
# ub.session.commit()
|
||||
numBooks = entries.__len__()
|
||||
pagination = Pagination((int(off) / (int(config.config_books_per_page)) + 1),
|
||||
config.config_books_per_page, numBooks)
|
||||
@ -153,8 +150,10 @@ def feed_hot():
|
||||
@requires_basic_auth_if_no_ano
|
||||
def feed_authorindex():
|
||||
off = request.args.get("offset") or 0
|
||||
entries = calibre_db.session.query(db.Authors).join(db.books_authors_link).join(db.Books).filter(common_filters())\
|
||||
.group_by(text('books_authors_link.author')).order_by(db.Authors.sort).limit(config.config_books_per_page)\
|
||||
entries = calibre_db.session.query(db.Authors).join(db.books_authors_link).join(db.Books)\
|
||||
.filter(calibre_db.common_filters())\
|
||||
.group_by(text('books_authors_link.author'))\
|
||||
.order_by(db.Authors.sort).limit(config.config_books_per_page)\
|
||||
.offset(off)
|
||||
pagination = Pagination((int(off) / (int(config.config_books_per_page)) + 1), config.config_books_per_page,
|
||||
len(calibre_db.session.query(db.Authors).all()))
|
||||
@ -165,10 +164,10 @@ def feed_authorindex():
|
||||
@requires_basic_auth_if_no_ano
|
||||
def feed_author(book_id):
|
||||
off = request.args.get("offset") or 0
|
||||
entries, __, pagination = fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1),
|
||||
db.Books,
|
||||
db.Books.authors.any(db.Authors.id == book_id),
|
||||
[db.Books.timestamp.desc()])
|
||||
entries, __, pagination = calibre_db.fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1),
|
||||
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)
|
||||
|
||||
|
||||
@ -176,8 +175,11 @@ def feed_author(book_id):
|
||||
@requires_basic_auth_if_no_ano
|
||||
def feed_publisherindex():
|
||||
off = request.args.get("offset") or 0
|
||||
entries = calibre_db.session.query(db.Publishers).join(db.books_publishers_link).join(db.Books).filter(common_filters())\
|
||||
.group_by(text('books_publishers_link.publisher')).order_by(db.Publishers.sort)\
|
||||
entries = calibre_db.session.query(db.Publishers)\
|
||||
.join(db.books_publishers_link)\
|
||||
.join(db.Books).filter(calibre_db.common_filters())\
|
||||
.group_by(text('books_publishers_link.publisher'))\
|
||||
.order_by(db.Publishers.sort)\
|
||||
.limit(config.config_books_per_page).offset(off)
|
||||
pagination = Pagination((int(off) / (int(config.config_books_per_page)) + 1), config.config_books_per_page,
|
||||
len(calibre_db.session.query(db.Publishers).all()))
|
||||
@ -188,10 +190,10 @@ def feed_publisherindex():
|
||||
@requires_basic_auth_if_no_ano
|
||||
def feed_publisher(book_id):
|
||||
off = request.args.get("offset") or 0
|
||||
entries, __, pagination = fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1),
|
||||
db.Books,
|
||||
db.Books.publishers.any(db.Publishers.id == book_id),
|
||||
[db.Books.timestamp.desc()])
|
||||
entries, __, pagination = calibre_db.fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1),
|
||||
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)
|
||||
|
||||
|
||||
@ -199,8 +201,14 @@ def feed_publisher(book_id):
|
||||
@requires_basic_auth_if_no_ano
|
||||
def feed_categoryindex():
|
||||
off = request.args.get("offset") or 0
|
||||
entries = calibre_db.session.query(db.Tags).join(db.books_tags_link).join(db.Books).filter(common_filters())\
|
||||
.group_by(text('books_tags_link.tag')).order_by(db.Tags.name).offset(off).limit(config.config_books_per_page)
|
||||
entries = 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)\
|
||||
.offset(off)\
|
||||
.limit(config.config_books_per_page)
|
||||
pagination = Pagination((int(off) / (int(config.config_books_per_page)) + 1), config.config_books_per_page,
|
||||
len(calibre_db.session.query(db.Tags).all()))
|
||||
return render_xml_template('feed.xml', listelements=entries, folder='opds.feed_category', pagination=pagination)
|
||||
@ -210,10 +218,10 @@ def feed_categoryindex():
|
||||
@requires_basic_auth_if_no_ano
|
||||
def feed_category(book_id):
|
||||
off = request.args.get("offset") or 0
|
||||
entries, __, pagination = fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1),
|
||||
db.Books,
|
||||
db.Books.tags.any(db.Tags.id == book_id),
|
||||
[db.Books.timestamp.desc()])
|
||||
entries, __, pagination = calibre_db.fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1),
|
||||
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)
|
||||
|
||||
|
||||
@ -221,8 +229,13 @@ def feed_category(book_id):
|
||||
@requires_basic_auth_if_no_ano
|
||||
def feed_seriesindex():
|
||||
off = request.args.get("offset") or 0
|
||||
entries = calibre_db.session.query(db.Series).join(db.books_series_link).join(db.Books).filter(common_filters())\
|
||||
.group_by(text('books_series_link.series')).order_by(db.Series.sort).offset(off).all()
|
||||
entries = 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.sort)\
|
||||
.offset(off).all()
|
||||
pagination = Pagination((int(off) / (int(config.config_books_per_page)) + 1), config.config_books_per_page,
|
||||
len(calibre_db.session.query(db.Series).all()))
|
||||
return render_xml_template('feed.xml', listelements=entries, folder='opds.feed_series', pagination=pagination)
|
||||
@ -232,10 +245,10 @@ def feed_seriesindex():
|
||||
@requires_basic_auth_if_no_ano
|
||||
def feed_series(book_id):
|
||||
off = request.args.get("offset") or 0
|
||||
entries, __, pagination = fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1),
|
||||
db.Books,
|
||||
db.Books.series.any(db.Series.id == book_id),
|
||||
[db.Books.series_index])
|
||||
entries, __, pagination = calibre_db.fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1),
|
||||
db.Books,
|
||||
db.Books.series.any(db.Series.id == book_id),
|
||||
[db.Books.series_index])
|
||||
return render_xml_template('feed.xml', entries=entries, pagination=pagination)
|
||||
|
||||
|
||||
@ -245,8 +258,11 @@ 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(common_filters()) \
|
||||
.group_by(text('books_ratings_link.rating')).order_by(db.Ratings.rating).all()
|
||||
.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))
|
||||
@ -260,10 +276,10 @@ def feed_ratingindex():
|
||||
@requires_basic_auth_if_no_ano
|
||||
def feed_ratings(book_id):
|
||||
off = request.args.get("offset") or 0
|
||||
entries, __, pagination = fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1),
|
||||
db.Books,
|
||||
db.Books.ratings.any(db.Ratings.id == book_id),
|
||||
[db.Books.timestamp.desc()])
|
||||
entries, __, pagination = calibre_db.fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1),
|
||||
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)
|
||||
|
||||
|
||||
@ -271,8 +287,10 @@ def feed_ratings(book_id):
|
||||
@requires_basic_auth_if_no_ano
|
||||
def feed_formatindex():
|
||||
off = request.args.get("offset") or 0
|
||||
entries = calibre_db.session.query(db.Data).join(db.Books).filter(common_filters()) \
|
||||
.group_by(db.Data.format).order_by(db.Data.format).all()
|
||||
entries = 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()
|
||||
pagination = Pagination((int(off) / (int(config.config_books_per_page)) + 1), config.config_books_per_page,
|
||||
len(entries))
|
||||
|
||||
@ -286,10 +304,10 @@ def feed_formatindex():
|
||||
@requires_basic_auth_if_no_ano
|
||||
def feed_format(book_id):
|
||||
off = request.args.get("offset") or 0
|
||||
entries, __, pagination = fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1),
|
||||
db.Books,
|
||||
db.Books.data.any(db.Data.format == book_id.upper()),
|
||||
[db.Books.timestamp.desc()])
|
||||
entries, __, pagination = calibre_db.fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1),
|
||||
db.Books,
|
||||
db.Books.data.any(db.Data.format == book_id.upper()),
|
||||
[db.Books.timestamp.desc()])
|
||||
return render_xml_template('feed.xml', entries=entries, pagination=pagination)
|
||||
|
||||
|
||||
@ -299,7 +317,7 @@ def feed_format(book_id):
|
||||
def feed_languagesindex():
|
||||
off = request.args.get("offset") or 0
|
||||
if current_user.filter_language() == u"all":
|
||||
languages = speaking_language()
|
||||
languages = calibre_db.speaking_language()
|
||||
else:
|
||||
try:
|
||||
cur_l = LC.parse(current_user.filter_language())
|
||||
@ -320,10 +338,10 @@ def feed_languagesindex():
|
||||
@requires_basic_auth_if_no_ano
|
||||
def feed_languages(book_id):
|
||||
off = request.args.get("offset") or 0
|
||||
entries, __, pagination = fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1),
|
||||
db.Books,
|
||||
db.Books.languages.any(db.Languages.id == book_id),
|
||||
[db.Books.timestamp.desc()])
|
||||
entries, __, pagination = calibre_db.fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1),
|
||||
db.Books,
|
||||
db.Books.languages.any(db.Languages.id == book_id),
|
||||
[db.Books.timestamp.desc()])
|
||||
return render_xml_template('feed.xml', entries=entries, pagination=pagination)
|
||||
|
||||
|
||||
@ -356,7 +374,7 @@ def feed_shelf(book_id):
|
||||
books_in_shelf = ub.session.query(ub.BookShelf).filter(ub.BookShelf.shelf == book_id).order_by(
|
||||
ub.BookShelf.order.asc()).all()
|
||||
for book in books_in_shelf:
|
||||
cur_book = calibre_db.session.query(db.Books).filter(db.Books.id == book.book_id).first()
|
||||
cur_book = calibre_db.get_book(book.book_id)
|
||||
result.append(cur_book)
|
||||
pagination = Pagination((int(off) / (int(config.config_books_per_page)) + 1), config.config_books_per_page,
|
||||
len(result))
|
||||
@ -390,8 +408,7 @@ def get_metadata_calibre_companion(uuid, library):
|
||||
|
||||
def feed_search(term):
|
||||
if term:
|
||||
term = term.strip().lower()
|
||||
entries = get_search_results(term)
|
||||
entries = calibre_db.get_search_results(term)
|
||||
entriescount = len(entries) if len(entries) > 0 else 1
|
||||
pagination = Pagination(1, entriescount, entriescount)
|
||||
return render_xml_template('feed.xml', searchterm=term, entries=entries, pagination=pagination)
|
||||
|
@ -30,7 +30,6 @@ from sqlalchemy.sql.expression import func
|
||||
|
||||
from . import logger, ub, searched_ids, db, calibre_db
|
||||
from .web import render_title_template
|
||||
from .helper import common_filters
|
||||
|
||||
|
||||
shelf = Blueprint('shelf', __name__)
|
||||
@ -320,11 +319,11 @@ def show_shelf(shelf_type, shelf_id):
|
||||
books_in_shelf = ub.session.query(ub.BookShelf).filter(ub.BookShelf.shelf == shelf_id)\
|
||||
.order_by(ub.BookShelf.order.asc()).all()
|
||||
for book in books_in_shelf:
|
||||
cur_book = calibre_db.session.query(db.Books).filter(db.Books.id == book.book_id).filter(common_filters()).first()
|
||||
cur_book = calibre_db.get_filtered_book(book.book_id)
|
||||
if cur_book:
|
||||
result.append(cur_book)
|
||||
else:
|
||||
cur_book = calibre_db.session.query(db.Books).filter(db.Books.id == book.book_id).first()
|
||||
cur_book = calibre_db.get_book(book.book_id)
|
||||
if not cur_book:
|
||||
log.info('Not existing book %s in %s deleted', book.book_id, shelf)
|
||||
ub.session.query(ub.BookShelf).filter(ub.BookShelf.book_id == book.book_id).delete()
|
||||
@ -356,7 +355,7 @@ def order_shelf(shelf_id):
|
||||
books_in_shelf2 = ub.session.query(ub.BookShelf).filter(ub.BookShelf.shelf == shelf_id) \
|
||||
.order_by(ub.BookShelf.order.asc()).all()
|
||||
for book in books_in_shelf2:
|
||||
cur_book = calibre_db.session.query(db.Books).filter(db.Books.id == book.book_id).filter(common_filters()).first()
|
||||
cur_book = calibre_db.get_filtered_book(book.book_id)
|
||||
if cur_book:
|
||||
result.append({'title': cur_book.title,
|
||||
'id': cur_book.id,
|
||||
@ -364,7 +363,7 @@ def order_shelf(shelf_id):
|
||||
'series': cur_book.series,
|
||||
'series_index': cur_book.series_index})
|
||||
else:
|
||||
cur_book = calibre_db.session.query(db.Books).filter(db.Books.id == book.book_id).first()
|
||||
cur_book = calibre_db.get_book(book.book_id)
|
||||
result.append({'title': _('Hidden Book'),
|
||||
'id': cur_book.id,
|
||||
'author': [],
|
||||
|
179
cps/web.py
179
cps/web.py
@ -52,10 +52,9 @@ from . import constants, logger, isoLanguages, services, worker
|
||||
from . import searched_ids, lm, babel, db, ub, config, get_locale, app
|
||||
from . import calibre_db
|
||||
from .gdriveutils import getFileFromEbooksFolder, do_gdrive_download
|
||||
from .helper import common_filters, get_search_results, fill_indexpage, fill_indexpage_with_archived_books, \
|
||||
speaking_language, check_valid_domain, order_authors, get_typeahead, render_task_status, json_serial, \
|
||||
from .helper import check_valid_domain, render_task_status, json_serial, \
|
||||
get_cc_columns, get_book_cover, get_download_link, send_mail, generate_random_password, \
|
||||
send_registration_mail, check_send_to_kindle, check_read_formats, lcase, tags_filters, reset_password
|
||||
send_registration_mail, check_send_to_kindle, check_read_formats, tags_filters, reset_password
|
||||
from .pagination import Pagination
|
||||
from .redirect import redirect_back
|
||||
|
||||
@ -440,7 +439,7 @@ def toggle_read(book_id):
|
||||
else:
|
||||
try:
|
||||
calibre_db.update_title_sort(config)
|
||||
book = calibre_db.session.query(db.Books).filter(db.Books.id == book_id).filter(common_filters()).first()
|
||||
book = calibre_db.get_filtered_book(book_id)
|
||||
read_status = getattr(book, 'custom_column_' + str(config.config_read_column))
|
||||
if len(read_status):
|
||||
read_status[0].value = not read_status[0].value
|
||||
@ -497,7 +496,7 @@ def update_view():
|
||||
@web.route("/ajax/getcomic/<int:book_id>/<book_format>/<int:page>")
|
||||
@login_required
|
||||
def get_comic_book(book_id, book_format, page):
|
||||
book = calibre_db.session.query(db.Books).filter(db.Books.id == book_id).first()
|
||||
book = calibre_db.get_book(book_id)
|
||||
if not book:
|
||||
return "", 204
|
||||
else:
|
||||
@ -551,25 +550,25 @@ def get_comic_book(book_id, book_format, page):
|
||||
@web.route("/get_authors_json", methods=['GET'])
|
||||
@login_required_if_no_ano
|
||||
def get_authors_json():
|
||||
return get_typeahead(db.Authors, request.args.get('q'), ('|', ','))
|
||||
return calibre_db.get_typeahead(db.Authors, request.args.get('q'), ('|', ','))
|
||||
|
||||
|
||||
@web.route("/get_publishers_json", methods=['GET'])
|
||||
@login_required_if_no_ano
|
||||
def get_publishers_json():
|
||||
return get_typeahead(db.Publishers, request.args.get('q'), ('|', ','))
|
||||
return calibre_db.get_typeahead(db.Publishers, request.args.get('q'), ('|', ','))
|
||||
|
||||
|
||||
@web.route("/get_tags_json", methods=['GET'])
|
||||
@login_required_if_no_ano
|
||||
def get_tags_json():
|
||||
return get_typeahead(db.Tags, request.args.get('q'), tag_filter=tags_filters())
|
||||
return calibre_db.get_typeahead(db.Tags, request.args.get('q'), tag_filter=tags_filters())
|
||||
|
||||
|
||||
@web.route("/get_series_json", methods=['GET'])
|
||||
@login_required_if_no_ano
|
||||
def get_series_json():
|
||||
return get_typeahead(db.Series, request.args.get('q'))
|
||||
return calibre_db.get_typeahead(db.Series, request.args.get('q'))
|
||||
|
||||
|
||||
@web.route("/get_languages_json", methods=['GET'])
|
||||
@ -591,7 +590,7 @@ def get_languages_json():
|
||||
def get_matching_tags():
|
||||
tag_dict = {'tags': []}
|
||||
q = calibre_db.session.query(db.Books)
|
||||
calibre_db.session.connection().connection.connection.create_function("lower", 1, lcase)
|
||||
calibre_db.session.connection().connection.connection.create_function("lower", 1, calibre_db.lcase)
|
||||
author_input = request.args.get('author_name') or ''
|
||||
title_input = request.args.get('book_title') or ''
|
||||
include_tag_inputs = request.args.getlist('include_tag') or ''
|
||||
@ -621,7 +620,7 @@ def get_matching_tags():
|
||||
@web.route('/page/<int:page>')
|
||||
@login_required_if_no_ano
|
||||
def index(page):
|
||||
entries, random, pagination = fill_indexpage(page, db.Books, True, [db.Books.timestamp.desc()])
|
||||
entries, random, pagination = calibre_db.fill_indexpage(page, db.Books, True, [db.Books.timestamp.desc()])
|
||||
return render_title_template('index.html', random=random, entries=entries, pagination=pagination,
|
||||
title=_(u"Recently Added Books"), page="root")
|
||||
|
||||
@ -648,15 +647,17 @@ def books_list(data, sort, book_id, page):
|
||||
|
||||
if data == "rated":
|
||||
if current_user.check_visibility(constants.SIDEBAR_BEST_RATED):
|
||||
entries, random, pagination = fill_indexpage(page, db.Books, db.Books.ratings.any(db.Ratings.rating > 9),
|
||||
order)
|
||||
entries, random, pagination = calibre_db.fill_indexpage(page,
|
||||
db.Books,
|
||||
db.Books.ratings.any(db.Ratings.rating > 9),
|
||||
order)
|
||||
return render_title_template('index.html', random=random, entries=entries, pagination=pagination,
|
||||
id=book_id, title=_(u"Top Rated Books"), page="rated")
|
||||
else:
|
||||
abort(404)
|
||||
elif data == "discover":
|
||||
if current_user.check_visibility(constants.SIDEBAR_RANDOM):
|
||||
entries, __, pagination = fill_indexpage(page, db.Books, True, [func.randomblob(2)])
|
||||
entries, __, pagination = calibre_db.calibre_db.fill_indexpage(page, db.Books, True, [func.randomblob(2)])
|
||||
pagination = Pagination(1, config.config_books_per_page, config.config_books_per_page)
|
||||
return render_title_template('discover.html', entries=entries, pagination=pagination, id=book_id,
|
||||
title=_(u"Discover (Random Books)"), page="discover")
|
||||
@ -685,7 +686,7 @@ def books_list(data, sort, book_id, page):
|
||||
elif data == "archived":
|
||||
return render_archived_books(page, order)
|
||||
else:
|
||||
entries, random, pagination = fill_indexpage(page, db.Books, True, order)
|
||||
entries, random, pagination = calibre_db.fill_indexpage(page, db.Books, True, order)
|
||||
return render_title_template('index.html', random=random, entries=entries, pagination=pagination,
|
||||
title=_(u"Books"), page="newest")
|
||||
|
||||
@ -693,7 +694,7 @@ def books_list(data, sort, book_id, page):
|
||||
def render_hot_books(page):
|
||||
if current_user.check_visibility(constants.SIDEBAR_HOT):
|
||||
if current_user.show_detail_random():
|
||||
random = calibre_db.session.query(db.Books).filter(common_filters()) \
|
||||
random = calibre_db.session.query(db.Books).filter(calibre_db.common_filters()) \
|
||||
.order_by(func.random()).limit(config.config_random_books)
|
||||
else:
|
||||
random = false()
|
||||
@ -703,7 +704,7 @@ def render_hot_books(page):
|
||||
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(common_filters()).filter(
|
||||
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)
|
||||
@ -720,9 +721,12 @@ def render_hot_books(page):
|
||||
|
||||
|
||||
def render_author_books(page, author_id, order):
|
||||
entries, __, pagination = fill_indexpage(page, db.Books, db.Books.authors.any(db.Authors.id == author_id),
|
||||
[order[0], db.Series.name, db.Books.series_index],
|
||||
db.books_series_link, db.Series)
|
||||
entries, __, pagination = calibre_db.fill_indexpage(page,
|
||||
db.Books,
|
||||
db.Books.authors.any(db.Authors.id == author_id),
|
||||
[order[0], db.Series.name, db.Books.series_index],
|
||||
db.books_series_link,
|
||||
db.Series)
|
||||
if entries is None or not len(entries):
|
||||
flash(_(u"Oops! Selected book title is unavailable. File does not exist or is not accessible"),
|
||||
category="error")
|
||||
@ -745,10 +749,12 @@ def render_author_books(page, author_id, order):
|
||||
def render_publisher_books(page, book_id, order):
|
||||
publisher = calibre_db.session.query(db.Publishers).filter(db.Publishers.id == book_id).first()
|
||||
if publisher:
|
||||
entries, random, pagination = fill_indexpage(page, db.Books,
|
||||
db.Books.publishers.any(db.Publishers.id == book_id),
|
||||
[db.Series.name, order[0], db.Books.series_index],
|
||||
db.books_series_link, db.Series)
|
||||
entries, random, pagination = calibre_db.fill_indexpage(page,
|
||||
db.Books,
|
||||
db.Books.publishers.any(db.Publishers.id == book_id),
|
||||
[db.Series.name, order[0], db.Books.series_index],
|
||||
db.books_series_link,
|
||||
db.Series)
|
||||
return render_title_template('index.html', random=random, entries=entries, pagination=pagination, id=book_id,
|
||||
title=_(u"Publisher: %(name)s", name=publisher.name), page="publisher")
|
||||
else:
|
||||
@ -758,8 +764,10 @@ def render_publisher_books(page, book_id, order):
|
||||
def render_series_books(page, book_id, order):
|
||||
name = calibre_db.session.query(db.Series).filter(db.Series.id == book_id).first()
|
||||
if name:
|
||||
entries, random, pagination = fill_indexpage(page, db.Books, db.Books.series.any(db.Series.id == book_id),
|
||||
[db.Books.series_index, order[0]])
|
||||
entries, random, pagination = calibre_db.fill_indexpage(page,
|
||||
db.Books,
|
||||
db.Books.series.any(db.Series.id == book_id),
|
||||
[db.Books.series_index, order[0]])
|
||||
return render_title_template('index.html', random=random, pagination=pagination, entries=entries, id=book_id,
|
||||
title=_(u"Series: %(serie)s", serie=name.name), page="series")
|
||||
else:
|
||||
@ -768,8 +776,10 @@ def render_series_books(page, book_id, order):
|
||||
|
||||
def render_ratings_books(page, book_id, order):
|
||||
name = calibre_db.session.query(db.Ratings).filter(db.Ratings.id == book_id).first()
|
||||
entries, random, pagination = fill_indexpage(page, db.Books, db.Books.ratings.any(db.Ratings.id == book_id),
|
||||
[db.Books.timestamp.desc(), order[0]])
|
||||
entries, random, pagination = calibre_db.fill_indexpage(page,
|
||||
db.Books,
|
||||
db.Books.ratings.any(db.Ratings.id == book_id),
|
||||
[db.Books.timestamp.desc(), order[0]])
|
||||
if name and name.rating <= 10:
|
||||
return render_title_template('index.html', random=random, pagination=pagination, entries=entries, id=book_id,
|
||||
title=_(u"Rating: %(rating)s stars", rating=int(name.rating / 2)), page="ratings")
|
||||
@ -780,9 +790,10 @@ def render_ratings_books(page, book_id, order):
|
||||
def render_formats_books(page, book_id, order):
|
||||
name = calibre_db.session.query(db.Data).filter(db.Data.format == book_id.upper()).first()
|
||||
if name:
|
||||
entries, random, pagination = fill_indexpage(page, db.Books,
|
||||
db.Books.data.any(db.Data.format == book_id.upper()),
|
||||
[db.Books.timestamp.desc(), order[0]])
|
||||
entries, random, pagination = calibre_db.fill_indexpage(page,
|
||||
db.Books,
|
||||
db.Books.data.any(db.Data.format == book_id.upper()),
|
||||
[db.Books.timestamp.desc(), order[0]])
|
||||
return render_title_template('index.html', random=random, pagination=pagination, entries=entries, id=book_id,
|
||||
title=_(u"File format: %(format)s", format=name.format), page="formats")
|
||||
else:
|
||||
@ -792,9 +803,11 @@ def render_formats_books(page, book_id, order):
|
||||
def render_category_books(page, book_id, order):
|
||||
name = calibre_db.session.query(db.Tags).filter(db.Tags.id == book_id).first()
|
||||
if name:
|
||||
entries, random, pagination = fill_indexpage(page, db.Books, db.Books.tags.any(db.Tags.id == book_id),
|
||||
[order[0], db.Series.name, db.Books.series_index],
|
||||
db.books_series_link, db.Series)
|
||||
entries, random, pagination = calibre_db.fill_indexpage(page,
|
||||
db.Books,
|
||||
db.Books.tags.any(db.Tags.id == book_id),
|
||||
[order[0], db.Series.name, db.Books.series_index],
|
||||
db.books_series_link, db.Series)
|
||||
return render_title_template('index.html', random=random, entries=entries, pagination=pagination, id=book_id,
|
||||
title=_(u"Category: %(name)s", name=name.name), page="category")
|
||||
else:
|
||||
@ -810,8 +823,10 @@ def render_language_books(page, name, order):
|
||||
lang_name = _(isoLanguages.get(part3=name).name)
|
||||
except KeyError:
|
||||
abort(404)
|
||||
entries, random, pagination = fill_indexpage(page, db.Books, db.Books.languages.any(db.Languages.lang_code == name),
|
||||
[db.Books.timestamp.desc(), order[0]])
|
||||
entries, random, pagination = calibre_db.fill_indexpage(page,
|
||||
db.Books,
|
||||
db.Books.languages.any(db.Languages.lang_code == name),
|
||||
[db.Books.timestamp.desc(), order[0]])
|
||||
return render_title_template('index.html', random=random, entries=entries, pagination=pagination, id=name,
|
||||
title=_(u"Language: %(name)s", name=lang_name), page="language")
|
||||
|
||||
@ -827,10 +842,10 @@ def books_table():
|
||||
def author_list():
|
||||
if current_user.check_visibility(constants.SIDEBAR_AUTHOR):
|
||||
entries = calibre_db.session.query(db.Authors, func.count('books_authors_link.book').label('count')) \
|
||||
.join(db.books_authors_link).join(db.Books).filter(common_filters()) \
|
||||
.join(db.books_authors_link).join(db.Books).filter(calibre_db.common_filters()) \
|
||||
.group_by(text('books_authors_link.author')).order_by(db.Authors.sort).all()
|
||||
charlist = calibre_db.session.query(func.upper(func.substr(db.Authors.sort, 1, 1)).label('char')) \
|
||||
.join(db.books_authors_link).join(db.Books).filter(common_filters()) \
|
||||
.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()
|
||||
for entry in entries:
|
||||
entry.Authors.name = entry.Authors.name.replace('|', ',')
|
||||
@ -845,10 +860,10 @@ def author_list():
|
||||
def publisher_list():
|
||||
if current_user.check_visibility(constants.SIDEBAR_PUBLISHER):
|
||||
entries = calibre_db.session.query(db.Publishers, func.count('books_publishers_link.book').label('count')) \
|
||||
.join(db.books_publishers_link).join(db.Books).filter(common_filters()) \
|
||||
.join(db.books_publishers_link).join(db.Books).filter(calibre_db.common_filters()) \
|
||||
.group_by(text('books_publishers_link.publisher')).order_by(db.Publishers.name).all()
|
||||
charlist = calibre_db.session.query(func.upper(func.substr(db.Publishers.name, 1, 1)).label('char')) \
|
||||
.join(db.books_publishers_link).join(db.Books).filter(common_filters()) \
|
||||
.join(db.books_publishers_link).join(db.Books).filter(calibre_db.common_filters()) \
|
||||
.group_by(func.upper(func.substr(db.Publishers.name, 1, 1))).all()
|
||||
return render_title_template('list.html', entries=entries, folder='web.books_list', charlist=charlist,
|
||||
title=_(u"Publishers"), page="publisherlist", data="publisher")
|
||||
@ -862,19 +877,19 @@ def series_list():
|
||||
if current_user.check_visibility(constants.SIDEBAR_SERIES):
|
||||
if current_user.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(common_filters()) \
|
||||
.join(db.books_series_link).join(db.Books).filter(calibre_db.common_filters()) \
|
||||
.group_by(text('books_series_link.series')).order_by(db.Series.sort).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(common_filters()) \
|
||||
.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")
|
||||
else:
|
||||
entries = calibre_db.session.query(db.Books, func.count('books_series_link').label('count')) \
|
||||
.join(db.books_series_link).join(db.Series).filter(common_filters()) \
|
||||
.join(db.books_series_link).join(db.Series).filter(calibre_db.common_filters()) \
|
||||
.group_by(text('books_series_link.series')).order_by(db.Series.sort).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(common_filters()) \
|
||||
.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,
|
||||
@ -889,7 +904,7 @@ def ratings_list():
|
||||
if current_user.check_visibility(constants.SIDEBAR_RATING):
|
||||
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(common_filters()) \
|
||||
.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()
|
||||
return render_title_template('list.html', entries=entries, folder='web.books_list', charlist=list(),
|
||||
title=_(u"Ratings list"), page="ratingslist", data="ratings")
|
||||
@ -901,8 +916,10 @@ def ratings_list():
|
||||
@login_required_if_no_ano
|
||||
def formats_list():
|
||||
if current_user.check_visibility(constants.SIDEBAR_FORMAT):
|
||||
entries = calibre_db.session.query(db.Data, func.count('data.book').label('count'), db.Data.format.label('format')) \
|
||||
.join(db.Books).filter(common_filters()) \
|
||||
entries = calibre_db.session.query(db.Data,
|
||||
func.count('data.book').label('count'),
|
||||
db.Data.format.label('format')) \
|
||||
.join(db.Books).filter(calibre_db.common_filters()) \
|
||||
.group_by(db.Data.format).order_by(db.Data.format).all()
|
||||
return render_title_template('list.html', entries=entries, folder='web.books_list', charlist=list(),
|
||||
title=_(u"File formats list"), page="formatslist", data="formats")
|
||||
@ -916,7 +933,7 @@ def language_overview():
|
||||
if current_user.check_visibility(constants.SIDEBAR_LANGUAGE):
|
||||
charlist = list()
|
||||
if current_user.filter_language() == u"all":
|
||||
languages = speaking_language()
|
||||
languages = calibre_db.speaking_language()
|
||||
# ToDo: generate first character list for languages
|
||||
else:
|
||||
try:
|
||||
@ -944,10 +961,10 @@ def language_overview():
|
||||
def category_list():
|
||||
if current_user.check_visibility(constants.SIDEBAR_CATEGORY):
|
||||
entries = calibre_db.session.query(db.Tags, func.count('books_tags_link.book').label('count')) \
|
||||
.join(db.books_tags_link).join(db.Books).order_by(db.Tags.name).filter(common_filters()) \
|
||||
.join(db.books_tags_link).join(db.Books).order_by(db.Tags.name).filter(calibre_db.common_filters()) \
|
||||
.group_by(text('books_tags_link.tag')).all()
|
||||
charlist = calibre_db.session.query(func.upper(func.substr(db.Tags.name, 1, 1)).label('char')) \
|
||||
.join(db.books_tags_link).join(db.Books).filter(common_filters()) \
|
||||
.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()
|
||||
return render_title_template('list.html', entries=entries, folder='web.books_list', charlist=charlist,
|
||||
title=_(u"Categories"), page="catlist", data="category")
|
||||
@ -980,8 +997,7 @@ def reconnect():
|
||||
def search():
|
||||
term = request.args.get("query")
|
||||
if term:
|
||||
term.strip().lower()
|
||||
entries = get_search_results(term)
|
||||
entries = calibre_db.get_search_results(term)
|
||||
ids = list()
|
||||
for element in entries:
|
||||
ids.append(element.id)
|
||||
@ -1004,8 +1020,8 @@ def search():
|
||||
def advanced_search():
|
||||
# Build custom columns names
|
||||
cc = get_cc_columns()
|
||||
calibre_db.session.connection().connection.connection.create_function("lower", 1, lcase)
|
||||
q = calibre_db.session.query(db.Books).filter(common_filters()).order_by(db.Books.sort)
|
||||
calibre_db.session.connection().connection.connection.create_function("lower", 1, calibre_db.lcase)
|
||||
q = calibre_db.session.query(db.Books).filter(calibre_db.common_filters()).order_by(db.Books.sort)
|
||||
|
||||
include_tag_inputs = request.args.getlist('include_tag')
|
||||
exclude_tag_inputs = request.args.getlist('exclude_tag')
|
||||
@ -1064,7 +1080,7 @@ def advanced_search():
|
||||
searchterm.extend(serie.name for serie in serie_names)
|
||||
language_names = calibre_db.session.query(db.Languages).filter(db.Languages.id.in_(include_languages_inputs)).all()
|
||||
if language_names:
|
||||
language_names = speaking_language(language_names)
|
||||
language_names = calibre_db.speaking_language(language_names)
|
||||
searchterm.extend(language.name for language in language_names)
|
||||
if rating_high:
|
||||
searchterm.extend([_(u"Rating <= %(rating)s", rating=rating_high)])
|
||||
@ -1137,15 +1153,15 @@ def advanced_search():
|
||||
return render_title_template('search.html', adv_searchterm=searchterm,
|
||||
entries=q, title=_(u"search"), page="search")
|
||||
# prepare data for search-form
|
||||
tags = calibre_db.session.query(db.Tags).join(db.books_tags_link).join(db.Books).filter(common_filters()) \
|
||||
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(common_filters()) \
|
||||
.group_by(text('books_series_link.series')).order_by(db.Series.name).filter(common_filters()).all()
|
||||
extensions = calibre_db.session.query(db.Data).join(db.Books).filter(common_filters()) \
|
||||
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()
|
||||
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 = speaking_language()
|
||||
languages = calibre_db.speaking_language()
|
||||
else:
|
||||
languages = None
|
||||
return render_title_template('search_form.html', tags=tags, languages=languages, extensions=extensions,
|
||||
@ -1160,20 +1176,22 @@ def render_read_books(page, are_read, as_xml=False, order=None, *args, **kwargs)
|
||||
ub.ReadBook.read_status == ub.ReadBook.STATUS_FINISHED)
|
||||
else:
|
||||
db_filter = coalesce(ub.ReadBook.read_status, 0) != ub.ReadBook.STATUS_FINISHED
|
||||
entries, random, pagination = fill_indexpage(page, db.Books,
|
||||
db_filter,
|
||||
order,
|
||||
ub.ReadBook, db.Books.id==ub.ReadBook.book_id)
|
||||
entries, random, pagination = calibre_db.fill_indexpage(page,
|
||||
db.Books,
|
||||
db_filter,
|
||||
order,
|
||||
ub.ReadBook, db.Books.id==ub.ReadBook.book_id)
|
||||
else:
|
||||
try:
|
||||
if are_read:
|
||||
db_filter = db.cc_classes[config.config_read_column].value == True
|
||||
else:
|
||||
db_filter = coalesce(db.cc_classes[config.config_read_column].value, False) != True
|
||||
entries, random, pagination = fill_indexpage(page, db.Books,
|
||||
db_filter,
|
||||
order,
|
||||
db.cc_classes[config.config_read_column])
|
||||
entries, random, pagination = calibre_db.fill_indexpage(page,
|
||||
db.Books,
|
||||
db_filter,
|
||||
order,
|
||||
db.cc_classes[config.config_read_column])
|
||||
except KeyError:
|
||||
log.error("Custom Column No.%d is not existing in calibre database", config.config_read_column)
|
||||
if not as_xml:
|
||||
@ -1207,8 +1225,11 @@ def render_archived_books(page, order):
|
||||
|
||||
archived_filter = db.Books.id.in_(archived_book_ids)
|
||||
|
||||
entries, random, pagination = fill_indexpage_with_archived_books(page, db.Books, archived_filter, order,
|
||||
allow_show_archived=True)
|
||||
entries, random, pagination = calibre_db.fill_indexpage_with_archived_books(page,
|
||||
db.Books,
|
||||
archived_filter,
|
||||
order,
|
||||
allow_show_archived=True)
|
||||
|
||||
name = _(u'Archived Books') + ' (' + str(len(archived_book_ids)) + ')'
|
||||
pagename = "archived"
|
||||
@ -1230,9 +1251,8 @@ def get_cover(book_id):
|
||||
@viewer_required
|
||||
def serve_book(book_id, book_format, anyname):
|
||||
book_format = book_format.split(".")[0]
|
||||
book = calibre_db.session.query(db.Books).filter(db.Books.id == book_id).first()
|
||||
data = calibre_db.session.query(db.Data).filter(db.Data.book == book.id).filter(db.Data.format == book_format.upper()) \
|
||||
.first()
|
||||
book = calibre_db.get_book(book_id)
|
||||
data = calibre_db.get_book_format(book.id, book_format.upper())
|
||||
log.info('Serving book: %s', data.name)
|
||||
if config.config_use_google_drive:
|
||||
headers = Headers()
|
||||
@ -1514,7 +1534,7 @@ def token_verified():
|
||||
@login_required
|
||||
def profile():
|
||||
downloads = list()
|
||||
languages = speaking_language()
|
||||
languages = calibre_db.speaking_language()
|
||||
translations = babel.list_translations() + [LC('en')]
|
||||
kobo_support = feature_support['kobo'] and config.config_kobo_sync
|
||||
if feature_support['oauth']:
|
||||
@ -1523,9 +1543,9 @@ def profile():
|
||||
oauth_status = None
|
||||
|
||||
for book in current_user.downloads:
|
||||
downloadBook = calibre_db.session.query(db.Books).filter(db.Books.id == book.book_id).first()
|
||||
downloadBook = calibre_db.get_book(book.book_id)
|
||||
if downloadBook:
|
||||
downloads.append(calibre_db.session.query(db.Books).filter(db.Books.id == book.book_id).first())
|
||||
downloads.append(downloadBook)
|
||||
else:
|
||||
ub.delete_download(book.book_id)
|
||||
if request.method == "POST":
|
||||
@ -1604,7 +1624,7 @@ def profile():
|
||||
@login_required_if_no_ano
|
||||
@viewer_required
|
||||
def read_book(book_id, book_format):
|
||||
book = calibre_db.session.query(db.Books).filter(db.Books.id == book_id).filter(common_filters()).first()
|
||||
book = calibre_db.get_filtered_book(book_id)
|
||||
if not book:
|
||||
flash(_(u"Error opening eBook. File does not exist or file is not accessible:"), category="error")
|
||||
log.debug(u"Error opening eBook. File does not exist or file is not accessible:")
|
||||
@ -1628,7 +1648,7 @@ def read_book(book_id, book_format):
|
||||
else:
|
||||
for fileExt in constants.EXTENSIONS_AUDIO:
|
||||
if book_format.lower() == fileExt:
|
||||
entries = calibre_db.session.query(db.Books).filter(db.Books.id == book_id).filter(common_filters()).first()
|
||||
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(),
|
||||
title=_(u"Read a Book"), entry=entries, bookmark=bookmark)
|
||||
@ -1654,8 +1674,7 @@ def read_book(book_id, book_format):
|
||||
@web.route("/book/<int:book_id>")
|
||||
@login_required_if_no_ano
|
||||
def show_book(book_id):
|
||||
entries = calibre_db.session.query(db.Books).filter(and_(db.Books.id == book_id,
|
||||
common_filters(allow_show_archived=True))).first()
|
||||
entries = calibre_db.get_filtered_book(book_id, allow_show_archived=True)
|
||||
if entries:
|
||||
for index in range(0, len(entries.languages)):
|
||||
try:
|
||||
|
@ -291,7 +291,7 @@ class WorkerThread(threading.Thread):
|
||||
w_session = Session()
|
||||
engine.execute("attach database '{}' as calibre;".format(dbpath))'''
|
||||
file_path = self.queue[index]['file_path']
|
||||
bookid = self.queue[index]['bookid']
|
||||
book_id = self.queue[index]['bookid']
|
||||
format_old_ext = u'.' + self.queue[index]['settings']['old_book_format'].lower()
|
||||
format_new_ext = u'.' + self.queue[index]['settings']['new_book_format'].lower()
|
||||
|
||||
@ -299,15 +299,15 @@ class WorkerThread(threading.Thread):
|
||||
# if it does - mark the conversion task as complete and return a success
|
||||
# this will allow send to kindle workflow to continue to work
|
||||
if os.path.isfile(file_path + format_new_ext):
|
||||
log.info("Book id %d already converted to %s", bookid, format_new_ext)
|
||||
cur_book = calibre_db.session.query(db.Books).filter(db.Books.id == bookid).first()
|
||||
log.info("Book id %d already converted to %s", book_id, format_new_ext)
|
||||
cur_book = calibre_db.get_book(book_id)
|
||||
self.queue[index]['path'] = file_path
|
||||
self.queue[index]['title'] = cur_book.title
|
||||
self._handleSuccess()
|
||||
return file_path + format_new_ext
|
||||
else:
|
||||
log.info("Book id %d - target format of %s does not exist. Moving forward with convert.",
|
||||
bookid,
|
||||
book_id,
|
||||
format_new_ext)
|
||||
|
||||
if config.config_kepubifypath and format_old_ext == '.epub' and format_new_ext == '.kepub':
|
||||
@ -324,13 +324,13 @@ class WorkerThread(threading.Thread):
|
||||
check, error_message = self._convert_calibre(file_path, format_old_ext, format_new_ext, index)
|
||||
|
||||
if check == 0:
|
||||
cur_book = calibre_db.session.query(db.Books).filter(db.Books.id == bookid).first()
|
||||
cur_book = calibre_db.get_book(book_id)
|
||||
if os.path.isfile(file_path + format_new_ext):
|
||||
# self.db_queue.join()
|
||||
new_format = db.Data(name=cur_book.data[0].name,
|
||||
book_format=self.queue[index]['settings']['new_book_format'].upper(),
|
||||
book=bookid, uncompressed_size=os.path.getsize(file_path + format_new_ext))
|
||||
task = {'task':'add_format','id': bookid, 'format': new_format}
|
||||
book=book_id, uncompressed_size=os.path.getsize(file_path + format_new_ext))
|
||||
task = {'task':'add_format','id': book_id, 'format': new_format}
|
||||
self.db_queue.put(task)
|
||||
# To Do how to handle error?
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user