Books are removed from synced books upon archiving (from kobo or calibre-web side)
unicode texts (title, author) are showing up right on kobo reader Added some missing kobo routes (prevents 404 response) Added a lot of debug output on kobo sync requests
This commit is contained in:
parent
87e526642c
commit
7640ac1b3b
2 changed files with 27 additions and 13 deletions
37
cps/kobo.py
37
cps/kobo.py
|
@ -22,6 +22,7 @@ import datetime
|
|||
import os
|
||||
import uuid
|
||||
from time import gmtime, strftime
|
||||
import json
|
||||
|
||||
try:
|
||||
from urllib import unquote
|
||||
|
@ -102,6 +103,8 @@ def make_request_to_kobo_store(sync_token=None):
|
|||
allow_redirects=False,
|
||||
timeout=(2, 10)
|
||||
)
|
||||
log.debug("Content: " + str(store_response.content))
|
||||
log.debug("StatusCode: " + str(store_response.status_code))
|
||||
return store_response
|
||||
|
||||
|
||||
|
@ -110,7 +113,8 @@ def redirect_or_proxy_request():
|
|||
if request.method == "GET":
|
||||
return redirect(get_store_url_for_current_request(), 307)
|
||||
else:
|
||||
# The Kobo device turns other request types into GET requests on redirects, so we instead proxy to the Kobo store ourselves.
|
||||
# The Kobo device turns other request types into GET requests on redirects,
|
||||
# so we instead proxy to the Kobo store ourselves.
|
||||
store_response = make_request_to_kobo_store()
|
||||
|
||||
response_headers = store_response.headers
|
||||
|
@ -205,8 +209,8 @@ def HandleSyncRequest():
|
|||
books = calibre_db.session.execute(changed_entries.limit(SYNC_ITEM_LIMIT))
|
||||
else:
|
||||
books = changed_entries.limit(SYNC_ITEM_LIMIT)
|
||||
log.debug("Books to Sync: {}".format(books.count()))
|
||||
for book in books:
|
||||
kobo_sync_status.add_synced_books(book.Books.id)
|
||||
formats = [data.format for data in book.Books.data]
|
||||
if not 'KEPUB' in formats and config.config_kepubifypath and 'EPUB' in formats:
|
||||
helper.convert_book_format(book.Books.id, config.config_calibre_dir, 'EPUB', 'KEPUB', current_user.name)
|
||||
|
@ -245,6 +249,7 @@ def HandleSyncRequest():
|
|||
pass
|
||||
|
||||
new_books_last_created = max(ts_created, new_books_last_created)
|
||||
kobo_sync_status.add_synced_books(book.Books.id)
|
||||
|
||||
if sqlalchemy_version2:
|
||||
max_change = calibre_db.session.execute(changed_entries
|
||||
|
@ -330,9 +335,10 @@ def generate_sync_response(sync_token, sync_results, set_cont=False):
|
|||
extra_headers["x-kobo-sync"] = "continue"
|
||||
sync_token.to_headers(extra_headers)
|
||||
|
||||
# log.debug("Kobo Sync Content: {}".format(sync_results))
|
||||
response = make_response(jsonify(sync_results), extra_headers)
|
||||
|
||||
log.debug("Kobo Sync Content: {}".format(sync_results))
|
||||
# jsonify decodes the unicode string different to what kobo expects
|
||||
response = make_response(json.dumps(sync_results), extra_headers)
|
||||
response.headers["Content-Type"] = "application/json; charset=utf-8"
|
||||
return response
|
||||
|
||||
|
||||
|
@ -377,7 +383,7 @@ def get_download_url_for_book(book, book_format):
|
|||
|
||||
|
||||
def create_book_entitlement(book, archived):
|
||||
book_uuid = book.uuid
|
||||
book_uuid = str(book.uuid)
|
||||
return {
|
||||
"Accessibility": "Full",
|
||||
"ActivePeriod": {"From": convert_to_kobo_timestamp_string(datetime.datetime.now())},
|
||||
|
@ -404,7 +410,6 @@ def get_description(book):
|
|||
return book.comments[0].text
|
||||
|
||||
|
||||
# TODO handle multiple authors
|
||||
def get_author(book):
|
||||
if not book.authors:
|
||||
return {"Contributors": None}
|
||||
|
@ -412,10 +417,11 @@ def get_author(book):
|
|||
author_list = []
|
||||
autor_roles = []
|
||||
for author in book.authors:
|
||||
autor_roles.append({"Name":author.name, "Role":"Author"})
|
||||
autor_roles.append({"Name":author.name}) #.encode('unicode-escape').decode('latin-1')
|
||||
author_list.append(author.name)
|
||||
return {"ContributorRoles": autor_roles, "Contributors":author_list}
|
||||
return {"ContributorRoles": [{"Name":book.authors[0].name, "Role":"Author"}], "Contributors": book.authors[0].name}
|
||||
return {"ContributorRoles": [{"Name":book.authors[0].name}],
|
||||
"Contributors": book.authors[0].name}
|
||||
|
||||
|
||||
def get_publisher(book):
|
||||
|
@ -472,9 +478,7 @@ def get_metadata(book):
|
|||
"IsSocialEnabled": True,
|
||||
"Language": "en",
|
||||
"PhoneticPronunciations": {},
|
||||
# TODO: Fix book.pubdate to return a datetime object so that we can easily
|
||||
# convert it to the format Kobo devices expect.
|
||||
"PublicationDate": book.pubdate,
|
||||
"PublicationDate": convert_to_kobo_timestamp_string(book.pubdate),
|
||||
"Publisher": {"Imprint": "", "Name": get_publisher(book),},
|
||||
"RevisionId": book_uuid,
|
||||
"Title": book.title,
|
||||
|
@ -489,7 +493,7 @@ def get_metadata(book):
|
|||
"Number": get_seriesindex(book), # ToDo Check int() ?
|
||||
"NumberFloat": float(get_seriesindex(book)),
|
||||
# Get a deterministic id based on the series name.
|
||||
"Id": uuid.uuid3(uuid.NAMESPACE_DNS, name),
|
||||
"Id": str(uuid.uuid3(uuid.NAMESPACE_DNS, name)),
|
||||
}
|
||||
|
||||
return metadata
|
||||
|
@ -958,6 +962,8 @@ def HandleBookDeletionRequest(book_uuid):
|
|||
|
||||
ub.session.merge(archived_book)
|
||||
ub.session_commit()
|
||||
if archived_book.is_archived:
|
||||
kobo_sync_status.remove_synced_book(book_id)
|
||||
return "", 204
|
||||
|
||||
|
||||
|
@ -986,11 +992,16 @@ def HandleUserRequest(dummy=None):
|
|||
@kobo.route("/v1/products/<dummy>/recommendations", methods=["GET", "POST"])
|
||||
@kobo.route("/v1/products/<dummy>/nextread", methods=["GET", "POST"])
|
||||
@kobo.route("/v1/products/<dummy>/reviews", methods=["GET", "POST"])
|
||||
@kobo.route("/v1/products/featured/<dummy>", methods=["GET", "POST"])
|
||||
@kobo.route("/v1/products/featured/", methods=["GET", "POST"])
|
||||
@kobo.route("/v1/products/books/external/<dummy>", methods=["GET", "POST"])
|
||||
@kobo.route("/v1/products/books/series/<dummy>", methods=["GET", "POST"])
|
||||
@kobo.route("/v1/products/books/<dummy>", methods=["GET", "POST"])
|
||||
@kobo.route("/v1/products/books/<dummy>/", methods=["GET", "POST"])
|
||||
@kobo.route("/v1/products/dailydeal", methods=["GET", "POST"])
|
||||
@kobo.route("/v1/products/deals", methods=["GET", "POST"])
|
||||
@kobo.route("/v1/products", methods=["GET", "POST"])
|
||||
@kobo.route("/v1/affiliate", methods=["GET", "POST"])
|
||||
def HandleProductsRequest(dummy=None):
|
||||
log.debug("Unimplemented Products Request received: %s", request.base_url)
|
||||
return redirect_or_proxy_request()
|
||||
|
|
|
@ -54,6 +54,7 @@ from .helper import check_valid_domain, render_task_status, check_email, check_u
|
|||
from .pagination import Pagination
|
||||
from .redirect import redirect_back
|
||||
from .usermanagement import login_required_if_no_ano
|
||||
from .kobo_sync_status import remove_synced_book
|
||||
from .render_template import render_title_template
|
||||
|
||||
feature_support = {
|
||||
|
@ -206,6 +207,8 @@ def toggle_archived(book_id):
|
|||
archived_book.is_archived = True
|
||||
ub.session.merge(archived_book)
|
||||
ub.session_commit("Book {} archivebit toggled".format(book_id))
|
||||
if archived_book.is_archived:
|
||||
remove_synced_book(book_id)
|
||||
return ""
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue