diff options
| -rw-r--r-- | internal/oi/oi.go | 58 | ||||
| -rw-r--r-- | internal/schedule/schedule.go | 9 | ||||
| -rw-r--r-- | internal/schedule/stats.go | 61 |
3 files changed, 73 insertions, 55 deletions
diff --git a/internal/oi/oi.go b/internal/oi/oi.go index ea95212..c6b569f 100644 --- a/internal/oi/oi.go +++ b/internal/oi/oi.go @@ -8,7 +8,6 @@ import ( "path/filepath" "time" - "codeberg.org/snonux/gos/internal/entry" "golang.org/x/exp/rand" ) @@ -25,8 +24,9 @@ func EnsureParentDirExists(dir string) error { return EnsureDirExists(filepath.Dir(dir)) } -func ReadDirFilter(dir string, filter func(file os.DirEntry) bool) (chan string, error) { - ch := make(chan string) +// Rename to ReadDirCh +func ReadDirFilter[T any](dir string, cb func(file os.DirEntry) (T, bool)) (chan T, error) { + ch := make(chan T) if err := EnsureDirExists(dir); err != nil { return ch, err @@ -40,41 +40,65 @@ func ReadDirFilter(dir string, filter func(file os.DirEntry) bool) (chan string, go func() { defer close(ch) for _, file := range files { - if filter(file) { - ch <- filepath.Join(dir, file.Name()) + if val, ok := cb(file); ok { + ch <- val } } }() return ch, nil } +func TraverseDir(dir string, cb func(file os.DirEntry) error) error { + if err := EnsureDirExists(dir); err != nil { + return err + } + + files, err := os.ReadDir(dir) + if err != nil { + return err + } -func ReadDirSlurp(dir string, filter func(file os.DirEntry) bool) ([]string, error) { - var files []string + var errs []error - ch, err := ReadDirFilter(dir, filter) + for _, file := range files { + if err := cb(file); err != nil { + errs = append(errs, err) + } + } + + return errors.Join(errs...) +} + +// Rename to ReadDir +func ReadDirSlurp[T any](dir string, cb func(file os.DirEntry) (T, bool)) ([]T, error) { + var results []T + + ch, err := ReadDirFilter(dir, cb) if err != err { - return files, err + return results, err } for file := range ch { - files = append(files, file) + results = append(results, file) } - return files, nil + return results, nil } -func ReadDirRandomEntry(dir string, filter func(file os.DirEntry) bool) (entry.Entry, error) { - files, err := ReadDirSlurp(dir, filter) +func ReadDirRandomEntry[T any](dir string, cb func(file os.DirEntry) (T, bool)) (T, error) { + results, err := ReadDirSlurp(dir, cb) + if err != nil { - return entry.Zero, err + var zero T + return zero, err } - if len(files) == 0 { - return entry.Zero, ErrNotFound + if len(results) == 0 { + var zero T + return zero, ErrNotFound } rand.Seed(uint64(time.Now().UnixNano())) - return entry.New(files[rand.Intn(len(files))]) + return results[rand.Intn(len(results))], nil } func IsRegular(path string) bool { diff --git a/internal/schedule/schedule.go b/internal/schedule/schedule.go index 9a9121e..4ed3094 100644 --- a/internal/schedule/schedule.go +++ b/internal/schedule/schedule.go @@ -5,6 +5,7 @@ import ( "fmt" "log" "os" + "path/filepath" "strings" "codeberg.org/snonux/gos/internal/config" @@ -31,8 +32,12 @@ func Run(args config.Args, platform string) (entry.Entry, error) { } // Schedule random qeued entry for platform - ent, err := oi.ReadDirRandomEntry(dir, func(file os.DirEntry) bool { - return strings.HasSuffix(file.Name(), ".queued") + // TODO: Rename ReadDirRandomEntry to ReadDirRandom + ent, err := oi.ReadDirRandomEntry(dir, func(file os.DirEntry) (entry.Entry, bool) { + if ent, err := entry.New(filepath.Join(dir, file.Name())); err != nil { + return ent, ent.State == entry.Queued + } + return entry.Zero, false }) if err != nil { diff --git a/internal/schedule/stats.go b/internal/schedule/stats.go index e6b2b29..919d0a1 100644 --- a/internal/schedule/stats.go +++ b/internal/schedule/stats.go @@ -1,10 +1,9 @@ package schedule import ( - "errors" "fmt" "os" - "strings" + "path/filepath" "time" "codeberg.org/snonux/gos/internal/entry" @@ -45,65 +44,55 @@ func (s stats) targetHit() bool { } func (s *stats) gatherPostedStats(dir string, lookbackTime time.Time) error { - ch, err := oi.ReadDirFilter(dir, func(file os.DirEntry) bool { - return strings.HasSuffix(file.Name(), ".posted") - }) - if err != nil { - return err - } - var ( now time.Time = nowTime() oldest time.Time = now ) - var errs []error - for filePath := range ch { + err := oi.TraverseDir(dir, func(file os.DirEntry) error { + filePath := filepath.Join(dir, file.Name()) ent, err := entry.New(filePath) if err != nil { - errs = append(errs, err) - continue + return err } - if ent.Time.Before(lookbackTime) { - continue + if ent.State != entry.Posted || ent.Time.Before(lookbackTime) { + return nil } if ent.Time.Before(oldest) { oldest = ent.Time } s.posted++ + return nil + }) + if err != nil { + return err } since := now.Sub(oldest) s.sinceDays = since.Abs().Hours() / 24 s.postsPerDay = float64(s.posted) / float64(s.sinceDays) - return errors.Join(errs...) + return nil } func (s *stats) gatherQueuedStats(dir string) error { - ch, err := oi.ReadDirFilter(dir, func(file os.DirEntry) bool { - return strings.HasSuffix(file.Name(), ".queued") - }) - if err != nil { - return err - } + var firstQueuedPath string - var ( - firstQueuedPath string - errs []error - ) - for filePath := range ch { - // Here, we only test whether we can parse the entry. - if _, err := entry.New(filePath); err != nil { - errs = append(errs, err) - continue + err := oi.TraverseDir(dir, func(file os.DirEntry) error { + filePath := filepath.Join(dir, file.Name()) + ent, err := entry.New(filePath) + if err != nil { + return err } - if firstQueuedPath == "" { - firstQueuedPath = filePath + if ent.State == entry.Queued { + if firstQueuedPath == "" { + firstQueuedPath = filePath + } + s.queued++ } - s.queued++ - } + return nil + }) - return errors.Join(errs...) + return err } // Make a simpler "now" time which gets rid of any extra information like offsets etc. |
