chiark / gitweb /
UNTESTED attempt to make bidirectional incremental feeds
authorSimon Tatham <anakin@pobox.com>
Mon, 4 Dec 2023 19:58:56 +0000 (19:58 +0000)
committerSimon Tatham <anakin@pobox.com>
Mon, 4 Dec 2023 19:58:56 +0000 (19:58 +0000)
client.py

index 20e6d666bd45afabcbb2b2461474350c04db89aa..7c44d249b0679b90a63a220a39c9245668688d0c 100644 (file)
--- a/client.py
+++ b/client.py
@@ -99,6 +99,15 @@ class Client:
                 break
             base, path = None, links['next']
 
+    def get_incremental_start(self, path, base='api', **params):
+        params.setdefault('limit', 32)
+        data = self.method(requests.get, path, base, params, links)
+        return data, links
+
+    def get_incremental_cont(self, link):
+        data = self.method(requests.get, link, None, {}, links)
+        return data, links
+
     def get_url(self, path, base='api', **params):
         r = requests.Request(method="GET", url=self.urls[base] + path,
                              params=params)
@@ -109,6 +118,57 @@ class Client:
         return (account_name if '@' in account_name
                 else account_name + '@' + self.instance_domain)
 
+class Feed:
+    """Base class that encapsulates some kind of collection of _things_ we
+    can get from the server, with both the ability to go backwards in
+    time (into existing history) and forwards in time (waiting for
+    updates that maybe haven't yet been posted).
+    """
+    def __init__(self, client):
+        self.client = client
+
+class IncrementalServerFeed(Feed):
+    """A Feed that fetches something from the server via get_incremental."""
+
+    def __init__(self, client, url, params, get=lambda item: item):
+        super().__init__(client)
+        self.url = url
+        self.params = params
+        self.get = get
+
+    def start(self):
+        data, links = self.client.get_incremental_start(self.url, self.params)
+        self.data = list(reversed(data))
+        self.origin = len(self.data)
+        self.prev_link = self.links['prev']
+        self.next_link = self.links['next']
+
+    def min_index(self):
+        return -self.origin
+    def max_index(self):
+        return len(self.data) - self.origin
+    def __getitem__(self, n):
+        return self.data[n + self.origin]
+
+    def extend_past(self):
+        data, links = self.client.get_incremental_cont(links, 'prev')
+        self.data[0:0] = list(reversed(data))
+        self.origin += len(data)
+        self.prev_link = self.links['prev']
+
+    def extend_future(self):
+        data, links = self.client.get_incremental_cont(links, 'next')
+        self.data.extend(reversed(data))
+        self.next_link = self.links['next']
+
+class HomeTimelineFeed(IncrementalServerFeed):
+    def __init__(self, client):
+        super().__init__(client, "timelines/home")
+
+class MentionsFeed(IncrementalServerFeed):
+    def __init__(self, client):
+        super().__init__(client, "notifications", **{"types[]":['mention']})
+
 class Status:
     def __init__(self, data, client):
         rb = data.get('reblog')