#!/usr/bin/env python3importosimportsubprocessimportsysfrompathlibimportPathUPLOAD_URL="https://st.ht/api/upload"SITE_DIR=Path("_site")ARCHIVE_PATH=Path(".stht-upload/site.tar.gz")MAX_ARCHIVE_BYTES=32*1024*1024deffail(message:str):print(message,file=sys.stderr)sys.exit(1)defrun(*args:str):print("$"," ".join(args))result=subprocess.run(args)ifresult.returncode!=0:fail(f"Command failed with exit code {result.returncode}: {args[0]}")deffmt_mib(n:int)->str:returnf"{n/1024/1024:.2f} MiB"token=os.environ.get("STHT_TOKEN")ifnottoken:fail("Missing STHT_TOKEN. Export it before running.")run("bun","run","build")ifnot(SITE_DIR/"index.html").exists():fail(f"Missing {SITE_DIR}/index.html. st.ht requires index.html at the archive root.")ARCHIVE_PATH.parent.mkdir(parents=True,exist_ok=True)ARCHIVE_PATH.unlink(missing_ok=True)run("tar","-czf",str(ARCHIVE_PATH),"-C",str(SITE_DIR),".")size=ARCHIVE_PATH.stat().st_sizeifsize>MAX_ARCHIVE_BYTES:fail(f"Archive is too large: {fmt_mib(size)}. Maximum is {fmt_mib(MAX_ARCHIVE_BYTES)}.")print(f"Uploading {ARCHIVE_PATH} ({fmt_mib(size)}) to st.ht...")importurllib.requestwithopen(ARCHIVE_PATH,"rb")asf:data=f.read()boundary="----PythonFormBoundary"body=(f"--{boundary}\r\n"f'Content-Disposition: form-data; name="file"; filename="site.tar.gz"\r\n'f"Content-Type: application/gzip\r\n\r\n").encode()+data+f"\r\n--{boundary}--\r\n".encode()req=urllib.request.Request(UPLOAD_URL,data=body,headers={"Authorization":f"Bearer {token}","Content-Type":f"multipart/form-data; boundary={boundary}",},method="POST",)try:withurllib.request.urlopen(req)asresp:print(resp.read().decode()or"Upload complete.")excepturllib.error.HTTPErrorase:fail(f"Upload failed: HTTP {e.code}{e.reason}\n{e.read().decode()}")ARCHIVE_PATH.unlink(missing_ok=True)
Warning
LINK
You are about to visit a link which has been flagged with the above content warnings. Do you wish to continue?