Skip to content

Commit

Permalink
feat: add openers for links (#62)
Browse files Browse the repository at this point in the history
* feat: add openers for links

allows custom commands to open links bsed on a regex

closes #53
  • Loading branch information
guyfedwards authored Apr 17, 2024
1 parent d0b5208 commit baf48ed
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 18 deletions.
47 changes: 32 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,30 +15,44 @@ See [releases](https://github.com/guyfedwards/nom/releases) for binaries. E.g.
$ curl -L https://github.com/guyfedwards/nom/releases/download/v2.1.4/nom_2.1.4_darwin_amd64.tar.gz | tar -xzvf -
```

## Config
Config lives by default in `$XDG_CONFIG_HOME/nom/config.yml`
### Feeds
Add feeds with the `add` command
## Usage
```sh
$ nom add <url>
$ nom # start TUI
$ nom list -n 20 # list feed items in $PAGER, optionally show more
$ nom add <feed_url>
$ nom --feed <feed_url> # preview feed without adding to config
```
or add directly to the config at `$XDG_CONFIG_HOME/nom/config.yml` on unix systems and `$HOME/Library/Application Support/nom/config.yml` on darwin.

## Config
Config lives by default in `$XDG_CONFIG_HOME/nom/config.yml` or `$HOME/Library/Application Support/nom/config.yml` on darwin.
You can customise the location of the config file with the `--config-path` flag.

### Feeds
Feeds are added to the config file and have a url and name.
```yaml
feeds:
- url: https://dropbox.tech/feed
# name will be prefixed to all entries in the list
name: dropbox
- url: https://snyk.io/blog/feed
```
You can customise the location of the config file with the `--config-path` flag.
You can also add feeds with the `add` command:
```sh
$ nom add <url>
```
#### Youtube feeds
To add youtube feeds you can go to a channel and run the following in the browser console to get the rss feed link:
```js
console.log(`https://www.youtube.com/feeds/videos.xml?channel_id=${document.querySelector("link[rel='canonical']").href.split('/channel/').reverse()[0]}`)
```

### Show read (default: false)
Show read items by default. (can be toggled with M)
```yaml
showread: true
```
### Auto read (default: false)
Automatically mark items as read on selection or navigation through items. ()
Automatically mark items as read on selection or navigation through items.
```yaml
autoread: true
```
Expand All @@ -56,16 +70,19 @@ backends:
password: muchstrong
```
### Openers
By default links are opened in the browser, you can specify commands to open certain links based on a regex string.
`regex` can be any valid golang regex string, it will be matched against the feed item link.
`cmd` is run as a child command. The `%s` denotes the position of the link in the command.
```yaml
openers:
- regex: "youtube"
cmd: "mpv %s"
```

## Store
`nom` uses sqlite as a store for feeds and metadata. It is stored next to the config in `$XDG_CONFIG_HOME/nom/nom.db`. This can be backed up like any file and will store articles, read state etc. It can also be deleted to start from scratch redownloading all articles and no state.

## Usage
```sh
$ nom # open TUI
$ nom list -n 20 # optionally show more
$ nom add <feed_url>
$ nom --feed <feed_url> # preview feed without adding to config
```
## Building and Running via Docker
Build nom image
```sh
Expand Down
21 changes: 21 additions & 0 deletions internal/commands/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,27 @@ func convertItems(its []store.Item) []list.Item {
return items
}

func (c Commands) OpenLink(url string) error {
for _, o := range c.config.Openers {
match, err := regexp.MatchString(o.Regex, url)
if err != nil {
return fmt.Errorf("OpenLink: regex: %w", err)
}

if match {
c := fmt.Sprintf(o.Cmd, url)
parts := strings.Fields(c)

cmd := exec.Command(parts[0], parts[1:]...)
if err := cmd.Run(); err != nil {
return fmt.Errorf("OpenLink: exec: %w", err)
}
}
}

return c.OpenInBrowser(url)
}

func (c Commands) OpenInBrowser(url string) error {
var cmd string
var args []string
Expand Down
6 changes: 3 additions & 3 deletions internal/commands/tui.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ func updateList(msg tea.Msg, m model) (tea.Model, tea.Cmd) {
break
}
current := m.list.SelectedItem().(TUIItem)
err := m.commands.OpenInBrowser(current.URL)
err := m.commands.OpenLink(current.URL)
if err != nil {
return m, tea.Quit
}
Expand Down Expand Up @@ -287,7 +287,7 @@ func updateViewport(msg tea.Msg, m model) (tea.Model, tea.Cmd) {

case "o":
current := m.list.SelectedItem().(TUIItem)
err := m.commands.OpenInBrowser(current.URL)
err := m.commands.OpenLink(current.URL)
if err != nil {
return m, tea.Quit
}
Expand Down Expand Up @@ -431,7 +431,7 @@ func Render(items []list.Item, cmds Commands, errors []string) error {
return []key.Binding{
key.NewBinding(
key.WithKeys("o"),
key.WithHelp("o", "open in browser"),
key.WithHelp("o", "open link"),
),
}
}
Expand Down
8 changes: 8 additions & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ type Backends struct {
FreshRSS *FreshRSSBackend `yaml:"freshrss,omitempty"`
}

type Opener struct {
Regex string `yaml:"regex"`
Cmd string `yaml:"cmd"`
}

// need to add to Load() below if loading from config file
type Config struct {
configPath string
ConfigDir string `yaml:"-"`
Expand All @@ -42,6 +48,7 @@ type Config struct {
ShowRead bool `yaml:"showread,omitempty"`
AutoRead bool `yaml:"autoread,omitempty"`
ShowFavourites bool
Openers []Opener `yaml:"openers,omitempty"`
}

func (c *Config) ToggleShowRead() {
Expand Down Expand Up @@ -110,6 +117,7 @@ func (c *Config) Load() error {
c.AutoRead = fileConfig.AutoRead

c.Feeds = fileConfig.Feeds
c.Openers = fileConfig.Openers
// only set pager if it's not defined already, config file is lower
// precidence than flags/env that can be passed to New
if c.Pager == "" {
Expand Down

0 comments on commit baf48ed

Please sign in to comment.