Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ sqlite:
vhs:
docker run --rm -v $PWD:/vhs ghcr.io/charmbracelet/vhs .github/demo.tape

backends:
docker-compose -f backends-compose.yml up

# Copied from https://github.com/goreleaser/goreleaser-cross-example/blob/master/Makefile
PACKAGE_NAME := github.com/guyfedwards/nom
Expand Down
35 changes: 18 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,26 @@

![](./.github/demo.gif)

## Migrating to V3
**NOTE** When upgrading to V3 if you are using `config.backends` for Miniflux or FreshRSS support, you will need to update your config to be arrays.

## Install

See [releases](https://github.com/guyfedwards/nom/releases) for binaries. E.g.

```sh
curl -L https://github.com/guyfedwards/nom/releases/download/v2.16.2/nom_2.16.2_darwin_amd64.tar.gz | tar -xzvf -
curl -L https://github.com/guyfedwards/nom/releases/download/v3.0.0/nom_3.0.0_darwin_amd64.tar.gz | tar -xzvf -
```

To install the `nom` binary into `/usr/local/bin` (or into the location of your choice) in a single step:

```sh
curl -L https://github.com/guyfedwards/nom/releases/download/v2.16.2/nom_2.16.2_darwin_amd64.tar.gz |
sudo tar -C /usr/local/bin -xvzf - nom
curl -L https://github.com/guyfedwards/nom/releases/download/v3.0.0/nom_3.0.0_darwin_amd64.tar.gz |
sudo tar -C /usr/local/bin -xvzf - nom
```

```sh
nom -c my-custom-config.yml
```

## Usage
Expand All @@ -34,14 +41,6 @@ nom add <feed_url> <optional feed_name>
nom -h # see all available command and options
```

## Configuration

Configuration 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 configuration file with the `--config-path` (`-c`) flag:

```sh
nom -c my-custom-config.yml
```

### Feeds

Feeds are listed in the `feeds` section of the configuration file. They have a URL, an option name, and an optional list of tags:
Expand Down Expand Up @@ -146,13 +145,15 @@ As well as adding feeds directly, you can pull in feeds from another source. You
```yaml
backends:
miniflux:
host: http://myminiflux.foo
api_key: jafksdljfladjfk
- host: http://myminiflux.foo
api_key: jafksdljfladjfk
- host: http://yourminiflux.foo
api_key: adfhdlsajfsifdi
freshrss:
host: http://myfreshrss.bar
user: admin
password: muchstrong
prefixCats: true # prefix feed name for freshrss entries
- host: http://myfreshrss.bar
user: admin
password: muchstrong
prefixCats: true # prefix feed name for freshrss entries
```

#### FreshRSS
Expand Down
45 changes: 45 additions & 0 deletions backends-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,23 @@ services:
- db
environment:
- DATABASE_URL=postgres://miniflux:secret@db:5432/miniflux?sslmode=disable
- RUN_MIGRATIONS=1
- CREATE_ADMIN=1
- ADMIN_USERNAME=admin
- ADMIN_PASSWORD=miniflux

miniflux2:
image: miniflux/miniflux:latest
ports:
- "8085:8080"
depends_on:
- db2
environment:
- DATABASE_URL=postgres://miniflux:secret@db2:5432/miniflux?sslmode=disable
- RUN_MIGRATIONS=1
- CREATE_ADMIN=1
- ADMIN_USERNAME=admin
- ADMIN_PASSWORD=miniflux

db:
image: postgres:15
Expand All @@ -21,6 +38,18 @@ services:
interval: 10s
start_period: 30s

db2:
image: postgres:15
environment:
- POSTGRES_USER=miniflux
- POSTGRES_PASSWORD=secret
volumes:
- miniflux-db2:/var/lib/postgresql/data
healthcheck:
test: ["CMD", "pg_isready", "-U", "miniflux"]
interval: 10s
start_period: 30s

freshrss:
image: freshrss/freshrss
container_name: freshrss
Expand All @@ -36,7 +65,23 @@ services:
ports:
- "8081:80"

freshrss2:
image: freshrss/freshrss
container_name: freshrss2
hostname: freshrss2
restart: unless-stopped
environment:
TZ: Europe/Paris
CRON_MIN: '3,33'
FRESHRSS_ENV: development
ADMIN_EMAIL: admin@example.net
ADMIN_PASSWORD: freshrss
ADMIN_API_PASSWORD: freshrss
ports:
- "8082:80"

volumes:
miniflux-db:
miniflux-db2:
data:
extensions:
3 changes: 3 additions & 0 deletions cmd/nom/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,15 +126,18 @@ func getCmds() (*commands.Commands, error) {
if err = cfg.Load(); err != nil {
return nil, err
}

var s store.Store
if cfg.IsPreviewMode() {
s, err = store.NewInMemorySQLiteStore()
} else {
s, err = store.NewSQLiteStore(cfg.ConfigDir, cfg.Database)
}

if err != nil {
return nil, fmt.Errorf("main.go: %w", err)
}

cmds := commands.New(cfg, s)
return cmds, nil
}
Expand Down
4 changes: 2 additions & 2 deletions internal/config/backends.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ type FreshRSSBackend struct {
}

type Backends struct {
Miniflux *MinifluxBackend `yaml:"miniflux,omitempty"`
FreshRSS *FreshRSSBackend `yaml:"freshrss,omitempty"`
Miniflux []MinifluxBackend `yaml:"miniflux,omitempty"`
FreshRSS []FreshRSSBackend `yaml:"freshrss,omitempty"`
}

func (mfb *MinifluxBackend) GetFeeds() ([]Feed, error) {
Expand Down
44 changes: 31 additions & 13 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"
"os"
"path/filepath"
"strings"

"gopkg.in/yaml.v3"

Expand All @@ -14,6 +15,7 @@ import (

var (
ErrFeedAlreadyExists = errors.New("config.AddFeed: feed already exists")
ErrOutdatedConfigV3 = errors.New("outdated config, see docs for v3 changes")
DefaultConfigDirName = "nom"
DefaultConfigFileName = "config.yml"
DefaultDatabaseName = "nom.db"
Expand Down Expand Up @@ -161,7 +163,11 @@ func (c *Config) Load() error {
var fileConfig Config
err = yaml.Unmarshal(rawData, &fileConfig)
if err != nil {
return fmt.Errorf("config.Read: %w", err)
if isBackendArrayError(err) {
return ErrOutdatedConfigV3
}

return fmt.Errorf("config.Load: %w", err)
}

c.ShowRead = fileConfig.ShowRead
Expand Down Expand Up @@ -217,22 +223,26 @@ func (c *Config) Load() error {
}

if fileConfig.Backends != nil {
if fileConfig.Backends.Miniflux != nil {
mffeeds, err := fileConfig.Backends.Miniflux.GetFeeds()
if err != nil {
return err
if len(fileConfig.Backends.Miniflux) > 0 {
for _, be := range fileConfig.Backends.Miniflux {
mffeeds, err := be.GetFeeds()
if err != nil {
return err
}

c.Feeds = append(c.Feeds, mffeeds...)
}

c.Feeds = append(c.Feeds, mffeeds...)
}

if fileConfig.Backends.FreshRSS != nil {
freshfeeds, err := fileConfig.Backends.FreshRSS.GetFeeds()
if err != nil {
return err
}
if len(fileConfig.Backends.FreshRSS) > 0 {
for _, be := range fileConfig.Backends.FreshRSS {
freshfeeds, err := be.GetFeeds()
if err != nil {
return err
}

c.Feeds = append(c.Feeds, freshfeeds...)
c.Feeds = append(c.Feeds, freshfeeds...)
}
}
}

Expand Down Expand Up @@ -315,3 +325,11 @@ func (c *Config) ImportFeeds() ([]Feed, error) {

return nil, nil
}

const errorPrefix = "cannot unmarshal !!map into "

// somewhat hacky check for a parsing error on the config.backends node
func isBackendArrayError(e error) bool {
return strings.Contains(e.Error(), errorPrefix+"[]config.FreshRSSBackend") ||
strings.Contains(e.Error(), errorPrefix+"[]config.MinifluxBackend")
}