diff options
| author | Paul Buetow <paul@buetow.org> | 2025-09-24 22:45:46 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2025-09-24 22:45:46 +0300 |
| commit | 970b9b3754f2798f234f99c54f161acb4931b3b7 (patch) | |
| tree | f8b1af179e59ab05bc749dc20892e59f382dbde7 | |
| parent | 16ce1d306f89f44974eb033056bc65c1be9a5f8a (diff) | |
add --stats flag
| -rw-r--r-- | internal/config/args.go | 1 | ||||
| -rw-r--r-- | internal/config/config_test.go | 2 | ||||
| -rw-r--r-- | internal/main.go | 9 | ||||
| -rw-r--r-- | internal/schedule/schedule.go | 2 | ||||
| -rw-r--r-- | internal/schedule/stats.go | 25 | ||||
| -rw-r--r-- | internal/schedule/stats_test.go | 46 |
6 files changed, 56 insertions, 29 deletions
diff --git a/internal/config/args.go b/internal/config/args.go index d1a23b9..be7353b 100644 --- a/internal/config/args.go +++ b/internal/config/args.go @@ -26,6 +26,7 @@ type Args struct { GemtexterEnable bool GeminiCapsules []string ComposeMode bool + StatsOnly bool } func (a *Args) ParsePlatforms(platformStrs string) error { diff --git a/internal/config/config_test.go b/internal/config/config_test.go index 5aed307..adecc18 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -187,4 +187,4 @@ func TestIsPausedCurrentTime(t *testing.T) { if paused { t.Errorf("Expected not to be paused for past dates, but got true") } -}
\ No newline at end of file +} diff --git a/internal/main.go b/internal/main.go index 1e7d023..9bc0507 100644 --- a/internal/main.go +++ b/internal/main.go @@ -10,6 +10,7 @@ import ( "time" "codeberg.org/snonux/gos/internal/config" + "codeberg.org/snonux/gos/internal/schedule" ) func Main(composeModeDefault bool) { @@ -31,6 +32,7 @@ func Main(composeModeDefault bool) { geminiSummaryFor := flag.String("geminiSummaryFor", "", "Generate a summary in Gemini Gemtext format, format is coma separated string of months, e.g. 202410,202411") geminiCapsules := flag.String("geminiCapsules", "foo.zone", "Comma sepaeated list Gemini capsules. Used by geminiEnable to detect Gemtext links") gemtexterEnable := flag.Bool("gemtexterEnable", false, "Add special Gemtexter (the static site generator) tags to the Gemini Gemtext summary") + statsOnly := flag.Bool("stats", false, "Print statistics for all social networks and exit") flag.Parse() conf, err := config.New(configPath, *composeMode) @@ -54,6 +56,7 @@ func Main(composeModeDefault bool) { GemtexterEnable: *gemtexterEnable, GeminiCapsules: strings.Split(*geminiCapsules, ","), ComposeMode: *composeMode, + StatsOnly: *statsOnly, } if *geminiSummaryFor != "" { args.GeminiSummaryFor = strings.Split(*geminiSummaryFor, ",") @@ -68,6 +71,12 @@ func Main(composeModeDefault bool) { return } + if args.StatsOnly { + // Call the new function to print all stats + schedule.PrintAllStats(args) + return // Exit after printing stats + } + ctx, cancel := context.WithCancel(context.Background()) defer cancel() diff --git a/internal/schedule/schedule.go b/internal/schedule/schedule.go index bf86bcc..0e3e8b3 100644 --- a/internal/schedule/schedule.go +++ b/internal/schedule/schedule.go @@ -23,7 +23,7 @@ var ( func Run(args config.Args, platform platforms.Platform) (entry.Entry, error) { dir := fmt.Sprintf("%s/db/platforms/%s", args.GosDir, platform.String()) - stats, err := newStats(dir, args.Lookback, args.Target, args.PauseDays, args.MaxDaysQueued, args.Config) + stats, err := newStats(args.GosDir, platform.String(), args.Lookback, args.Target, args.PauseDays, args.MaxDaysQueued, args.Config) if err != nil { return entry.Zero, err } diff --git a/internal/schedule/stats.go b/internal/schedule/stats.go index b0f35d1..55d5f8c 100644 --- a/internal/schedule/stats.go +++ b/internal/schedule/stats.go @@ -32,7 +32,8 @@ type stats struct { pauseDays int } -func newStats(dir string, lookback time.Duration, target, pauseDays, maxQueuedDays int, cfg config.Config) (stats, error) { +func newStats(gosDir string, platformName string, lookback time.Duration, target, pauseDays, maxQueuedDays int, cfg config.Config) (stats, error) { + dir := filepath.Join(gosDir, "db", "platforms", strings.ToLower(platformName)) s := stats{postsPerDayTarget: float64(target) / 7, pauseDays: pauseDays} if err := s.gatherPostedStats(dir, pastTime(lookback), cfg); err != nil { @@ -50,10 +51,10 @@ func newStats(dir string, lookback time.Duration, target, pauseDays, maxQueuedDa } newTarget := s.postsPerDayTarget + add - colour.Infoln("Increasing posts per day target", s.postsPerDayTarget, "by", add, "to", newTarget) + colour.Infoln(platformName, "- Increasing posts per day target", s.postsPerDayTarget, "by", add, "to", newTarget) s.postsPerDayTarget = newTarget - colour.Infoln("Decreasing pause days from", s.pauseDays, "to", s.pauseDays-1) + colour.Infoln(platformName, "- Decreasing pause days from", s.pauseDays, "to", s.pauseDays-1) s.pauseDays-- } @@ -115,7 +116,7 @@ func (s *stats) gatherPostedStats(dir string, lookbackTime time.Time, cfg config since := now.Sub(oldest) s.sinceDays = since.Abs().Hours() / 24.0 - + // Subtract paused days from the calculation period pausedDays := calculatePausedDays(oldest, now, cfg) activeDays := s.sinceDays - pausedDays @@ -225,3 +226,19 @@ func minTime(a, b time.Time) time.Time { } return b } + +func PrintAllStats(args config.Args) { + for platformName := range args.Platforms { + platform, err := platforms.New(platformName) + if err != nil { + colour.Warnln("Error creating platform for", platformName, ":", err) + continue + } + s, err := newStats(args.GosDir, platformName, args.Lookback, args.Target, args.PauseDays, args.MaxDaysQueued, args.Config) + if err != nil { + colour.Warnln("Error gathering stats for", platformName, ":", err) + continue + } + s.RenderTable(platform) + } +} diff --git a/internal/schedule/stats_test.go b/internal/schedule/stats_test.go index af71222..7751212 100644 --- a/internal/schedule/stats_test.go +++ b/internal/schedule/stats_test.go @@ -21,44 +21,44 @@ func TestGatherPostedStats(t *testing.T) { // Create test posted files with different timestamps now := time.Now() testFiles := []struct { - filename string - content string + filename string + content string timestamp time.Time }{ { // Posted entry from 5 days ago - filename: "post1.txt." + now.AddDate(0, 0, -5).Format(timestamp.Format) + ".posted", - content: "Test post 1", + filename: "post1.txt." + now.AddDate(0, 0, -5).Format(timestamp.Format) + ".posted", + content: "Test post 1", timestamp: now.AddDate(0, 0, -5), }, { // Posted entry from 3 days ago - filename: "post2.txt." + now.AddDate(0, 0, -3).Format(timestamp.Format) + ".posted", - content: "Test post 2", + filename: "post2.txt." + now.AddDate(0, 0, -3).Format(timestamp.Format) + ".posted", + content: "Test post 2", timestamp: now.AddDate(0, 0, -3), }, { // Posted entry from 1 day ago - filename: "post3.txt." + now.AddDate(0, 0, -1).Format(timestamp.Format) + ".posted", - content: "Test post 3", + filename: "post3.txt." + now.AddDate(0, 0, -1).Format(timestamp.Format) + ".posted", + content: "Test post 3", timestamp: now.AddDate(0, 0, -1), }, { // Posted entry from 10 days ago (outside lookback period) - filename: "old_post.txt." + now.AddDate(0, 0, -10).Format(timestamp.Format) + ".posted", - content: "Old test post", + filename: "old_post.txt." + now.AddDate(0, 0, -10).Format(timestamp.Format) + ".posted", + content: "Old test post", timestamp: now.AddDate(0, 0, -10), }, { // Queued entry (should be ignored) - filename: "queued_post.txt." + now.AddDate(0, 0, -2).Format(timestamp.Format) + ".queued", - content: "Queued post", + filename: "queued_post.txt." + now.AddDate(0, 0, -2).Format(timestamp.Format) + ".queued", + content: "Queued post", timestamp: now.AddDate(0, 0, -2), }, { // Posted entry with .now. tag (should be ignored) - filename: "now_post.now.txt." + now.AddDate(0, 0, -2).Format(timestamp.Format) + ".posted", - content: "Now post", + filename: "now_post.now.txt." + now.AddDate(0, 0, -2).Format(timestamp.Format) + ".posted", + content: "Now post", timestamp: now.AddDate(0, 0, -2), }, } @@ -74,7 +74,7 @@ func TestGatherPostedStats(t *testing.T) { // Initialize stats and run gatherPostedStats s := &stats{} lookbackTime := now.AddDate(0, 0, -7) // 7 days lookback - cfg := config.Config{} // Empty config (no pause) + cfg := config.Config{} // Empty config (no pause) err = s.gatherPostedStats(tmpDir, lookbackTime, cfg) if err != nil { @@ -226,23 +226,23 @@ func TestGatherPostedStatsWithPause(t *testing.T) { // Key test: postsPerDay should exclude the pause period // Let's calculate this step by step: - + // 1. Find the actual time range of our posts oldestPost := now.AddDate(0, 0, -8) - + // 2. Calculate paused days using our helper function actualPausedDays := calculatePausedDays(oldestPost, now, cfg) - + // 3. Calculate expected values expectedActiveDays := s.sinceDays - actualPausedDays expectedPostsPerDay := float64(expectedPosted) / expectedActiveDays - + // Debug info for understanding the calculation - // t.Logf("Debug: sinceDays=%.1f, actualPausedDays=%.1f, expectedActiveDays=%.1f", + // t.Logf("Debug: sinceDays=%.1f, actualPausedDays=%.1f, expectedActiveDays=%.1f", // s.sinceDays, actualPausedDays, expectedActiveDays) - + if s.postsPerDay < expectedPostsPerDay-0.01 || s.postsPerDay > expectedPostsPerDay+0.01 { - t.Errorf("Expected postsPerDay≈%.2f (%.0f posts / %.1f active days), got postsPerDay=%.2f", + t.Errorf("Expected postsPerDay≈%.2f (%.0f posts / %.1f active days), got postsPerDay=%.2f", expectedPostsPerDay, float64(expectedPosted), expectedActiveDays, s.postsPerDay) } } @@ -316,4 +316,4 @@ func TestCalculatePausedDays(t *testing.T) { } }) } -}
\ No newline at end of file +} |
