diff --git a/example_config.yaml b/example_config.yaml new file mode 100644 index 0000000..c70cf40 --- /dev/null +++ b/example_config.yaml @@ -0,0 +1,23 @@ + +# Configuration on how to open specific resources +# Via the args it is possible to provide flags to the application +# the arg $ will be replaced by the url of the resource +# +Application: + Image: + path: sxiv + args: + - $ + Audio: + path: mpv + args: + - $ + Video: + path: mpv + args: + - $ + HTML: + path: qutebrowser + args: + - $ + diff --git a/go.mod b/go.mod index 8c05433..553e903 100644 --- a/go.mod +++ b/go.mod @@ -11,6 +11,7 @@ require ( github.com/charmbracelet/glamour v0.6.0 github.com/charmbracelet/lipgloss v0.9.1 github.com/muesli/reflow v0.3.0 + gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c ) require ( diff --git a/go.sum b/go.sum index f1322e4..12d993f 100644 --- a/go.sum +++ b/go.sum @@ -32,8 +32,10 @@ github.com/dlclark/regexp2 v1.4.0 h1:F1rxgk7p4uKjwIQxBs9oAXe5CqrXlCduYEJvrF4u93E github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= @@ -140,6 +142,7 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/main.go b/main.go index a1a0b6c..16d5948 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,7 @@ package main import ( + "flag" "fmt" "os" @@ -8,7 +9,14 @@ import ( ) func main() { - p := tea.NewProgram(InitialModel(), + + configFile := flag.String("config", "~/.config/nachrichten/config.yaml", "Path to configuration file") + + flag.Parse() + + configuration := loadConfig(*configFile) + + p := tea.NewProgram(InitialModel(configuration), tea.WithAltScreen(), // tea.WithMouseCellMotion(), ) diff --git a/models.go b/models.go index 57ff836..eedad96 100644 --- a/models.go +++ b/models.go @@ -49,3 +49,28 @@ type VideoURLs struct { Medium string `json:"h264m"` Big string `json:"h264xl"` } + +type Configuration struct { + AppConfig ApplicationsConfig `yaml:"Application"` +} + +type ApplicationsConfig struct { + Image ApplicationConfig `yaml:"Image,omitempty"` + Audio ApplicationConfig `yaml:"Audio,omitempty"` + Video ApplicationConfig `yaml:"Video,omitempty"` + HTML ApplicationConfig `yaml:"HTML,omitempty"` +} + +type ApplicationConfig struct { + Path string `yaml:"path"` + Args []string `yaml:"args"` +} + +type ResourceType int + +const ( + TypeImage ResourceType = iota + TypeAudio + TypeVideo + TypeHTML +) diff --git a/tui.go b/tui.go index d35c800..5fd2208 100644 --- a/tui.go +++ b/tui.go @@ -73,6 +73,7 @@ func (k keymap) FullHelp() [][]key.Binding { } type Model struct { + configuration Configuration news News keymap keymap style Style @@ -129,8 +130,9 @@ func NewHelper(s Style) help.Model { return h } -func InitialModel() Model { +func InitialModel(c Configuration) Model { m := Model{ + configuration: c, keymap: keymap{ quit: key.NewBinding( key.WithKeys("q", "esc", "ctrl+c"), @@ -253,13 +255,13 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { m.activeListIndex = (len(m.lists) + m.activeListIndex - 1) % len(m.lists) case key.Matches(msg, m.keymap.open): article := m.SelectedArticle() - _ = open_url(article.URL) + _ = openUrl(TypeHTML, m.configuration, article.URL) case key.Matches(msg, m.keymap.video): article := m.SelectedArticle() - _ = open_url(article.Video.VideoURLs.Big) + _ = openUrl(TypeVideo, m.configuration, article.Video.VideoURLs.Big) case key.Matches(msg, m.keymap.shortNews): url, _ := getShortNewsURL() - _ = open_url(url) + _ = openUrl(TypeVideo, m.configuration, url) } case tea.WindowSizeMsg: m.updateSizes(msg.Width, msg.Height) diff --git a/util.go b/util.go index 58e2f59..e890681 100644 --- a/util.go +++ b/util.go @@ -1,6 +1,8 @@ package main import ( + "fmt" + "os" "os/exec" "runtime" "strings" @@ -8,9 +10,41 @@ import ( md "github.com/JohannesKaufmann/html-to-markdown" "github.com/charmbracelet/glamour" "github.com/charmbracelet/lipgloss" + "gopkg.in/yaml.v3" ) -func open_url(url string) error { +func openUrl(t ResourceType, c Configuration, url string) error { + var appConfig ApplicationConfig + + switch t { + case TypeImage: + appConfig = c.AppConfig.Image + case TypeAudio: + appConfig = c.AppConfig.Audio + case TypeVideo: + appConfig = c.AppConfig.Video + case TypeHTML: + appConfig = c.AppConfig.HTML + default: + return defaultOpenUrl(url) + } + + cConfig := appConfig + cConfig.Args = append([]string(nil), appConfig.Args...) + + if cConfig.Path == "" || len(cConfig.Args) == 0 { + return defaultOpenUrl(url) + } + + for i, arg := range cConfig.Args { + if arg == "$" { + cConfig.Args[i] = url + } + } + return exec.Command(cConfig.Path, cConfig.Args...).Start() +} + +func defaultOpenUrl(url string) error { var cmd string var args []string @@ -27,6 +61,22 @@ func open_url(url string) error { return exec.Command(cmd, args...).Start() } +func loadConfig(path string) Configuration { + var config Configuration + + data, err := os.ReadFile(path) + if err != nil { + fmt.Println(err) + return config + } + + err = yaml.Unmarshal(data, &config) + if err != nil { + fmt.Println(err) + } + return config +} + func ContentToText(content []Content, width int) string { converter := md.NewConverter("", true, nil) renderer, _ := glamour.NewTermRenderer(