diff --git a/src/void_tools/cli.py b/src/void_tools/cli.py index b946846..61b7ae2 100644 --- a/src/void_tools/cli.py +++ b/src/void_tools/cli.py @@ -68,6 +68,63 @@ def cmd_post(args): print(f"Error creating post: {e}", file=sys.stderr) sys.exit(1) +def cmd_search(args): + client = get_client() + try: + print(f"Searching for: '{args.query}'...") + # Note: atproto SDK search_posts takes q, limit, etc. + response = client.app.bsky.feed.search_posts({'q': args.query, 'limit': args.limit}) + for post in response.posts: + print(f"From @{post.author.handle}") + print(f" URI: {post.uri}") + print(f" CID: {post.cid}") + print(f" Text: {post.record.text}") + print("-" * 40) + except Exception as e: + print(f"Error searching posts: {e}", file=sys.stderr) + sys.exit(1) + + +def cmd_profile(args): + client = get_client() + if args.action == "view": + actor = args.handle if args.handle else client.me.handle + try: + profile = client.app.bsky.actor.get_profile({'actor': actor}) + print(f"Profile for @{profile.handle}") + print(f"Display Name: {profile.display_name}") + print(f"Description:\n{profile.description}") + except Exception as e: + print(f"Error fetching profile: {e}", file=sys.stderr) + elif args.action == "update": + try: + from atproto import models + try: + record_resp = client.com.atproto.repo.get_record({ + 'repo': client.me.did, + 'collection': 'app.bsky.actor.profile', + 'rkey': 'self' + }) + record = record_resp.value + except Exception: + record = models.AppBskyActorProfile.Main() + + if args.description is not None: + record.description = args.description + if args.display_name is not None: + record.display_name = args.display_name + + client.com.atproto.repo.put_record({ + 'repo': client.me.did, + 'collection': 'app.bsky.actor.profile', + 'rkey': 'self', + 'record': record + }) + print("Profile updated successfully.") + except Exception as e: + print(f"Error updating profile: {e}", file=sys.stderr) + sys.exit(1) + def main(): parser = argparse.ArgumentParser(description="Void ATProto CLI Tools") subparsers = parser.add_subparsers(dest="command", required=True) @@ -82,12 +139,33 @@ def main(): post_parser.add_argument("text", help="Text to post") post_parser.add_argument("--reply-to", help="AT-URI of the post to reply to") + # Search + search_parser = subparsers.add_parser("search", help="Search posts") + search_parser.add_argument("query", help="Search query string") + search_parser.add_argument("--limit", type=int, default=10, help="Number of posts to return") + + + # Profile + profile_parser = subparsers.add_parser("profile", help="Manage profile") + profile_subparsers = profile_parser.add_subparsers(dest="action", required=True) + + view_parser = profile_subparsers.add_parser("view", help="View a profile") + view_parser.add_argument("handle", nargs="?", help="Handle to view (defaults to self)") + + update_parser = profile_subparsers.add_parser("update", help="Update own profile") + update_parser.add_argument("--description", help="New description/bio") + update_parser.add_argument("--display-name", help="New display name") + args = parser.parse_args() if args.command == "notifs": cmd_notifications(args) elif args.command == "post": cmd_post(args) + elif args.command == "search": + cmd_search(args) + elif args.command == "profile": + cmd_profile(args) if __name__ == "__main__": main()