zettel/add_zettel

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()