From cd9bb56db5a59bcb02f2bae72e9512c64eb1c988 Mon Sep 17 00:00:00 2001 From: Ozzieisaacs Date: Mon, 20 Jan 2020 06:14:53 +0100 Subject: [PATCH] Cleanup Kobo integration --- cps/about.py | 1 - cps/admin.py | 22 ---------------------- cps/config_sql.py | 2 -- cps/constants.py | 1 - cps/kobo.py | 16 +++++++++------- cps/services/SyncToken.py | 2 +- cps/templates/config_edit.html | 4 ---- cps/templates/user_edit.html | 4 ---- cps/ub.py | 2 +- cps/web.py | 12 ++---------- 10 files changed, 13 insertions(+), 53 deletions(-) diff --git a/cps/about.py b/cps/about.py index ceef7308..edbdb6ab 100644 --- a/cps/about.py +++ b/cps/about.py @@ -68,7 +68,6 @@ _VERSIONS = OrderedDict( Flask_SimpleLDAP = u'installed' if bool(services.ldap) else u'not installed', Goodreads = u'installed' if bool(services.goodreads_support) else u'not installed', jsonschema = services.SyncToken.__version__ if bool(services.SyncToken) else u'not installed', - ) _VERSIONS.update(uploader.get_versions()) diff --git a/cps/admin.py b/cps/admin.py index 91ebe997..ab3d0f22 100644 --- a/cps/admin.py +++ b/cps/admin.py @@ -64,7 +64,6 @@ except ImportError: oauth_check = {} - feature_support['gdrive'] = gdrive_support admi = Blueprint('admin', __name__) log = logger.create() @@ -491,7 +490,6 @@ def _configuration_update_helper(): db_change = False to_save = request.form.to_dict() - # _config_dict = lambda x: config.set_from_dictionary(to_save, x, lambda y: y['id']) _config_string = lambda x: config.set_from_dictionary(to_save, x, lambda y: y.strip() if y else y) _config_int = lambda x: config.set_from_dictionary(to_save, x, int) _config_checkbox = lambda x: config.set_from_dictionary(to_save, x, lambda y: y == "on", False) @@ -531,8 +529,6 @@ def _configuration_update_helper(): if config.config_certfile and not os.path.isfile(config.config_certfile): return _configuration_result('Certfile location is not valid, please enter correct path', gdriveError) - _config_string("config_server_url") - _config_checkbox_int("config_uploading") _config_checkbox_int("config_anonbrowse") _config_checkbox_int("config_public_reg") @@ -845,24 +841,6 @@ def edit_user(user_id): content.default_language = to_save["default_language"] if "locale" in to_save and to_save["locale"]: content.locale = to_save["locale"] - - if "kobo_user_key" in to_save and to_save["kobo_user_key"]: - kobo_user_key_hash = generate_password_hash(to_save["kobo_user_key"]) - if kobo_user_key_hash != content.kobo_user_key_hash: - existing_kobo_user_key = ub.session.query(ub.User).filter(ub.User.kobo_user_key_hash == kobo_user_key_hash).first() - if not existing_kobo_user_key: - content.kobo_user_key_hash = kobo_user_key_hash - else: - flash(_(u"Found an existing account for this Kobo UserKey."), category="error") - return render_title_template("user_edit.html", - translations=translations, - languages=languages, - new_user=0, - content=content, - downloads=downloads, - registered_oauth=oauth_check, - feature_support=feature_support, - title=_(u"Edit User %(nick)s", nick=content.nickname), page="edituser") if to_save["email"] and to_save["email"] != content.email: existing_email = ub.session.query(ub.User).filter(ub.User.email == to_save["email"].lower()) \ .first() diff --git a/cps/config_sql.py b/cps/config_sql.py index 86279331..a00b4217 100644 --- a/cps/config_sql.py +++ b/cps/config_sql.py @@ -49,7 +49,6 @@ class _Settings(_Base): config_port = Column(Integer, default=constants.DEFAULT_PORT) config_certfile = Column(String) config_keyfile = Column(String) - config_server_url = Column(String, default='') config_calibre_web_title = Column(String, default=u'Calibre-Web') config_books_per_page = Column(Integer, default=60) @@ -313,7 +312,6 @@ def _migrate_table(session, orm_class): if changed: session.commit() - session.query def autodetect_calibre_binary(): if sys.platform == "win32": diff --git a/cps/constants.py b/cps/constants.py index 7630b38f..a78c31b3 100644 --- a/cps/constants.py +++ b/cps/constants.py @@ -106,7 +106,6 @@ except ValueError: del env_CALIBRE_PORT - EXTENSIONS_AUDIO = {'mp3', 'm4a', 'm4b'} EXTENSIONS_CONVERT = {'pdf', 'epub', 'mobi', 'azw3', 'docx', 'rtf', 'fb2', 'lit', 'lrf', 'txt', 'htmlz', 'rtf', 'odt'} EXTENSIONS_UPLOAD = {'txt', 'pdf', 'epub', 'mobi', 'azw', 'azw3', 'cbr', 'cbz', 'cbt', 'djvu', 'prc', 'doc', 'docx', diff --git a/cps/kobo.py b/cps/kobo.py index 73536551..7e1cbc8e 100644 --- a/cps/kobo.py +++ b/cps/kobo.py @@ -40,7 +40,8 @@ from werkzeug.datastructures import Headers from sqlalchemy import func import requests -from . import config, logger, kobo_auth, db, helper, services +from . import config, logger, kobo_auth, db, helper +from .services import SyncToken as SyncToken from .web import download_required KOBO_FORMATS = {"KEPUB": ["KEPUB"], "EPUB": ["EPUB", "EPUB3"]} @@ -72,6 +73,8 @@ CONNECTION_SPECIFIC_HEADERS = [ def redirect_or_proxy_request(): if request.method == "GET": return redirect(get_store_url_for_current_request(), 307) + if request.method == "DELETE": + return make_response(jsonify({})) else: # The Kobo device turns other request types into GET requests on redirects, so we instead proxy to the Kobo store ourselves. outgoing_headers = Headers(request.headers) @@ -97,7 +100,7 @@ def redirect_or_proxy_request(): @login_required @download_required def HandleSyncRequest(): - sync_token = services.SyncToken.from_headers(request.headers) + sync_token = SyncToken.SyncToken.from_headers(request.headers) log.info("Kobo library sync request received.") # TODO: Limit the number of books return per sync call, and rely on the sync-continuatation header @@ -117,7 +120,7 @@ def HandleSyncRequest(): changed_entries = ( db.session.query(db.Books) .join(db.Data) - .filter(func.datetime(db.Books.last_modified) > sync_token.books_last_modified) + .filter(func.datetime(db.Books.last_modified) != sync_token.books_last_modified) .filter(db.Data.format.in_(KOBO_FORMATS)) .all() ) @@ -322,11 +325,10 @@ def reading_state(book): return reading_state -@kobo.route( - "//image.jpg" -) +@kobo.route("//image.jpg") @login_required def HandleCoverImageRequest(book_uuid): + log.debug("Cover request received for book %s" % book_uuid) book_cover = helper.get_book_cover_with_uuid( book_uuid, use_generic_cover_on_failure=False ) @@ -346,7 +348,7 @@ def TopLevelEndpoint(): @kobo.route("/v1/library/tags", methods=["POST"]) @kobo.route("/v1/library/tags/", methods=["POST"]) @kobo.route("/v1/library/tags/", methods=["DELETE"]) -def HandleUnimplementedRequest(book_uuid=None, shelf_name=None, tag_id=None): +def HandleUnimplementedRequest(dummy=None, book_uuid=None, shelf_name=None, tag_id=None): return redirect_or_proxy_request() diff --git a/cps/services/SyncToken.py b/cps/services/SyncToken.py index 2a17f7b5..21f16acc 100644 --- a/cps/services/SyncToken.py +++ b/cps/services/SyncToken.py @@ -42,7 +42,7 @@ def to_epoch_timestamp(datetime_object): return (datetime_object - datetime(1970, 1, 1)).total_seconds() -class SyncToken: +class SyncToken(): """ The SyncToken is used to persist state accross requests. When serialized over the response headers, the Kobo device will propagate the token onto following requests to the service. As an example use-case, the SyncToken is used to detect books that have been added to the library since the last time the device synced to the server. diff --git a/cps/templates/config_edit.html b/cps/templates/config_edit.html index 2ae56a38..b0ad49f7 100644 --- a/cps/templates/config_edit.html +++ b/cps/templates/config_edit.html @@ -104,10 +104,6 @@ -
- - -
diff --git a/cps/templates/user_edit.html b/cps/templates/user_edit.html index a044f270..9ef11979 100644 --- a/cps/templates/user_edit.html +++ b/cps/templates/user_edit.html @@ -27,10 +27,6 @@
-
- - -