Fix for #2437 (advanced search for read status crashes calibre-web)

This commit is contained in:
Ozzie Isaacs 2022-06-08 17:17:07 +02:00
parent f44d42f834
commit 91df265d40
5 changed files with 25 additions and 63 deletions

View File

@ -627,7 +627,7 @@ class CalibreDB:
.join(read_column, read_column.book == book_id, .join(read_column, read_column.book == book_id,
isouter=True)) isouter=True))
except (KeyError, AttributeError, IndexError): except (KeyError, AttributeError, IndexError):
log.error("Custom Column No.{} is not existing in calibre database".format(read_column)) log.error("Custom Column No.{} does not exist in calibre database".format(read_column))
# Skip linking read column and return None instead of read status # Skip linking read column and return None instead of read status
bd = self.session.query(Books, None, ub.ArchivedBook.is_archived) bd = self.session.query(Books, None, ub.ArchivedBook.is_archived)
return (bd.filter(Books.id == book_id) return (bd.filter(Books.id == book_id)
@ -674,9 +674,9 @@ class CalibreDB:
except (KeyError, AttributeError, IndexError): except (KeyError, AttributeError, IndexError):
pos_content_cc_filter = false() pos_content_cc_filter = false()
neg_content_cc_filter = true() neg_content_cc_filter = true()
log.error("Custom Column No.{} is not existing in calibre database".format( log.error("Custom Column No.{} does not exist in calibre database".format(
self.config.config_restricted_column)) self.config.config_restricted_column))
flash(_("Custom Column No.%(column)d is not existing in calibre database", flash(_("Custom Column No.%(column)d does not exist in calibre database",
column=self.config.config_restricted_column), column=self.config.config_restricted_column),
category="error") category="error")
@ -699,7 +699,7 @@ class CalibreDB:
.select_from(Books) .select_from(Books)
.outerjoin(read_column, read_column.book == Books.id)) .outerjoin(read_column, read_column.book == Books.id))
except (KeyError, AttributeError, IndexError): except (KeyError, AttributeError, IndexError):
log.error("Custom Column No.{} is not existing in calibre database".format(config_read_column)) log.error("Custom Column No.{} does not exist in calibre database".format(config_read_column))
# Skip linking read column and return None instead of read status # Skip linking read column and return None instead of read status
query = self.session.query(database, None, ub.ArchivedBook.is_archived) query = self.session.query(database, None, ub.ArchivedBook.is_archived)
return query.outerjoin(ub.ArchivedBook, and_(Books.id == ub.ArchivedBook.book_id, return query.outerjoin(ub.ArchivedBook, and_(Books.id == ub.ArchivedBook.book_id,

View File

@ -336,8 +336,8 @@ def edit_book_read_status(book_id, read_status=None):
calibre_db.session.commit() calibre_db.session.commit()
except (KeyError, AttributeError, IndexError): except (KeyError, AttributeError, IndexError):
log.error( log.error(
"Custom Column No.{} is not existing in calibre database".format(config.config_read_column)) "Custom Column No.{} does not exist in calibre database".format(config.config_read_column))
return "Custom Column No.{} is not existing in calibre database".format(config.config_read_column) return "Custom Column No.{} does not exist in calibre database".format(config.config_read_column)
except (OperationalError, InvalidRequestError) as ex: except (OperationalError, InvalidRequestError) as ex:
calibre_db.session.rollback() calibre_db.session.rollback()
log.error(u"Read status could not set: {}".format(ex)) log.error(u"Read status could not set: {}".format(ex))

View File

@ -101,19 +101,6 @@ def get_sidebar_config(kwargs=None):
"show_text": _('Show Books List'), "config_show": content}) "show_text": _('Show Books List'), "config_show": content})
return sidebar, simple return sidebar, simple
'''def get_readbooks_ids():
if not config.config_read_column:
readBooks = ub.session.query(ub.ReadBook).filter(ub.ReadBook.user_id == int(current_user.id))\
.filter(ub.ReadBook.read_status == ub.ReadBook.STATUS_FINISHED).all()
return frozenset([x.book_id for x in readBooks])
else:
try:
readBooks = calibre_db.session.query(db.cc_classes[config.config_read_column])\
.filter(db.cc_classes[config.config_read_column].value == True).all()
return frozenset([x.book for x in readBooks])
except (KeyError, AttributeError, IndexError):
log.error("Custom Column No.{} is not existing in calibre database".format(config.config_read_column))
return []'''
# Returns the template for rendering and includes the instance name # Returns the template for rendering and includes the instance name
def render_title_template(*args, **kwargs): def render_title_template(*args, **kwargs):

View File

@ -22,7 +22,7 @@ from flask import session as flask_session
from flask_login import current_user from flask_login import current_user
from flask_babel import format_date from flask_babel import format_date
from flask_babel import gettext as _ from flask_babel import gettext as _
from sqlalchemy.sql.expression import func, not_, and_, or_, text from sqlalchemy.sql.expression import func, not_, and_, or_, text, true
from sqlalchemy.sql.functions import coalesce from sqlalchemy.sql.functions import coalesce
from . import logger, db, calibre_db, config, ub from . import logger, db, calibre_db, config, ub
@ -119,32 +119,23 @@ def adv_search_ratings(q, rating_high, rating_low):
return q return q
def adv_search_read_status(q, read_status): def adv_search_read_status(read_status):
if read_status: if not config.config_read_column:
if config.config_read_column: if read_status == "True":
try: db_filter = and_(ub.ReadBook.user_id == int(current_user.id),
if read_status == "True": ub.ReadBook.read_status == ub.ReadBook.STATUS_FINISHED)
q = q.join(db.cc_classes[config.config_read_column], isouter=True) \
.filter(db.cc_classes[config.config_read_column].value == True)
else:
q = q.join(db.cc_classes[config.config_read_column], isouter=True) \
.filter(coalesce(db.cc_classes[config.config_read_column].value, False) != True)
except (KeyError, AttributeError):
log.error(u"Custom Column No.%d is not existing in calibre database", config.config_read_column)
flash(_("Custom Column No.%(column)d is not existing in calibre database",
column=config.config_read_column),
category="error")
return q
else: else:
db_filter = coalesce(ub.ReadBook.read_status, 0) != ub.ReadBook.STATUS_FINISHED
else:
try:
if read_status == "True": if read_status == "True":
q = q.join(ub.ReadBook, db.Books.id == ub.ReadBook.book_id, isouter=True) \ db_filter = db.cc_classes[config.config_read_column].value == True
.filter(ub.ReadBook.user_id == int(current_user.id),
ub.ReadBook.read_status == ub.ReadBook.STATUS_FINISHED)
else: else:
q = q.join(ub.ReadBook, db.Books.id == ub.ReadBook.book_id, isouter=True) \ db_filter = coalesce(db.cc_classes[config.config_read_column].value, False) != True
.filter(ub.ReadBook.user_id == int(current_user.id), except (KeyError, AttributeError, IndexError):
coalesce(ub.ReadBook.read_status, 0) != ub.ReadBook.STATUS_FINISHED) log.error("Custom Column No.{} does not exist in calibre database".format(config.config_read_column))
return q return true()
return db_filter
def adv_search_extension(q, include_extension_inputs, exclude_extension_inputs): def adv_search_extension(q, include_extension_inputs, exclude_extension_inputs):
@ -238,23 +229,7 @@ def render_adv_search_results(term, offset=None, order=None, limit=None):
cc = calibre_db.get_cc_columns(config, filter_config_custom_read=True) cc = calibre_db.get_cc_columns(config, filter_config_custom_read=True)
calibre_db.session.connection().connection.connection.create_function("lower", 1, db.lcase) calibre_db.session.connection().connection.connection.create_function("lower", 1, db.lcase)
if not config.config_read_column: query = calibre_db.generate_linked_query(config.config_read_column, db.Books)
query = (calibre_db.session.query(db.Books, ub.ArchivedBook.is_archived, ub.ReadBook).select_from(db.Books)
.outerjoin(ub.ReadBook, and_(db.Books.id == ub.ReadBook.book_id,
int(current_user.id) == ub.ReadBook.user_id)))
else:
try:
read_column = cc[config.config_read_column]
query = (calibre_db.session.query(db.Books, ub.ArchivedBook.is_archived, read_column.value)
.select_from(db.Books)
.outerjoin(read_column, read_column.book == db.Books.id))
except (KeyError, AttributeError):
log.error("Custom Column No.%d is not existing in calibre database", config.config_read_column)
# Skip linking read column
query = calibre_db.session.query(db.Books, ub.ArchivedBook.is_archived, None)
query = query.outerjoin(ub.ArchivedBook, and_(db.Books.id == ub.ArchivedBook.book_id,
int(current_user.id) == ub.ArchivedBook.user_id))
q = query.outerjoin(db.books_series_link, db.Books.id == db.books_series_link.c.book)\ q = query.outerjoin(db.books_series_link, db.Books.id == db.books_series_link.c.book)\
.outerjoin(db.Series)\ .outerjoin(db.Series)\
.filter(calibre_db.common_filters(True)) .filter(calibre_db.common_filters(True))
@ -324,7 +299,7 @@ def render_adv_search_results(term, offset=None, order=None, limit=None):
q = q.filter(func.datetime(db.Books.pubdate) > func.datetime(pub_start)) q = q.filter(func.datetime(db.Books.pubdate) > func.datetime(pub_start))
if pub_end: if pub_end:
q = q.filter(func.datetime(db.Books.pubdate) < func.datetime(pub_end)) q = q.filter(func.datetime(db.Books.pubdate) < func.datetime(pub_end))
q = adv_search_read_status(q, read_status) q = q.filter(adv_search_read_status(read_status))
if publisher: if publisher:
q = q.filter(db.Books.publishers.any(func.lower(db.Publishers.name).ilike("%" + publisher + "%"))) q = q.filter(db.Books.publishers.any(func.lower(db.Publishers.name).ilike("%" + publisher + "%")))
q = adv_search_tag(q, tags['include_tag'], tags['exclude_tag']) q = adv_search_tag(q, tags['include_tag'], tags['exclude_tag'])

View File

@ -715,9 +715,9 @@ def render_read_books(page, are_read, as_xml=False, order=None):
else: else:
db_filter = coalesce(db.cc_classes[config.config_read_column].value, False) != True db_filter = coalesce(db.cc_classes[config.config_read_column].value, False) != True
except (KeyError, AttributeError, IndexError): except (KeyError, AttributeError, IndexError):
log.error("Custom Column No.{} is not existing in calibre database".format(config.config_read_column)) log.error("Custom Column No.{} does not exist in calibre database".format(config.config_read_column))
if not as_xml: if not as_xml:
flash(_("Custom Column No.%(column)d is not existing in calibre database", flash(_("Custom Column No.%(column)d does not exist in calibre database",
column=config.config_read_column), column=config.config_read_column),
category="error") category="error")
return redirect(url_for("web.index")) return redirect(url_for("web.index"))