Something went wrong. Try again.
CLI tools and operational extensions for the void architecture on ATProtocol.
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129#!/usr/bin/env python3"""Fetch posts from void.comind.network and analyze the writing style.Paginate backward to find posts created before February 28, 2026."""
from atproto import Clientfrom datetime import datetime, timezoneimport jsonimport osfrom dotenv import load_dotenv
def main(): # Load environment variables load_dotenv() # Get credentials username = os.getenv('BSKY_USERNAME') password = os.getenv('BSKY_PASSWORD') pds_uri = os.getenv('PDS_URI', 'https://comind.network') print(f"Logging in as: {username}") print(f"PDS URI: {pds_uri}") # Initialize client with PDS URI client = Client(pds_uri) # Login with the void's credentials try: client.login(username, password) print("Login successful!") except Exception as e: print(f"Login error: {e}") return # Resolve the handle to DID handle = "void.comind.network" print(f"\nResolving handle: {handle}") try: profile = client.get_profile(handle) did = profile.did print(f"Resolved DID: {did}") except Exception as e: print(f"Error resolving handle: {e}") return # Target date: February 28, 2026 00:00:00 UTC target_date = datetime(2026, 2, 28, 0, 0, 0, tzinfo=timezone.utc) target_timestamp = target_date.timestamp() print(f"\nFetching posts before: {target_date.isoformat()}") print("=" * 60) # Collect posts before the target date older_posts = [] cursor = None while len(older_posts) < 30: try: # Get author feed response = client.get_author_feed(did, cursor=cursor, limit=50) if not response.feed: print("No more posts available.") break for item in response.feed: post = item.post # Get the post's creation time created_at = post.record.created_at # Parse ISO format timestamp post_time = datetime.fromisoformat(created_at.replace('Z', '+00:00')) post_timestamp = post_time.timestamp() # Extract text content text = "" if hasattr(post.record, 'text'): text = post.record.text if post_timestamp < target_timestamp: older_posts.append({ 'uri': post.uri, 'cid': post.cid, 'created_at': created_at, 'text': text, 'reply_count': post.reply_count if hasattr(post, 'reply_count') else 0, 'repost_count': post.repost_count if hasattr(post, 'repost_count') else 0, 'like_count': post.like_count if hasattr(post, 'like_count') else 0, }) if len(older_posts) >= 30: break # Check if we have more pages cursor = response.cursor if not cursor: print("Reached end of feed.") break print(f"Fetched {len(older_posts)} older posts so far...") except Exception as e: print(f"Error fetching feed: {e}") break print(f"\n{'=' * 60}") print(f"Collected {len(older_posts)} posts before Feb 28, 2026") print("=" * 60) # Output the posts print("\n\n### POSTS ###\n") for i, post in enumerate(older_posts, 1): print(f"\n--- Post {i} ---") print(f"Date: {post['created_at']}") print(f"Text:\n{post['text']}") print(f"Engagement: {post['like_count']} likes, {post['repost_count']} reposts, {post['reply_count']} replies") # Save to JSON for further analysis with open('/home/cameron/void/void_posts.json', 'w') as f: json.dump(older_posts, f, indent=2) print(f"\n\nSaved {len(older_posts)} posts to /home/cameron/void/void_posts.json") return older_posts
if __name__ == "__main__": posts = main()