koreader-calibre-plugin icon indicating copy to clipboard operation
koreader-calibre-plugin copied to clipboard

[Bug] ProgressSync with "No data received" error

Open sjhayman opened this issue 8 months ago • 11 comments

KOreader Sync plugin version

0.7.1

KOreader version

2024.11

Operating System

Linux

Connection type

Wired (over usb cable)

Describe the bug

I've set up a personal koreader sync server. My ereader (Kobo) successfully syncs with the koreader sync server. But when I try to use the sync from ProgressSync functionality of the koreader sync plugin for Calibre, it fails to sync with a "no data receved" error. Nothing shows up in the calibre debug logs. No activity show up in the koreader sync logs, which seems to suggest that the problem is with the plugin.

Is there anyway to debug the plugin?

How to reproduce

  • install koreader sync plugin
  • configure progresssync
  • sync kobo device running koreader with calibre
  • read some pages on the kobo device
  • sync the kobo device with the koreader sync server (which works)
  • start progress sync in calibre
  • see error messages

Expected behavior

progress of read book should be updated in calibre

Provide details output from plugin pop-up window

error : no data to receive appears

[{'title': 'The Pyramid: And Four Other Kurt Wallander Mysteries', 'book_uuid': '0aa35dda-6879-43c9-8ea9-7f7e7b3b4c0c', 'md5_value': '35b6ad1d90dc0af3b2690dd3510f57d6', 'error': 'No data received'}, {'title': "In the Garden of Beasts: Love, Terror, and an American Family in Hitler's Berlin", 'book_uuid': 'fe6cf580-087e-4b58-b177-6cc71eb75f9e', 'md5_value': '538496802376b8a610746906576af558', 'error': 'No data received'}]

Screenshots

No response

Any additional info

No response

sjhayman avatar May 16 '25 16:05 sjhayman

Seems like error due to connect issue to your server? E.g. wrong url or network issue.

@jbhul what do you think?

kyxap avatar May 16 '25 16:05 kyxap

FYI - I've tried using both http and https, and I pasted the URL in a browser address bar of the same machine that is running Calibre, and it works.

FYI - the koreader sync server is running on the same machine as Calibre.

sjhayman avatar May 16 '25 17:05 sjhayman

So this error comes up on a HTTPError or URLError. Truthfully I never tested this with my own PS server since I don't have one, but let's try and figure this out.

Could you try going to [the url you entered in config]/syncs/progress/[md5_value] in your browser and see what happens? This is what the plugin is doing under the hood.

jbhul avatar May 16 '25 18:05 jbhul

This is what is returned:
{ "code": 101, "message": "Invalid Accept header format." }

FYI - this is the koreader sync server that I'm running - https://github.com/koreader/koreader-sync-server

sjhayman avatar May 16 '25 19:05 sjhayman

How is the userid & password used in the request? Are they encoded somehow? I ask because I tried the same format of URL at https://sync.koreader.rocks and received the same result (I don't have an account at sync.koreader.rocks)

sjhayman avatar May 16 '25 20:05 sjhayman

Hmm actually not too sure if trying in the browser would do anything, it would have to be a browser console curl request to send the headers out. The code with headers and whatnot is here: https://github.com/harmtemolder/koreader-calibre-plugin/blob/7ba57f6c855f07f178561d29d7c543512b5d5cb7/action.py#L905

username is plaintext and password is encoded per sync.koreader.rocks spec when saved in config.

jbhul avatar May 17 '25 04:05 jbhul

This is what is returned: { "code": 101, "message": "Invalid Accept header format." }

FYI - this is the koreader sync server that I'm running - https://github.com/koreader/koreader-sync-server

exact same thing for me

5rxiq avatar May 19 '25 21:05 5rxiq

This is what is returned: { "code": 101, "message": "Invalid Accept header format." } FYI - this is the koreader sync server that I'm running - https://github.com/koreader/koreader-sync-server

exact same thing for me @sjhayman @5rxiq

Yeah that's expected... if it's just the URL in browser there are no headers being sent, no login or body or anything. You'd have to actually send a curl request in your browser console or via postman or similar with the relevant headers in the code to get an actual error message.

jbhul avatar May 20 '25 01:05 jbhul

Would it be possible to add some error / debug logging to the plugin, rather than trying to match what the plugin is doing in a curl request?

-- Scott Hayman @.***

On Mon, May 19, 2025, 21:23 Jeevan Bhullar @.***> wrote:

jbhul left a comment (harmtemolder/koreader-calibre-plugin#89) https://github.com/harmtemolder/koreader-calibre-plugin/issues/89#issuecomment-2892637361

This is what is returned: { "code": 101, "message": "Invalid Accept header format." } FYI - this is the koreader sync server that I'm running - https://github.com/koreader/koreader-sync-server

exact same thing for me @sjhayman https://github.com/sjhayman @5rxiq https://github.com/5rxiq

Yeah that's expected... if it's just the URL in browser there are no headers being sent, no login or body or anything. You'd have to actually send a curl request in your browser console or via postman or similar with the relevant headers in the code to get an actual error message.

— Reply to this email directly, view it on GitHub https://github.com/harmtemolder/koreader-calibre-plugin/issues/89#issuecomment-2892637361, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAGQCH32BQFPRPAWBNOT2IT27J7Y5AVCNFSM6AAAAAB5JE7EQCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDQOJSGYZTOMZWGE . You are receiving this because you were mentioned.Message ID: @.***>

sjhayman avatar May 20 '25 11:05 sjhayman

Having the same issue. Are there any insights into the root cause of the issue in the meantime?

I have the following additional info from the sync-server error logs.

SSL_do_handshake() failed (SSL: error:14094418:SSL routines:ssl3_read_bytes:tlsv1 alert unknown ca:SSL alert number

So this seems to be related to a certificate error somehow.

Would it be an option to have an extra checkbox to ignore certificate errors in the plugin?

kymograph avatar Aug 03 '25 20:08 kymograph

Here is the curl command to test your server to get your hashed password: echo -n "password" | md5sum | awk '{print $1}' result: 5f4dcc3b5aa765d61d8327deb882cf99

curl -X GET
-H "x-auth-user: USER"
-H "x-auth-key: 5f4dcc3b5aa765d61d8327deb882cf99"
-H "Accept: application/vnd.koreader.v1+json"
-H "Connection: keep-alive"
-H "Cache-Control: no-cache"
-H "User-Agent: CalibreKOReaderSync/0.72.0"
https://192.168.2.209:7200/syncs/progress/9e5c2b064fd157ff7d337d443b7421cc

curl error: **curl: (60) SSL certificate problem: self-signed certificate More details here: https://curl.se/docs/sslcerts.html

curl failed to verify the legitimacy of the server and therefore could not establish a secure connection to it. To learn more about this situation and how to fix it, please visit the web page mentioned above.**

urlopen error (this plugin uses it) URL Error: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate (_ssl.c:1006)

curl -X GET
-H "x-auth-user: USER"
-H "x-auth-key: 5f4dcc3b5aa765d61d8327deb882cf99"
-H "Accept: application/vnd.koreader.v1+json"
-H "Connection: keep-alive"
-H "Cache-Control: no-cache"
-H "User-Agent: CalibreKOReaderSync/0.72.0"
https://koreader-sync.CENSORED.duckdns.org/syncs/progress/9e5c2b064fd157ff7d337d443b7421cc

this worked, with SSL and scheme "https" in nginx.

so yeah you probably have to use nginx or something to get SSL, I just used the free DuckDNS for the domain. it fixed it for me, but it would be nice to use the plain IP.

adding "ssl_context=None" would solve SSL issues, maybe make it a checkbox inside "Add ProgressSync Account" window.

action.py ` # Only get sync status if curr progress < 100 and status = reading or if curr_progress/status is not set yet metadata_status = metadata.get(status_key) metadata_read_percent = metadata.get(read_percent_key) if (metadata_status is None or metadata_status == "reading") and (metadata_read_percent is None or metadata_read_percent < 100): try: url = f'{CONFIG["progress_sync_url"]}/syncs/progress/{md5_value}' request = Request(url, headers=headers)

                context = None
                if not CONFIG['progress_sync_use_ssl']:
                    context = ssl._create_unverified_context()

                with urlopen(request, timeout=20, context=context) as response:
                    response_data = response.read()
                    if response_data == b'{}':
                        results.append({
                            'md5_value': md5_value,
                            'error': 'No ProgressSync entry for md5 hash'
                        })
                        num_skip += 1
                        continue
                    progress_data = json.loads(response_data.decode('utf-8'))

                # Kinda Janky edge case handling`

config.py `.. CONFIG.defaults['progress_sync_password'] = '' CONFIG.defaults['progress_sync_use_ssl'] = True .......... layout.addWidget(self.password_input)

    self.use_ssl_checkbox = QCheckBox('Use SSL', self)
    self.use_ssl_checkbox.setChecked(CONFIG['progress_sync_use_ssl'])
    layout.addWidget(self.use_ssl_checkbox)

    self.note_label = QLabel(
        'Enter any custom server or leave the default filled in.\n'
        'Enter your username and password. Then click log in, this does not validate your account so make sure you enter the correct info.\n'
        'Make sure you have one or more of the following columns set up: column_percent_read, column_percent_read_int, column_last_read_location\n'
        'You must have a percent read (int or float) and status text column.',
        self
    )
    self.note_label.setWordWrap(True)
    layout.addWidget(self.note_label)

    self.login_button = QPushButton('Log In', self)
    self.login_button.clicked.connect(self.save_progress_sync_settings)
    layout.addWidget(self.login_button)

def save_progress_sync_settings(self):
    CONFIG['progress_sync_url'] = self.url_input.text()
    CONFIG['progress_sync_username'] = self.username_input.text()
    CONFIG['progress_sync_password'] = self.hash_password(
        self.password_input.text())
    CONFIG['progress_sync_use_ssl'] = self.use_ssl_checkbox.isChecked()
    self.accept()`

ScheKaa avatar Sep 06 '25 14:09 ScheKaa