package rss import ( "errors" "local/rssmon3/config" "log" "net/http" "regexp" "time" "github.com/mmcdole/gofeed" ) const NSFeeds = "NSFeeds" type feed struct { Key string URL string Updated time.Time TitleFilter string ContentFilter string Tags []string *config.Encodable } func newFeed(key string) *feed { return &feed{ Key: key, Encodable: &config.Encodable{}, } } func (f *feed) load() error { if f.Key == "" { return errors.New("cannot load nil feed") } db := config.Values().DB b, err := db.Get(f.Key, NSFeeds) if err != nil { return err } return f.Decode(b) } func (f *feed) pull() error { if f.URL == "" { if err := f.load(); err != nil { return err } } resp, err := http.Get(f.URL) if err != nil { return err } defer resp.Body.Close() gofeed, err := gofeed.NewParser().Parse(resp.Body) if err != nil { return err } itemTSs := []*time.Time{} for _, i := range gofeed.Items { ts := latestTSPtr(i.UpdatedParsed, i.PublishedParsed) itemTSs = append(itemTSs, &ts) if ts.Before(f.Updated) { log.Println("Skipping old item") continue } if ok := regexp.MustCompile(f.TitleFilter).MatchString(i.Title); !ok { log.Println("Skipping bad titled item") continue } item, err := newItem(i, f.ContentFilter) if err != nil { log.Println(err) continue } if err := item.save(); err != nil { log.Println(err) continue } } f.Updated = latestTSPtr(gofeed.PublishedParsed, gofeed.UpdatedParsed) f.Updated = latestTSPtr(append(itemTSs, &f.Updated)...) return nil } func (f *feed) save() error { b, err := f.Encode() if err != nil { return err } db := config.Values().DB return db.Set(f.Key, b, NSFeeds) } func latestTSPtr(times ...*time.Time) time.Time { var t time.Time for i := range times { if times[i] == nil { continue } if times[i].After(t) { t = *times[i] } } return t }