a digital entity named phi that roams bsky
1#!/usr/bin/env python3
2"""View phi's recent posts without authentication."""
3
4import httpx
5from datetime import datetime
6from rich.console import Console
7from rich.panel import Panel
8from rich.text import Text
9
10console = Console()
11
12PHI_HANDLE = "phi.zzstoatzz.io"
13
14
15def fetch_phi_posts(limit: int = 10):
16 """Fetch phi's recent posts using public API."""
17 # Resolve handle to DID
18 response = httpx.get(
19 "https://public.api.bsky.app/xrpc/com.atproto.identity.resolveHandle",
20 params={"handle": PHI_HANDLE}
21 )
22 did = response.json()["did"]
23
24 # Get author feed (public posts)
25 response = httpx.get(
26 "https://public.api.bsky.app/xrpc/app.bsky.feed.getAuthorFeed",
27 params={"actor": did, "limit": limit}
28 )
29
30 return response.json()["feed"]
31
32
33def format_timestamp(iso_time: str) -> str:
34 """Format ISO timestamp to readable format."""
35 dt = datetime.fromisoformat(iso_time.replace("Z", "+00:00"))
36 now = datetime.now(dt.tzinfo)
37 delta = now - dt
38
39 if delta.seconds < 60:
40 return f"{delta.seconds}s ago"
41 elif delta.seconds < 3600:
42 return f"{delta.seconds // 60}m ago"
43 elif delta.seconds < 86400:
44 return f"{delta.seconds // 3600}h ago"
45 else:
46 return f"{delta.days}d ago"
47
48
49def display_posts(feed_items):
50 """Display posts in a readable format."""
51 for item in feed_items:
52 post = item["post"]
53 record = post["record"]
54
55 # Check if this is a reply
56 is_reply = "reply" in record
57 reply_indicator = "↳ REPLY" if is_reply else "✓ POST"
58
59 # Format header
60 timestamp = format_timestamp(post["indexedAt"])
61 header = f"[cyan]{reply_indicator}[/cyan] [dim]{timestamp}[/dim]"
62
63 # Get post text
64 text = record.get("text", "[no text]")
65
66 # Show parent if it's a reply
67 parent_text = ""
68 if is_reply:
69 parent_uri = record["reply"]["parent"]["uri"]
70 parent_text = f"[dim]replying to: {parent_uri}[/dim]\n\n"
71
72 # Format post
73 content = Text()
74 if parent_text:
75 content.append(parent_text, style="dim")
76 content.append(text)
77
78 # Display
79 panel = Panel(
80 content,
81 title=header,
82 border_style="blue" if is_reply else "green",
83 width=80
84 )
85 console.print(panel)
86 console.print()
87
88
89def main():
90 console.print("[bold]Fetching phi's recent posts...[/bold]\n")
91
92 try:
93 feed = fetch_phi_posts(limit=10)
94 display_posts(feed)
95 console.print(f"[dim]Showing {len(feed)} most recent posts[/dim]")
96 except Exception as e:
97 console.print(f"[red]Error: {e}[/red]")
98
99
100if __name__ == "__main__":
101 main()