"""List my own top-level Bluesky posts (public appview, no login). Writes posts.json.""" import importlib.util, json, sys, urllib.parse from pathlib import Path sp = importlib.util.spec_from_file_location("core", Path(__file__).with_name("bsky_public.py")) core = importlib.util.module_from_spec(sp); sp.loader.exec_module(core) out, cur = [], "" while True: j = core._pub("app.bsky.feed.getAuthorFeed", f"actor={core.MY_DID}&limit=100&filter=posts_no_replies" + (f"&cursor={urllib.parse.quote(cur)}" if cur else "")) for it in j.get("feed", []): p = it["post"] if it.get("reason") or p["author"]["did"] != core.MY_DID: continue out.append({"uri": p["uri"], "rkey": p["uri"].rsplit("/", 1)[1], "created": p["record"]["createdAt"], "text": p["record"].get("text", ""), "likes": p.get("likeCount", 0), "reposts": p.get("repostCount", 0), "replies": p.get("replyCount", 0), "quotes": p.get("quoteCount", 0)}) cur = j.get("cursor") if not cur or not j.get("feed"): break out.sort(key=lambda x: x["created"]) Path("posts.json").write_text(json.dumps(out, indent=1, ensure_ascii=False), encoding="utf-8") for p in out: print(p["created"][:16], p["rkey"], f"L{p['likes']} R{p['reposts']} re{p['replies']} q{p['quotes']}", p["text"][:90].replace("\n", " ")) print(len(out), "posts")