all repos — artbound-go @ 7434a4e2029cf4a5cb865af295d9c14ff3f23181

The official administration panel for ArtBound, by EarthBound Café.

cache.go (view raw)

  1package main
  2
  3import (
  4	"fmt"
  5	"log"
  6	"os"
  7	"path/filepath"
  8	"strings"
  9	"time"
 10)
 11
 12var cachePath = filepath.Join("static", "res", "cache")
 13
 14type UpdateDBPayload struct {
 15	LastUpdated string `json:"timestamp"`
 16	NewEntries  int    `json:"new"`
 17}
 18
 19type DB struct {
 20	LastUpdated   time.Time
 21	Entries       []Entry
 22	cachedEntries []FileDetails
 23	googleApi     GoogleAPI
 24}
 25
 26type FileDetails struct {
 27	FileName  string
 28	Extension string
 29}
 30
 31func initDB(googleApi *GoogleAPI) *DB {
 32	files, err := listCachedEntries(cachePath)
 33	if err != nil {
 34		log.Fatal("Could not list cached entries.")
 35	}
 36	db := &DB{time.Now(), []Entry{}, files, *googleApi}
 37	db.update()
 38	return db
 39}
 40
 41func (db *DB) update() (error, int) {
 42	entries, err := getEntries(&db.googleApi)
 43	if err != nil {
 44		log.Fatal("Could not update DB!", err)
 45		return err, 0
 46	}
 47	newEntries := len(entries) - len(db.Entries)
 48	db.Entries = entries
 49	db.LastUpdated = time.Now()
 50	return nil, newEntries
 51}
 52
 53func (db *DB) UpdateCall() UpdateDBPayload {
 54	err, newEntries := db.update()
 55	if err != nil {
 56		log.Fatal("Could not update DB!", err)
 57		newEntries = 0
 58	}
 59	return UpdateDBPayload{db.LastUpdated.Format("02/01/2006 15:04"), newEntries}
 60}
 61
 62func filter[T any](ss []T, test func(T) bool) (ret []T) {
 63	for _, s := range ss {
 64		if test(s) {
 65			ret = append(ret, s)
 66		}
 67	}
 68	return
 69}
 70
 71func listCachedEntries(cachePath string) ([]FileDetails, error) {
 72	var files []FileDetails
 73
 74	err := filepath.Walk(cachePath, func(path string, info os.FileInfo, err error) error {
 75		if err != nil {
 76			return err
 77		}
 78
 79		if info.IsDir() {
 80			return nil // Skip directories
 81		}
 82
 83		fileName := info.Name()
 84		extension := filepath.Ext(fileName)
 85		fileNameWithoutExt := strings.TrimSuffix(fileName, extension)
 86
 87		file := FileDetails{
 88			FileName:  fileNameWithoutExt,
 89			Extension: extension,
 90		}
 91
 92		files = append(files, file)
 93		return nil
 94	})
 95
 96	if err != nil {
 97		return []FileDetails{}, err
 98	}
 99
100	return files, nil
101}
102
103func isCached(cachedEntries []FileDetails, target string) (bool, string) {
104	for _, file := range cachedEntries {
105		if file.FileName == target {
106			return true, file.Extension
107		}
108	}
109	return false, ""
110}
111
112func (db *DB) GetEntries(month string) ([]Entry, error) {
113	monthTest := func(f Entry) bool { return f.Month == month }
114	res := filter(db.Entries, monthTest)
115
116	if err := os.MkdirAll(cachePath, os.ModePerm); err != nil {
117		return nil, err
118	}
119
120	for i := range res {
121		e := &res[i]
122		isFileCached, ext := isCached(db.cachedEntries, e.FileID)
123		if isFileCached {
124			log.Println(e.FileID, "is cached.")
125			e.FilePath = filepath.Join(cachePath, e.FileID+ext)
126		} else {
127			log.Println(e.FileID, "is not cached. Downloading.")
128			ext, err := getFile(&db.googleApi, e.FileID, cachePath)
129			if err != nil {
130				log.Fatal("Could not download file", e.FileID)
131			}
132			e.FilePath = filepath.Join(cachePath, e.FileID+ext)
133		}
134	}
135
136	return res, nil
137}
138
139func (db *DB) Clear() error {
140	err := filepath.Walk(cachePath, func(path string, info os.FileInfo, err error) error {
141		if err != nil {
142			return err
143		}
144
145		if !info.IsDir() {
146			err := os.Remove(path)
147			if err != nil {
148				return err
149			}
150			fmt.Println("Deleted:", path)
151		}
152
153		return nil
154	})
155
156	if err != nil {
157		return err
158	}
159	db.cachedEntries = []FileDetails{}
160	return nil
161}