diff options
author | Florian Bruhin <me@the-compiler.org> | 2020-12-22 14:16:47 +0100 |
---|---|---|
committer | Florian Bruhin <me@the-compiler.org> | 2020-12-22 14:16:47 +0100 |
commit | 52af93eb53c212167a586dcf81af5d72b05007b2 (patch) | |
tree | ba27d70399baf52c664ac9e6d1e51930daf06990 /misc/userscripts | |
parent | 20c4fda9b77094fe5c91006b615e810c8909b784 (diff) | |
parent | 6f9d5bf43315ec83e10cae6342e0546eb318f017 (diff) | |
download | qutebrowser-52af93eb53c212167a586dcf81af5d72b05007b2.tar.gz qutebrowser-52af93eb53c212167a586dcf81af5d72b05007b2.zip |
Merge remote-tracking branch 'origin/pr/5939'
Diffstat (limited to 'misc/userscripts')
-rw-r--r-- | misc/userscripts/README.md | 2 | ||||
-rwxr-xr-x | misc/userscripts/add-nextcloud-bookmarks | 171 | ||||
-rwxr-xr-x | misc/userscripts/add-nextcloud-cookbook | 131 |
3 files changed, 304 insertions, 0 deletions
diff --git a/misc/userscripts/README.md b/misc/userscripts/README.md index 669bfa664..7e809a20a 100644 --- a/misc/userscripts/README.md +++ b/misc/userscripts/README.md @@ -35,6 +35,8 @@ The following userscripts are included in the current directory. - [qr](./qr): Show a QR code for the current webpage via [qrencode](https://fukuchi.org/works/qrencode/). - [kodi](./kodi): Play videos in Kodi. +- [add-nextcloud-bookmarks](./add-nextcloud-bookmarks): create bookmarks in Nextcloud's Bookmarks app +- [add-nextcloud-cookbook](./add-nextcloud-cookbook): add recipes to Nextcloud's Cookbook app [castnow]: https://github.com/xat/castnow [youtube-dl]: https://rg3.github.io/youtube-dl/ diff --git a/misc/userscripts/add-nextcloud-bookmarks b/misc/userscripts/add-nextcloud-bookmarks new file mode 100755 index 000000000..4e66620dc --- /dev/null +++ b/misc/userscripts/add-nextcloud-bookmarks @@ -0,0 +1,171 @@ +#!/usr/bin/env python + +""" +Behavior: + A qutebrowser userscript that creates bookmarks in Nextcloud's Bookmarks app. + +Requirements: + requests + +userscript setup: + Optionally create ~/.config/qutebrowser/add-nextcloud-bookmarks.ini like: + +[nextcloud] +HOST=https://nextcloud.example.com +USER=username +;PASSWORD=lamepassword +DESCRIPTION=None +;TAGS=just-one +TAGS=read-me-later,added-by-qutebrowser, Another-One + + If settings aren't in the configuration file, the user will be prompted during + bookmark creation. If DESCRIPTION and TAGS are set to None, they will be left + blank. If the user does not want to be prompted for a password, it is recommended + to set up an 'app password'. See the following for instructions: + https://docs.nextcloud.com/server/latest/user_manual/en/session_management.html#managing-devices # noqa: E501 + +qutebrowser setup: + add bookmark via hints + config.bind('X', 'hint links userscript add-nextcloud-bookmarks') + + add bookmark of current URL + config.bind('X', 'spawn --userscript add-nextcloud-bookmarks') + +troubleshooting: + Errors detected within this userscript will have an exit of 231. All other + exit codes will come from requests. +""" + +import configparser +from json import dumps +from os import environ, path +from sys import argv, exit + +from PyQt5.QtWidgets import QApplication, QInputDialog, QLineEdit +from requests import get, post +from requests.auth import HTTPBasicAuth + + +def get_text(name, info): + """Get input from the user.""" + _app = QApplication(argv) # noqa: F841 + if name == "password": + text, ok = QInputDialog.getText( + None, + "add-nextcloud-bookmarks userscript", + "Please enter {}".format(info), + QLineEdit.Password, + ) + else: + text, ok = QInputDialog.getText( + None, "add-nextcloud-bookmarks userscript", "Please enter {}".format(info) + ) + if not ok: + message("info", "Dialog box canceled.") + exit(0) + return text + + +def message(level, text): + """display message""" + with open(environ["QUTE_FIFO"], "w") as fifo: + fifo.write( + 'message-{} "add-nextcloud-bookmarks userscript: {}"\n'.format(level, text) + ) + fifo.flush() + + +if "QUTE_FIFO" not in environ: + print( + "This script is designed to run as a qutebrowser userscript, " + "not as a standalone script." + ) + exit(231) + +if "QUTE_CONFIG_DIR" not in environ: + if "XDG_CONFIG_HOME" in environ: + QUTE_CONFIG_DIR = environ["XDG_CONFIG_HOME"] + "/qutebrowser" + else: + QUTE_CONFIG_DIR = environ["HOME"] + "/.config/qutebrowser" +else: + QUTE_CONFIG_DIR = environ["QUTE_CONFIG_DIR"] + +config_file = QUTE_CONFIG_DIR + "/add-nextcloud-bookmarks.ini" +if path.isfile(config_file): + config = configparser.ConfigParser() + config.read(config_file) + settings = dict(config.items("nextcloud")) +else: + settings = {} + +settings_info = [ + ("host", "host information.", "required"), + ("user", "username.", "required"), + ("password", "password.", "required"), + ("description", "description or leave blank", "optional"), + ("tags", "tags (comma separated) or leave blank", "optional"), +] + +# check for settings that need user interaction and clear optional setting if need be +for setting in settings_info: + if setting[0] not in settings: + userInput = get_text(setting[0], setting[1]) + settings[setting[0]] = userInput + if setting[2] == "optional": + if settings[setting[0]] == "None": + settings[setting[0]] = "" + +tags = settings["tags"].split(",") + +QUTE_URL = environ["QUTE_URL"] +api_url = settings["host"] + "/index.php/apps/bookmarks/public/rest/v2/bookmark" + +headers = {"Content-Type": "application/json"} +auth = HTTPBasicAuth(settings["user"], settings["password"]) + +# check if there is already a bookmark for the URL +r = get( + "{}?url={}".format(api_url, QUTE_URL), + auth=auth, + headers=headers, + timeout=(3.05, 27), +) +if r.status_code != 200: + message( + "error", + "Could not connect to {} with status code {}".format( + settings["host"], r.status_code + ), + ) + exit(r.status_code) + +try: + r.json()["data"][0]["id"] +except IndexError: + pass +else: + message("info", "bookmark already exists for {}".format(QUTE_URL)) + exit(0) + +if environ["QUTE_MODE"] == "hints": + QUTE_TITLE = QUTE_URL +else: + QUTE_TITLE = environ["QUTE_TITLE"] + +# JSON format +# https://nextcloud-bookmarks.readthedocs.io/en/latest/bookmark.html#create-a-bookmark +dict = { + "url": QUTE_URL, + "title": QUTE_TITLE, + "description": settings["description"], + "tags": tags, +} +data = dumps(dict) + +r = post(api_url, data=data, headers=headers, auth=auth, timeout=(3.05, 27)) + +if r.status_code == 200: + message("info", "bookmark {} added".format(QUTE_URL)) +else: + message("error", "something went wrong {} bookmark not added".format(QUTE_URL)) + exit(r.status_code) diff --git a/misc/userscripts/add-nextcloud-cookbook b/misc/userscripts/add-nextcloud-cookbook new file mode 100755 index 000000000..a348417e0 --- /dev/null +++ b/misc/userscripts/add-nextcloud-cookbook @@ -0,0 +1,131 @@ +#!/usr/bin/env python + +""" +Behavior: + A qutebrowser userscript that adds recipes to Nextcloud's Cookbook app. + +Requirements: + requests + +userscript setup: + Optionally create ~/.config/qutebrowser/add-nextcloud-cookbook.ini like: + +[nextcloud] +HOST=https://nextcloud.example.com +USER=username +;PASSWORD=lamepassword + + If settings aren't in the configuration file, the user will be prompted. + If the user does not want to be prompted for a password, it is recommended + to set up an 'app password' with 'Allow filesystem access' enabled. + See the following for instructions: + https://docs.nextcloud.com/server/latest/user_manual/en/session_management.html#managing-devices # noqa: E501 + +qutebrowser setup: + add recipe via hints + config.bind('X', 'hint links userscript add-nextcloud-cookbook') + + add recipe of current URL + config.bind('X', 'spawn --userscript add-nextcloud-cookbook') + +troubleshooting: + Errors detected within this userscript will have an exit of 231. All other + exit codes will come from requests. +""" + +import configparser +from os import environ, path +from sys import argv, exit + +from PyQt5.QtWidgets import QApplication, QInputDialog, QLineEdit +from requests import post +from requests.auth import HTTPBasicAuth + + +def get_text(name, info): + """Get input from the user.""" + _app = QApplication(argv) # noqa: F841 + if name == "password": + text, ok = QInputDialog.getText( + None, + "add-nextcloud-cookbook userscript", + "Please enter {}".format(info), + QLineEdit.Password, + ) + else: + text, ok = QInputDialog.getText( + None, "add-nextcloud-cookbook userscript", "Please enter {}".format(info) + ) + if not ok: + message("info", "Dialog box canceled.") + exit(0) + return text + + +def message(level, text): + """display message""" + with open(environ["QUTE_FIFO"], "w") as fifo: + fifo.write( + "message-{} 'add-nextcloud-cookbook userscript: {}'\n".format(level, text) + ) + fifo.flush() + + +if "QUTE_FIFO" not in environ: + print( + "This script is designed to run as a qutebrowser userscript, " + "not as a standalone script." + ) + exit(231) + +if "QUTE_CONFIG_DIR" not in environ: + if "XDG_CONFIG_HOME" in environ: + QUTE_CONFIG_DIR = environ["XDG_CONFIG_HOME"] + "/qutebrowser" + else: + QUTE_CONFIG_DIR = environ["HOME"] + "/.config/qutebrowser" +else: + QUTE_CONFIG_DIR = environ["QUTE_CONFIG_DIR"] + +config_file = QUTE_CONFIG_DIR + "/add-nextcloud-cookbook.ini" +if path.isfile(config_file): + config = configparser.ConfigParser() + config.read(config_file) + settings = dict(config.items("nextcloud")) +else: + settings = {} + +settings_info = [ + ("host", "host information.", "required"), + ("user", "username.", "required"), + ("password", "password.", "required"), +] + +# check for settings that need user interaction +for setting in settings_info: + if setting[0] not in settings: + userInput = get_text(setting[0], setting[1]) + settings[setting[0]] = userInput + +api_url = settings["host"] + "/index.php/apps/cookbook/import" +headers = {"Content-Type": "application/x-www-form-urlencoded"} +auth = HTTPBasicAuth(settings["user"], settings["password"]) +data = "url=" + environ["QUTE_URL"] + +message("info", "starting to process {}".format(environ["QUTE_URL"])) + +r = post(api_url, data=data, headers=headers, auth=auth, timeout=(3.05, 27)) + +if r.status_code == 200: + message("info", "recipe from {} added.".format(environ["QUTE_URL"])) + exit(0) +elif r.status_code == 500: + message("warning", "Cookbook app reports {}".format(r.text)) + exit(0) +else: + message( + "error", + "Could not connect to {} with status code {}".format( + settings["host"], r.status_code + ), + ) + exit(r.status_code) |