diff --git a/cps/db.py b/cps/db.py index b9853896..1ef06427 100755 --- a/cps/db.py +++ b/cps/db.py @@ -33,7 +33,7 @@ from sqlalchemy.ext.declarative import declarative_base session = None cc_exceptions = ['datetime', 'comments', 'float', 'composite', 'series'] cc_classes = {} - +engine = None Base = declarative_base() @@ -288,7 +288,7 @@ class Books(Base): @property def atom_timestamp(self): - return (self.timestamp or '').replace(' ', 'T') + return (self.timestamp.strftime('%Y-%m-%dT%H:%M:%S+00:00') or '') class Custom_Columns(Base): __tablename__ = 'custom_columns' @@ -327,6 +327,7 @@ def update_title_sort(config, conn=None): def setup_db(config): dispose() + global engine if not config.config_calibre_dir: config.invalidate() @@ -428,3 +429,8 @@ def dispose(): if name.startswith("custom_column_") or name.startswith("books_custom_column_"): if table is not None: Base.metadata.remove(table) + +def reconnect_db(config): + session.close() + engine.dispose() + setup_db(config) diff --git a/cps/opds.py b/cps/opds.py index f5cc4673..3ff718da 100644 --- a/cps/opds.py +++ b/cps/opds.py @@ -276,7 +276,7 @@ def feed_languages(book_id): isoLanguages.get(part3=entry.languages[index].lang_code).name)''' return render_xml_template('feed.xml', entries=entries, pagination=pagination) -@opds.route("/opds/shelfindex/", defaults={'public': 0}) +@opds.route("/opds/shelfindex", defaults={'public': 0}) @opds.route("/opds/shelfindex/") @requires_basic_auth_if_no_ano def feed_shelfindex(public): @@ -378,15 +378,16 @@ def render_xml_template(*args, **kwargs): def feed_get_cover(book_id): return get_book_cover(book_id) -@opds.route("/opds/readbooks/") +@opds.route("/opds/readbooks") @requires_basic_auth_if_no_ano def feed_read_books(): off = request.args.get("offset") or 0 - return render_read_books(int(off) / (int(config.config_books_per_page)) + 1, True, True) + result, pagination = render_read_books(int(off) / (int(config.config_books_per_page)) + 1, True, True) + return render_xml_template('feed.xml', entries=result, pagination=pagination) - -@opds.route("/opds/unreadbooks/") +@opds.route("/opds/unreadbooks") @requires_basic_auth_if_no_ano def feed_unread_books(): off = request.args.get("offset") or 0 - return render_read_books(int(off) / (int(config.config_books_per_page)) + 1, False, True) + result, pagination = render_read_books(int(off) / (int(config.config_books_per_page)) + 1, False, True) + return render_xml_template('feed.xml', entries=result, pagination=pagination) diff --git a/cps/web.py b/cps/web.py index 572ac969..7e91e5f9 100644 --- a/cps/web.py +++ b/cps/web.py @@ -43,7 +43,7 @@ from werkzeug.exceptions import default_exceptions from werkzeug.datastructures import Headers from werkzeug.security import generate_password_hash, check_password_hash -from . import constants, logger, isoLanguages, services, worker +from . import constants, config, logger, isoLanguages, services, worker from . import searched_ids, lm, babel, db, ub, config, get_locale, app from .gdriveutils import getFileFromEbooksFolder, do_gdrive_download from .helper import common_filters, get_search_results, fill_indexpage, speaking_language, check_valid_domain, \ @@ -93,12 +93,11 @@ def error_http(error): def internal_error(error): - __, __, tb = sys.exc_info() return render_template('http_error.html', error_code="Internal Server Error", error_name=str(error), issue=True, - error_stack=traceback.format_tb(tb), + error_stack=traceback.format_exc().split("\n"), instance=config.config_calibre_web_title ), 500 @@ -791,9 +790,7 @@ def get_tasks_status(): @app.route("/reconnect") def reconnect(): - db.session.close() - db.engine.dispose() - db.setup_db() + db.reconnect_db(config) return json.dumps({}) @web.route("/search", methods=["GET"]) @@ -985,10 +982,7 @@ def render_read_books(page, are_read, as_xml=False, order=None): entries, random, pagination = fill_indexpage(page, db.Books, db_filter, order) if as_xml: - xml = render_title_template('feed.xml', entries=entries, pagination=pagination) - response = make_response(xml) - response.headers["Content-Type"] = "application/xml; charset=utf-8" - return response + return entries, pagination else: if are_read: name = _(u'Read Books') + ' (' + str(len(readBookIds)) + ')' diff --git a/cps/worker.py b/cps/worker.py index b508c437..409201c7 100644 --- a/cps/worker.py +++ b/cps/worker.py @@ -231,7 +231,7 @@ class WorkerThread(threading.Thread): self.queue.pop(index) self.UIqueue.pop(index) # if we are deleting entries before the current index, adjust the index - if index <= self.current and index: + if index <= self.current and self.current: self.current -= 1 self.last = len(self.queue) diff --git a/test/Calibre-Web TestSummary.html b/test/Calibre-Web TestSummary.html index 6963d268..a0116a33 100644 --- a/test/Calibre-Web TestSummary.html +++ b/test/Calibre-Web TestSummary.html @@ -30,15 +30,15 @@
-

Start Time: 2019-07-09 18:14:27.709466

+

Start Time: 2019-12-24 11:33:41.346894

-

Stop Time: 2019-07-09 19:21:03.774799

+

Stop Time: 2019-12-24 12:34:15.226846

-

Duration: 1:06:36.065333

+

Duration: 1:00:33.879952

@@ -96,7 +96,7 @@ View - test_opds_feed.test_opds_feed + test_opds_feed.test_opds_feed_Python27 16 2 0 @@ -441,42 +441,25 @@ - test_register.test_register - 4 + test_opds_feed.test_opds_feed_Python36 + 16 + 2 0 0 - 0 - 4 + 14 - Detail + Detail - + -
test_login_with_password
- - -
- SKIP -
- - - +
test_opds
+ PASS -
test_registering_user
+
test_opds_author
@@ -499,7 +482,7 @@ -
test_registering_user_fail
+
test_opds_calibre_companion
@@ -522,7 +505,7 @@ -
test_resend_password
+
test_opds_cover
@@ -543,6 +526,471 @@ + + +
test_opds_download_book
+ + +
+ SKIP +
+ + + + + + + +
test_opds_guest_user
+ + PASS + + + +
test_opds_hot
+ + +
+ SKIP +
+ + + + + + + +
test_opds_language
+ + +
+ SKIP +
+ + + + + + + +
test_opds_non_admin
+ + +
+ SKIP +
+ + + + + + + +
test_opds_paging
+ + +
+ SKIP +
+ + + + + + + +
test_opds_publisher
+ + +
+ SKIP +
+ + + + + + + +
test_opds_random
+ + +
+ SKIP +
+ + + + + + + +
test_opds_read_unread
+ + +
+ SKIP +
+ + + + + + + +
test_opds_search
+ + +
+ SKIP +
+ + + + + + + +
test_opds_series
+ + +
+ SKIP +
+ + + + + + + +
test_opds_shelf_access
+ + +
+ SKIP +
+ + + + + + + test_register.test_register_Python27 + 4 + 0 + 0 + 0 + 4 + + Detail + + + + +
test_login_with_password
+ + +
+ SKIP +
+ + + + + + + +
test_registering_user
+ + +
+ SKIP +
+ + + + + + + +
test_registering_user_fail
+ + +
+ SKIP +
+ + + + + + + +
test_resend_password
+ + +
+ SKIP +
+ + + + + + + test_register.test_register_Python36 + 4 + 0 + 0 + 0 + 4 + + Detail + + + + +
test_login_with_password
+ + +
+ SKIP +
+ + + + + + + +
test_registering_user
+ + +
+ SKIP +
+ + + + + + + +
test_registering_user_fail
+ + +
+ SKIP +
+ + + + + + + +
test_resend_password
+ + +
+ SKIP +
+ + + + + test_email_ssl.test_SSL_Python27 4 @@ -551,84 +999,84 @@ 0 0 - Detail + Detail - +
test_SSL_None_setup_error
- PASS + PASS
-