Read media viewer from settings

This commit is contained in:
Ivan Habunek 2023-11-19 10:18:09 +01:00
parent ef19449190
commit 5a83cd7d3b
No known key found for this signature in database
GPG Key ID: F5F0623FF5EBCB3D
4 changed files with 32 additions and 33 deletions

View File

@ -51,6 +51,21 @@ visibility = "unlisted"
scheduled_in = "30 minutes" scheduled_in = "30 minutes"
``` ```
## TUI view images
> Introduced in toot 0.39.0
You can view images in a toot using an external program by setting the
`tui.media_viewer` option to your desired image viewer. When a toot is focused,
pressing `m` will launch the specified executable giving one or more URLs as
arguments. This works well with image viewers like `feh` which accept URLs as
arguments.
```toml
[tui]
media_viewer = "feh"
```
## TUI color palette ## TUI color palette
TUI uses Urwid which provides several color modes. See TUI uses Urwid which provides several color modes. See

View File

@ -1,4 +1,5 @@
import logging import logging
import subprocess
import urwid import urwid
from concurrent.futures import ThreadPoolExecutor from concurrent.futures import ThreadPoolExecutor
@ -14,7 +15,7 @@ from .overlays import ExceptionStackTrace, GotoMenu, Help, StatusSource, StatusL
from .overlays import StatusDeleteConfirmation, Account from .overlays import StatusDeleteConfirmation, Account
from .poll import Poll from .poll import Poll
from .timeline import Timeline from .timeline import Timeline
from .utils import get_max_toot_chars, parse_content_links, show_media, copy_to_clipboard from .utils import get_max_toot_chars, parse_content_links, copy_to_clipboard
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -138,6 +139,7 @@ class TUI(urwid.Frame):
self.can_translate = False self.can_translate = False
self.account = None self.account = None
self.followed_accounts = [] self.followed_accounts = []
self.media_viewer = settings.get_setting("tui.media_viewer", str)
super().__init__(self.body, header=self.header, footer=self.footer) super().__init__(self.body, header=self.header, footer=self.footer)
@ -498,8 +500,13 @@ class TUI(urwid.Frame):
def show_media(self, status): def show_media(self, status):
urls = [m["url"] for m in status.original.data["media_attachments"]] urls = [m["url"] for m in status.original.data["media_attachments"]]
if urls: if not urls:
show_media(urls) return
if self.media_viewer:
subprocess.run([self.media_viewer] + urls)
else:
self.footer.set_error_message("Media viewer not configured")
def show_context_menu(self, status): def show_context_menu(self, status):
# TODO: show context menu # TODO: show context menu

View File

@ -95,6 +95,7 @@ class Timeline(urwid.Columns):
return None return None
poll = status.original.data.get("poll") poll = status.original.data.get("poll")
show_media = status.original.data["media_attachments"] and self.tui.media_viewer
options = [ options = [
"[A]ccount" if not status.is_mine else "", "[A]ccount" if not status.is_mine else "",
@ -105,6 +106,8 @@ class Timeline(urwid.Columns):
"[V]iew", "[V]iew",
"[T]hread" if not self.is_thread else "", "[T]hread" if not self.is_thread else "",
"L[i]nks", "L[i]nks",
"[M]edia" if show_media else "",
self.tui.media_viewer,
"[R]eply", "[R]eply",
"[P]oll" if poll and not poll["expired"] else "", "[P]oll" if poll and not poll["expired"] else "",
"So[u]rce", "So[u]rce",

View File

@ -1,12 +1,12 @@
import base64 import base64
import re import re
import shutil
import subprocess
import urwid import urwid
from functools import reduce from functools import lru_cache, reduce
from html.parser import HTMLParser from html.parser import HTMLParser
from typing import List from typing import List, Optional
from toot import settings
HASHTAG_PATTERN = re.compile(r'(?<!\w)(#\w+)\b') HASHTAG_PATTERN = re.compile(r'(?<!\w)(#\w+)\b')
@ -47,33 +47,7 @@ def highlight_hashtags(line):
return hline return hline
def show_media(paths):
"""
Attempt to open an image viewer to show given media files.
FIXME: This is not very thought out, but works for me.
Once settings are implemented, add an option for the user to configure their
prefered media viewer.
"""
viewer = None
potential_viewers = [
"feh",
"eog",
"display"
]
for v in potential_viewers:
viewer = shutil.which(v)
if viewer:
break
if not viewer:
raise Exception("Cannot find an image viewer")
subprocess.run([viewer] + paths)
class LinkParser(HTMLParser): class LinkParser(HTMLParser):
def reset(self): def reset(self):
super().reset() super().reset()
self.links = [] self.links = []