From 25154cbc20983aba7c1c2715c5bbb2fe55cf7ceb Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Sat, 2 Dec 2023 17:38:25 +0000 Subject: [PATCH] Show media attachments in posts --- client.py | 4 ++++ cursesclient.py | 2 ++ mastodonochrome | 1 + text.py | 48 +++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 54 insertions(+), 1 deletion(-) diff --git a/client.py b/client.py index fae611c..e7640f1 100644 --- a/client.py +++ b/client.py @@ -98,6 +98,8 @@ class Status: hp.done() self.content = hp.paras + self.media = data.get('media_attachments', []) + def text(self): yield text.SeparatorLine(self.datestamp) yield text.FromLine('@' + self.account['acct'], @@ -108,3 +110,5 @@ class Status: yield text.BlankLine() yield from self.content yield text.BlankLine() + for media in self.media: + yield text.Media(media['url'], media.get('description')) diff --git a/cursesclient.py b/cursesclient.py index 8690074..bd821fd 100644 --- a/cursesclient.py +++ b/cursesclient.py @@ -47,6 +47,8 @@ class CursesUI(client.Client): attr, fg, bg = 0, default_fg, default_bg elif code == 1: attr |= curses.A_BOLD + elif code == 4: + attr |= curses.A_UNDERLINE elif code == 7: attr |= curses.A_REVERSE elif 30 <= code <= 37: diff --git a/mastodonochrome b/mastodonochrome index fdfd3ee..b857039 100755 --- a/mastodonochrome +++ b/mastodonochrome @@ -25,6 +25,7 @@ class MyTestLoader(unittest.TestLoader): def loadTestsFromModule(self, module): suite = super().loadTestsFromModule(module) if module.__name__ == '__main__': + import text suite.addTests(super().loadTestsFromModule(text)) return suite diff --git a/text.py b/text.py index dfa17eb..684035a 100644 --- a/text.py +++ b/text.py @@ -20,6 +20,8 @@ colourmap = { 'c': [0, 33], '#': [0, 36], '@': [0, 32], + 'M': [0, 1, 4, 35], + 'm': [0, 35], } class ColouredString: @@ -118,6 +120,23 @@ class BoosterLine(UsernameHeader): header = "Via" colour = "f" +class Media: + def __init__(self, url, description): + self.url = url + if description is None: + self.description = None + else: + self.description = Paragraph() + self.description.add(ColouredString(description, 'm')) + self.description.end_word() + + def render(self, width): + yield ColouredString(self.url, "M") + if self.description is not None: + for line in self.description.render(width-4): + yield ColouredString(" ") + line + yield ColouredString("") + class Paragraph: def __init__(self): self.words = [] @@ -152,7 +171,7 @@ class Paragraph: def add(self, text): for c in text: - if c == ' ': + if str(c) == ' ': self.end_word() else: self.unfinished_word += c @@ -295,3 +314,30 @@ class RenderTests(unittest.TestCase): ColouredString('Test of a @username', ' @@@@@@@@@'), ]) + + def testMedia(self): + ma = Media('https://a.b/c', 'foo foo foo foo foo foo foo') + self.assertEqual(list(ma.render(16)), [ + ColouredString('https://a.b/c', + 'MMMMMMMMMMMMM'), + ColouredString(' foo foo foo', + ' mmm mmm mmm'), + ColouredString(' foo foo foo', + ' mmm mmm mmm'), + ColouredString(' foo', + ' mmm'), + ColouredString(''), + ]) + self.assertEqual(list(ma.render(15)), [ + ColouredString('https://a.b/c', + 'MMMMMMMMMMMMM'), + ColouredString(' foo foo', + ' mmm mmm'), + ColouredString(' foo foo', + ' mmm mmm'), + ColouredString(' foo foo', + ' mmm mmm'), + ColouredString(' foo', + ' mmm'), + ColouredString(''), + ]) -- 2.30.2