diff --git a/cps/admin.py b/cps/admin.py index 5d8ed9c1..fedee340 100644 --- a/cps/admin.py +++ b/cps/admin.py @@ -863,10 +863,10 @@ def delete_restriction(res_type, user_id): usr = current_user if element['id'].startswith('a'): usr.allowed_tags = restriction_deletion(element, usr.list_allowed_tags) - ub.session_commit("Deleted allowed tags of user {}: {}".format(usr.name, usr.list_allowed_tags)) + ub.session_commit("Deleted allowed tags of user {}: {}".format(usr.name, element['Element'])) elif element['id'].startswith('d'): usr.denied_tags = restriction_deletion(element, usr.list_denied_tags) - ub.session_commit("Deleted denied tags of user {}: {}".format(usr.name, usr.list_allowed_tags)) + ub.session_commit("Deleted denied tag of user {}: {}".format(usr.name, element['Element'])) elif res_type == 3: # Columns per user if isinstance(user_id, int): usr = ub.session.query(ub.User).filter(ub.User.id == int(user_id)).first() @@ -875,12 +875,12 @@ def delete_restriction(res_type, user_id): if element['id'].startswith('a'): usr.allowed_column_value = restriction_deletion(element, usr.list_allowed_column_values) ub.session_commit("Deleted allowed columns of user {}: {}".format(usr.name, - usr.list_allowed_column_values)) + usr.list_allowed_column_values())) elif element['id'].startswith('d'): usr.denied_column_value = restriction_deletion(element, usr.list_denied_column_values) ub.session_commit("Deleted denied columns of user {}: {}".format(usr.name, - usr.list_denied_column_values)) + usr.list_denied_column_values())) return "" diff --git a/cps/opds.py b/cps/opds.py index c0637c6b..c8ccdea9 100644 --- a/cps/opds.py +++ b/cps/opds.py @@ -26,7 +26,7 @@ from functools import wraps from flask import Blueprint, request, render_template, Response, g, make_response, abort from flask_login import current_user -from sqlalchemy.sql.expression import func, text, or_, and_, true +from sqlalchemy.sql.expression import func, text, or_, and_, any_, true from werkzeug.security import check_password_hash from . import constants, logger, config, db, calibre_db, ub, services, get_locale, isoLanguages from .helper import get_download_link, get_book_cover @@ -34,7 +34,7 @@ from .pagination import Pagination from .web import render_read_books from .usermanagement import load_user_from_request from flask_babel import gettext as _ - +from sqlalchemy.orm import InstrumentedAttribute opds = Blueprint('opds', __name__) log = logger.create() @@ -298,7 +298,7 @@ def feed_ratingindex(): @opds.route("/opds/ratings/") @requires_basic_auth_if_no_ano def feed_ratings(book_id): - return render_xml_dataset(db.Tags, book_id) + return render_xml_dataset(db.Ratings, book_id) @opds.route("/opds/formats") @@ -493,7 +493,7 @@ def render_xml_dataset(data_table, book_id): off = request.args.get("offset") or 0 entries, __, pagination = calibre_db.fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1), 0, db.Books, - data_table.any(data_table.id == book_id), + getattr(db.Books, data_table.__tablename__).any(data_table.id == book_id), [db.Books.timestamp.desc()]) return render_xml_template('feed.xml', entries=entries, pagination=pagination) @@ -502,7 +502,7 @@ def render_element_index(database_column, linked_table, folder): shift = 0 off = int(request.args.get("offset") or 0) entries = calibre_db.session.query(func.upper(func.substr(database_column, 1, 1)).label('id')) - if linked_table: + if linked_table is not None: entries = entries.join(linked_table).join(db.Books) entries = entries.filter(calibre_db.common_filters()).group_by(func.upper(func.substr(database_column, 1, 1))).all() elements = [] diff --git a/cps/web.py b/cps/web.py index 6f2f1af1..b1f27035 100644 --- a/cps/web.py +++ b/cps/web.py @@ -1129,27 +1129,6 @@ def adv_search_custom_columns(cc, term, q): return q -def adv_search_language(q, include_languages_inputs, exclude_languages_inputs): - if current_user.filter_language() != "all": - q = q.filter(db.Books.languages.any(db.Languages.lang_code == current_user.filter_language())) - else: - for language in include_languages_inputs: - q = q.filter(db.Books.languages.any(db.Languages.id == language)) - for language in exclude_languages_inputs: - q = q.filter(not_(db.Books.series.any(db.Languages.id == language))) - return q - - -def adv_search_ratings(q, rating_high, rating_low): - if rating_high: - rating_high = int(rating_high) * 2 - q = q.filter(db.Books.ratings.any(db.Ratings.rating <= rating_high)) - if rating_low: - rating_low = int(rating_low) * 2 - q = q.filter(db.Books.ratings.any(db.Ratings.rating >= rating_low)) - return q - - def adv_search_read_status(q, read_status): if read_status: if config.config_read_column: @@ -1178,38 +1157,32 @@ def adv_search_read_status(q, read_status): return q -def adv_search_text(q, include_inputs, exclude_inputs, data_value): +def adv_search_language(q, include_languages_inputs, exclude_languages_inputs): + if current_user.filter_language() != "all": + q = q.filter(db.Books.languages.any(db.Languages.lang_code == current_user.filter_language())) + else: + return adv_search_text(q, include_languages_inputs, exclude_languages_inputs, db.Languages.id) + return q + + +def adv_search_ratings(q, rating_high, rating_low): + if rating_high: + rating_high = int(rating_high) * 2 + q = q.filter(db.Books.ratings.any(db.Ratings.rating <= rating_high)) + if rating_low: + rating_low = int(rating_low) * 2 + q = q.filter(db.Books.ratings.any(db.Ratings.rating >= rating_low)) + return q + + +def adv_search_text(q, include_inputs, exclude_inputs, data_table): for inp in include_inputs: - q = q.filter(db.Books.data.any(data_value == inp)) + q = q.filter(getattr(db.Books, data_table.class_.__tablename__).any(data_table == inp)) for excl in exclude_inputs: - q = q.filter(not_(db.Books.data.any(data_value == excl))) + q = q.filter(not_(getattr(db.Books, data_table.class_.__tablename__).any(data_table == excl))) return q -'''def adv_search_extension(q, include_extension_inputs, exclude_extension_inputs): - for extension in include_extension_inputs: - q = q.filter(db.Books.data.any(db.Data.format == extension)) - for extension in exclude_extension_inputs: - q = q.filter(not_(db.Books.data.any(db.Data.format == extension))) - return q - - -def adv_search_tag(q, include_tag_inputs, exclude_tag_inputs): - for tag in include_tag_inputs: - q = q.filter(db.Books.tags.any(db.Tags.id == tag)) - for tag in exclude_tag_inputs: - q = q.filter(not_(db.Books.tags.any(db.Tags.id == tag))) - return q - - -def adv_search_serie(q, include_series_inputs, exclude_series_inputs): - for serie in include_series_inputs: - q = q.filter(db.Books.series.any(db.Series.id == serie)) - for serie in exclude_series_inputs: - q = q.filter(not_(db.Books.series.any(db.Series.id == serie))) - return q''' - - def adv_search_shelf(q, include_shelf_inputs, exclude_shelf_inputs): q = q.outerjoin(ub.BookShelf, db.Books.id == ub.BookShelf.book_id) \ .filter(or_(ub.BookShelf.shelf == None, ub.BookShelf.shelf.notin_(exclude_shelf_inputs))) @@ -1376,7 +1349,7 @@ def render_adv_search_results(term, offset=None, order=None, limit=None): q = adv_search_text(q, tags['include_serie'], tags['exclude_serie'], db.Series.id) q = adv_search_text(q, tags['include_extension'], tags['exclude_extension'], db.Data.format) q = adv_search_shelf(q, tags['include_shelf'], tags['exclude_shelf']) - q = adv_search_language(q, tags['include_language'], tags['exclude_language'], ) + q = adv_search_language(q, tags['include_language'], tags['exclude_language']) q = adv_search_ratings(q, rating_high, rating_low, ) if description: diff --git a/test/Calibre-Web TestSummary_Linux.html b/test/Calibre-Web TestSummary_Linux.html index 580cf3c9..b2de4c81 100644 --- a/test/Calibre-Web TestSummary_Linux.html +++ b/test/Calibre-Web TestSummary_Linux.html @@ -37,20 +37,20 @@
-

Start Time: 2022-03-12 22:57:13

+

Start Time: 2022-03-13 21:32:38

-

Stop Time: 2022-03-13 03:46:17

+

Stop Time: 2022-03-14 02:20:13

-

Duration: 4h 0 min

+

Duration: 3h 59 min

@@ -363,11 +363,11 @@ - + TestCoverEditBooks 2 - 2 - 0 + 1 + 1 0 0 @@ -386,11 +386,31 @@ - +
TestCoverEditBooks - test_upload_jpg
- PASS + +
+ FAIL +
+ + + + @@ -681,11 +701,11 @@ - + TestEbookConvertGDriveKepubify 3 - 3 - 0 + 2 + 1 0 0 @@ -704,11 +724,33 @@ - +
TestEbookConvertGDriveKepubify - test_convert_only
- PASS + +
+ FAIL +
+ + + + @@ -1586,12 +1628,12 @@ - + TestEditBooksOnGdrive 20 - 17 + 16 3 - 0 + 1 0 Detail @@ -1609,11 +1651,41 @@ - +
TestEditBooksOnGdrive - test_edit_author
- PASS + +
+ ERROR +
+ + + + @@ -1761,7 +1833,7 @@
Traceback (most recent call last):
-  File "/home/ozzie/Development/calibre-web-test/test/test_edit_ebooks_gdrive.py", line 865, in test_upload_book_epub
+  File "/home/ozzie/Development/calibre-web-test/test/test_edit_ebooks_gdrive.py", line 868, in test_upload_book_epub
     self.assertEqual('8936', resp.headers['Content-Length'])
 AssertionError: '8936' != '1103'
 - 8936
@@ -1801,7 +1873,7 @@ AssertionError: '8936' != '1103'
                     
Traceback (most recent call last):
-  File "/home/ozzie/Development/calibre-web-test/test/test_edit_ebooks_gdrive.py", line 778, in test_upload_cover_hdd
+  File "/home/ozzie/Development/calibre-web-test/test/test_edit_ebooks_gdrive.py", line 781, in test_upload_cover_hdd
     self.assertGreater(diff('original.png', 'jpeg.png', delete_diff_file=True), 0.02)
 AssertionError: 0.0 not greater than 0.02
@@ -1830,9 +1902,9 @@ AssertionError: 0.0 not greater than 0.02
Traceback (most recent call last):
-  File "/home/ozzie/Development/calibre-web-test/test/test_edit_ebooks_gdrive.py", line 947, in test_watch_metadata
+  File "/home/ozzie/Development/calibre-web-test/test/test_edit_ebooks_gdrive.py", line 950, in test_watch_metadata
     self.assertNotIn('series', book)
-AssertionError: 'series' unexpectedly found in {'id': 5, 'reader': [], 'title': 'testbook', 'author': ['John Döe'], 'rating': 0, 'languages': ['English'], 'identifier': [], 'cover': '/cover/5?edit=4a23d5c4-e97a-42e1-bd43-351fb1de43df', 'tag': [], 'publisher': ['Randomhäus'], 'pubdate': 'Jan 19, 2017', 'comment': 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Aenean commodo ligula eget dolor.Aenean massa.Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem.Nulla consequat massa quis enim.Donec pede justo, fringilla vel, aliquet nec, vulputate', 'add_shelf': [], 'del_shelf': [], 'edit_enable': True, 'kindle': None, 'kindlebtn': None, 'download': ['EPUB (6.7 kB)'], 'read': False, 'archived': False, 'series_all': 'Book 1 of test', 'series_index': '1', 'series': 'test', 'cust_columns': []}
+AssertionError: 'series' unexpectedly found in {'id': 5, 'reader': [], 'title': 'testbook', 'author': ['John Döe'], 'rating': 0, 'languages': ['English'], 'identifier': [], 'cover': '/cover/5?edit=f66a16a8-b9e1-446d-b1ad-21b11df67753', 'tag': [], 'publisher': ['Randomhäus'], 'pubdate': 'Jan 19, 2017', 'comment': 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Aenean commodo ligula eget dolor.Aenean massa.Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem.Nulla consequat massa quis enim.Donec pede justo, fringilla vel, aliquet nec, vulputate', 'add_shelf': [], 'del_shelf': [], 'edit_enable': True, 'kindle': None, 'kindlebtn': None, 'download': ['EPUB (6.7 kB)'], 'read': False, 'archived': False, 'series_all': 'Book 1 of test', 'series_index': '1', 'series': 'test', 'cust_columns': []}
@@ -2891,12 +2963,12 @@ AssertionError: 'series' unexpectedly found in {'id': 5, 're - + TestOPDSFeed 23 - 23 - 0 - 0 + 14 + 4 + 5 0 Detail @@ -2905,20 +2977,62 @@ AssertionError: 'series' unexpectedly found in {'id': 5, 're - +
TestOPDSFeed - test_opds
- PASS + +
+ FAIL +
+ + + + - +
TestOPDSFeed - test_opds_author
- PASS + +
+ ERROR +
+ + + + @@ -2977,11 +3091,31 @@ AssertionError: 'series' unexpectedly found in {'id': 5, 're - +
TestOPDSFeed - test_opds_guest_user
- PASS + +
+ FAIL +
+ + + + @@ -3004,20 +3138,62 @@ AssertionError: 'series' unexpectedly found in {'id': 5, 're - +
TestOPDSFeed - test_opds_non_admin
- PASS + +
+ FAIL +
+ + + + - +
TestOPDSFeed - test_opds_publisher
- PASS + +
+ ERROR +
+ + + + @@ -3031,11 +3207,33 @@ AssertionError: 'series' unexpectedly found in {'id': 5, 're - +
TestOPDSFeed - test_opds_ratings
- PASS + +
+ ERROR +
+ + + + @@ -3049,20 +3247,62 @@ AssertionError: 'series' unexpectedly found in {'id': 5, 're - +
TestOPDSFeed - test_opds_search
- PASS + +
+ FAIL +
+ + + + - +
TestOPDSFeed - test_opds_series
- PASS + +
+ ERROR +
+ + + + @@ -3076,11 +3316,33 @@ AssertionError: 'series' unexpectedly found in {'id': 5, 're - +
TestOPDSFeed - test_opds_tags
- PASS + +
+ ERROR +
+ + + + @@ -3113,12 +3375,12 @@ AssertionError: 'series' unexpectedly found in {'id': 5, 're - - TestUploadPDF - 1 + + _ErrorHolder 1 0 0 + 1 0 Detail @@ -3127,144 +3389,34 @@ AssertionError: 'series' unexpectedly found in {'id': 5, 're - + -
TestUploadPDF - test_upload_invalid_pdf
- - PASS - - - - - - - TestReader - 5 - 4 - 1 - 0 - 0 - - Detail - - - - - - - -
TestReader - test_comic_reader
- - PASS - - - - - - -
TestReader - test_epub_reader
- - PASS - - - - - - -
TestReader - test_pdf_reader
- - PASS - - - - - - -
TestReader - test_sound_listener
+
tearDownClass (test_opds_feed)
- FAIL + ERROR
-