aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRené 'Necoro' Neumann <necoro@necoro.eu>2020-04-24 00:22:19 +0200
committerRené 'Necoro' Neumann <necoro@necoro.eu>2020-04-24 00:22:19 +0200
commitc08aff21cd67cc27926a4cb1ca72ffe67e015ebf (patch)
treec9b0185424e0e74bc092a2606c6164c4e6698e48
parent8467dbb9bd9960191f16def3ba43dcbde0fdda14 (diff)
downloadfeed2imap-go-c08aff21cd67cc27926a4cb1ca72ffe67e015ebf.tar.gz
feed2imap-go-c08aff21cd67cc27926a4cb1ca72ffe67e015ebf.tar.bz2
feed2imap-go-c08aff21cd67cc27926a4cb1ca72ffe67e015ebf.zip
Started caching
-rw-r--r--.gitignore3
-rw-r--r--internal/cache/cache.go120
-rw-r--r--main.go11
3 files changed, 133 insertions, 1 deletions
diff --git a/.gitignore b/.gitignore
index 03644cb..a7b2c17 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
.idea
-config*.yml \ No newline at end of file
+config*.yml
+*.cache
diff --git a/internal/cache/cache.go b/internal/cache/cache.go
new file mode 100644
index 0000000..979d661
--- /dev/null
+++ b/internal/cache/cache.go
@@ -0,0 +1,120 @@
+package cache
+
+import (
+ "bufio"
+ "encoding/gob"
+ "errors"
+ "fmt"
+ "os"
+
+ "github.com/Necoro/feed2imap-go/internal/log"
+)
+
+const currentVersion byte = 1
+
+type Cache interface {
+ Version() byte
+ transformToCurrent() (Cache, error)
+}
+
+type feedId struct {
+ Name string
+ Url string
+}
+
+type v1Cache struct {
+ version byte
+ Ids map[feedId]uint64
+ NextId uint64
+}
+
+func (cache *v1Cache) Version() byte {
+ return cache.version
+}
+
+func New() Cache {
+ cache := v1Cache{Ids: map[feedId]uint64{}}
+ cache.version = currentVersion
+ return &cache
+}
+
+func cacheForVersion(version byte) (Cache, error) {
+ switch version {
+ case 1:
+ return New(), nil
+ default:
+ return nil, fmt.Errorf("unknown cache version '%d'", version)
+ }
+}
+
+func (cache *v1Cache) transformToCurrent() (Cache, error) {
+ return cache, nil
+}
+
+func Store(fileName string, cache Cache) error {
+ if cache == nil {
+ return fmt.Errorf("trying to store nil cache")
+ }
+ if cache.Version() != currentVersion {
+ return fmt.Errorf("trying to store cache with unsupported version '%d' (current: '%d')", cache.Version(), currentVersion)
+ }
+
+ f, err := os.Create(fileName)
+ if err != nil {
+ return fmt.Errorf("trying to store cache to '%s': %w", fileName, err)
+ }
+ defer f.Close()
+
+ writer := bufio.NewWriter(f)
+ if err = writer.WriteByte(currentVersion); err != nil {
+ return fmt.Errorf("writing to '%s': %w", fileName, err)
+ }
+
+ encoder := gob.NewEncoder(writer)
+ if err = encoder.Encode(cache); err != nil {
+ return fmt.Errorf("encoding cache: %w", err)
+ }
+
+ writer.Flush()
+ log.Printf("Stored cache to '%s'.", fileName)
+
+ return nil
+}
+
+func Read(fileName string) (Cache, error) {
+ f, err := os.Open(fileName)
+ if err != nil {
+ if errors.Is(err, os.ErrNotExist) {
+ // no cache there yet -- make new
+ return New(), nil
+ }
+ return nil, fmt.Errorf("opening cache at '%s': %w", fileName, err)
+ }
+ defer f.Close()
+
+ log.Printf("Loading cache from '%s'", fileName)
+
+ reader := bufio.NewReader(f)
+ version, err := reader.ReadByte()
+ if err != nil {
+ return nil, fmt.Errorf("reading from '%s': %w", fileName, err)
+ }
+
+ cache, err := cacheForVersion(version)
+ if err != nil {
+ return nil, err
+ }
+
+ decoder := gob.NewDecoder(reader)
+ if err = decoder.Decode(cache); err != nil {
+ return nil, fmt.Errorf("decoding for version '%d' from '%s': %w", version, fileName, err)
+ }
+
+ if cache, err = cache.transformToCurrent(); err != nil {
+ return nil, fmt.Errorf("cannot transform from version %d to %d: %w", version, currentVersion, err)
+ }
+
+ log.Printf("Loaded cache (version %d), transformed to version %d.", version, currentVersion)
+
+ return cache, nil
+}
diff --git a/main.go b/main.go
index de59f18..c4afc11 100644
--- a/main.go
+++ b/main.go
@@ -7,6 +7,7 @@ import (
"os"
"sync"
+ "github.com/Necoro/feed2imap-go/internal/cache"
"github.com/Necoro/feed2imap-go/internal/config"
"github.com/Necoro/feed2imap-go/internal/feed"
"github.com/Necoro/feed2imap-go/internal/imap"
@@ -15,6 +16,7 @@ import (
)
var cfgFile = flag.String("f", "config.yml", "configuration file")
+var cacheFile = flag.String("c", "feed.cache", "cache file")
var verbose = flag.Bool("v", false, "enable verbose output")
func processFeed(feed *feed.Feed, cfg *config.Config, client *imap.Client, wg *sync.WaitGroup) {
@@ -64,6 +66,11 @@ func run() error {
return fmt.Errorf("No successfull feed fetch.")
}
+ feedCache, err := cache.Read(*cacheFile)
+ if err != nil {
+ return err
+ }
+
imapUrl, err := url.Parse(cfg.Target)
if err != nil {
return fmt.Errorf("parsing 'target': %w", err)
@@ -83,6 +90,10 @@ func run() error {
}
wg.Wait()
+ if err = cache.Store(*cacheFile, feedCache); err != nil {
+ return err
+ }
+
return nil
}