add visibility and dpaste expirations

This commit is contained in:
Mirek Kratochvil 2025-10-13 21:29:09 +02:00
parent 9b6b4e6c61
commit daf737fa08

View file

@ -54,7 +54,22 @@ def auth_headers(args):
return {"Authorization": f"Bearer {token}"}
def do_post_status(args, body, parent=None, optional=None):
def post_visibility(args, is_head):
"""
choose the status visibility based on args and head-ness
"""
if args.direct:
return "direct"
if args.private:
return "private"
if args.public:
return "public" if is_head else "unlisted"
if args.all_public:
return "public"
return "public" if is_head else "unlisted"
def do_post_status(args, body, is_head, parent=None, optional=None):
"""
POST a new status with body, optionally in reply-to `parent` post ID, and
with attached `optional` contents to body.
@ -67,7 +82,7 @@ def do_post_status(args, body, parent=None, optional=None):
if optional
else ""
)
data = {"status": st, "visibility": "direct"} # TODO parametrize direct
data = {"status": st, "visibility": post_visibility(args, is_head)}
# visibility options: public head+unlisted, all unlisted, all private, all direct
if parent:
data["in_reply_to_id"] = parent
@ -86,29 +101,33 @@ def do_post_status(args, body, parent=None, optional=None):
return (rj["id"], rj["url"])
def do_pastebin_file(file):
def do_pastebin_file(args):
"""
Send the `file` to dpaste, returning URL for the raw file.
"""
# DPASTE API USE RULES:
# - user-agent must be set properly
# - 1 second between requests
trace(f"sending `{file}' to dpaste...")
r = requests.post(
DPASTE_URL + "/api/v2/",
data={
"content": Path(file).read_text(),
"syntax": "diff",
"title": os.path.basename(file),
"expiry_days": 1, # TODO remove after testing
},
headers={"User-agent": f"patchodon v{__version__}"},
timeout=300, # TODO passthrough args
)
time.sleep(1.1)
if r.status_code != 201:
raise RuntimeError("dpaste POST failed for `{file}'")
return r.headers["location"] + ".txt"
def f(file):
# DPASTE API USE RULES:
# - user-agent must be set properly
# - 1 second between requests
trace(f"sending `{file}' to dpaste...")
r = requests.post(
DPASTE_URL + "/api/v2/",
data={
"content": Path(file).read_text(),
"syntax": "diff",
"title": os.path.basename(file),
"expiry_days": args.paste_expire_days,
},
headers={"User-agent": f"patchodon v{__version__}"},
timeout=args.timeout,
)
time.sleep(1.1)
if r.status_code != 201:
raise RuntimeError("dpaste POST failed for `{file}'")
return r.headers["location"] + ".txt"
return f
def split_off_diff(s):
@ -150,12 +169,13 @@ def do_post(args):
)
short_hashes = mapl(lambda x: x[0:8], hashes)
full_hash = hashlib.sha1(" ".join(hashes).encode()).hexdigest()
paste_raw_urls = mapl(do_pastebin_file, files)
paste_raw_urls = mapl(do_pastebin_file(args), files)
trace("posting the header...")
parent_post_id, url = do_post_status(
args,
f"{mayline(args.recipient)}{mayline(args.subject)}"
f"[patchodon: {full_hash} / {' '.join(short_hashes)}]",
True,
)
for fn, pst, hsh, series in zip(
files, paste_raw_urls, hashes, range(n_patches)
@ -166,6 +186,7 @@ def do_post(args):
f"{mayline(args.recipient)}"
f"[patchodon {series+1}/{n_patches} {hsh}]\n"
f"{pst}\n",
False,
parent=parent_post_id,
optional=split_off_diff(Path(fn).read_text()),
)
@ -384,6 +405,12 @@ def main():
" target project and patch topic"
),
)
post.add_argument(
"-x",
"--paste-expire-days",
default=14,
help="how many days should dpaste.com hold the patches (default: 14)",
)
post.add_argument(
"patchfile",
nargs="*",
@ -393,6 +420,31 @@ def main():
" into patchodon)"
),
)
visibility = post.add_mutually_exclusive_group()
visibility.add_argument(
"--public",
action="store_true",
help=(
"post head status publicly, patches unlisted (this is the default)"
),
)
visibility.add_argument(
"--all-public",
action="store_true",
help="post head status and all patches publicly",
)
visibility.add_argument(
"--private",
action="store_true",
help=(
"post statuses as private (visible by followers and recipient only)"
),
)
visibility.add_argument(
"--direct",
action="store_true",
help="post statuses as direct (visible only by the tagged recipients)",
)
get = cmds.add_parser("get")
get.add_argument(