package subscriptions import ( "sync" "time" "github.com/mmcdole/gofeed" ) /* Example stored JSON. { "feeds": { "url1": <gofeed.Feed>, "url2": <gofeed.Feed>, }, "pages": { "url1": { "hash": <hash>, "changed": <time> }, "url2": { "hash": <hash>, "changed": <time> } } } "pages" are the pages tracked for changes that aren't feeds. The hash used is SHA-256. The time is in RFC 3339 format, preferably in the UTC timezone. */ // Decoded JSON type jsonData struct { feedMu *sync.RWMutex pageMu *sync.RWMutex Feeds map[string]*gofeed.Feed `json:"feeds,omitempty"` Pages map[string]*pageJSON `json:"pages,omitempty"` } // Lock locks both feed and page mutexes. func (j *jsonData) Lock() { j.feedMu.Lock() j.pageMu.Lock() } // Unlock unlocks both feed and page mutexes. func (j *jsonData) Unlock() { j.feedMu.Unlock() j.pageMu.Unlock() } // RLock read-locks both feed and page mutexes. func (j *jsonData) RLock() { j.feedMu.RLock() j.pageMu.RLock() } // RUnlock read-unlocks both feed and page mutexes. func (j *jsonData) RUnlock() { j.feedMu.RUnlock() j.pageMu.RUnlock() } type pageJSON struct { Hash string `json:"hash"` Changed time.Time `json:"changed"` // When the latest change happened } // Global instance of jsonData - loaded from JSON and used var data = jsonData{ feedMu: &sync.RWMutex{}, pageMu: &sync.RWMutex{}, // Maps are created in Init() } // 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 URL string Published time.Time } // 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 } // Implement sort.Interface func (e *PageEntries) Len() int { return len(e.Entries) } func (e *PageEntries) Less(i, j int) bool { return e.Entries[i].Published.After(e.Entries[j].Published) } func (e *PageEntries) Swap(i, j int) { e.Entries[i], e.Entries[j] = e.Entries[j], e.Entries[i] }