1
0
mirror of https://github.com/makew0rld/amfora.git synced 2024-06-15 19:15:24 +00:00

Switch subscription-based naming

This commit is contained in:
makeworld 2020-11-27 17:01:29 -05:00
parent ba28b2b5f9
commit f6e89fdaa1
15 changed files with 155 additions and 153 deletions

View File

@ -1,6 +1,6 @@
# Notes
## Feeds (temp)
## Subscriptions (temp)
- TODO: remove all logger lines
## Issues

View File

@ -128,9 +128,9 @@ Features in *italics* are in the master branch, but not in the latest release.
- Manage and browse them
- Similar to [Kristall](https://github.com/MasterQ32/kristall)
- https://lists.orbitalfox.eu/archives/gemini/2020/001400.html
- [x] Subscribe to feeds and display them
- Tracking page changes is also supported
- [x] Subscriptions
- RSS, Atom, and [JSON Feeds](https://jsonfeed.org/) are all supported
- So is tracking any page to be notified when it changes
- [ ] Stream support
- [ ] Table of contents for pages
- [ ] History browser

View File

@ -7,8 +7,8 @@ import (
"github.com/makeworld-the-better-one/amfora/client"
"github.com/makeworld-the-better-one/amfora/config"
"github.com/makeworld-the-better-one/amfora/display"
"github.com/makeworld-the-better-one/amfora/feeds"
"github.com/makeworld-the-better-one/amfora/logger"
"github.com/makeworld-the-better-one/amfora/subscriptions"
)
var (
@ -45,9 +45,9 @@ func main() {
fmt.Fprintf(os.Stderr, "Config error: %v\n", err)
os.Exit(1)
}
err = feeds.Init()
err = subscriptions.Init()
if err != nil {
fmt.Fprintf(os.Stderr, "feeds.json error: %v\n", err)
fmt.Fprintf(os.Stderr, "subscriptions.json error: %v\n", err)
os.Exit(1)
}

View File

@ -39,9 +39,9 @@ var bkmkPath string
var DownloadsDir string
// Feeds
var feedDir string
var FeedPath string
// Subscriptions
var subscriptionDir string
var SubscriptionPath string
// Command for opening HTTP(S) URLs in the browser, from "a-general.http" in config.
var HTTPCommand []string
@ -103,18 +103,18 @@ func Init() error {
// Feeds dir and path
if runtime.GOOS == "windows" {
// In APPDATA beside other Amfora files
feedDir = amforaAppData
subscriptionDir = amforaAppData
} else {
// XDG data dir on POSIX systems
xdg_data, ok := os.LookupEnv("XDG_DATA_HOME")
if ok && strings.TrimSpace(xdg_data) != "" {
feedDir = filepath.Join(xdg_data, "amfora")
subscriptionDir = filepath.Join(xdg_data, "amfora")
} else {
// Default to ~/.local/share/amfora
feedDir = filepath.Join(home, ".local", "share", "amfora")
subscriptionDir = filepath.Join(home, ".local", "share", "amfora")
}
}
FeedPath = filepath.Join(feedDir, "feeds.json")
SubscriptionPath = filepath.Join(subscriptionDir, "subscriptions.json")
// *** Create necessary files and folders ***
@ -152,7 +152,7 @@ func Init() error {
f.Close()
}
// Feeds
err = os.MkdirAll(feedDir, 0755)
err = os.MkdirAll(subscriptionDir, 0755)
if err != nil {
return err
}
@ -234,9 +234,9 @@ func Init() error {
viper.SetDefault("url-handlers.other", "off")
viper.SetDefault("cache.max_size", 0)
viper.SetDefault("cache.max_pages", 20)
viper.SetDefault("feeds.popup", true)
viper.SetDefault("feeds.update_interval", 1800)
viper.SetDefault("feeds.workers", 3)
viper.SetDefault("subscriptions.popup", true)
viper.SetDefault("subscriptions.update_interval", 1800)
viper.SetDefault("subscriptions.workers", 3)
viper.SetConfigFile(configPath)
viper.SetConfigType("toml")

View File

@ -135,22 +135,22 @@ max_pages = 30 # The maximum number of pages the cache will store
# Note that HTTP and HTTPS are treated as separate protocols here.
[feeds]
[subscriptions]
# For tracking feeds and pages
# Whether a pop-up appears when viewing a potential feed
popup = true
# How often to check for new feeds and pages in the background, in seconds.
# Note Amfora will check for updates on browser start anyway.
# Set it to 0 or below to disable this feature. You can still update individual
# feeds manually, or just restart the browser to update all of them.
# How often to check for updates to subscriptions in the background, in seconds.
# Set it to 0 to disable this feature. You can still update individual feeds
# manually, or restart the browser.
#
# Note Amfora will check for updates on browser start no matter what this setting is.
update_interval = 1800 # 30 mins
# How many pages/feeds can be checked at the same time when updating.
# If you are tracking many feeds and pages you may want to increase this for
# faster update times.
# Any value below 1 will be corrected to 1.
# How many subscriptions can be checked at the same time when updating.
# If you have many subscriptions you may want to increase this for faster
# update times. Any value below 1 will be corrected to 1.
workers = 3
@ -212,8 +212,8 @@ workers = 3
# yesno_modal_text
# tofu_modal_bg
# tofu_modal_text
# feed_modal_bg
# feed_modal_text
# subscription_modal_bg
# subscription_modal_text
# input_modal_bg
# input_modal_text

View File

@ -26,20 +26,20 @@ var theme = map[string]tcell.Color{
"btn_bg": tcell.ColorNavy, // All modal buttons
"btn_text": tcell.ColorWhite,
"dl_choice_modal_bg": tcell.ColorPurple,
"dl_choice_modal_text": tcell.ColorWhite,
"dl_modal_bg": tcell.Color130, // xterm:DarkOrange3, #af5f00
"dl_modal_text": tcell.ColorWhite,
"info_modal_bg": tcell.ColorGray,
"info_modal_text": tcell.ColorWhite,
"error_modal_bg": tcell.ColorMaroon,
"error_modal_text": tcell.ColorWhite,
"yesno_modal_bg": tcell.ColorPurple,
"yesno_modal_text": tcell.ColorWhite,
"tofu_modal_bg": tcell.ColorMaroon,
"tofu_modal_text": tcell.ColorWhite,
"feed_modal_bg": tcell.Color61, // xterm:SlateBlue3, #5f5faf
"feed_modal_text": tcell.ColorWhite,
"dl_choice_modal_bg": tcell.ColorPurple,
"dl_choice_modal_text": tcell.ColorWhite,
"dl_modal_bg": tcell.Color130, // xterm:DarkOrange3, #af5f00
"dl_modal_text": tcell.ColorWhite,
"info_modal_bg": tcell.ColorGray,
"info_modal_text": tcell.ColorWhite,
"error_modal_bg": tcell.ColorMaroon,
"error_modal_text": tcell.ColorWhite,
"yesno_modal_bg": tcell.ColorPurple,
"yesno_modal_text": tcell.ColorWhite,
"tofu_modal_bg": tcell.ColorMaroon,
"tofu_modal_text": tcell.ColorWhite,
"subscription_modal_bg": tcell.Color61, // xterm:SlateBlue3, #5f5faf
"subscription_modal_text": tcell.ColorWhite,
"input_modal_bg": tcell.ColorGreen,
"input_modal_text": tcell.ColorWhite,

View File

@ -132,22 +132,22 @@ max_pages = 30 # The maximum number of pages the cache will store
# Note that HTTP and HTTPS are treated as separate protocols here.
[feeds]
[subscriptions]
# For tracking feeds and pages
# Whether a pop-up appears when viewing a potential feed
popup = true
# How often to check for new feeds and pages in the background, in seconds.
# Note Amfora will check for updates on browser start anyway.
# Set it to 0 or below to disable this feature. You can still update individual
# feeds manually, or just restart the browser to update all of them.
# How often to check for updates to subscriptions in the background, in seconds.
# Set it to 0 to disable this feature. You can still update individual feeds
# manually, or restart the browser.
#
# Note Amfora will check for updates on browser start no matter what this setting is.
update_interval = 1800 # 30 mins
# How many pages/feeds can be checked at the same time when updating.
# If you are tracking many feeds and pages you may want to increase this for
# faster update times.
# Any value below 1 will be corrected to 1.
# How many subscriptions can be checked at the same time when updating.
# If you have many subscriptions you may want to increase this for faster
# update times. Any value below 1 will be corrected to 1.
workers = 3
@ -209,8 +209,8 @@ workers = 3
# yesno_modal_text
# tofu_modal_bg
# tofu_modal_text
# feed_modal_bg
# feed_modal_text
# subscription_modal_bg
# subscription_modal_text
# input_modal_bg
# input_modal_text

View File

@ -294,11 +294,11 @@ func Init() {
}
return nil
case tcell.KeyCtrlA:
Feeds(tabs[curTab])
tabs[curTab].addToHistory("about:feeds")
Subscriptions(tabs[curTab])
tabs[curTab].addToHistory("about:subscriptions")
return nil
case tcell.KeyCtrlX:
go addFeed()
go addSubscription()
return nil
case tcell.KeyRune:
// Regular key was sent
@ -583,9 +583,9 @@ func URL(u string) {
tabs[curTab].addToHistory("about:bookmarks")
return
}
if u == "about:feeds" { //nolint:goconst
Feeds(tabs[curTab])
tabs[curTab].addToHistory("about:feeds")
if u == "about:subscriptions" { //nolint:goconst
Subscriptions(tabs[curTab])
tabs[curTab].addToHistory("about:subscriptions")
return
}
if u == "about:newtab" {

View File

@ -42,8 +42,8 @@ Ctrl-R, R|Reload a page, discarding the cached version.
Ctrl-B|View bookmarks
Ctrl-D|Add, change, or remove a bookmark for the current page.
Ctrl-S|Save the current page to your downloads.
Ctrl-A|View tracked feeds and pages.
Ctrl-X|Track or update the current feed/page.
Ctrl-A|View subscriptions
Ctrl-X|Add or update a subscription
q, Ctrl-Q|Quit
Ctrl-C|Hard quit. This can be used when in the middle of downloading,
|for example.

View File

@ -18,7 +18,7 @@ You can customize this page by creating a gemtext file called newtab.gmi, in Amf
Happy browsing!
=> about:bookmarks Bookmarks
=> about:feeds Feed and Page Tracking
=> about:subscriptions Feed and Page Tracking
=> //gemini.circumlunar.space Project Gemini
=> https://github.com/makeworld-the-better-one/amfora Amfora homepage [HTTPS]

View File

@ -16,9 +16,9 @@ import (
"github.com/makeworld-the-better-one/amfora/cache"
"github.com/makeworld-the-better-one/amfora/client"
"github.com/makeworld-the-better-one/amfora/config"
"github.com/makeworld-the-better-one/amfora/feeds"
"github.com/makeworld-the-better-one/amfora/renderer"
"github.com/makeworld-the-better-one/amfora/structs"
"github.com/makeworld-the-better-one/amfora/subscriptions"
"github.com/makeworld-the-better-one/amfora/webbrowser"
"github.com/makeworld-the-better-one/go-gemini"
"github.com/makeworld-the-better-one/go-isemoji"
@ -39,9 +39,9 @@ func followLink(t *tab, prev, next string) {
t.addToHistory("about:bookmarks")
return
}
if next == "about:feeds" {
Feeds(t)
t.addToHistory("about:feeds")
if next == "about:subscriptions" {
Subscriptions(t)
t.addToHistory("about:subscriptions")
return
}
if strings.HasPrefix(next, "about:") {
@ -340,7 +340,7 @@ func handleURL(t *tab, u string, numRedirects int) (string, bool) {
t.mode = tabModeDone
go func(p *structs.Page) {
if b && t.hasContent() && !feeds.IsTracked(s) && viper.GetBool("feeds.popup") {
if b && t.hasContent() && !subscriptions.IsSubscribed(s) && viper.GetBool("subscriptions.popup") {
// The current page might be an untracked feed, and the user wants
// to be notified in such cases.
@ -365,9 +365,9 @@ func handleURL(t *tab, u string, numRedirects int) (string, bool) {
Bookmarks(t)
return ret("about:bookmarks", true)
}
if u == "about:feeds" {
Feeds(t)
return ret("about:feeds", true)
if u == "about:subscriptions" {
Subscriptions(t)
return ret("about:subscriptions", true)
}
u = normalizeURL(u)
@ -613,10 +613,10 @@ func handleURL(t *tab, u string, numRedirects int) (string, bool) {
// First see if it's a feed, and ask the user about adding it if it is
filename := path.Base(parsed.Path)
mediatype, _, _ := mime.ParseMediaType(res.Meta)
feed, ok := feeds.GetFeed(mediatype, filename, res.Body)
feed, ok := subscriptions.GetFeed(mediatype, filename, res.Body)
if ok {
go func() {
added := addFeedDirect(u, feed, feeds.IsTracked(u))
added := addFeedDirect(u, feed, subscriptions.IsSubscribed(u))
if !added {
// Otherwise offer download choices
go dlChoice("That file could not be displayed. What would you like to do?", u, res)

View File

@ -11,15 +11,15 @@ import (
"github.com/gdamore/tcell"
"github.com/makeworld-the-better-one/amfora/cache"
"github.com/makeworld-the-better-one/amfora/config"
"github.com/makeworld-the-better-one/amfora/feeds"
"github.com/makeworld-the-better-one/amfora/logger"
"github.com/makeworld-the-better-one/amfora/renderer"
"github.com/makeworld-the-better-one/amfora/structs"
"github.com/makeworld-the-better-one/amfora/subscriptions"
"github.com/mmcdole/gofeed"
"github.com/spf13/viper"
)
var feedPageUpdated time.Time
var subscriptionPageUpdated time.Time
// toLocalDay truncates the provided time to a date only,
// but converts to the local time first.
@ -29,21 +29,21 @@ func toLocalDay(t time.Time) time.Time {
}
// Feeds displays the feeds page on the current tab.
func Feeds(t *tab) {
logger.Log.Println("display.Feeds called")
func Subscriptions(t *tab) {
logger.Log.Println("display.Subscriptions called")
// Retrieve cached version if there hasn't been any updates
p, ok := cache.GetPage("about:feeds")
if feedPageUpdated.After(feeds.LastUpdated) && ok {
logger.Log.Println("using cached feeds page")
p, ok := cache.GetPage("about:subscriptions")
if subscriptionPageUpdated.After(subscriptions.LastUpdated) && ok {
logger.Log.Println("using cached subscriptions page")
setPage(t, p)
t.applyBottomBar()
return
}
logger.Log.Println("started rendering feeds page")
logger.Log.Println("started rendering subscriptions page")
feedPageRaw := "# Feeds & Pages\n\n" +
subscriptionPageRaw := "# Subscriptions\n\n" +
"See the help (by pressing ?) for details on how to use this page.\n\n" +
"If you just opened Amfora then updates will appear incrementally. Reload the page to see them.\n"
@ -58,7 +58,7 @@ func Feeds(t *tab) {
// the UTC timezone is specified. I believe gemfeed does this.
curDay := toLocalDay(time.Now()).Add(26 * time.Hour)
pe := feeds.GetPageEntries()
pe := subscriptions.GetPageEntries()
for _, entry := range pe.Entries { // From new to old
// Convert to local time, remove sub-day info
@ -67,24 +67,24 @@ func Feeds(t *tab) {
if pub.Before(curDay) {
// This post is on a new day, add a day header
curDay = pub
feedPageRaw += fmt.Sprintf("\n## %s\n\n", curDay.Format("Jan 02, 2006"))
subscriptionPageRaw += fmt.Sprintf("\n## %s\n\n", curDay.Format("Jan 02, 2006"))
}
if entry.Title == "" || entry.Title == "/" {
// Just put author/title
// Mainly used for when you're tracking the root domain of a site
feedPageRaw += fmt.Sprintf("=>%s %s\n", entry.URL, entry.Prefix)
subscriptionPageRaw += fmt.Sprintf("=>%s %s\n", entry.URL, entry.Prefix)
} else {
// Include title and dash
feedPageRaw += fmt.Sprintf("=>%s %s - %s\n", entry.URL, entry.Prefix, entry.Title)
subscriptionPageRaw += fmt.Sprintf("=>%s %s - %s\n", entry.URL, entry.Prefix, entry.Title)
}
}
content, links := renderer.RenderGemini(feedPageRaw, textWidth(), leftMargin(), false)
content, links := renderer.RenderGemini(subscriptionPageRaw, textWidth(), leftMargin(), false)
page := structs.Page{
Raw: feedPageRaw,
Raw: subscriptionPageRaw,
Content: content,
Links: links,
URL: "about:feeds",
URL: "about:subscriptions",
Width: termW,
Mediatype: structs.TextGemini,
}
@ -92,26 +92,26 @@ func Feeds(t *tab) {
setPage(t, &page)
t.applyBottomBar()
feedPageUpdated = time.Now()
subscriptionPageUpdated = time.Now()
logger.Log.Println("done rendering feeds page")
logger.Log.Println("done rendering subscriptions page")
}
// openFeedModal displays the "Add feed/page" modal
// It returns whether the user wanted to add the feed/page.
// The tracked arg specifies whether this feed/page is already
// being tracked.
func openFeedModal(validFeed, tracked bool) bool {
// openSubscriptionModal displays the "Add subscription" modal
// It returns whether the user wanted to subscribe to feed/page.
// The subscribed arg specifies whether this feed/page is already
// subscribed to.
func openSubscriptionModal(validFeed, subscribed bool) bool {
logger.Log.Println("display.openFeedModal called")
// Reuses yesNoModal
if viper.GetBool("a-general.color") {
yesNoModal.
SetBackgroundColor(config.GetColor("feed_modal_bg")).
SetTextColor(config.GetColor("feed_modal_text"))
SetBackgroundColor(config.GetColor("subscription_modal_bg")).
SetTextColor(config.GetColor("subscription_modal_text"))
yesNoModal.GetFrame().
SetBorderColor(config.GetColor("feed_modal_text")).
SetTitleColor(config.GetColor("feed_modal_text"))
SetBorderColor(config.GetColor("subscription_modal_text")).
SetTitleColor(config.GetColor("subscription_modal_text"))
} else {
yesNoModal.
SetBackgroundColor(tcell.ColorBlack).
@ -121,18 +121,18 @@ func openFeedModal(validFeed, tracked bool) bool {
SetTitleColor(tcell.ColorWhite)
}
if validFeed {
yesNoModal.GetFrame().SetTitle("Feed Tracking")
if tracked {
yesNoModal.SetText("This is already being tracked. Would you like to manually update it?")
yesNoModal.GetFrame().SetTitle("Feed Subscription")
if subscribed {
yesNoModal.SetText("You are already subscribed to this feed. Would you like to manually update it?")
} else {
yesNoModal.SetText("Would you like to start tracking this feed?")
yesNoModal.SetText("Would you like to subscribe to this feed?")
}
} else {
yesNoModal.GetFrame().SetTitle("Page Tracking")
if tracked {
yesNoModal.SetText("This is already being tracked. Would you like to manually update it?")
yesNoModal.GetFrame().SetTitle("Page Subscription")
if subscribed {
yesNoModal.SetText("You are already subscribed to this page. Would you like to manually update it?")
} else {
yesNoModal.SetText("Would you like to start tracking this page?")
yesNoModal.SetText("Would you like to subscribe to this page?")
}
}
@ -148,12 +148,12 @@ func openFeedModal(validFeed, tracked bool) bool {
return resp
}
// getFeedFromPage is like feeds.GetFeed but takes a structs.Page as input.
// getFeedFromPage is like subscriptions.GetFeed but takes a structs.Page as input.
func getFeedFromPage(p *structs.Page) (*gofeed.Feed, bool) {
parsed, _ := url.Parse(p.URL)
filename := path.Base(parsed.Path)
r := strings.NewReader(p.Raw)
return feeds.GetFeed(p.RawMediatype, filename, r)
return subscriptions.GetFeed(p.RawMediatype, filename, r)
}
// addFeedDirect is only for adding feeds, not pages.
@ -166,8 +166,8 @@ func getFeedFromPage(p *structs.Page) (*gofeed.Feed, bool) {
func addFeedDirect(u string, feed *gofeed.Feed, tracked bool) bool {
logger.Log.Println("display.addFeedDirect called")
if openFeedModal(true, tracked) {
err := feeds.AddFeed(u, feed)
if openSubscriptionModal(true, tracked) {
err := subscriptions.AddFeed(u, feed)
if err != nil {
Error("Feed Error", err.Error())
}
@ -176,10 +176,10 @@ func addFeedDirect(u string, feed *gofeed.Feed, tracked bool) bool {
return false
}
// addFeed goes through the process of tracking the current page/feed.
// addFeed goes through the process of subscribing to the current page/feed.
// It is the high-level way of doing it. It should be called in a goroutine.
func addFeed() {
logger.Log.Println("display.addFeed called")
func addSubscription() {
logger.Log.Println("display.addSubscription called")
t := tabs[curTab]
p := t.page
@ -190,15 +190,15 @@ func addFeed() {
}
feed, isFeed := getFeedFromPage(p)
tracked := feeds.IsTracked(p.URL)
tracked := subscriptions.IsSubscribed(p.URL)
if openFeedModal(isFeed, tracked) {
if openSubscriptionModal(isFeed, tracked) {
var err error
if isFeed {
err = feeds.AddFeed(p.URL, feed)
err = subscriptions.AddFeed(p.URL, feed)
} else {
err = feeds.AddPage(p.URL, strings.NewReader(p.Raw))
err = subscriptions.AddPage(p.URL, strings.NewReader(p.Raw))
}
if err != nil {

View File

@ -1,4 +1,4 @@
package feeds
package subscriptions
import (
"net/url"
@ -10,7 +10,7 @@ import (
)
// This file contains funcs for creating PageEntries, which
// are consumed by display/feeds.go
// are consumed by display/subscriptions.go
// getURL returns a URL to be used in a PageEntry, from a
// list of URLs for that item. It prefers gemini URLs, then
@ -42,7 +42,7 @@ func getURL(urls []string) string {
// so this function needs to be called again to get updates.
// It always returns sorted entries - by post time, from newest to oldest.
func GetPageEntries() *PageEntries {
logger.Log.Println("feeds.GetPageEntries called")
logger.Log.Println("subscriptions.GetPageEntries called")
var pe PageEntries

View File

@ -1,4 +1,4 @@
package feeds
package subscriptions
import (
"sync"
@ -77,8 +77,8 @@ var data = jsonData{
Pages: make(map[string]*pageJSON),
}
// PageEntry is a single item on a feed page.
// It is used both for tracked feeds and pages.
// PageEntry is a single item on a subscriptions page.
// It is used for both feeds and pages.
type PageEntry struct {
Prefix string // Feed/log title, author, etc - something before the post title
Title string
@ -86,9 +86,10 @@ type PageEntry struct {
Published time.Time
}
// PageEntries is new-to-old list of Entry structs, used to create a feed page.
// It should always be assumed to be sorted when used in other packages.
// Sorted by post time, from newest to oldest.
// PageEntries is new-to-old list of Entry structs, used to create a
// subscriptions page.
// It should always be assumed to be sorted when used in other packages,
// by post time, from newest to oldest.
type PageEntries struct {
Entries []*PageEntry
}

View File

@ -1,4 +1,4 @@
package feeds
package subscriptions
import (
"crypto/sha256"
@ -31,15 +31,15 @@ var (
ErrNotFeed = errors.New("not a valid feed")
)
var writeMu = sync.Mutex{} // Prevent concurrent writes to feeds.json file
var writeMu = sync.Mutex{} // Prevent concurrent writes to subscriptions.json file
// LastUpdated is the time when the in-memory data was last updated.
// It can be used to know if the feed page should be regenerated.
// It can be used to know if the subscriptions page should be regenerated.
var LastUpdated time.Time
// Init should be called after config.Init.
func Init() error {
f, err := os.Open(config.FeedPath)
f, err := os.Open(config.SubscriptionPath)
if err == nil {
// File exists and could be opened
defer f.Close()
@ -50,26 +50,26 @@ func Init() error {
dec := json.NewDecoder(f)
err = dec.Decode(&data)
if err != nil && err != io.EOF {
return fmt.Errorf("feeds.json is corrupted: %w", err) //nolint:goerr113
return fmt.Errorf("subscriptions.json is corrupted: %w", err) //nolint:goerr113
}
}
} else if !os.IsNotExist(err) {
// There's an error opening the file, but it's not bc is doesn't exist
return fmt.Errorf("open feeds.json error: %w", err) //nolint:goerr113
return fmt.Errorf("open subscriptions.json error: %w", err) //nolint:goerr113
}
LastUpdated = time.Now()
if viper.GetInt("feeds.update_interval") > 0 {
// Update feeds and pages every so often
if viper.GetInt("subscriptions.update_interval") > 0 {
// Update subscriptions every so often
go func() {
for {
updateAll()
time.Sleep(time.Duration(viper.GetInt("feeds.update_interval")) * time.Second)
time.Sleep(time.Duration(viper.GetInt("subscriptions.update_interval")) * time.Second)
}
}()
} else {
// User disabled automatic feed/page updates
// User disabled automatic updates
// So just update once at the beginning
go updateAll()
}
@ -77,9 +77,10 @@ func Init() error {
return nil
}
// IsTracked returns true if the feed/page URL is already being tracked.
func IsTracked(url string) bool {
logger.Log.Println("feeds.IsTracked called")
// IsSubscribed returns true if the URL is already subscribed to,
// whether a feed or page.
func IsSubscribed(url string) bool {
logger.Log.Println("subscriptions.IsSubscribed called")
data.feedMu.RLock()
for u := range data.Feeds {
@ -103,7 +104,7 @@ func IsTracked(url string) bool {
// GetFeed returns a Feed object and a bool indicating whether the passed
// content was actually recognized as a feed.
func GetFeed(mediatype, filename string, r io.Reader) (*gofeed.Feed, bool) {
logger.Log.Println("feeds.GetFeed called")
logger.Log.Println("subscriptions.GetFeed called")
if r == nil {
return nil, false
@ -124,14 +125,14 @@ func GetFeed(mediatype, filename string, r io.Reader) (*gofeed.Feed, bool) {
}
func writeJSON() error {
logger.Log.Println("feeds.writeJSON called")
logger.Log.Println("subscriptions.writeJSON called")
writeMu.Lock()
defer writeMu.Unlock()
f, err := os.OpenFile(config.FeedPath, os.O_WRONLY|os.O_CREATE, 0666)
f, err := os.OpenFile(config.SubscriptionPath, os.O_WRONLY|os.O_CREATE, 0666)
if err != nil {
logger.Log.Println("feeds.writeJSON error", err)
logger.Log.Println("subscriptions.writeJSON error", err)
return err
}
defer f.Close()
@ -140,12 +141,12 @@ func writeJSON() error {
enc.SetIndent("", " ")
data.Lock()
logger.Log.Println("feeds.writeJSON acquired data lock")
logger.Log.Println("subscriptions.writeJSON acquired data lock")
err = enc.Encode(&data)
data.Unlock()
if err != nil {
logger.Log.Println("feeds.writeJSON error", err)
logger.Log.Println("subscriptions.writeJSON error", err)
}
return err
@ -155,7 +156,7 @@ func writeJSON() error {
// It can be used to update a feed for a URL, although the package
// will handle that on its own.
func AddFeed(url string, feed *gofeed.Feed) error {
logger.Log.Println("feeds.AddFeed called")
logger.Log.Println("subscriptions.AddFeed called")
if feed == nil {
panic("feed is nil")
@ -205,7 +206,7 @@ func AddFeed(url string, feed *gofeed.Feed) error {
// It can be used to update the page as well, although the package
// will handle that on its own.
func AddPage(url string, r io.Reader) error {
logger.Log.Println("feeds.AddPage called")
logger.Log.Println("subscriptions.AddPage called")
if r == nil {
return nil
@ -241,7 +242,7 @@ func AddPage(url string, r io.Reader) error {
}
func updateFeed(url string) error {
logger.Log.Println("feeds.updateFeed called")
logger.Log.Println("subscriptions.updateFeed called")
res, err := client.Fetch(url)
if err != nil {
@ -268,7 +269,7 @@ func updateFeed(url string) error {
}
func updatePage(url string) error {
logger.Log.Println("feeds.updatePage called")
logger.Log.Println("subscriptions.updatePage called")
res, err := client.Fetch(url)
if err != nil {
@ -286,10 +287,10 @@ func updatePage(url string) error {
return AddPage(url, res.Body)
}
// updateAll updates all feeds and pages using workers.
// updateAll updates all subscriptions using workers.
// It only returns once all the workers are done.
func updateAll() {
logger.Log.Println("feeds.updateAll called")
logger.Log.Println("subscriptions.updateAll called")
// TODO: Is two goroutines the right amount?
@ -318,7 +319,7 @@ func updateAll() {
return
}
numWorkers := viper.GetInt("feeds.workers")
numWorkers := viper.GetInt("subscriptions.workers")
if numWorkers < 1 {
numWorkers = 1
}