mirror of
https://github.com/ihabunek/toot.git
synced 2025-02-02 15:07:51 -05:00
Read media viewer from settings
This commit is contained in:
parent
ef19449190
commit
5a83cd7d3b
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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",
|
||||||
|
@ -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 = []
|
||||||
|
Loading…
x
Reference in New Issue
Block a user