package main import ( "errors" "time" ) type Comic struct { Name string Artist string Slug string Source string Desc string LastUpdate time.Time } func NewComic(s, n, a, source string) *Comic { return &Comic{ Name: n, Artist: a, Slug: s, Source: source, } } func (c *Comic) GetBucket() []string { return []string{"comics", c.Source, c.Slug} } func (c *Comic) Update() error { dt := time.Now() desc, err := getComicDesc(c.Source, c.Slug, dt) if err != nil { return err } if desc == c.Desc { return errors.New("Comic didn't change") } c.Desc = desc c.LastUpdate = dt return nil } func (c *Comic) GetUrl(dt time.Time) string { var v string var e error if v, e = getComicUrl(c.Source, c.Slug, dt); e != nil { return "" } return v } func (c *Comic) GetDesc(dt time.Time) string { var v string var e error if v, e = getComicDesc(c.Source, c.Slug, dt); e != nil { return "" } return v } func (c *Comic) GetRssItem() string { var v string var e error if v, e = getRssItem(c.Source, c.Slug); e != nil { return "" } return v } // DB Function to save a comic func (m *model) SaveComic(c *Comic) error { var err error if err = m.bolt.OpenDB(); err != nil { return err } defer m.bolt.CloseDB() bkt := c.GetBucket() if err = m.bolt.MkBucketPath(bkt); err != nil { return err } if err = m.bolt.SetValue(bkt, "name", c.Name); err != nil { return err } if err = m.bolt.SetValue(bkt, "artist", c.Artist); err != nil { return err } if err = m.bolt.SetValue(bkt, "desc", c.Desc); err != nil { return err } if err = m.bolt.SetTimestamp(bkt, "lastupdate", c.LastUpdate); err != nil { return err } // Add it to the cached list for i, v := range m.Comics { if v.Source == c.Source && v.Slug == c.Slug { m.Comics[i] = *c return nil } } m.Comics = append(m.Comics, *c) return nil } // DB Function to get a comic func (m *model) GetComic(source, slug string) (*Comic, error) { var err error if err = m.bolt.OpenDB(); err != nil { return nil, err } defer m.bolt.CloseDB() ret := new(Comic) ret.Source = source ret.Slug = slug bkt := ret.GetBucket() if ret.Name, err = m.bolt.GetValue(bkt, "name"); err != nil { return nil, err } if ret.Artist, err = m.bolt.GetValue(bkt, "artist"); err != nil { return nil, err } if ret.Desc, err = m.bolt.GetValue(bkt, "desc"); err != nil { return nil, err } if ret.LastUpdate, err = m.bolt.GetTimestamp(bkt, "lastupdate"); err != nil { return nil, err } return ret, nil } // Load all comics into the model func (m *model) LoadComics() error { m.Comics = m.GetAllComics() return nil } // Save all comics to the DB func (m *model) SaveAllComics(comics []Comic) { var err error if err = m.bolt.OpenDB(); err != nil { return } defer m.bolt.CloseDB() for i := range comics { m.SaveComic(&comics[i]) } } // Get all comics from the db func (m *model) GetAllComics() []Comic { var ret []Comic var err error if err = m.bolt.OpenDB(); err != nil { return ret } defer m.bolt.CloseDB() var srcs []string bkt := []string{"comics"} if srcs, err = m.bolt.GetBucketList(bkt); err != nil { return ret } for _, src := range srcs { srcBkt := append(bkt, src) var slugs []string if slugs, err = m.bolt.GetBucketList(srcBkt); err != nil { return ret } for _, slg := range slugs { c, err := m.GetComic(src, slg) if err == nil { ret = append(ret, *c) } } } return ret } // Delete a comic from the DB func (m *model) DeleteComic(slug string) error { var err error if err = m.bolt.OpenDB(); err != nil { return err } defer m.bolt.CloseDB() return m.bolt.DeleteBucket([]string{"comics"}, slug) } func (m *model) RemoveMissingComics(comics []Comic) { for _, c := range m.Comics { var fnd bool for _, nc := range comics { if nc.Slug == c.Slug { fnd = true break } } if !fnd { m.DeleteComic(c.Slug) } } }