mirror of
https://github.com/janeczku/calibre-web
synced 2024-12-18 14:10:30 +00:00
Enabled search for text based custom column content in simple search (fix for #2279)
This commit is contained in:
parent
32a3c45ee0
commit
2f949ce1dd
75
cps/db.py
75
cps/db.py
@ -819,38 +819,21 @@ class CalibreDB:
|
|||||||
def check_exists_book(self, authr, title):
|
def check_exists_book(self, authr, title):
|
||||||
self.session.connection().connection.connection.create_function("lower", 1, lcase)
|
self.session.connection().connection.connection.create_function("lower", 1, lcase)
|
||||||
q = list()
|
q = list()
|
||||||
authorterms = re.split(r'\s*&\s*', authr)
|
author_terms = re.split(r'\s*&\s*', authr)
|
||||||
for authorterm in authorterms:
|
for author_term in author_terms:
|
||||||
q.append(Books.authors.any(func.lower(Authors.name).ilike("%" + authorterm + "%")))
|
q.append(Books.authors.any(func.lower(Authors.name).ilike("%" + author_term + "%")))
|
||||||
|
|
||||||
return self.session.query(Books) \
|
return self.session.query(Books) \
|
||||||
.filter(and_(Books.authors.any(and_(*q)), func.lower(Books.title).ilike("%" + title + "%"))).first()
|
.filter(and_(Books.authors.any(and_(*q)), func.lower(Books.title).ilike("%" + title + "%"))).first()
|
||||||
|
|
||||||
def search_query(self, term, config_read_column, *join):
|
def search_query(self, term, config, *join):
|
||||||
term.strip().lower()
|
term.strip().lower()
|
||||||
self.session.connection().connection.connection.create_function("lower", 1, lcase)
|
self.session.connection().connection.connection.create_function("lower", 1, lcase)
|
||||||
q = list()
|
q = list()
|
||||||
authorterms = re.split("[, ]+", term)
|
author_terms = re.split("[, ]+", term)
|
||||||
for authorterm in authorterms:
|
for author_term in author_terms:
|
||||||
q.append(Books.authors.any(func.lower(Authors.name).ilike("%" + authorterm + "%")))
|
q.append(Books.authors.any(func.lower(Authors.name).ilike("%" + author_term + "%")))
|
||||||
query = self.generate_linked_query(config_read_column, Books)
|
query = self.generate_linked_query(config.config_read_column, Books)
|
||||||
'''if not config_read_column:
|
|
||||||
query = (self.session.query(Books, ub.ArchivedBook.is_archived, ub.ReadBook).select_from(Books)
|
|
||||||
.outerjoin(ub.ReadBook, and_(Books.id == ub.ReadBook.book_id,
|
|
||||||
int(current_user.id) == ub.ReadBook.user_id)))
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
read_column = cc_classes[config_read_column]
|
|
||||||
query = (self.session.query(Books, ub.ArchivedBook.is_archived, read_column.value)
|
|
||||||
.select_from(Books)
|
|
||||||
.outerjoin(read_column, read_column.book == Books.id))
|
|
||||||
except (KeyError, AttributeError, IndexError):
|
|
||||||
log.error("Custom Column No.{} is not existing in calibre database".format(config_read_column))
|
|
||||||
# Skip linking read column
|
|
||||||
query = self.session.query(Books, ub.ArchivedBook.is_archived, None)
|
|
||||||
query = query.outerjoin(ub.ArchivedBook, and_(Books.id == ub.ArchivedBook.book_id,
|
|
||||||
int(current_user.id) == ub.ArchivedBook.user_id))'''
|
|
||||||
|
|
||||||
if len(join) == 6:
|
if len(join) == 6:
|
||||||
query = query.outerjoin(join[0], join[1]).outerjoin(join[2]).outerjoin(join[3], join[4]).outerjoin(join[5])
|
query = query.outerjoin(join[0], join[1]).outerjoin(join[2]).outerjoin(join[3], join[4]).outerjoin(join[5])
|
||||||
if len(join) == 3:
|
if len(join) == 3:
|
||||||
@ -859,20 +842,42 @@ class CalibreDB:
|
|||||||
query = query.outerjoin(join[0], join[1])
|
query = query.outerjoin(join[0], join[1])
|
||||||
elif len(join) == 1:
|
elif len(join) == 1:
|
||||||
query = query.outerjoin(join[0])
|
query = query.outerjoin(join[0])
|
||||||
return query.filter(self.common_filters(True)).filter(
|
|
||||||
or_(Books.tags.any(func.lower(Tags.name).ilike("%" + term + "%")),
|
cc = self.get_cc_columns(config, filter_config_custom_read=True)
|
||||||
Books.series.any(func.lower(Series.name).ilike("%" + term + "%")),
|
filter_expression = [Books.tags.any(func.lower(Tags.name).ilike("%" + term + "%")),
|
||||||
Books.authors.any(and_(*q)),
|
Books.series.any(func.lower(Series.name).ilike("%" + term + "%")),
|
||||||
Books.publishers.any(func.lower(Publishers.name).ilike("%" + term + "%")),
|
Books.authors.any(and_(*q)),
|
||||||
func.lower(Books.title).ilike("%" + term + "%")
|
Books.publishers.any(func.lower(Publishers.name).ilike("%" + term + "%")),
|
||||||
))
|
func.lower(Books.title).ilike("%" + term + "%")]
|
||||||
|
for c in cc:
|
||||||
|
if c.datatype not in ["datetime", "rating", "bool", "int", "float"]:
|
||||||
|
filter_expression.append(
|
||||||
|
getattr(Books,
|
||||||
|
'custom_column_' + str(c.id)).any(
|
||||||
|
func.lower(cc_classes[c.id].value).ilike("%" + term + "%")))
|
||||||
|
return query.filter(self.common_filters(True)).filter(or_(*filter_expression))
|
||||||
|
|
||||||
|
def get_cc_columns(self, config, filter_config_custom_read=False):
|
||||||
|
tmp_cc = self.session.query(CustomColumns).filter(CustomColumns.datatype.notin_(cc_exceptions)).all()
|
||||||
|
cc = []
|
||||||
|
r = None
|
||||||
|
if config.config_columns_to_ignore:
|
||||||
|
r = re.compile(config.config_columns_to_ignore)
|
||||||
|
|
||||||
|
for col in tmp_cc:
|
||||||
|
if filter_config_custom_read and config.config_read_column and config.config_read_column == col.id:
|
||||||
|
continue
|
||||||
|
if r and r.match(col.name):
|
||||||
|
continue
|
||||||
|
cc.append(col)
|
||||||
|
|
||||||
|
return cc
|
||||||
|
|
||||||
# read search results from calibre-database and return it (function is used for feed and simple search
|
# read search results from calibre-database and return it (function is used for feed and simple search
|
||||||
def get_search_results(self, term, offset=None, order=None, limit=None,
|
def get_search_results(self, term, config, offset=None, order=None, limit=None, *join):
|
||||||
config_read_column=False, *join):
|
|
||||||
order = order[0] if order else [Books.sort]
|
order = order[0] if order else [Books.sort]
|
||||||
pagination = None
|
pagination = None
|
||||||
result = self.search_query(term, config_read_column, *join).order_by(*order).all()
|
result = self.search_query(term, config, *join).order_by(*order).all()
|
||||||
result_count = len(result)
|
result_count = len(result)
|
||||||
if offset != None and limit != None:
|
if offset != None and limit != None:
|
||||||
offset = int(offset)
|
offset = int(offset)
|
||||||
|
@ -953,24 +953,6 @@ def check_valid_domain(domain_text):
|
|||||||
return not len(result)
|
return not len(result)
|
||||||
|
|
||||||
|
|
||||||
def get_cc_columns(filter_config_custom_read=False):
|
|
||||||
tmpcc = calibre_db.session.query(db.CustomColumns)\
|
|
||||||
.filter(db.CustomColumns.datatype.notin_(db.cc_exceptions)).all()
|
|
||||||
cc = []
|
|
||||||
r = None
|
|
||||||
if config.config_columns_to_ignore:
|
|
||||||
r = re.compile(config.config_columns_to_ignore)
|
|
||||||
|
|
||||||
for col in tmpcc:
|
|
||||||
if filter_config_custom_read and config.config_read_column and config.config_read_column == col.id:
|
|
||||||
continue
|
|
||||||
if r and r.match(col.name):
|
|
||||||
continue
|
|
||||||
cc.append(col)
|
|
||||||
|
|
||||||
return cc
|
|
||||||
|
|
||||||
|
|
||||||
def get_download_link(book_id, book_format, client):
|
def get_download_link(book_id, book_format, client):
|
||||||
book_format = book_format.split(".")[0]
|
book_format = book_format.split(".")[0]
|
||||||
book = calibre_db.get_filtered_book(book_id, allow_show_archived=True)
|
book = calibre_db.get_filtered_book(book_id, allow_show_archived=True)
|
||||||
|
@ -467,7 +467,7 @@ def feed_unread_books():
|
|||||||
|
|
||||||
def feed_search(term):
|
def feed_search(term):
|
||||||
if term:
|
if term:
|
||||||
entries, __, ___ = calibre_db.get_search_results(term, config_read_column=config.config_read_column)
|
entries, __, ___ = calibre_db.get_search_results(term, config=config)
|
||||||
entries_count = len(entries) if len(entries) > 0 else 1
|
entries_count = len(entries) if len(entries) > 0 else 1
|
||||||
pagination = Pagination(1, entries_count, entries_count)
|
pagination = Pagination(1, entries_count, entries_count)
|
||||||
return render_xml_template('feed.xml', searchterm=term, entries=entries, pagination=pagination)
|
return render_xml_template('feed.xml', searchterm=term, entries=entries, pagination=pagination)
|
||||||
|
39
cps/web.py
39
cps/web.py
@ -50,7 +50,7 @@ from . import babel, db, ub, config, get_locale, app
|
|||||||
from . import calibre_db, kobo_sync_status
|
from . import calibre_db, kobo_sync_status
|
||||||
from .gdriveutils import getFileFromEbooksFolder, do_gdrive_download
|
from .gdriveutils import getFileFromEbooksFolder, do_gdrive_download
|
||||||
from .helper import check_valid_domain, render_task_status, check_email, check_username, \
|
from .helper import check_valid_domain, render_task_status, check_email, check_username, \
|
||||||
get_cc_columns, get_book_cover, get_download_link, send_mail, generate_random_password, \
|
get_book_cover, get_download_link, send_mail, generate_random_password, \
|
||||||
send_registration_mail, check_send_to_kindle, check_read_formats, tags_filters, reset_password, valid_email, \
|
send_registration_mail, check_send_to_kindle, check_read_formats, tags_filters, reset_password, valid_email, \
|
||||||
edit_book_read_status
|
edit_book_read_status
|
||||||
from .pagination import Pagination
|
from .pagination import Pagination
|
||||||
@ -724,10 +724,10 @@ def render_prepare_search_form(cc):
|
|||||||
def render_search_results(term, offset=None, order=None, limit=None):
|
def render_search_results(term, offset=None, order=None, limit=None):
|
||||||
join = db.books_series_link, db.books_series_link.c.book == db.Books.id, db.Series
|
join = db.books_series_link, db.books_series_link.c.book == db.Books.id, db.Series
|
||||||
entries, result_count, pagination = calibre_db.get_search_results(term,
|
entries, result_count, pagination = calibre_db.get_search_results(term,
|
||||||
|
config,
|
||||||
offset,
|
offset,
|
||||||
order,
|
order,
|
||||||
limit,
|
limit,
|
||||||
config.config_read_column,
|
|
||||||
*join)
|
*join)
|
||||||
return render_title_template('search.html',
|
return render_title_template('search.html',
|
||||||
searchterm=term,
|
searchterm=term,
|
||||||
@ -765,7 +765,7 @@ def books_list(data, sort_param, book_id, page):
|
|||||||
@login_required
|
@login_required
|
||||||
def books_table():
|
def books_table():
|
||||||
visibility = current_user.view_settings.get('table', {})
|
visibility = current_user.view_settings.get('table', {})
|
||||||
cc = get_cc_columns(filter_config_custom_read=True)
|
cc = calibre_db.get_cc_columns(config, filter_config_custom_read=True)
|
||||||
return render_title_template('book_table.html', title=_(u"Books List"), cc=cc, page="book_table",
|
return render_title_template('book_table.html', title=_(u"Books List"), cc=cc, page="book_table",
|
||||||
visiblility=visibility)
|
visiblility=visibility)
|
||||||
|
|
||||||
@ -809,7 +809,7 @@ def list_books():
|
|||||||
calibre_db.common_filters(allow_show_archived=True)).count()
|
calibre_db.common_filters(allow_show_archived=True)).count()
|
||||||
if state is not None:
|
if state is not None:
|
||||||
if search_param:
|
if search_param:
|
||||||
books = calibre_db.search_query(search_param, config.config_read_column).all()
|
books = calibre_db.search_query(search_param, config).all()
|
||||||
filtered_count = len(books)
|
filtered_count = len(books)
|
||||||
else:
|
else:
|
||||||
query = calibre_db.generate_linked_query(config.config_read_column, db.Books)
|
query = calibre_db.generate_linked_query(config.config_read_column, db.Books)
|
||||||
@ -817,10 +817,10 @@ def list_books():
|
|||||||
entries = calibre_db.get_checkbox_sorted(books, state, off, limit, order, True)
|
entries = calibre_db.get_checkbox_sorted(books, state, off, limit, order, True)
|
||||||
elif search_param:
|
elif search_param:
|
||||||
entries, filtered_count, __ = calibre_db.get_search_results(search_param,
|
entries, filtered_count, __ = calibre_db.get_search_results(search_param,
|
||||||
|
config,
|
||||||
off,
|
off,
|
||||||
[order, ''],
|
[order, ''],
|
||||||
limit,
|
limit,
|
||||||
config.config_read_column,
|
|
||||||
*join)
|
*join)
|
||||||
else:
|
else:
|
||||||
entries, __, __ = calibre_db.fill_indexpage_with_archived_books((int(off) / (int(limit)) + 1),
|
entries, __, __ = calibre_db.fill_indexpage_with_archived_books((int(off) / (int(limit)) + 1),
|
||||||
@ -1232,26 +1232,9 @@ def render_adv_search_results(term, offset=None, order=None, limit=None):
|
|||||||
sort_param = order[0] if order else [db.Books.sort]
|
sort_param = order[0] if order else [db.Books.sort]
|
||||||
pagination = None
|
pagination = None
|
||||||
|
|
||||||
cc = get_cc_columns(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)
|
||||||
query = calibre_db.generate_linked_query(config.config_read_column, db.Books)
|
query = calibre_db.generate_linked_query(config.config_read_column, db.Books)
|
||||||
'''if not config.config_read_column:
|
|
||||||
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 = db.cc_classes[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, IndexError):
|
|
||||||
log.error("Custom Column No.{} is not existing in calibre database".format(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_series_link.c.book == db.Books.id) \
|
q = query.outerjoin(db.books_series_link, db.books_series_link.c.book == db.Books.id) \
|
||||||
.outerjoin(db.Series) \
|
.outerjoin(db.Series) \
|
||||||
.filter(calibre_db.common_filters(True))
|
.filter(calibre_db.common_filters(True))
|
||||||
@ -1338,7 +1321,7 @@ def render_adv_search_results(term, offset=None, order=None, limit=None):
|
|||||||
if description:
|
if description:
|
||||||
q = q.filter(db.Books.comments.any(func.lower(db.Comments.text).ilike("%" + description + "%")))
|
q = q.filter(db.Books.comments.any(func.lower(db.Comments.text).ilike("%" + description + "%")))
|
||||||
|
|
||||||
# search custom culumns
|
# search custom columns
|
||||||
try:
|
try:
|
||||||
q = adv_search_custom_columns(cc, term, q)
|
q = adv_search_custom_columns(cc, term, q)
|
||||||
except AttributeError as ex:
|
except AttributeError as ex:
|
||||||
@ -1370,7 +1353,7 @@ def render_adv_search_results(term, offset=None, order=None, limit=None):
|
|||||||
@login_required_if_no_ano
|
@login_required_if_no_ano
|
||||||
def advanced_search_form():
|
def advanced_search_form():
|
||||||
# Build custom columns names
|
# Build custom columns names
|
||||||
cc = get_cc_columns(filter_config_custom_read=True)
|
cc = calibre_db.get_cc_columns(config, filter_config_custom_read=True)
|
||||||
return render_prepare_search_form(cc)
|
return render_prepare_search_form(cc)
|
||||||
|
|
||||||
|
|
||||||
@ -1757,10 +1740,10 @@ def show_book(book_id):
|
|||||||
for lang_index in range(0, len(entry.languages)):
|
for lang_index in range(0, len(entry.languages)):
|
||||||
entry.languages[lang_index].language_name = isoLanguages.get_language_name(get_locale(), entry.languages[
|
entry.languages[lang_index].language_name = isoLanguages.get_language_name(get_locale(), entry.languages[
|
||||||
lang_index].lang_code)
|
lang_index].lang_code)
|
||||||
cc = get_cc_columns(filter_config_custom_read=True)
|
cc = calibre_db.get_cc_columns(config, filter_config_custom_read=True)
|
||||||
book_in_shelves = []
|
book_in_shelves = []
|
||||||
shelfs = ub.session.query(ub.BookShelf).filter(ub.BookShelf.book_id == book_id).all()
|
shelves = ub.session.query(ub.BookShelf).filter(ub.BookShelf.book_id == book_id).all()
|
||||||
for sh in shelfs:
|
for sh in shelves:
|
||||||
book_in_shelves.append(sh.shelf)
|
book_in_shelves.append(sh.shelf)
|
||||||
|
|
||||||
entry.tags = sort(entry.tags, key=lambda tag: tag.name)
|
entry.tags = sort(entry.tags, key=lambda tag: tag.name)
|
||||||
|
Loading…
Reference in New Issue
Block a user