From: Simon Tatham Date: Thu, 7 Dec 2023 05:33:13 +0000 (+0000) Subject: Show a Re: header on reply posts. X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ian/git?a=commitdiff_plain;h=285edd8a45118e1d8b14166ed52f5a588853cadf;p=mastodonochrome.git Show a Re: header on reply posts. --- diff --git a/client.py b/client.py index 302c135..38bf8dc 100644 --- a/client.py +++ b/client.py @@ -27,6 +27,10 @@ class Client: self.bearer_token = None self.log_response = lambda *args, **kws: None + # A global cache across all feeds etc of statuses by id, so + # that we can look up the text of one to show in a 'Re:' header + self.status_cache = {} + def set_instance_url(self, instance_url): self.instance_url = instance_url self.urls = { @@ -156,6 +160,16 @@ class Client: def ego_feed(self): return EgoFeed(self) + def cache_status(self, status): + self.status_cache[status['id']] = status + + def get_status_by_id(self, id): + if id in self.status_cache: + return self.status_cache[id] + st = self.get(f"statuses/{id}") + self.cache_status(st) + return st + 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 @@ -242,6 +256,8 @@ class Status: else: self.booster = None + client.cache_status(data) + self.post_id = data['id'] self.datestamp = parse_creation_time(data['created_at']) @@ -255,6 +271,8 @@ class Status: self.media = data.get('media_attachments', []) + self.reply_id = data.get('in_reply_to_id') + self.client = client def text(self): @@ -264,6 +282,15 @@ class Status: if self.booster is not None: yield text.BoosterLine(self.client.fq(self.booster['acct']), self.booster['display_name']) + if self.reply_id is not None: + hp = text.HTMLParser() + try: + reply_status = self.client.get_status_by_id(self.reply_id) + hp.feed(reply_status['content']) + except HTTPError as ex: + hp.feed(f'[unavailable: {ex.response.status_code}]') + hp.done() + yield text.InReplyToLine(hp.paras) yield text.BlankLine() yield from self.content if len(self.content) > 0: @@ -279,6 +306,7 @@ class Notification: self.datestamp = parse_creation_time(data['created_at']) st = data.get('status') if st is not None: + client.cache_status(st) hp = text.HTMLParser() hp.feed(st['content']) hp.done() diff --git a/text.py b/text.py index 7e1de02..43220b9 100644 --- a/text.py +++ b/text.py @@ -142,6 +142,30 @@ class BoosterLine(UsernameHeader): header = "Via" colour = "f" +class InReplyToLine: + def __init__(self, cparas): + self.para = Paragraph() + self.para.add(ColouredString("Re:")) + self.para.end_word() + + currlen = len(self.para) + for cpara in cparas: + self.para.add_para(cpara) + self.para.delete_mention_words_from(currlen) + + def render(self, width): + it = self.para.render(width-3) + line = next(it) + try: + next(it) + + if line.width < width-3: + line += ColouredString(" ") + line += ColouredString("...") + except StopIteration: + pass + yield line + class Media: def __init__(self, url, description): self.url = url