From: Simon Tatham Date: Fri, 15 Dec 2023 07:56:14 +0000 (+0000) Subject: Lists of followers, folllowees, favers and boosters. X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ian/git?a=commitdiff_plain;h=89814465c4a3053dc26b011a703c2b8e66e13ae0;p=mastodonochrome.git Lists of followers, folllowees, favers and boosters. --- diff --git a/client.py b/client.py index e24d710..8fbc42f 100644 --- a/client.py +++ b/client.py @@ -260,6 +260,10 @@ class UserStatusesFeed(IncrementalServerFeed): def __init__(self, client, account_id): super().__init__(client, f"accounts/{account_id}/statuses", {}) +class UserListFeed(IncrementalServerFeed): + def __init__(self, client, url): + super().__init__(client, url, {}) + class ThreadFeed(Feed): def __init__(self, client, post_id, full): super().__init__(client) @@ -636,3 +640,19 @@ class UserInfo: yield self.client.fq(self.account['acct']) def get_reply_id(self): return None + +class UserListEntry: + def __init__(self, data, client): + self.account = data + self.client = client + + def text(self): + yield text.UserListEntry(self.client.fq(self.account['acct']), + self.account['display_name']) + + def get_account_id(self): + return self.account['id'] + def get_reply_recipients(self): + yield self.client.fq(self.account['acct']) + def get_reply_id(self): + return None diff --git a/cursesclient.py b/cursesclient.py index 44a70bf..16f9624 100644 --- a/cursesclient.py +++ b/cursesclient.py @@ -729,6 +729,14 @@ class ObjectFile(File): sl.keys.append(('-', None)) sl.keys.append(('+', None)) sl.keys.append(('Q', 'Quit')) + elif self.mode == 'list_users': + if isinstance(self, UserInfoFile): + sl.keys.append(('I', 'List Followers')) + sl.keys.append(('O', 'List Followed')) + if isinstance(self, StatusInfoFile): + sl.keys.append(('F', 'List Favouriters')) + sl.keys.append(('B', 'List Boosters')) + sl.keys.append(('Q', 'Quit')) else: if self.linepos >= len(self.lines): sl.keys.append(('-', 'Up')) @@ -742,6 +750,9 @@ class ObjectFile(File): # sl.keys.append(('E', 'Examine')) if isinstance(self, UserInfoFile): sl.keys.append(('P', 'Posts')) + sl.keys.append(('L', 'List')) + if isinstance(self, StatusInfoFile): + sl.keys.append(('L', 'List')) if self.items_are_statuses: sl.keys.append(('F', 'Fave')) sl.keys.append(('^B', 'Boost')) @@ -913,20 +924,48 @@ class NotificationsFile(ObjectFile): def __init__(self, cc, feed, title): super().__init__(cc, client.Notification, feed, title) +class UserListFile(ObjectFile): + items_are_statuses = False + items_have_authors = True + def __init__(self, cc, feed, title): + super().__init__(cc, client.UserListEntry, feed, title) + class StatusInfoFile(ObjectFile): items_are_statuses = True items_have_authors = True def __init__(self, cc, postid): title = text.ColouredString(f"Information about post {postid}", 'H') self.data = cc.get_status_by_id(postid) + self.postid = postid super().__init__( cc, lambda x,cc:x, client.StatusInfoFeed(cc, self.data), title) + def handle_key(self, ch): + if self.mode == 'normal' and ch in {'l', 'L'}: + self.mode = 'list_users' + elif self.mode == 'list_users' and ch in {'f', 'F'}: + feed = client.UserListFeed(self.cc, + f"statuses/{self.postid}/favourited_by") + title = text.ColouredString( + f"Users who favourited post {self.postid}", 'H') + self.chain_to(UserListFile(self.cc, feed, title)) + elif self.mode == 'list_users' and ch in {'b', 'B'}: + feed = client.UserListFeed(self.cc, + f"statuses/{self.postid}/reblogged_by") + title = text.ColouredString( + f"Users who boosted post {self.postid}", 'H') + self.chain_to(UserListFile(self.cc, feed, title)) + elif self.mode == 'list_users': + self.mode = 'normal' + else: + return super().handle_key(ch) + class UserInfoFile(ObjectFile): items_are_statuses = False items_have_authors = True def __init__(self, cc, account): self.account = account + self.account_id = account['id'] name = cc.fq(account['acct']) title = text.ColouredString(f"Information about user {name}", 'H') super().__init__( @@ -939,10 +978,26 @@ class UserInfoFile(ObjectFile): def handle_key(self, ch): if self.mode == 'normal' and ch in {'p', 'P'}: - feed = client.UserStatusesFeed(self.cc, self.account['id']) + feed = client.UserStatusesFeed(self.cc, self.account_id) name = self.cc.fq(self.account['acct']) title = text.ColouredString(f"Posts from user {name}", 'H') self.chain_to(StatusFile(self.cc, feed, title)) + elif self.mode == 'normal' and ch in {'l', 'L'}: + self.mode = 'list_users' + elif self.mode == 'list_users' and ch in {'i', 'I'}: + feed = client.UserListFeed(self.cc, + f"accounts/{self.account_id}/followers") + name = self.cc.fq(self.account['acct']) + title = text.ColouredString(f"Users who follow {name}", 'H') + self.chain_to(UserListFile(self.cc, feed, title)) + elif self.mode == 'list_users' and ch in {'o', 'O'}: + feed = client.UserListFeed(self.cc, + f"accounts/{self.account_id}/following") + name = self.cc.fq(self.account['acct']) + title = text.ColouredString(f"Users who {name} follows", 'H') + self.chain_to(UserListFile(self.cc, feed, title)) + elif self.mode == 'list_users': + self.mode = 'normal' else: return super().handle_key(ch) diff --git a/text.py b/text.py index 2b8b627..1543124 100644 --- a/text.py +++ b/text.py @@ -455,6 +455,21 @@ class NotificationLog: line += ColouredString("...") yield line +class UserListEntry: + can_highlight_as_target = True + + def __init__(self, account, nameline): + self.account = account + self.nameline = nameline + self.account_desc = f"{self.nameline} ({self.account})" + + def render(self, width, target=False): + para = IndentedParagraph(0, 2) + para.add(ColouredString( + self.account_desc, "f" if target else " ")) + para.end_word() + yield from para.render(width) + class HTMLParser(html.parser.HTMLParser): def __init__(self): super().__init__()