package data import ( "encoding/gob" "fmt" "os" "sync" "github.com/gorilla/feeds" ) type Feed struct { addCh chan *feeds.Item setCh chan feeds.Feed getCh chan feeds.Feed feed feeds.Feed wg sync.WaitGroup } func minFeed() *Feed { return &Feed{ addCh: make(chan *feeds.Item), setCh: make(chan feeds.Feed), getCh: make(chan feeds.Feed), } } func (f *Feed) start() { f.wg.Done() for { select { case item := <-f.addCh: f.feed.Items = append(f.feed.Items, item) case f.getCh <- f.feed: case f.feed = <-f.setCh: } } } func NewFeed(title, link, desc string) *Feed { feed := minFeed() feed.feed = feeds.Feed{ Title: title, Link: &feeds.Link{Href: link}, Description: desc, } feed.wg.Add(1) go feed.start() feed.wg.Wait() return feed } func (f *Feed) Get() feeds.Feed { return <-f.getCh } func (f *Feed) Set(feed feeds.Feed) { f.setCh <- feed } func OpenFeed(filename string) (*Feed, error) { file, err := os.Open(filename) if err != nil { return nil, fmt.Errorf("error opening file %v: %v", filename, err) } defer file.Close() feed := minFeed() feed.wg.Add(1) go feed.start() feed.wg.Wait() decoder := gob.NewDecoder(file) tmpFeed := new(feeds.Feed) err = decoder.Decode(tmpFeed) if err != nil { return nil, fmt.Errorf("error decoding file %v: %v", filename, err) } feed.Set(*tmpFeed) return feed, nil } func (f *Feed) Save(filename string) error { file, err := os.Create(filename) if err != nil { return fmt.Errorf("error creating file %v: %v", filename, err) } defer file.Close() encoder := gob.NewEncoder(file) feed := f.Get() err = encoder.Encode(feed) if err != nil { return fmt.Errorf("error encoding file %v: %v", filename, err) } return nil } func (f *Feed) Add(i *feeds.Item) { f.addCh <- i }