post version 0, zero debugging yet

technically I'm vibecoding this and I'm the LLM here
This commit is contained in:
Mirek Kratochvil 2025-10-11 21:12:19 +02:00
parent 92d36ddc7e
commit c0b4d8692b

View file

@ -3,9 +3,118 @@
import sys, os
import argparse
import requests
import hashlib
import time
# NOTES: html2text: html2text
# the replies are listed by context, should be link-listed to avoid issues,
# should specify next hash to provide some kind of a filter
# visibility public+unlisted, all unlisted, all private, all direct
VERSION = "0.1.0"
DPASTE_URL = "https://dpaste.com"
STATUS_LENGTH_LIMIT = 400
def trace(x):
sys.stderr.write(sys.argv[0] + ": " + x + "\n")
def api_token(args):
if args.debug_api_token:
return args.debug_api_token
if args.env_api_token:
return os.environ["PATCHODON_API_TOKEN"]
raise ("API token not specified")
def do_post_status(args, body, parent=None, optional=None):
if len(body) > STATUS_LENGTH_LIMIT:
raise ("required status body too long")
if not args.instance_url:
raise ("mastodon instance not specified")
token = api_token(args)
headers = {"Authorization": f"Bearer {token}"}
st = body + (
"\n" + optional[0 : (STATUS_LENGTH_LIMIT - len(body) - 1)]
if optional
else ""
)
data = {status: st, visibility: "unlisted"}
if parent:
data["in_reply_to_id"] = parent
r = requests.post(
args.instance_url + "/api/v1/statuses", data=data, headers=headers
)
if r.status_code != 200:
raise ("mastodon status posting failed ({r.status_code})")
return r.json.id
def do_pastebin_file(file):
# DPASTE API USE RULES:
# - user-agent must be set properly
# - 1 second between requests
trace(f"pasting {file}...")
r = requests.post(
DPASTE_URL + "/api/v2/",
data={
"contents": open(file, "r").read(),
"syntax": "diff",
"title": os.path.basename(file),
"expiry_days": 30,
},
headers={"User-agent": f"patchodon v{VERSION}"},
)
if r.status_code != 201:
raise (f"dpaste POST failed for `{file}'")
sleep(1.1)
return r.headers["location"] + ".txt"
def split_off_diff(s):
return s.split("\ndiff --git ")[0]
def do_post(args):
files = args.patchfile
if not files:
trace("reading patchfile series from stdin")
files = sys.stdin.readlines().map(lambda x: x.rstrip(chars="\n"))
n_patches = len(files)
hashes = files.map(lambda x: hashlib.sha1(open(x, "r").read()).hexdigest())
short_hashes = hashes.map(lambda x: x[0:8])
full_hash = hashlib.sha1(hashes.join(" ")).hexdigest()
paste_raw_urls = map(do_pastebin_file, files)
trace("posting the header...")
parent_post_id, url = do_post_status(
args,
args.subject
+ f"\n[patchodon hash {full_hash} shorts {short_hashes.join(' ')}]",
)
for fn, pst, hsh, series in zip(
files, paste_raw_urls, hashes, range(n_patches)
):
trace(f"posting patch {series+1}/{n_patches}...")
parent_post_id, _ = do_post_status(
args,
f"[patchodon {series+1}/{n_patches} {hsh}\n{pst}\n",
parent=parent_post_id,
optional=split_off_diff(open(fn, "r").read()),
)
print(url)
def do_get(args):
pass
def main():
ap = argparse.ArgumentParser(
@ -38,7 +147,13 @@ def main():
"-i", "--instance-url", help="mastodon instance URL to post to"
)
post.add_argument(
"-r", "--recipient", help="recipient to tag in the initial post"
"-s",
"--subject",
default="",
help=(
"start of the initial post (e.g. to @tag someone and name the"
" project and topic)"
),
)
post.add_argument(
"patchfile",
@ -93,7 +208,13 @@ def main():
),
)
args = ap.parse_args()
print(args)
if args.command == "post":
do_post(args)
elif args.command == "get":
do_get(args)
else:
raise ("fatal: args borked")
if __name__ == "__main__":