diff --git a/README.md b/README.md index 3d35d95..0946133 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,7 @@ to use with the argument `-db` to the binary. - Mark all as read/unread - Undo last read (mark it as unread) - Search titles +- System notifications ## Configuration Example (Default config) It's possible to specify configuration file as a flag, default is `gorss.conf`. @@ -114,12 +115,13 @@ and name fields. (See the example below for supported options). "keyQuit": "Esc", "keyUndoLastRead": "u", "keySearchPromt": "/", + "notifications": true, "customCommands": [ - { + { "key": "j", "Cmd": "echo 'ARTICLE.Content' 'ARTICLE.Link' > /tmp/test2.txt" }, - { + { "key": "k", "Cmd": "echo 'ARTICLE.Title' 'ARTICLE.Feed' > /tmp/test.txt" } diff --git a/go.mod b/go.mod index 84e32e6..97ccd9c 100644 --- a/go.mod +++ b/go.mod @@ -1,15 +1,36 @@ module github.com/Lallassu/gorss -go 1.12 +go 1.20 require ( github.com/OpenPeeDeeP/xdg v0.2.0 github.com/gdamore/tcell v1.2.0 + github.com/gen2brain/beeep v0.0.0-20230307103607-6e717729cb4f github.com/gilliek/go-opml v1.0.0 github.com/mattn/go-sqlite3 v1.11.0 github.com/mmcdole/gofeed v1.1.0 - github.com/olekukonko/tablewriter v0.0.1 // indirect github.com/rivo/tview v0.0.0-20190829161255-f8bc69b90341 - github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect jaytaylor.com/html2text v0.0.0-20190408195923-01ec452cbe43 ) + +require ( + github.com/PuerkitoBio/goquery v1.5.1 // indirect + github.com/andybalholm/cascadia v1.1.0 // indirect + github.com/gdamore/encoding v1.0.0 // indirect + github.com/go-toast/toast v0.0.0-20190211030409-01e6764cf0a4 // indirect + github.com/godbus/dbus/v5 v5.1.0 // indirect + github.com/json-iterator/go v1.1.10 // indirect + github.com/lucasb-eyer/go-colorful v1.0.2 // indirect + github.com/mattn/go-runewidth v0.0.4 // indirect + github.com/mmcdole/goxpp v0.0.0-20181012175147-0068e33feabf // indirect + github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect + github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 // indirect + github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d // indirect + github.com/olekukonko/tablewriter v0.0.1 // indirect + github.com/rivo/uniseg v0.0.0-20190513083848-b9f5b9457d44 // indirect + github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect + github.com/tadvi/systray v0.0.0-20190226123456-11a2b8fa57af // indirect + golang.org/x/net v0.0.0-20200301022130-244492dfa37a // indirect + golang.org/x/sys v0.6.0 // indirect + golang.org/x/text v0.3.2 // indirect +) diff --git a/go.sum b/go.sum index 985b842..0da7f2e 100644 --- a/go.sum +++ b/go.sum @@ -16,8 +16,14 @@ github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo github.com/gdamore/tcell v1.1.2/go.mod h1:h3kq4HO9l2On+V9ed8w8ewqQEmGCSSHOgQ+2h8uzurE= github.com/gdamore/tcell v1.2.0 h1:ikixzsxc8K8o3V2/CEmyoEW8mJZaNYQQ3NP3VIQdUe4= github.com/gdamore/tcell v1.2.0/go.mod h1:Hjvr+Ofd+gLglo7RYKxxnzCBmev3BzsS67MebKS4zMM= +github.com/gen2brain/beeep v0.0.0-20230307103607-6e717729cb4f h1:oRm7Hy2dQWfHgOuOWRaYZf+kZcWJst7fxAlq+yjdLss= +github.com/gen2brain/beeep v0.0.0-20230307103607-6e717729cb4f/go.mod h1:0W7dI87PvXJ1Sjs0QPvWXKcQmNERY77e8l7GFhZB/s4= github.com/gilliek/go-opml v1.0.0 h1:X8xVjtySRXU/x6KvaiXkn7OV3a4DHqxY8Rpv6U/JvCY= github.com/gilliek/go-opml v1.0.0/go.mod h1:fOxmtlzyBvUjU6bjpdjyxCGlWz+pgtAHrHf/xRZl3lk= +github.com/go-toast/toast v0.0.0-20190211030409-01e6764cf0a4 h1:qZNfIGkIANxGv/OqtnntR4DfOY2+BgwR60cAcu/i3SE= +github.com/go-toast/toast v0.0.0-20190211030409-01e6764cf0a4/go.mod h1:kW3HQ4UdaAyrUCSSDR4xUzBKW6O2iA4uHhk7AtyYp10= +github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= +github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -35,6 +41,8 @@ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OH github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d h1:VhgPp6v9qf9Agr/56bj7Y/xa04UccTW04VP0Qed4vnQ= +github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d/go.mod h1:YUTz3bUH2ZwIWBy3CJBeOBEugqcmXREj14T+iG/4k4U= github.com/olekukonko/tablewriter v0.0.1 h1:b3iUnf1v+ppJiOfNX4yxxqfWKMQPZR5yoh8urCTFX88= github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -53,6 +61,8 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/tadvi/systray v0.0.0-20190226123456-11a2b8fa57af h1:6yITBqGTE2lEeTPG04SN9W+iWHCRyHqlVYILiSXziwk= +github.com/tadvi/systray v0.0.0-20190226123456-11a2b8fa57af/go.mod h1:4F09kP5F+am0jAwlQLddpoMDM+iewkxxt6nxUQ5nq5o= github.com/urfave/cli v1.22.3/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -60,8 +70,9 @@ golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200301022130-244492dfa37a h1:GuSPYbZzB5/dcLNCwLQLsg3obCJtX9IJhpXkvY7kzk0= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756 h1:9nuHUbU8dRnRRfj9KjWUVrJeoexdbeMjttk6Oh1rD10= golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= diff --git a/gorss.conf b/gorss.conf index 6e2c974..5e2d532 100644 --- a/gorss.conf +++ b/gorss.conf @@ -47,6 +47,7 @@ "keyQuit": "Esc", "keyUndoLastRead": "u", "keySearchPromt": "/", + "notifications": false, "customCommands": [ { "key": "j", diff --git a/internal/config.go b/internal/config.go index 3536863..e75c626 100644 --- a/internal/config.go +++ b/internal/config.go @@ -53,6 +53,7 @@ type Config struct { // * `open` for Darwin WebBrowser string `json:"webBrowser"` CustomCommands []Command `json:"customCommands"` + Notifications bool `json:notifications"` } // Feed - diff --git a/internal/controller.go b/internal/controller.go index b0c05c5..731b4d0 100644 --- a/internal/controller.go +++ b/internal/controller.go @@ -13,6 +13,7 @@ import ( "time" "github.com/gdamore/tcell" + "github.com/gen2brain/beeep" "github.com/rivo/tview" ) @@ -139,6 +140,7 @@ func (c *Controller) Quit() { // UpdateFeeds updates the articles kept in the controller func (c *Controller) UpdateFeeds() { c.rss.Update() + news := make(map[string]int) for _, f := range c.rss.feeds { if f.feed == nil { continue @@ -187,10 +189,36 @@ func (c *Controller) UpdateFeeds() { } if !exists { + if f.displayName != "" { + news[f.displayName]++ + } else { + news[f.feed.Title]++ + } c.db.Save(a) } } } + + if c.conf.Notifications { + // skip error handling, best effort to show notifications. + newArticles := "" + total := 0 + for k, v := range news { + if v > 0 { + newArticles += fmt.Sprintf("[%d] %s\n", v, k) + total += v + } + } + + if total > 0 { + articles := "Articles" + if total == 1 { + articles = "Article" + } + beeep.Notify(fmt.Sprintf("%s GORSS: %d New %s", c.theme.PreviewIcon, total, articles), newArticles, "") + } + } + c.lastUpdate = time.Now() c.GetArticlesFromDB() c.isUpdated = true @@ -220,9 +248,8 @@ func (c *Controller) OpenLink(link string) { browser := c.conf.WebBrowser if browser != "" { if err = exec.Command(browser, link).Start(); err != nil { - log.Println("unable to open %s on %s: %v", link, browser, err) + log.Printf("unable to open %s on %s: %v\n", link, browser, err) } - return }