Merge remote-tracking branch 'origin/pr/5939'
This commit is contained in:
commit
52af93eb53
|
|
@ -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/
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -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)
|
||||
Loading…
Reference in New Issue