From d6ff3cc3a80f83c834e6cb57602e1e52a4d3df80 Mon Sep 17 00:00:00 2001 From: Ivan Habunek Date: Thu, 16 Nov 2023 11:46:54 +0100 Subject: [PATCH] Extract url_to_widget, add fallback --- toot/tui/richtext/__init__.py | 5 ++++- toot/tui/richtext/richtext.py | 5 +++++ toot/tui/timeline.py | 23 +++-------------------- 3 files changed, 12 insertions(+), 21 deletions(-) diff --git a/toot/tui/richtext/__init__.py b/toot/tui/richtext/__init__.py index 6359c24..07e31c8 100644 --- a/toot/tui/richtext/__init__.py +++ b/toot/tui/richtext/__init__.py @@ -5,7 +5,7 @@ from toot.utils import format_content from typing import List try: - from .richtext import html_to_widgets + from .richtext import html_to_widgets, url_to_widget except ImportError: # Fallback if urwidgets are not available def html_to_widgets(html: str) -> List[urwid.Widget]: @@ -13,3 +13,6 @@ except ImportError: urwid.Text(highlight_hashtags(line)) for line in format_content(html) ] + + def url_to_widget(url: str): + return urwid.Text(("link", url)) diff --git a/toot/tui/richtext/richtext.py b/toot/tui/richtext/richtext.py index 9db7e73..71897c4 100644 --- a/toot/tui/richtext/richtext.py +++ b/toot/tui/richtext/richtext.py @@ -59,6 +59,11 @@ def html_to_widgets(html, recovery_attempt=False) -> List[urwid.Widget]: return widgets[:-1] # but suppress the last blank line +def url_to_widget(url: str): + widget = len(url), urwid.Filler(Hyperlink(url, "link", url)) + return TextEmbed(widget) + + def inline_tag_to_text(tag) -> Tuple: """Convert html tag to plain text with tag as attributes recursively""" markups = process_inline_tag_children(tag) diff --git a/toot/tui/timeline.py b/toot/tui/timeline.py index b278d08..93421ce 100644 --- a/toot/tui/timeline.py +++ b/toot/tui/timeline.py @@ -1,12 +1,11 @@ import logging -import re import urwid import webbrowser from typing import List, Optional from toot.tui import app -from toot.tui.richtext import html_to_widgets +from toot.tui.richtext import html_to_widgets, url_to_widget from toot.utils.datetime import parse_datetime, time_ago from toot.utils.language import language_name @@ -14,8 +13,6 @@ from toot.entities import Status from toot.tui.scroll import Scrollable, ScrollBar from toot.tui.utils import highlight_keys from toot.tui.widgets import SelectableText, SelectableColumns -from toot.utils import urlencode_url -from toot.tui.stubs.urwidgets import Hyperlink, TextEmbed, parse_text, has_urwidgets logger = logging.getLogger("toot") @@ -320,20 +317,6 @@ class StatusDetails(urwid.Pile): if status else ()) return super().__init__(widget_list) - def linkify_content(self, text) -> urwid.Widget: - if not has_urwidgets: - return urwid.Text(("link", text)) - TRANSFORM = { - # convert http[s] URLs to Hyperlink widgets for nesting in a TextEmbed widget - re.compile(r'(https?://[^\s]+)'): - lambda g: (len(g[1]), urwid.Filler(Hyperlink(urlencode_url(g[1]), "link", g[1]))), - } - markup_list = [] - - markup_list.append(parse_text(text, TRANSFORM, - lambda pattern, groups, span: TRANSFORM[pattern](groups))) - return TextEmbed(markup_list, align='left') - def content_generator(self, status, reblogged_by): if reblogged_by: text = "♺ {} boosted".format(reblogged_by.display_name or reblogged_by.username) @@ -368,7 +351,7 @@ class StatusDetails(urwid.Pile): yield ("pack", urwid.Text([("bold", "Media attachment"), " (", m["type"], ")"])) if m["description"]: yield ("pack", urwid.Text(m["description"])) - yield ("pack", self.linkify_content(m["url"])) + yield ("pack", url_to_widget(m["url"])) poll = status.original.data.get("poll") if poll: @@ -428,7 +411,7 @@ class StatusDetails(urwid.Pile): if card["description"]: yield urwid.Text(card["description"].strip()) yield urwid.Text("") - yield self.linkify_content(card["url"]) + yield url_to_widget(card["url"]) def poll_generator(self, poll): for idx, option in enumerate(poll["options"]):