FooSoft / anki-connect

Anki plugin to expose a remote API for creating flash cards.
https://foosoft.net/projects/anki-connect/
Other
1.94k stars 220 forks source link

popclip extension breaks with text selection containing new line #307

Open codingbulljunky opened 2 years ago

codingbulljunky commented 2 years ago

I've written a small popclip extension for sending selection into Anki, which works perfectly as long as the selection does not contain a break. I'm wondering if anyone might know why it breaks if the text contains a break? For example:

"When should an infant be tested for galactosemia?" works fine

but

"When should an infant be tested for galactosemia?"

throws the following error:

"Anki 2.1.42 (8eebfe18) Python 3.8.6 Qt 5.14.2 PyQt 5.14.2 Platform: Mac 10.16 Flags: frz=True ao=True sv=2 Add-ons, last update check: 2022-03-08 09:45:28 Add-ons possibly involved: ⁨AnkiConnect⁩

Caught exception: Traceback (most recent call last): File "/Users/h/Library/Application Support/Anki2/addons21/2055492159/init.py", line 96, in advance self.server.advance() File "/Users/h/Library/Application Support/Anki2/addons21/2055492159/web.py", line 135, in advance self.advanceClients() File "/Users/h/Library/Application Support/Anki2/addons21/2055492159/web.py", line 150, in advanceClients self.clients = list(filter(lambda c: c.advance(), self.clients)) File "/Users/h/Library/Application Support/Anki2/addons21/2055492159/web.py", line 150, in self.clients = list(filter(lambda c: c.advance(), self.clients)) File "/Users/h/Library/Application Support/Anki2/addons21/2055492159/web.py", line 67, in advance self.writeBuff += self.handler(req) File "/Users/h/Library/Application Support/Anki2/addons21/2055492159/web.py", line 190, in handlerWrapper if params.get('action', '') == 'requestPermission': UnboundLocalError: local variable 'params' referenced before assignment"

The following is my pop clip extension code:

`#!/bin/bash ref=$(osascript '/Users/h/Documents/Archived/Computer/Popclip/get_ref.scpt') ref_name=$(osascript '/Users/h/Documents/Archived/Computer/Popclip/get_ref_name.scpt') tg=$(shortcuts run "Get OneThing text")

curl localhost:8765 -X POST -d "{ \"action\": \"guiAddCards\", \"version\": 6, \"params\": { \"note\": { \"deckName\": \"Master\", \"modelName\": \"Source\", \"fields\": { \"Front\": \"$POPCLIP_TEXT\", \"Back\": \"$POPCLIP_TEXT\", \"Source\": \"$ref\", \"SName\": \"$ref_name\" }, \"options\": { \"closeAfterAdding\": true }, \"tags\": [ \"$tg\" ] } } }"`

git-akihakune commented 2 years ago

I got the exact same error, but worse, it seems to appear on every action.

image

I. Full Anki error

Error
An error occurred. Please start Anki while holding down the shift key, which will temporarily disable the add-ons you have installed.
If the issue only occurs when add-ons are enabled, please use the Tools > Add-ons menu item to disable some add-ons and restart Anki, repeating until you discover the add-on that is causing the problem.
When you've discovered the add-on that is causing the problem, please report the issue on the add-on support site.

II. Platform information

Debug info:
Anki 2.1.49 (dc80804a) Python 3.8.1 Qt 5.15.1 PyQt 5.15.1
Platform: Linux
Flags: frz=True ao=True sv=2
Add-ons, last update check: 2022-03-23 19:48:01
Add-ons possibly involved: ⁨AnkiConnect⁩

For more information, I'm running Linux Mint 20.3 and sending requests library of Python 3.8.10.

III. Bug reproduction

import requests

data = {
        "action": "addNote",
        "version": 6,
        "params": {
            "note": {
                "deckName": "testdeck",
                "modelName": "Cloze",
                "fields": {
                    "Text": "The capital of Romania is {{c1::Bucharest}}",
                    "Extra": "Romania is a country in Europe",
                },
                "options": {"closeAfterAdding": False},
                "tags": ["countries"],
                "picture": [
                    {
                        "url": "https://upload.wikimedia.org/wikipedia/commons/thumb/1/13/EU-Romania.svg/285px-EU-Romania.svg.png",
                        "filename": "romania.png",
                        "fields": ["Extra"],
                    }
                ],
            }
        },
    }

url = "http://127.0.0.1:8765"
response = requests.post(url, data=data)
print(response.text)

This script also gave the same error:

import requests

data = {"action": "deckNames", "version": 6}

url = "http://127.0.0.1:8765"
response = requests.post(url, data=data)
print(response.text)

IV. Debug information

Caught exception:
Traceback (most recent call last):
  File "/home/aki/.local/share/Anki2/addons21/2055492159/__init__.py", line 96, in advance
    self.server.advance()
  File "/home/aki/.local/share/Anki2/addons21/2055492159/web.py", line 135, in advance
    self.advanceClients()
  File "/home/aki/.local/share/Anki2/addons21/2055492159/web.py", line 150, in advanceClients
    self.clients = list(filter(lambda c: c.advance(), self.clients))
  File "/home/aki/.local/share/Anki2/addons21/2055492159/web.py", line 150, in <lambda>
    self.clients = list(filter(lambda c: c.advance(), self.clients))
  File "/home/aki/.local/share/Anki2/addons21/2055492159/web.py", line 67, in advance
    self.writeBuff += self.handler(req)
  File "/home/aki/.local/share/Anki2/addons21/2055492159/web.py", line 190, in handlerWrapper
    if params.get('action', '') == 'requestPermission':
UnboundLocalError: local variable 'params' referenced before assignment
B0sh commented 2 years ago

I had this error too on my script and it turns out this error occurs when you have an invalid json input. Once I fixed my json input the error went away. (For me it was that I upgraded macOS and python 2 was no longer available in the command line... which is what broke my previous working json. Took quite a while to figure out).

The code referenced below is what's throwing. I can't make 100% sense out of what's going on here, but it seems to me like there should be a 400 bad request thrown when the json input is invalid.

https://github.com/FooSoft/anki-connect/blob/54a7105bf9da31dabe884a96464206a0fc87c58d/plugin/web.py#L180-L208

As for the poster above you can't use extra commas for the last property in json :). I think that would fix yours

git-akihakune commented 2 years ago

Thanks for your suggestion, I've found the problem in my script.

I. Quick fix

requestJson = json.dumps(self.content).encode("utf-8")
response = requests.post('http://localhost:8765', data=requestJson)

II. Explanation

The problem was, indeed, because of invalid json input. In my case, that's because I directly sent the Python dictionary object without properly utf-8 encoded it first.

III. Fix

I suggest adding a more helpful error message in this check from web.py:

https://github.com/FooSoft/anki-connect/blob/04482f43860916eeb5a8b0affb887c8680a8a390/plugin/web.py#L180-L184