From bcdd60c51b35750e76cc13f7251ccd3f3d018bc8 Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Thu, 23 Jul 2026 22:14:14 +0200 Subject: cli,liturgy: lectio --clean prunes readings cache older than one year --- internal/liturgy/fetch.go | 48 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'internal/liturgy/fetch.go') diff --git a/internal/liturgy/fetch.go b/internal/liturgy/fetch.go index 32eaaad..f4f6992 100644 --- a/internal/liturgy/fetch.go +++ b/internal/liturgy/fetch.go @@ -41,6 +41,12 @@ var publishedRe = regexp.MustCompile(`id="\w*0all"`) // validate its own input first. var dateRe = regexp.MustCompile(`^\d{4}-\d{2}-\d{2}$`) +// cacheFileRe matches the cache file names Load/Harvest write into +// cacheDir(): ".html" or ".json". CleanCache uses it +// to tell cache entries apart from anything else that might be sitting in +// the directory. +var cacheFileRe = regexp.MustCompile(`^(\d{4}-\d{2}-\d{2})\.(html|json)$`) + // Options controls how Load resolves a day's readings. type Options struct { // Date is the day to load, formatted YYYY-MM-DD. @@ -135,6 +141,48 @@ func Load(opts Options) ([]Section, error) { return secs, nil } +// CleanCache removes cached readings whose date is before `before` from +// cacheDir(). It matches only files named ".html"/".json"; +// anything else in the directory (e.g. a stray notes.txt, or the sigla +// store, which lives elsewhere entirely) is left alone. A missing cache dir +// is not an error -- it just means there is nothing to clean yet. +func CleanCache(before time.Time) (removed int, freed int64, err error) { + dir := cacheDir() + entries, err := os.ReadDir(dir) + if err != nil { + if os.IsNotExist(err) { + return 0, 0, nil + } + return 0, 0, err + } + + for _, entry := range entries { + if entry.IsDir() { + continue + } + m := cacheFileRe.FindStringSubmatch(entry.Name()) + if m == nil { + continue + } + date, perr := time.Parse("2006-01-02", m[1]) + if perr != nil || !date.Before(before) { + continue + } + + path := filepath.Join(dir, entry.Name()) + info, serr := os.Stat(path) + if serr != nil { + return removed, freed, serr + } + if rerr := os.Remove(path); rerr != nil { + return removed, freed, rerr + } + removed++ + freed += info.Size() + } + return removed, freed, nil +} + // loadJSONCache reads and unmarshals the parsed-sections cache file. func loadJSONCache(path string) ([]Section, error) { data, err := os.ReadFile(path) -- cgit v1.3