mirror of
				https://github.com/janeczku/calibre-web
				synced 2025-10-31 15:23:02 +00:00 
			
		
		
		
	Sort authors additionally to series and series_index (Fix #2001)
Sqlalchemy version2 is now a global flag
This commit is contained in:
		| @@ -20,6 +20,9 @@ from __future__ import division, print_function, unicode_literals | |||||||
| import sys | import sys | ||||||
| import os | import os | ||||||
| from collections import namedtuple | from collections import namedtuple | ||||||
|  | from sqlalchemy import __version__ as sql_version | ||||||
|  |  | ||||||
|  | sqlalchemy_version2 = ([int(x) for x in sql_version.split('.')] >= [2,0,0]) | ||||||
|  |  | ||||||
| # if installed via pip this variable is set to true (empty file with name .HOMEDIR present) | # if installed via pip this variable is set to true (empty file with name .HOMEDIR present) | ||||||
| HOME_CONFIG = os.path.isfile(os.path.join(os.path.dirname(os.path.abspath(__file__)), '.HOMEDIR')) | HOME_CONFIG = os.path.isfile(os.path.join(os.path.dirname(os.path.abspath(__file__)), '.HOMEDIR')) | ||||||
|   | |||||||
| @@ -690,6 +690,8 @@ class CalibreDB(): | |||||||
|             randm = false() |             randm = false() | ||||||
|         off = int(int(pagesize) * (page - 1)) |         off = int(int(pagesize) * (page - 1)) | ||||||
|         query = self.session.query(database) |         query = self.session.query(database) | ||||||
|  |         if len(join) == 6: | ||||||
|  |             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: | ||||||
|             query = query.outerjoin(join[0], join[1]).outerjoin(join[2]) |             query = query.outerjoin(join[0], join[1]).outerjoin(join[2]) | ||||||
|         elif len(join) == 2: |         elif len(join) == 2: | ||||||
| @@ -755,6 +757,8 @@ class CalibreDB(): | |||||||
|         for authorterm in authorterms: |         for authorterm in authorterms: | ||||||
|             q.append(Books.authors.any(func.lower(Authors.name).ilike("%" + authorterm + "%"))) |             q.append(Books.authors.any(func.lower(Authors.name).ilike("%" + authorterm + "%"))) | ||||||
|         query = self.session.query(Books) |         query = self.session.query(Books) | ||||||
|  |         if len(join) == 6: | ||||||
|  |             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: | ||||||
|             query = query.outerjoin(join[0], join[1]).outerjoin(join[2]) |             query = query.outerjoin(join[0], join[1]).outerjoin(join[2]) | ||||||
|         elif len(join) == 2: |         elif len(join) == 2: | ||||||
|   | |||||||
							
								
								
									
										15
									
								
								cps/kobo.py
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								cps/kobo.py
									
									
									
									
									
								
							| @@ -44,11 +44,11 @@ from werkzeug.datastructures import Headers | |||||||
| from sqlalchemy import func | from sqlalchemy import func | ||||||
| from sqlalchemy.sql.expression import and_, or_ | from sqlalchemy.sql.expression import and_, or_ | ||||||
| from sqlalchemy.exc import StatementError | from sqlalchemy.exc import StatementError | ||||||
| from sqlalchemy import __version__ as sql_version |  | ||||||
| from sqlalchemy.sql import select | from sqlalchemy.sql import select | ||||||
| import requests | import requests | ||||||
|  |  | ||||||
| from . import config, logger, kobo_auth, db, calibre_db, helper, shelf as shelf_lib, ub | from . import config, logger, kobo_auth, db, calibre_db, helper, shelf as shelf_lib, ub | ||||||
|  | from .constants import sqlalchemy_version2 | ||||||
| from .helper import get_download_link | from .helper import get_download_link | ||||||
| from .services import SyncToken as SyncToken | from .services import SyncToken as SyncToken | ||||||
| from .web import download_required | from .web import download_required | ||||||
| @@ -66,7 +66,6 @@ kobo_auth.register_url_value_preprocessor(kobo) | |||||||
|  |  | ||||||
| log = logger.create() | log = logger.create() | ||||||
|  |  | ||||||
| sql2 = ([int(x) for x in sql_version.split('.')] >= [2,0,0]) |  | ||||||
|  |  | ||||||
| def get_store_url_for_current_request(): | def get_store_url_for_current_request(): | ||||||
|     # Programmatically modify the current url to point to the official Kobo store |     # Programmatically modify the current url to point to the official Kobo store | ||||||
| @@ -159,7 +158,7 @@ def HandleSyncRequest(): | |||||||
|     only_kobo_shelves = current_user.kobo_only_shelves_sync |     only_kobo_shelves = current_user.kobo_only_shelves_sync | ||||||
|  |  | ||||||
|     if only_kobo_shelves: |     if only_kobo_shelves: | ||||||
|         if sql2: |         if sqlalchemy_version2: | ||||||
|             changed_entries = select(db.Books, |             changed_entries = select(db.Books, | ||||||
|                                      ub.ArchivedBook.last_modified, |                                      ub.ArchivedBook.last_modified, | ||||||
|                                      ub.BookShelf.date_added, |                                      ub.BookShelf.date_added, | ||||||
| @@ -183,7 +182,7 @@ def HandleSyncRequest(): | |||||||
|                 .distinct() |                 .distinct() | ||||||
|         ) |         ) | ||||||
|     else: |     else: | ||||||
|         if sql2: |         if sqlalchemy_version2: | ||||||
|             changed_entries = select(db.Books, ub.ArchivedBook.last_modified, ub.ArchivedBook.is_archived) |             changed_entries = select(db.Books, ub.ArchivedBook.last_modified, ub.ArchivedBook.is_archived) | ||||||
|         else: |         else: | ||||||
|             changed_entries = calibre_db.session.query(db.Books, |             changed_entries = calibre_db.session.query(db.Books, | ||||||
| @@ -202,7 +201,7 @@ def HandleSyncRequest(): | |||||||
|         changed_entries = changed_entries.filter(db.Books.id > sync_token.books_last_id) |         changed_entries = changed_entries.filter(db.Books.id > sync_token.books_last_id) | ||||||
|  |  | ||||||
|     reading_states_in_new_entitlements = [] |     reading_states_in_new_entitlements = [] | ||||||
|     if sql2: |     if sqlalchemy_version2: | ||||||
|         books = calibre_db.session.execute(changed_entries.limit(SYNC_ITEM_LIMIT)) |         books = calibre_db.session.execute(changed_entries.limit(SYNC_ITEM_LIMIT)) | ||||||
|     else: |     else: | ||||||
|         books = changed_entries.limit(SYNC_ITEM_LIMIT) |         books = changed_entries.limit(SYNC_ITEM_LIMIT) | ||||||
| @@ -246,7 +245,7 @@ def HandleSyncRequest(): | |||||||
|  |  | ||||||
|         new_books_last_created = max(ts_created, new_books_last_created) |         new_books_last_created = max(ts_created, new_books_last_created) | ||||||
|  |  | ||||||
|     if sql2: |     if sqlalchemy_version2: | ||||||
|         max_change = calibre_db.session.execute(changed_entries |         max_change = calibre_db.session.execute(changed_entries | ||||||
|                                                 .filter(ub.ArchivedBook.is_archived) |                                                 .filter(ub.ArchivedBook.is_archived) | ||||||
|                                                 .order_by(func.datetime(ub.ArchivedBook.last_modified).desc()))\ |                                                 .order_by(func.datetime(ub.ArchivedBook.last_modified).desc()))\ | ||||||
| @@ -260,7 +259,7 @@ def HandleSyncRequest(): | |||||||
|     new_archived_last_modified = max(new_archived_last_modified, max_change) |     new_archived_last_modified = max(new_archived_last_modified, max_change) | ||||||
|  |  | ||||||
|     # no. of books returned |     # no. of books returned | ||||||
|     if sql2: |     if sqlalchemy_version2: | ||||||
|         entries = calibre_db.session.execute(changed_entries).all() |         entries = calibre_db.session.execute(changed_entries).all() | ||||||
|         book_count = len(entries) |         book_count = len(entries) | ||||||
|     else: |     else: | ||||||
| @@ -697,7 +696,7 @@ def sync_shelves(sync_token, sync_results, only_kobo_shelves=False): | |||||||
|             }) |             }) | ||||||
|         extra_filters.append(ub.Shelf.kobo_sync) |         extra_filters.append(ub.Shelf.kobo_sync) | ||||||
|  |  | ||||||
|     if sql2: |     if sqlalchemy_version2: | ||||||
|         shelflist = ub.session.execute(select(ub.Shelf).outerjoin(ub.BookShelf).filter( |         shelflist = ub.session.execute(select(ub.Shelf).outerjoin(ub.BookShelf).filter( | ||||||
|             or_(func.datetime(ub.Shelf.last_modified) > sync_token.tags_last_modified, |             or_(func.datetime(ub.Shelf.last_modified) > sync_token.tags_last_modified, | ||||||
|                 func.datetime(ub.BookShelf.date_added) > sync_token.tags_last_modified), |                 func.datetime(ub.BookShelf.date_added) > sync_token.tags_last_modified), | ||||||
|   | |||||||
							
								
								
									
										10
									
								
								cps/shelf.py
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								cps/shelf.py
									
									
									
									
									
								
							| @@ -380,7 +380,9 @@ def order_shelf(shelf_id): | |||||||
|  |  | ||||||
|  |  | ||||||
| def change_shelf_order(shelf_id, order): | def change_shelf_order(shelf_id, order): | ||||||
|     result = calibre_db.session.query(db.Books).join(ub.BookShelf, ub.BookShelf.book_id == db.Books.id) \ |     result = calibre_db.session.query(db.Books).outerjoin(db.books_series_link, | ||||||
|  |                                                           db.Books.id == db.books_series_link.c.book)\ | ||||||
|  |         .outerjoin(db.Series).join(ub.BookShelf, ub.BookShelf.book_id == db.Books.id) \ | ||||||
|         .filter(ub.BookShelf.shelf == shelf_id).order_by(*order).all() |         .filter(ub.BookShelf.shelf == shelf_id).order_by(*order).all() | ||||||
|     for index, entry in enumerate(result): |     for index, entry in enumerate(result): | ||||||
|         book = ub.session.query(ub.BookShelf).filter(ub.BookShelf.shelf == shelf_id) \ |         book = ub.session.query(ub.BookShelf).filter(ub.BookShelf.shelf == shelf_id) \ | ||||||
| @@ -410,9 +412,11 @@ def render_show_shelf(shelf_type, shelf_id, page_no, sort_param): | |||||||
|             if sort_param == 'old': |             if sort_param == 'old': | ||||||
|                 change_shelf_order(shelf_id, [db.Books.timestamp]) |                 change_shelf_order(shelf_id, [db.Books.timestamp]) | ||||||
|             if sort_param == 'authaz': |             if sort_param == 'authaz': | ||||||
|                 change_shelf_order(shelf_id, [db.Books.author_sort.asc()]) |                 change_shelf_order(shelf_id, [db.Books.author_sort.asc(), db.Series.name, db.Books.series_index]) | ||||||
|             if sort_param == 'authza': |             if sort_param == 'authza': | ||||||
|                 change_shelf_order(shelf_id, [db.Books.author_sort.desc()]) |                 change_shelf_order(shelf_id, [db.Books.author_sort.desc(), | ||||||
|  |                                               db.Series.name.desc(), | ||||||
|  |                                               db.Books.series_index.desc()]) | ||||||
|             page = "shelf.html" |             page = "shelf.html" | ||||||
|             pagesize = 0 |             pagesize = 0 | ||||||
|         else: |         else: | ||||||
|   | |||||||
							
								
								
									
										30
									
								
								cps/web.py
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								cps/web.py
									
									
									
									
									
								
							| @@ -360,9 +360,9 @@ def get_sort_function(sort, data): | |||||||
|     if sort == 'old': |     if sort == 'old': | ||||||
|         order = [db.Books.timestamp] |         order = [db.Books.timestamp] | ||||||
|     if sort == 'authaz': |     if sort == 'authaz': | ||||||
|         order = [db.Books.author_sort.asc()] |         order = [db.Books.author_sort.asc(), db.Series.name, db.Books.series_index] | ||||||
|     if sort == 'authza': |     if sort == 'authza': | ||||||
|         order = [db.Books.author_sort.desc()] |         order = [db.Books.author_sort.desc(), db.Series.name.desc(), db.Books.series_index.desc()] | ||||||
|     if sort == 'seriesasc': |     if sort == 'seriesasc': | ||||||
|         order = [db.Books.series_index.asc()] |         order = [db.Books.series_index.asc()] | ||||||
|     if sort == 'seriesdesc': |     if sort == 'seriesdesc': | ||||||
| @@ -410,7 +410,10 @@ def render_books_list(data, sort, book_id, page): | |||||||
|         return render_adv_search_results(term, offset, order, config.config_books_per_page) |         return render_adv_search_results(term, offset, order, config.config_books_per_page) | ||||||
|     else: |     else: | ||||||
|         website = data or "newest" |         website = data or "newest" | ||||||
|         entries, random, pagination = calibre_db.fill_indexpage(page, 0, db.Books, True, order) |         entries, random, pagination = calibre_db.fill_indexpage(page, 0, db.Books, True, order, | ||||||
|  |                                                                 db.books_series_link, | ||||||
|  |                                                                 db.Books.id == db.books_series_link.c.book, | ||||||
|  |                                                                 db.Series) | ||||||
|         return render_title_template('index.html', random=random, entries=entries, pagination=pagination, |         return render_title_template('index.html', random=random, entries=entries, pagination=pagination, | ||||||
|                                      title=_(u"Books"), page=website) |                                      title=_(u"Books"), page=website) | ||||||
|  |  | ||||||
| @@ -509,8 +512,10 @@ def render_author_books(page, author_id, order): | |||||||
|         flash(_(u"Oops! Selected book title is unavailable. File does not exist or is not accessible"), |         flash(_(u"Oops! Selected book title is unavailable. File does not exist or is not accessible"), | ||||||
|               category="error") |               category="error") | ||||||
|         return redirect(url_for("web.index")) |         return redirect(url_for("web.index")) | ||||||
|  |     if constants.sqlalchemy_version2: | ||||||
|     author = calibre_db.session.query(db.Authors).get(author_id) |         author = calibre_db.session.get(db.Authors, author_id) | ||||||
|  |     else: | ||||||
|  |         author = calibre_db.session.query(db.Authors).get(author_id) | ||||||
|     author_name = author.name.replace('|', ',') |     author_name = author.name.replace('|', ',') | ||||||
|  |  | ||||||
|     author_info = None |     author_info = None | ||||||
| @@ -713,7 +718,8 @@ 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): | ||||||
|     entries, result_count, pagination = calibre_db.get_search_results(term, offset, order, limit) |     join = db.books_series_link, db.Books.id == db.books_series_link.c.book, db.Series | ||||||
|  |     entries, result_count, pagination = calibre_db.get_search_results(term, offset, order, limit, *join) | ||||||
|     return render_title_template('search.html', |     return render_title_template('search.html', | ||||||
|                                  searchterm=term, |                                  searchterm=term, | ||||||
|                                  pagination=pagination, |                                  pagination=pagination, | ||||||
| @@ -775,8 +781,10 @@ def list_books(): | |||||||
|         order = [db.Publishers.name.asc()] if order == "asc" else [db.Publishers.name.desc()] |         order = [db.Publishers.name.asc()] if order == "asc" else [db.Publishers.name.desc()] | ||||||
|         join = db.books_publishers_link,db.Books.id == db.books_publishers_link.c.book, db.Publishers |         join = db.books_publishers_link,db.Books.id == db.books_publishers_link.c.book, db.Publishers | ||||||
|     elif sort == "authors": |     elif sort == "authors": | ||||||
|         order = [db.Authors.name.asc()] if order == "asc" else [db.Authors.name.desc()] |         order = [db.Authors.name.asc(), db.Series.name, db.Books.series_index] if order == "asc" \ | ||||||
|         join = db.books_authors_link,db.Books.id == db.books_authors_link.c.book, db.Authors |             else [db.Authors.name.desc(), db.Series.name.desc(), db.Books.series_index.desc()] | ||||||
|  |         join = db.books_authors_link, db.Books.id == db.books_authors_link.c.book, db.Authors, \ | ||||||
|  |                db.books_series_link, db.Books.id == db.books_series_link.c.book, db.Series | ||||||
|     elif sort == "languages": |     elif sort == "languages": | ||||||
|         order = [db.Languages.lang_code.asc()] if order == "asc" else [db.Languages.lang_code.desc()] |         order = [db.Languages.lang_code.asc()] if order == "asc" else [db.Languages.lang_code.desc()] | ||||||
|         join = db.books_languages_link,db.Books.id == db.books_languages_link.c.book, db.Languages |         join = db.books_languages_link,db.Books.id == db.books_languages_link.c.book, db.Languages | ||||||
| @@ -793,7 +801,7 @@ def list_books(): | |||||||
|             filtered_count = len(books) |             filtered_count = len(books) | ||||||
|         else: |         else: | ||||||
|             books = calibre_db.session.query(db.Books).filter(calibre_db.common_filters()).all() |             books = calibre_db.session.query(db.Books).filter(calibre_db.common_filters()).all() | ||||||
|         entries = calibre_db.get_checkbox_sorted(books, state, off, limit,order) |         entries = calibre_db.get_checkbox_sorted(books, state, off, limit, order) | ||||||
|     elif search: |     elif search: | ||||||
|         entries, filtered_count, __ = calibre_db.get_search_results(search, off, order, limit, *join) |         entries, filtered_count, __ = calibre_db.get_search_results(search, off, order, limit, *join) | ||||||
|     else: |     else: | ||||||
| @@ -1242,7 +1250,9 @@ def render_adv_search_results(term, offset=None, order=None, limit=None): | |||||||
|  |  | ||||||
|     cc = get_cc_columns(filter_config_custom_read=True) |     cc = get_cc_columns(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) | ||||||
|     q = calibre_db.session.query(db.Books).filter(calibre_db.common_filters(True)) |     q = calibre_db.session.query(db.Books).outerjoin(db.books_series_link, db.Books.id == db.books_series_link.c.book)\ | ||||||
|  |         .outerjoin(db.Series)\ | ||||||
|  |         .filter(calibre_db.common_filters(True)) | ||||||
|  |  | ||||||
|     # parse multiselects to a complete dict |     # parse multiselects to a complete dict | ||||||
|     tags = dict() |     tags = dict() | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Ozzie Isaacs
					Ozzie Isaacs