diff options
| author | Paul Buetow <paul@buetow.org> | 2024-09-22 17:40:41 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2024-09-22 17:40:41 +0300 |
| commit | b63cb8f762ab0bba7750d813924c54c3089a66d6 (patch) | |
| tree | 16aa1cc164cad6e03e1eaf6d3253b28f0ab27009 /internal | |
| parent | aa1a599f105850e41954ac22de05bf381cfa0d9a (diff) | |
can gather stats from post history
Diffstat (limited to 'internal')
| -rw-r--r-- | internal/format/time.go | 3 | ||||
| -rw-r--r-- | internal/queue/queue.go | 3 | ||||
| -rw-r--r-- | internal/run.go | 21 | ||||
| -rw-r--r-- | internal/schedule/schedule.go | 24 | ||||
| -rw-r--r-- | internal/schedule/stats.go | 109 |
5 files changed, 158 insertions, 2 deletions
diff --git a/internal/format/time.go b/internal/format/time.go new file mode 100644 index 0000000..cf35722 --- /dev/null +++ b/internal/format/time.go @@ -0,0 +1,3 @@ +package format + +const Time = "20060102-150405" diff --git a/internal/queue/queue.go b/internal/queue/queue.go index 66b7c38..e14ff90 100644 --- a/internal/queue/queue.go +++ b/internal/queue/queue.go @@ -10,6 +10,7 @@ import ( "time" "codeberg.org/snonux/gos/internal/config" + "codeberg.org/snonux/gos/internal/format" "codeberg.org/snonux/gos/internal/oi" ) @@ -39,7 +40,7 @@ func queueEntries(args config.Args) error { now := time.Now() for filePath := range ch { destPath := fmt.Sprintf("%s/db/%s.%s.queued", args.GosDir, - filepath.Base(filePath), now.Format("20060102-150405")) + filepath.Base(filePath), now.Format(format.Time)) if err := oi.Rename(filePath, destPath); err != nil { return err } diff --git a/internal/run.go b/internal/run.go index feb69f8..427384d 100644 --- a/internal/run.go +++ b/internal/run.go @@ -2,11 +2,30 @@ package internal import ( "context" + "log" "codeberg.org/snonux/gos/internal/config" "codeberg.org/snonux/gos/internal/queue" + "codeberg.org/snonux/gos/internal/schedule" ) func Run(ctx context.Context, args config.Args) error { - return queue.Run(args) + if err := queue.Run(args); err != nil { + return err + } + + for _, platform := range args.Platforms { + path, err := schedule.Run(args, platform) + switch err { + case nil: + log.Println("Scheduling", path) + // TODO: Implement action here to post it + case schedule.NothingToSchedule: + log.Println("Nothing to be scheduled for", platform) + default: + return err + } + } + + return nil } diff --git a/internal/schedule/schedule.go b/internal/schedule/schedule.go new file mode 100644 index 0000000..321e096 --- /dev/null +++ b/internal/schedule/schedule.go @@ -0,0 +1,24 @@ +package schedule + +import ( + "errors" + "fmt" + "log" + "strings" + + "codeberg.org/snonux/gos/internal/config" +) + +var NothingToSchedule = errors.New("nothing to schedule") + +func Run(args config.Args, platform string) (string, error) { + dir := fmt.Sprintf("%s/db/platforms/%s", args.GosDir, strings.ToLower(platform)) + stats, err := newStats(dir) + if err != nil { + return "", err + } + + log.Println("For", platform, "stats:", stats) + + return "", NothingToSchedule +} diff --git a/internal/schedule/stats.go b/internal/schedule/stats.go new file mode 100644 index 0000000..2be163c --- /dev/null +++ b/internal/schedule/stats.go @@ -0,0 +1,109 @@ +package schedule + +import ( + "fmt" + "os" + "strings" + "time" + + "codeberg.org/snonux/gos/internal/format" + "codeberg.org/snonux/gos/internal/oi" +) + +// Posting stats +type stats struct { + posted int + queued int + sinceDays float64 + postsPerDay float64 +} + +func (s stats) String() string { + return fmt.Sprintf("posted:%d,queued:%d,sinceDays:%v,postsPerDay:%v", + s.posted, s.queued, s.sinceDays, s.postsPerDay, + ) +} + +func newStats(dir string) (stats, error) { + var stats stats + + if err := stats.gatherPostedStats(dir); err != nil { + return stats, err + } + if err := stats.gatherQueuedStats(dir); err != nil { + return stats, err + } + + return stats, nil +} + +func (s *stats) gatherPostedStats(dir string) 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 + ) + + for filePath := range ch { + newOldest, err := parseEntryPath(filePath) + if err != nil { + return err + } + if newOldest.Before(oldest) { + oldest = newOldest + } + s.posted++ + } + + since := now.Sub(oldest) + s.sinceDays = since.Abs().Hours() / 24 + s.postsPerDay = float64(s.posted) / s.sinceDays + 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 + for filePath := range ch { + if _, err := parseEntryPath(filePath); err != nil { + return err + } + if firstQueuedPath == "" { + firstQueuedPath = filePath + } + s.queued++ + } + + return nil +} + +// Make a simpler "now" time which gets rid of any extra information like offsets etc. +func nowTime() time.Time { + simplerNow, err := time.Parse(format.Time, time.Now().Format(format.Time)) + if err != nil { + panic(err) + } + return simplerNow +} + +func parseEntryPath(filePath string) (time.Time, error) { + // Format: foobarbaz.something.here.txt.STAMP.{posted,queued} + // We want to get the STAMP! + parts := strings.Split(filePath, ".") + if len(parts) < 4 { + return time.Time{}, fmt.Errorf("not a valid entry path: %s", filePath) + } + return time.Parse(format.Time, parts[len(parts)-2]) +} |
