Daniel Schwarz 2023-11-26 21:04:40 +00:00 zatwierdzone przez GitHub
commit f1ee086aa2
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
8 zmienionych plików z 102 dodań i 28 usunięć

Wyświetl plik

@ -38,12 +38,16 @@ setup(
"beautifulsoup4>=4.5.0,<5.0",
"wcwidth>=0.1.7",
"urwid>=2.0.0,<3.0",
"tomlkit>=0.10.0,<1.0"
"tomlkit>=0.10.0,<1.0",
],
extras_require={
# Required to display rich text in the TUI
"richtext": [
"urwidgets>=0.1,<0.2"
"urwidgets>=0.1,<0.2",
],
"markdown": [
"pypandoc>=1.12.0,<2.0",
"pypandoc-binary>=1.12.0,<2.0",
],
"dev": [
"coverage",

Wyświetl plik

@ -363,8 +363,6 @@ def test_notifications(mock_get, capsys):
"────────────────────────────────────────────────────────────────────────────────────────────────────",
"",
])
@mock.patch('toot.http.get')
def test_notifications_empty(mock_get, capsys):
mock_get.return_value = MockResponse([])

Wyświetl plik

@ -5,7 +5,8 @@ import textwrap
from functools import lru_cache
from toot import settings
from toot.utils import get_text, html_to_paragraphs
from toot.utils import get_text
from toot.richtext import html_to_text
from toot.entities import Account, Instance, Notification, Poll, Status
from toot.wcstring import wc_wrap
from typing import Iterable, List
@ -174,7 +175,6 @@ def print_account(account: Account):
print_out(f"<green>@{account.acct}</green> {account.display_name}")
if account.note:
print_out("")
print_html(account.note)
since = account.created_at.strftime('%Y-%m-%d')
@ -299,7 +299,6 @@ def print_status(status: Status, width: int = 80):
f"<yellow>{time}</yellow>",
)
print_out("")
print_html(status.content, width)
if status.media_attachments:
@ -322,14 +321,9 @@ def print_status(status: Status, width: int = 80):
def print_html(text, width=80):
first = True
for paragraph in html_to_paragraphs(text):
if not first:
print_out("")
for line in paragraph:
for subline in wc_wrap(line, width):
print_out(highlight_hashtags(subline))
first = False
markdown = "\n".join(html_to_text(text, columns=width, highlight_tags=False))
print_out("")
print_out(markdown)
def print_poll(poll: Poll):

Wyświetl plik

@ -0,0 +1,25 @@
from toot.tui.utils import highlight_hashtags
from toot.utils import html_to_paragraphs
from toot.wcstring import wc_wrap
from typing import List
try:
# first preference, render markup with pypandoc
from .markdown import html_to_text
except ImportError:
# Fallback to render in plaintext
def html_to_text(html: str, columns=80, highlight_tags=False) -> List:
output = []
first = True
for paragraph in html_to_paragraphs(html):
if not first:
output.append("")
for line in paragraph:
for subline in wc_wrap(line, columns):
if highlight_tags:
output.append(highlight_hashtags(subline))
else:
output.append(subline)
first = False
return output

Wyświetl plik

@ -0,0 +1,11 @@
from pypandoc import convert_text
from typing import List
def html_to_text(html: str, columns=80, highlight_tags=False) -> List:
return [convert_text(
html,
format="html",
to="gfm-raw_html",
extra_args=["--wrap=auto", f"--columns={columns}"],
)]

Wyświetl plik

@ -7,6 +7,8 @@ from concurrent.futures import ThreadPoolExecutor
from toot import api, config, __version__, settings
from toot.console import get_default_visibility
from toot.exceptions import ApiError
from toot.richtext import html_to_text
from toot.utils.datetime import parse_datetime
from .compose import StatusComposer
from .constants import PALETTE
@ -659,9 +661,22 @@ class TUI(urwid.Frame):
return self.run_in_thread(_delete, done_callback=_done)
def copy_status(self, status):
# TODO: copy a better version of status content
# including URLs
copy_to_clipboard(self.screen, status.original.data["content"])
markdown = "\n".join(html_to_text(status.original.data["content"], columns=1024, highlight_tags=False))
time = parse_datetime(status.original.data['created_at'])
time = time.strftime('%Y-%m-%d %H:%M %Z')
text_status = (f"{status.original.data['url']}\n\n"
+ (status.original.author.display_name or "")
+ "\n"
+ (status.original.author.account or "")
+ "\n\n"
+ markdown
+ "\n\n"
+ f"Created at: {time}")
copy_to_clipboard(self.screen, text_status)
self.footer.set_message(f"Status {status.original.id} copied")
# --- Overlay handling -----------------------------------------------------

Wyświetl plik

@ -1,18 +1,24 @@
import urwid
from toot.tui.utils import highlight_hashtags
from toot.utils import format_content
from typing import List
try:
# our first preference is to render using urwidgets
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]:
return [
urwid.Text(highlight_hashtags(line))
for line in format_content(html)
]
def url_to_widget(url: str):
return urwid.Text(("link", url))
except ImportError:
try:
# second preference, render markup with pypandoc
from .markdown import html_to_widgets, url_to_widget
except ImportError:
# Fallback to render in plaintext
def url_to_widget(url: str):
return urwid.Text(("link", url))
def html_to_widgets(html: str) -> List[urwid.Widget]:
return [
urwid.Text(highlight_hashtags(line)) for line in format_content(html)
]

Wyświetl plik

@ -0,0 +1,21 @@
import urwid
from pypandoc import convert_text
from typing import List
def url_to_widget(url: str):
return urwid.Text(("link", url))
def html_to_widgets(html: str) -> List[urwid.Widget]:
return [
urwid.Text(
convert_text(
html,
format="html",
to="gfm-raw_html",
extra_args=["--wrap=none"],
)
)
]