Get rid of Hug dependency, use python default http server
This commit is contained in:
parent
fea9092497
commit
dc568f4785
|
@ -6,7 +6,7 @@ possibly selected text, additional comments or tags and send it into your [Org M
|
||||||
[See a short demo](https://www.youtube.com/watch?v=Z8Bk-IazdGo).
|
[See a short demo](https://www.youtube.com/watch?v=Z8Bk-IazdGo).
|
||||||
|
|
||||||
# Requirements
|
# Requirements
|
||||||
* `pip3 install --user hug` for [Hug](http://www.hug.rest/) HTTP server.
|
No third party dependencies! Just `python 3.6`.
|
||||||
|
|
||||||
# Running
|
# Running
|
||||||
1. Install server counterpart as systemd service (to autostart it): `server/setup --path /path/to/your/capture.org [--port <custom port>]`.
|
1. Install server counterpart as systemd service (to autostart it): `server/setup --path /path/to/your/capture.org [--port <custom port>]`.
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -eux
|
set -eux
|
||||||
# TODO add to proper ci pipeline
|
# TODO add to proper ci pipeline
|
||||||
pylint -E server.py setup
|
pylint -E *.py setup
|
||||||
|
|
||||||
# TODO ugh mypy complains at hug's annotations
|
mypy --check-untyped-defs *.py setup
|
||||||
mypy --check-untyped-defs server.py setup
|
|
||||||
|
|
|
@ -1,41 +1,38 @@
|
||||||
#!/usr/bin/python3
|
#!/usr/bin/python3
|
||||||
import argparse
|
import argparse
|
||||||
|
from http.server import BaseHTTPRequestHandler, HTTPServer
|
||||||
import json
|
import json
|
||||||
import re
|
|
||||||
import os
|
import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
import re
|
||||||
import hug # type: ignore
|
from typing import List
|
||||||
import hug.types as T # type: ignore
|
|
||||||
|
|
||||||
from org_tools import append_org_entry
|
from org_tools import append_org_entry
|
||||||
|
|
||||||
CAPTURE_PATH_VAR = 'GRASP_CAPTURE_PATH'
|
CAPTURE_PATH_VAR = 'GRASP_CAPTURE_PATH'
|
||||||
|
|
||||||
def empty(s) -> bool:
|
|
||||||
return s is None or len(s.strip()) == 0
|
|
||||||
|
|
||||||
def log(*things):
|
def log(*things):
|
||||||
# TODO proper logging
|
# TODO proper logging
|
||||||
print(*things)
|
print(*things)
|
||||||
|
|
||||||
# TODO allow to pass tags??
|
|
||||||
@hug.local()
|
|
||||||
@hug.post('/capture')
|
|
||||||
def capture(
|
def capture(
|
||||||
url: T.text,
|
url,
|
||||||
title: T.Nullable(T.text),
|
title,
|
||||||
selection: T.Nullable(T.text),
|
selection,
|
||||||
comment: T.Nullable(T.text),
|
comment,
|
||||||
tag_str: T.Nullable(T.text),
|
tag_str,
|
||||||
):
|
):
|
||||||
|
def empty(s) -> bool:
|
||||||
|
return s is None or len(s.strip()) == 0
|
||||||
|
|
||||||
log("capturing", url, title, selection, comment)
|
log("capturing", url, title, selection, comment)
|
||||||
|
|
||||||
capture_path = Path(os.environ[CAPTURE_PATH_VAR]).expanduser()
|
capture_path = Path(os.environ[CAPTURE_PATH_VAR]).expanduser()
|
||||||
|
|
||||||
heading = url
|
heading = url
|
||||||
parts = []
|
parts = []
|
||||||
tags = []
|
tags: List[str] = []
|
||||||
if not empty(tag_str):
|
if not empty(tag_str):
|
||||||
tags = re.split('[\s,]', tag_str)
|
tags = re.split('[\s,]', tag_str)
|
||||||
tags = [t for t in tags if not empty(t)] # just in case
|
tags = [t for t in tags if not empty(t)] # just in case
|
||||||
|
@ -81,19 +78,42 @@ def capture(
|
||||||
|
|
||||||
return json.dumps(response).encode('utf8')
|
return json.dumps(response).encode('utf8')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class GraspRequestHandler(BaseHTTPRequestHandler):
|
||||||
|
def handle_POST(self):
|
||||||
|
content_length = int(self.headers['Content-Length'])
|
||||||
|
post_data = self.rfile.read(content_length)
|
||||||
|
payload = json.loads(post_data.decode('utf8'))
|
||||||
|
log("incoming request:")
|
||||||
|
log(payload)
|
||||||
|
res = capture(**payload)
|
||||||
|
self.send_response(200)
|
||||||
|
self.send_header('Content-Type', 'application/json')
|
||||||
|
self.end_headers()
|
||||||
|
self.wfile.write(res)
|
||||||
|
|
||||||
|
def respond_error(self, message: str):
|
||||||
|
self.send_response(500)
|
||||||
|
self.send_header('Content-Type', 'text/html')
|
||||||
|
self.end_headers()
|
||||||
|
self.wfile.write(message.encode('utf8'))
|
||||||
|
|
||||||
|
def do_POST(self):
|
||||||
|
try:
|
||||||
|
self.handle_POST()
|
||||||
|
except Exception as e:
|
||||||
|
log("Error during processing")
|
||||||
|
log(str(e))
|
||||||
|
self.respond_error(message=str(e))
|
||||||
|
|
||||||
|
|
||||||
def run(port: str, capture_path: str):
|
def run(port: str, capture_path: str):
|
||||||
env = os.environ.copy()
|
|
||||||
# not sure if there is a simpler way to communicate with the server...
|
# not sure if there is a simpler way to communicate with the server...
|
||||||
env[CAPTURE_PATH_VAR] = capture_path
|
os.environ[CAPTURE_PATH_VAR] = capture_path
|
||||||
os.execvpe(
|
httpd = HTTPServer(('', int(port)), GraspRequestHandler)
|
||||||
'hug',
|
log(f"Starting httpd on port {port}")
|
||||||
[
|
httpd.serve_forever()
|
||||||
'grasp-server',
|
|
||||||
'-p', port,
|
|
||||||
'-f', __file__,
|
|
||||||
],
|
|
||||||
env,
|
|
||||||
)
|
|
||||||
|
|
||||||
def setup_parser(p):
|
def setup_parser(p):
|
||||||
p.add_argument('--port', type=str, default='12212', help='Port for communicating with extension')
|
p.add_argument('--port', type=str, default='12212', help='Port for communicating with extension')
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from subprocess import check_call
|
from subprocess import check_call, run
|
||||||
|
|
||||||
from grasp_server import setup_parser
|
from grasp_server import setup_parser
|
||||||
|
|
||||||
|
@ -20,8 +20,8 @@ Restart=always
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def systemd(*args):
|
def systemd(*args, method=check_call):
|
||||||
check_call([
|
method([
|
||||||
'systemctl', '--user', *args,
|
'systemctl', '--user', *args,
|
||||||
])
|
])
|
||||||
|
|
||||||
|
@ -40,6 +40,7 @@ def setup(args):
|
||||||
))
|
))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
systemd('stop' , unit_name, method=run) # ignore errors here if it wasn't running in the first place
|
||||||
systemd('daemon-reload')
|
systemd('daemon-reload')
|
||||||
systemd('enable', unit_name)
|
systemd('enable', unit_name)
|
||||||
systemd('start' , unit_name)
|
systemd('start' , unit_name)
|
||||||
|
|
|
@ -27,6 +27,7 @@ function makeCaptureRequest(
|
||||||
}
|
}
|
||||||
console.log('[background] status:', request.status);
|
console.log('[background] status:', request.status);
|
||||||
if (request.status >= 200 && request.status < 400) { // success
|
if (request.status >= 200 && request.status < 400) { // success
|
||||||
|
// TODO handle json parsing defensively here
|
||||||
var response = JSON.parse(request.responseText);
|
var response = JSON.parse(request.responseText);
|
||||||
console.log(`[background] success: ${response}`);
|
console.log(`[background] success: ${response}`);
|
||||||
showNotification(`OK: ${response}`);
|
showNotification(`OK: ${response}`);
|
||||||
|
|
Loading…
Reference in a new issue