75 lines
2.2 KiB
Python
75 lines
2.2 KiB
Python
#!/usr/bin/python3
|
|
|
|
import argparse
|
|
import html
|
|
import subprocess
|
|
import sys
|
|
import tempfile
|
|
|
|
import yaml
|
|
import psycopg
|
|
import requests
|
|
|
|
from bs4 import BeautifulSoup
|
|
|
|
ap = argparse.ArgumentParser()
|
|
ap.add_argument("--author", default="hjp")
|
|
ap.add_argument("--content_type", default="text/plain")
|
|
ap.add_argument("--tags", nargs="+")
|
|
g = ap.add_mutually_exclusive_group(required=True)
|
|
g.add_argument("--content")
|
|
g.add_argument("--url")
|
|
g.add_argument("--file")
|
|
g.add_argument("--editor", action="store_true")
|
|
args = ap.parse_args()
|
|
|
|
if args.content:
|
|
content = args.content
|
|
elif args.file:
|
|
with open(args.file) as fh:
|
|
content = fh.read()
|
|
elif args.url:
|
|
r = requests.get(args.url)
|
|
if r.status_code != 200:
|
|
print(f"GETting {args.url} failed with {r.status_code} {r.message}",
|
|
file=sys.stderr)
|
|
exit(1)
|
|
soup = BeautifulSoup(r.content, "lxml")
|
|
title = soup.find("title")
|
|
title = title.text
|
|
content = f"[{title}]({args.url})"
|
|
args.content_type = "text/markdown"
|
|
elif args.editor:
|
|
with tempfile.NamedTemporaryFile(delete_on_close=False) as tfh:
|
|
tfh.close()
|
|
subprocess.run(["sensible-editor", tfh.name])
|
|
with open(tfh.name, "r") as fh:
|
|
content = fh.read()
|
|
if len(content) == 0:
|
|
print("Content is empty. Aborting.", file=sys.stderr)
|
|
|
|
conn = psycopg.connect(dbname="zettel")
|
|
csr = conn.cursor(row_factory=psycopg.rows.namedtuple_row)
|
|
csr.execute("select * from role where name = %s", (args.author,))
|
|
author_id = csr.fetchone().id
|
|
csr.execute(
|
|
"""
|
|
insert into post(text, ts, content_type, author) values(%s, now(), %s, %s)
|
|
returning id
|
|
""",
|
|
(content, args.content_type, author_id,))
|
|
post_id = csr.fetchone().id
|
|
for tag in args.tags:
|
|
csr.execute("select * from tag where lower(name) = lower(%s)",
|
|
(tag,)) # XXX - use citext?
|
|
r = csr.fetchone()
|
|
if not r:
|
|
csr.execute("insert into tag(name) values(%s) returning id",
|
|
(tag,))
|
|
r = csr.fetchone()
|
|
tag_id = r.id
|
|
csr.execute("insert into tag_post(tag, post) values(%s, %s)",
|
|
(tag_id, post_id,))
|
|
csr.execute("insert into acl(post, role) values(%s, %s)", (post_id, author_id,))
|
|
conn.commit()
|