Here is a way to send URLs from the webbrowser to my local (shell)scripts.
among many other things, this allows me to:
- if URL is a wallpaper, save it and set it using
hsetroot
- epub, pdf links are passed to
calibre
- video links are sent to
youtube-dl
- .git URLs are cloned
This userscript can be used with browser extensions like f.i. Violentmonkey
It listens for key events, if the event is the
user pressing Alt+p
, it will send a HTTP
Request to http://127.0.0.1
(localhost) port 8210. With a JSON object
containing the single key "url":
that holds the
URL currently open in the browser.
// ==UserScript==
// @name Send current URL to localhost
// @namespace nergen.net
// @include *
// @run-at document-start
// @grant GM.xmlHttpRequest
// @version 1.0
// @author nergen
// @description 2023/7/8, 5:47:20 PM
// ==/UserScript==
document.addEventListener('keydown', function(e) {
const host = "http://127.0.0.1";
const port = 8210;
// Alt+p to trigger
if (e.code == "KeyP" && e.altKey) {
GM.xmlHttpRequest({
method: "POST",
url: `${host}:${port}`,
headers: {"Origin": "userscript"},
data: JSON.stringify({
url: location.href,
})
});
}
return false;
});
Without a local webserver the userscript is
useless. To see that it works we can start
NetCat
listening to port 8210, by executing the
command nc -l -p 8210
in a terminal:
002 ~ > nc -l -p 8210 POST / HTTP/1.1 Host: 127.0.0.1:8210 Connection: keep-alive Content-Length: 78 sec-ch-ua: "Not.A/Brand";v="8", "Chromium";v="114" Content-Type: text/plain;charset=UTF-8 sec-ch-ua-mobile: ?0 User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 sec-ch-ua-platform: "Linux" Accept: */* Sec-Fetch-Site: none Sec-Fetch-Mode: cors Sec-Fetch-Dest: empty Accept-Encoding: gzip, deflate, br Accept-Language: en-US,en;q=0.9 {"url":"https://github.com/avleen/bashttpd/blob/master/bashttpd"}
Personally I use a local python webserver:
#!/usr/bin/python3
from json import loads
import subprocess
from http.server import HTTPServer, BaseHTTPRequestHandler
SERVER_PORT = 8210
SERVER_HOST = '127.0.0.1'
COMMAND = 'notify-send'
class UserScriptServer(BaseHTTPRequestHandler):
def do_POST(self):
self.send_response(200)
self.send_header('Content-Type', 'text/plain')
self.end_headers()
origin = self.headers.get('Origin', '')
if origin == "userscript":
length = int(self.headers['Content-Length'])
content_str = self.rfile.read(length).decode('utf8')
content = loads(content_str)
print("userscript request:\n%s\n\n"%(content['url']))
if len(content['cmd']) > 0:
subprocess.Popen([COMMAND, content['url']])
self.wfile.write(''.encode('utf8'))
else:
print("WARNING, UNKNOWN request to userscript-server!! \n")
def init_server(server_class=HTTPServer):
server_address = (SERVER_HOST, SERVER_PORT)
httpd = server_class(server_address, UserScriptServer)
httpd.serve_forever()
try:
init_server()
except KeyboardInterrupt:
pass
This will pass the URL as an argument to the COMMAND,
in the example above notify-send
but you could replace
this with your own URL handler.
This was a demonstration of an example setup,
obviously the webserver and URL-handler can be
done in many other ways and languages. The
userscript itself could be extended, to pass more
stuff in the "data":
JSON, or maybe pre-format
it depending on the context, e.t.c.