mirror of
https://github.com/makeworld-the-better-one/amfora.git
synced 2024-11-22 15:46:51 +03:00
Support streaming; error if cmd or types are empty
This commit is contained in:
parent
41ebf22df8
commit
bf47a1d57a
@ -50,6 +50,7 @@ var HTTPCommand []string
|
||||
type MediaHandler struct {
|
||||
Cmd []string
|
||||
NoPrompt bool
|
||||
Stream bool
|
||||
}
|
||||
|
||||
var MediaHandlers = make(map[string]MediaHandler)
|
||||
@ -365,12 +366,20 @@ func Init() error {
|
||||
Cmd []string `mapstructure:"cmd"`
|
||||
Types []string `mapstructure:"types"`
|
||||
NoPrompt bool `mapstructure:"no_prompt"`
|
||||
Stream bool `mapstructure:"stream"`
|
||||
}
|
||||
err = viper.UnmarshalKey("mediatype-handlers", &rawMediaHandlers)
|
||||
if err != nil {
|
||||
return fmt.Errorf("couldn't parse mediatype-handlers section in config: %w", err)
|
||||
}
|
||||
for _, rawMediaHandler := range rawMediaHandlers {
|
||||
if len(rawMediaHandler.Cmd) == 0 {
|
||||
return fmt.Errorf("empty cmd array in mediatype-handlers section")
|
||||
}
|
||||
if len(rawMediaHandler.Types) == 0 {
|
||||
return fmt.Errorf("empty types array in mediatype-handlers section")
|
||||
}
|
||||
|
||||
for _, typ := range rawMediaHandler.Types {
|
||||
if _, ok := MediaHandlers[typ]; ok {
|
||||
return fmt.Errorf("multiple mediatype-handlers defined for %v", typ)
|
||||
@ -378,6 +387,7 @@ func Init() error {
|
||||
MediaHandlers[typ] = MediaHandler{
|
||||
Cmd: rawMediaHandler.Cmd,
|
||||
NoPrompt: rawMediaHandler.NoPrompt,
|
||||
Stream: rawMediaHandler.Stream,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -162,10 +162,13 @@ other = 'off'
|
||||
# You only need to configure this section if you want to override your default application,
|
||||
# or do special things like streaming.
|
||||
#
|
||||
# Note the use of single quotes for commands, so that backslashes will not be escaped.
|
||||
#
|
||||
#
|
||||
# To open jpeg files with the feh command:
|
||||
#
|
||||
# [[mediatype-handlers]]
|
||||
# cmd = ["feh"]
|
||||
# cmd = ['feh']
|
||||
# types = ["image/jpeg"]
|
||||
#
|
||||
# Each command that you specify must come under its own [[mediatype-handlers]]. You may
|
||||
@ -175,7 +178,7 @@ other = 'off'
|
||||
# entire type:
|
||||
#
|
||||
# [[mediatype-handlers]]
|
||||
# command = ["vlc", "--flag"]
|
||||
# command = ['vlc', '--flag']
|
||||
# types = ["audio", "video"]
|
||||
#
|
||||
# A catch-all handler can by specified with "*".
|
||||
@ -184,17 +187,30 @@ other = 'off'
|
||||
# want to override that.
|
||||
#
|
||||
# [[mediatype-handlers]]
|
||||
# cmd = ["some-command"]
|
||||
# cmd = ['some-command']
|
||||
# types = [
|
||||
# "application/pdf",
|
||||
# "*",
|
||||
# ]
|
||||
#
|
||||
# You can also choose to stream the data instead of downloading it all before
|
||||
# opening it. This is especially useful for large video or audio files, as
|
||||
# well as radio streams, which will never complete. You can do this like so:
|
||||
#
|
||||
# [[mediatype-handlers]]
|
||||
# cmd = ['vlc', '-']
|
||||
# types = ["audio", "video"]
|
||||
# stream = true
|
||||
#
|
||||
# This uses vlc to stream all video and audio content.
|
||||
# By default stream is set to off for all handlers
|
||||
#
|
||||
#
|
||||
# If you want to always open a type in its viewer without the download or open
|
||||
# prompt appearing, you can add no_prompt = true
|
||||
#
|
||||
# [[mediatype-handlers]]
|
||||
# cmd = ["feh"]
|
||||
# cmd = ['feh']
|
||||
# types = ["image"]
|
||||
# no_prompt = true
|
||||
#
|
||||
|
@ -159,10 +159,13 @@ other = 'off'
|
||||
# You only need to configure this section if you want to override your default application,
|
||||
# or do special things like streaming.
|
||||
#
|
||||
# Note the use of single quotes for commands, so that backslashes will not be escaped.
|
||||
#
|
||||
#
|
||||
# To open jpeg files with the feh command:
|
||||
#
|
||||
# [[mediatype-handlers]]
|
||||
# cmd = ["feh"]
|
||||
# cmd = ['feh']
|
||||
# types = ["image/jpeg"]
|
||||
#
|
||||
# Each command that you specify must come under its own [[mediatype-handlers]]. You may
|
||||
@ -172,7 +175,7 @@ other = 'off'
|
||||
# entire type:
|
||||
#
|
||||
# [[mediatype-handlers]]
|
||||
# command = ["vlc", "--flag"]
|
||||
# command = ['vlc', '--flag']
|
||||
# types = ["audio", "video"]
|
||||
#
|
||||
# A catch-all handler can by specified with "*".
|
||||
@ -181,17 +184,30 @@ other = 'off'
|
||||
# want to override that.
|
||||
#
|
||||
# [[mediatype-handlers]]
|
||||
# cmd = ["some-command"]
|
||||
# cmd = ['some-command']
|
||||
# types = [
|
||||
# "application/pdf",
|
||||
# "*",
|
||||
# ]
|
||||
#
|
||||
# You can also choose to stream the data instead of downloading it all before
|
||||
# opening it. This is especially useful for large video or audio files, as
|
||||
# well as radio streams, which will never complete. You can do this like so:
|
||||
#
|
||||
# [[mediatype-handlers]]
|
||||
# cmd = ['vlc', '-']
|
||||
# types = ["audio", "video"]
|
||||
# stream = true
|
||||
#
|
||||
# This uses vlc to stream all video and audio content.
|
||||
# By default stream is set to off for all handlers
|
||||
#
|
||||
#
|
||||
# If you want to always open a type in its viewer without the download or open
|
||||
# prompt appearing, you can add no_prompt = true
|
||||
#
|
||||
# [[mediatype-handlers]]
|
||||
# cmd = ["feh"]
|
||||
# cmd = ['feh']
|
||||
# types = ["image"]
|
||||
# no_prompt = true
|
||||
#
|
||||
|
@ -90,6 +90,7 @@ func getMediaHandler(resp *gemini.Response) config.MediaHandler {
|
||||
def := config.MediaHandler{
|
||||
Cmd: nil,
|
||||
NoPrompt: false,
|
||||
Stream: false,
|
||||
}
|
||||
|
||||
mediatype, _, err := mime.ParseMediaType(resp.Meta)
|
||||
@ -116,8 +117,6 @@ func getMediaHandler(resp *gemini.Response) config.MediaHandler {
|
||||
// dlChoice displays the download choice modal and acts on the user's choice.
|
||||
// It should run in a goroutine.
|
||||
func dlChoice(text, u string, resp *gemini.Response) {
|
||||
defer resp.Body.Close()
|
||||
|
||||
mediaHandler := getMediaHandler(resp)
|
||||
var choice string
|
||||
|
||||
@ -136,6 +135,7 @@ func dlChoice(text, u string, resp *gemini.Response) {
|
||||
tabPages.HidePage("dlChoice")
|
||||
App.Draw()
|
||||
downloadURL(config.DownloadsDir, u, resp)
|
||||
resp.Body.Close() // Only close when the file is downloaded
|
||||
return
|
||||
}
|
||||
if choice == "Open" {
|
||||
@ -154,6 +154,28 @@ func dlChoice(text, u string, resp *gemini.Response) {
|
||||
// with the default system viewer.
|
||||
func open(u string, resp *gemini.Response) {
|
||||
mediaHandler := getMediaHandler(resp)
|
||||
|
||||
if mediaHandler.Stream {
|
||||
// Run command with downloaded data from stdin
|
||||
|
||||
cmd := mediaHandler.Cmd
|
||||
var proc *exec.Cmd
|
||||
if len(cmd) == 1 {
|
||||
proc = exec.Command(cmd[0])
|
||||
} else {
|
||||
proc = exec.Command(cmd[0], cmd[1:]...)
|
||||
}
|
||||
proc.Stdin = resp.Body
|
||||
|
||||
err := proc.Start()
|
||||
if err != nil {
|
||||
Error("File Opening Error", "Error executing custom command: "+err.Error())
|
||||
return
|
||||
}
|
||||
Info("Opened with " + cmd[0])
|
||||
return
|
||||
}
|
||||
|
||||
path := downloadURL(config.TempDownloadsDir, u, resp)
|
||||
if path == "" {
|
||||
return
|
||||
|
Loading…
Reference in New Issue
Block a user