bachya / aiopinboard

A Python 3, asyncio-based library to interact with the Pinboard API

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Line breaks are lost from the description when retrieving a bookmark

davep opened this issue · comments

Describe the bug
If a bookmark is created such that it has line breaks in the description, when the bookmark is retrieved by the library, the line breaks are lost.

To Reproduce
Run this code, supplying a valid API token:

from asyncio import run
from aiopinboard import API

TOKEN = "<token here>"

URL = "https://www.example.com/multiple-lines"

async def show_problem():
    await API(TOKEN).bookmark.async_add_bookmark(
        url=URL,
        title=f"Test multiple lines",
        description="\n".join(f"Line {n}" for n in range(10)),
        shared=False,
        toread=True,
        replace=True,
    )
    print((await API(TOKEN).bookmark.async_get_bookmark_by_url(URL)).description)

if __name__ == "__main__":
    run(show_problem())

Expected behavior
It would be expected that the content of the description would match that found on Pinboard itself. With the above code, the bookmark that appears on Pinboard has the line breaks:

Screenshot 2023-12-13 at 15 12 45

but the above script prints this:

Line 0 Line 1 Line 2 Line 3 Line 4 Line 5 Line 6 Line 7 Line 8 Line 9

Looking at what comes down at a low-level, I can see that the data in the XML just uses line breaks; and if I remember correctly (it's been a while since I did anything involving XML) that's a no-no. I don't have this issue in pinboard.el, but there I used the JSON API.

I fear this is an issue that can't be addressed if using the XML API.

Good find, @davep. Would you recommend we wholesale shift to the JSON API under the hood?

I honestly can't remember why I went JSON vs XML (probably 'cos it's just easier to work with in Emacs Lisp), but if I'm reading the situation correctly that might be a good idea; or at least have it as an option (although I guess the idea of the library is to hide that detail).

This sort of feels like a bug in the Pinboard API itself, in respect to XML, so I guess JSON would be the only obvious workaround.

@davep Would it be worth reaching out to the Pinboard owner to see if this is a bug he can fix?

That might be worth a try; although I got the impression some time back that active development work on Pinboard was something that seldom happened these days (also I do wonder if the way the XML layer works is some sort of compatibility thing with the old del.icio.us API).

Got it. Let me explore the JSON API a bit—we may be able to do some under-the-hood surgery pretty easily.

@davep I've tried my darndest to access the V2 (JSON) API, but can't get it to work. This very simple cURL:

curl "https://api.pinboard.in/v2/hello/" -H 'X-Auth-Token: USER:TOKEN'

...returns an HTTP 403.

You mentioned above that your Emacs client uses this API; am I missing something obvious?

It looks like you're trying to use the v2 API there; which I don't think ever made it live? The URL I use is still the v1 API; so something like: https://api.pinboard.in/v1/{end-point-path}?auth_token={user-token}&format=json

At a quick glance, I suspect this should kick things off:

diff --git a/aiopinboard/api.py b/aiopinboard/api.py
index de6b34e..83e1e3b 100644
--- a/aiopinboard/api.py
+++ b/aiopinboard/api.py
@@ -61,6 +61,7 @@ class API:  # pylint: disable=too-few-public-methods
         """
         kwargs.setdefault("params", {})
         kwargs["params"]["auth_token"] = self._api_token
+        kwarks["params"]["format"] = "json"
 
         if use_running_session := self._session and not self._session.closed:
             session = self._session

@davep I whipped up a PR to migrate to Pinboard's JSON API: #309

I'd love your testing to ensure it (a) continues to work in your client and (b) fixes the issue you describe here.

Ahh cool! I did take the project off in a slightly different direction in the end anyway; but I can easily give this a run-through. All being well I should get a chance in the next day or so.