diff options
Diffstat (limited to 'internal/feed/cache.go')
-rw-r--r-- | internal/feed/cache.go | 131 |
1 files changed, 10 insertions, 121 deletions
diff --git a/internal/feed/cache.go b/internal/feed/cache.go index 411ed47..4a0bfe7 100644 --- a/internal/feed/cache.go +++ b/internal/feed/cache.go @@ -2,151 +2,40 @@ package feed import ( "bufio" - "crypto/sha256" "encoding/gob" "errors" "fmt" "os" - "time" "github.com/Necoro/feed2imap-go/pkg/log" ) +type Version byte + const ( - currentVersion byte = 1 - startFeedId uint64 = 1 + currentVersion Version = 1 ) type Cache interface { findItem(*Feed) CachedFeed - Version() byte + Version() Version transformToCurrent() (Cache, error) } -type feedId uint64 - -type feedDescriptor struct { - Name string - Url string -} - type CachedFeed interface { Checked(withFailure bool) Failures() uint } -type cachedFeed struct { - LastCheck time.Time - NumFailures uint // can't be named `Failures` b/c it'll collide with the interface - Items []cachedItem -} - -func (cf *cachedFeed) Checked(withFailure bool) { - cf.LastCheck = time.Now() - if withFailure { - cf.NumFailures++ - } else { - cf.NumFailures = 0 - } -} - -func (cf *cachedFeed) Failures() uint { - return cf.NumFailures -} - -type itemHash [sha256.Size]byte - -type cachedItem struct { - Uid string - Title string - Link string - Date time.Time - Updated time.Time - Creator string - Hash itemHash -} - -type v1Cache struct { - version byte - Ids map[feedDescriptor]feedId - NextId uint64 - Feeds map[feedId]*cachedFeed -} - -func (cache *v1Cache) Version() byte { - return cache.version -} - -func newCache() Cache { - cache := v1Cache{ - Ids: map[feedDescriptor]feedId{}, - Feeds: map[feedId]*cachedFeed{}, - NextId: startFeedId, - } - cache.version = currentVersion - return &cache -} - -func cacheForVersion(version byte) (Cache, error) { +func cacheForVersion(version Version) (Cache, error) { switch version { - case 1: - return newCache(), nil + case v1Version: + return newV1Cache(), nil default: return nil, fmt.Errorf("unknown cache version '%d'", version) } } -func (cache *v1Cache) transformToCurrent() (Cache, error) { - return cache, nil -} - -func (cache *v1Cache) getItem(id feedId) CachedFeed { - feed, ok := cache.Feeds[id] - if !ok { - feed = &cachedFeed{} - cache.Feeds[id] = feed - } - return feed -} - -func (cache *v1Cache) findItem(feed *Feed) CachedFeed { - if feed.cached != nil { - return feed.cached.(*cachedFeed) - } - - fDescr := feed.descriptor() - id, ok := cache.Ids[fDescr] - if !ok { - var otherId feedDescriptor - changed := false - for otherId, id = range cache.Ids { - if otherId.Name == fDescr.Name { - log.Warnf("Feed %s seems to have changed URLs: newCache '%s', old '%s'. Updating.", - fDescr.Name, fDescr.Url, otherId.Url) - changed = true - break - } else if otherId.Url == fDescr.Url { - log.Warnf("Feed with URL '%s' seems to have changed its name: newCache '%s', old '%s'. Updating", - fDescr.Url, fDescr.Name, otherId.Name) - changed = true - break - } - } - if changed { - delete(cache.Ids, otherId) - } else { - id = feedId(cache.NextId) - cache.NextId++ - } - - cache.Ids[fDescr] = id - } - - item := cache.getItem(id) - feed.cached = item - return item -} - func storeCache(cache Cache, fileName string) error { if cache == nil { return fmt.Errorf("trying to store nil cache") @@ -162,7 +51,7 @@ func storeCache(cache Cache, fileName string) error { defer f.Close() writer := bufio.NewWriter(f) - if err = writer.WriteByte(currentVersion); err != nil { + if err = writer.WriteByte(byte(currentVersion)); err != nil { return fmt.Errorf("writing to '%s': %w", fileName, err) } @@ -182,7 +71,7 @@ func loadCache(fileName string) (Cache, error) { if err != nil { if errors.Is(err, os.ErrNotExist) { // no cache there yet -- make new - return newCache(), nil + return cacheForVersion(currentVersion) } return nil, fmt.Errorf("opening cache at '%s': %w", fileName, err) } @@ -196,7 +85,7 @@ func loadCache(fileName string) (Cache, error) { return nil, fmt.Errorf("reading from '%s': %w", fileName, err) } - cache, err := cacheForVersion(version) + cache, err := cacheForVersion(Version(version)) if err != nil { return nil, err } |