chiark / gitweb /
Lists of followers, folllowees, favers and boosters.
authorSimon Tatham <anakin@pobox.com>
Fri, 15 Dec 2023 07:56:14 +0000 (07:56 +0000)
committerSimon Tatham <anakin@pobox.com>
Fri, 15 Dec 2023 08:08:00 +0000 (08:08 +0000)
client.py
cursesclient.py
text.py

index e24d7108d655178ffcd206964ef5db3a24930d42..8fbc42fa41822fe7c7dec5cefc6eced5b957a58f 100644 (file)
--- 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
index 44a70bf4d91e4e7abf2131bb75362179783a1168..16f962401ea71a570fab6da676e67a63c6e576ba 100644 (file)
@@ -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 2b8b627d0e3cfcaea996833c17f3b21b0a104b17..1543124d54c4594737e5477e9e50aeacae7743ff 100644 (file)
--- 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__()