From 4311dda7c75fe01565b04f43f76da37aeae71d33 Mon Sep 17 00:00:00 2001 From: d5xtgr Date: Wed, 6 May 2020 12:50:40 -0400 Subject: [PATCH 1/3] Allow multipart media-viewer commands Closes #7 by splitting image-viewer, video-viewer, and audio-viewer strings into fields separated by whitespace, using the first field as the command name and the others as arguments to be given. --- config.go | 37 +++++++++++++++++++++++++------------ util.go | 18 ++++++++++++------ 2 files changed, 37 insertions(+), 18 deletions(-) diff --git a/config.go b/config.go index 679d059..c28ab63 100644 --- a/config.go +++ b/config.go @@ -2,6 +2,7 @@ package main import ( "os" + "strings" "github.com/gdamore/tcell" "github.com/kyoh86/xdg" @@ -44,10 +45,13 @@ type StyleConfig struct { type MediaConfig struct { ImageViewer string + ImageArgs []string ImageSingle bool VideoViewer string + VideoArgs []string VideoSingle bool AudioViewer string + AudioArgs []string AudioSingle bool } @@ -139,25 +143,34 @@ func parseGeneral(cfg *ini.File) GeneralConfig { func parseMedia(cfg *ini.File) MediaConfig { media := MediaConfig{} - imageViewer := cfg.Section("media").Key("image-viewer").String() - if imageViewer == "" { - imageViewer = "xdg-open" + imageViewerComponents := strings.Fields(cfg.Section("media").Key("image-viewer").String()) + if len(imageViewerComponents) == 0 { + media.ImageViewer = "xdg-open" + media.ImageArgs = []string{} + } else { + media.ImageViewer = imageViewerComponents[0] + media.ImageArgs = imageViewerComponents[1:] } - media.ImageViewer = imageViewer media.ImageSingle = cfg.Section("media").Key("image-single").MustBool(true) - videoViewer := cfg.Section("media").Key("video-viewer").String() - if videoViewer == "" { - videoViewer = "xdg-open" + videoViewerComponents := strings.Fields(cfg.Section("media").Key("video-viewer").String()) + if len(videoViewerComponents) == 0 { + media.VideoViewer = "xdg-open" + media.VideoArgs = []string{} + } else { + media.VideoViewer = videoViewerComponents[0] + media.VideoArgs = videoViewerComponents[1:] } - media.VideoViewer = videoViewer media.VideoSingle = cfg.Section("media").Key("video-single").MustBool(true) - audioViewer := cfg.Section("media").Key("audio-viewer").String() - if audioViewer == "" { - videoViewer = "xdg-open" + audioViewerComponents := strings.Fields(cfg.Section("media").Key("audio-viewer").String()) + if len(audioViewerComponents) == 0 { + media.AudioViewer = "xdg-open" + media.AudioArgs = []string{} + } else { + media.AudioViewer = audioViewerComponents[0] + media.AudioArgs = audioViewerComponents[1:] } - media.AudioViewer = audioViewer media.AudioSingle = cfg.Section("media").Key("audio-single").MustBool(true) return media diff --git a/util.go b/util.go index a901106..1665e1a 100644 --- a/util.go +++ b/util.go @@ -109,26 +109,32 @@ func openMediaType(conf MediaConfig, filenames []string, mediaType string) { case "image": if conf.ImageSingle { for _, f := range filenames { - exec.Command(conf.ImageViewer, f).Run() + args := append(conf.ImageArgs, f) + exec.Command(conf.ImageViewer, args...).Run() } } else { - exec.Command(conf.ImageViewer, filenames...).Run() + args := append(conf.ImageArgs, filenames...) + exec.Command(conf.ImageViewer, args...).Run() } case "video", "gifv": if conf.VideoSingle { for _, f := range filenames { - exec.Command(conf.VideoViewer, f).Run() + args := append(conf.VideoArgs, f) + exec.Command(conf.VideoViewer, args...).Run() } } else { - exec.Command(conf.VideoViewer, filenames...).Run() + args := append(conf.VideoArgs, filenames...) + exec.Command(conf.VideoViewer, args...).Run() } case "audio": if conf.AudioSingle { for _, f := range filenames { - exec.Command(conf.AudioViewer, f).Run() + args := append(conf.AudioArgs, f) + exec.Command(conf.AudioViewer, args...).Run() } } else { - exec.Command(conf.AudioViewer, filenames...).Run() + args := append(conf.AudioArgs, filenames...) + exec.Command(conf.AudioViewer, args...).Run() } } From 9ccb9b3ca69209bc3b0ff2e58259f62092d7cb1d Mon Sep 17 00:00:00 2001 From: d5xtgr Date: Wed, 6 May 2020 13:04:12 -0400 Subject: [PATCH 2/3] Persist files until tut exits Leaves media files in /tmp until tut exits. Some media-handling programs allow only one copy to run at a time, while subsequent invocations cause the original copy to load the file and may exit before it has done so. In this case, it is not safe to delete the file immediately after exec.Command().Run() returns. --- app.go | 1 + main.go | 7 +++++++ ui.go | 1 + util.go | 4 ---- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/app.go b/app.go index b29e2a7..d8427f8 100644 --- a/app.go +++ b/app.go @@ -10,4 +10,5 @@ type App struct { API *API Config *Config HaveAccount bool + FileList []string } diff --git a/main.go b/main.go index 37c7666..23a6983 100644 --- a/main.go +++ b/main.go @@ -5,6 +5,7 @@ import ( "fmt" "log" "strings" + "os" "github.com/gdamore/tcell" ) @@ -78,6 +79,8 @@ func main() { app.UI.LoggedIn() } + app.FileList = []string{} + app.UI.Root.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey { if !app.HaveAccount { if event.Key() == tcell.KeyRune { @@ -242,4 +245,8 @@ func main() { if err := app.UI.Root.SetRoot(app.UI.Pages, true).Run(); err != nil { panic(err) } + + for _, f := range app.FileList { + os.Remove(f) + } } diff --git a/ui.go b/ui.go index 665a094..9d4ee48 100644 --- a/ui.go +++ b/ui.go @@ -220,6 +220,7 @@ func (ui *UI) OpenMedia(status *mastodon.Status) { files = append(files, f) } go openMediaType(ui.app.Config.Media, files, key) + ui.app.FileList = append(ui.app.FileList, files...) } } diff --git a/util.go b/util.go index 1665e1a..b584b13 100644 --- a/util.go +++ b/util.go @@ -137,10 +137,6 @@ func openMediaType(conf MediaConfig, filenames []string, mediaType string) { exec.Command(conf.AudioViewer, args...).Run() } } - - for _, f := range filenames { - os.Remove(f) - } } func downloadFile(url string) (string, error) { From 505ae2b0542320cc74ef5209bfd62adc7e8c8695 Mon Sep 17 00:00:00 2001 From: d5xtgr Date: Wed, 6 May 2020 22:36:24 -0400 Subject: [PATCH 3/3] Allow user to configure link viewer Following the pattern of image-viewer, video-viewer, and audio-viewer, this adds an entry to the [media] section of the config file called link-viewer, which allows the user to set his own browser. This is important because, as a TUI application, tut may be running with no display, in which case the usual browser invoked by xdg-open is likely unavailable but text-mode browsers may be. --- authoverlay.go | 2 +- config.go | 15 +++++++++++++++ linkoverlay.go | 2 +- util.go | 5 +++-- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/authoverlay.go b/authoverlay.go index 4800aae..34f47d0 100644 --- a/authoverlay.go +++ b/authoverlay.go @@ -66,7 +66,7 @@ func (a *AuthOverlay) GotInput() { return } a.account = acc - openURL(acc.AuthURI) + openURL(a.app.Config.Media, acc.AuthURI) a.Input.SetText("") a.authStep = authCodeStep a.Draw() diff --git a/config.go b/config.go index c28ab63..c40bb6f 100644 --- a/config.go +++ b/config.go @@ -53,6 +53,8 @@ type MediaConfig struct { AudioViewer string AudioArgs []string AudioSingle bool + LinkViewer string + LinkArgs []string } func parseColor(input string, def string) tcell.Color { @@ -173,6 +175,15 @@ func parseMedia(cfg *ini.File) MediaConfig { } media.AudioSingle = cfg.Section("media").Key("audio-single").MustBool(true) + linkViewerComponents := strings.Fields(cfg.Section("media").Key("link-viewer").String()) + if len(linkViewerComponents) == 0 { + media.LinkViewer = "xdg-open" + media.LinkArgs = []string{} + } else { + media.LinkViewer = linkViewerComponents[0] + media.LinkArgs = linkViewerComponents[1:] + } + return media } @@ -267,6 +278,10 @@ audio-viewer=xdg-open # default=true audio-single=true +# Your web browser +# default=xdg-open +link-viewer=xdg-open + [style] # All styles can be represented in their HEX value like #ffffff or # with their name, so in this case white. diff --git a/linkoverlay.go b/linkoverlay.go index c60338a..06209a1 100644 --- a/linkoverlay.go +++ b/linkoverlay.go @@ -85,7 +85,7 @@ func (l *LinkOverlay) Open() { return } if index < len(l.urls) { - openURL(l.urls[index].URL) + openURL(l.app.Config.Media, l.urls[index].URL) return } mIndex := index - len(l.urls) diff --git a/util.go b/util.go index b584b13..cdbdd16 100644 --- a/util.go +++ b/util.go @@ -100,8 +100,9 @@ func openEditor(app *tview.Application, content string) (string, error) { return strings.TrimSpace(string(text)), nil } -func openURL(url string) { - exec.Command("xdg-open", url).Start() +func openURL(conf MediaConfig, url string) { + args := append(conf.LinkArgs, url) + exec.Command(conf.LinkViewer, args...).Start() } func openMediaType(conf MediaConfig, filenames []string, mediaType string) {