summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--internal/oi/oi.go58
-rw-r--r--internal/schedule/schedule.go9
-rw-r--r--internal/schedule/stats.go61
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.