maybe a fork of sparrowhe's "bluesky circle" webapp, to frontend only?
1from PIL import Image, ImageOps, ImageDraw 2import math 3import requests 4from io import BytesIO 5from atproto import Client 6 7def parse_friends(client: Client, handle: str) -> dict: 8 friends = dict() 9 def update_data(friendData): 10 did = friendData.pop('did') 11 if did in friends: 12 friends[did]['reply_score'] += friendData['reply_score'] 13 else: 14 friends[did] = friendData 15 # Get profile's posts. Use pagination (cursor + limit) to fetch all 16 profile_feed = client.get_author_feed(actor=handle) 17 for feed_view in profile_feed.feed: 18 if feed_view.post.record.reply != None: 19 reply_parent = feed_view.post.record.reply.parent 20 try: 21 reply_parent_author = client.get_post_thread(reply_parent.uri).thread.post.author 22 except: 23 continue # Skip if the author of the parent post is not found 24 25 if reply_parent_author.handle == handle: 26 continue 27 friendData = { 28 'did': reply_parent_author.did, 29 'avatar': reply_parent_author.avatar, 30 'display_name': reply_parent_author.display_name, 31 'reply_score': 1, 32 } 33 update_data(friendData) 34 elif feed_view.post.author.handle == handle: 35 replies = client.get_post_thread(feed_view.post.uri).thread.replies 36 for reply in replies: 37 if reply.post.author.handle == handle: 38 continue 39 friendData = { 40 'did': reply.post.author.did, 41 'avatar': reply.post.author.avatar, 42 'display_name': reply.post.author.display_name, 43 'reply_score': 1.5, 44 } 45 update_data(friendData) 46 47 return friends