summaryrefslogtreecommitdiff
path: root/internal/run.go
blob: 43874bf47ae35f935151dd0080f19de81c8001ef (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
package internal

import (
	"context"
	"errors"
	"fmt"
	"time"

	"codeberg.org/snonux/gos/internal/colour"
	"codeberg.org/snonux/gos/internal/config"
	"codeberg.org/snonux/gos/internal/platforms"
	"codeberg.org/snonux/gos/internal/prompt"
	"codeberg.org/snonux/gos/internal/queue"
	"codeberg.org/snonux/gos/internal/schedule"
	"codeberg.org/snonux/gos/internal/summary"
)

func run(ctx context.Context, args config.Args) error {
	if len(args.GeminiSummaryFor) > 0 {
		return summary.Run(ctx, args)
	}
	now := time.Now().Unix()
	printLogo()

	// Check if posting is paused
	if err := checkPauseStatus(args); err != nil {
		return err
	}

	// Handle compose mode
	if args.ComposeMode {
		if err := handleComposeMode(args); err != nil {
			return err
		}
	}

	// Run queue operations
	if err := runQueueOperations(args); err != nil {
		return err
	}

	// Check run interval
	if err := checkRunInterval(args); err != nil {
		return err
	}

	// Post to platforms
	if err := postToPlatforms(ctx, args); err != nil {
		return err
	}

	// Update last run time
	args.Config.LastRunEpoch = now
	return args.Config.WriteToDisk(args.ConfigPath)
}

func runPlatform(ctx context.Context, args config.Args, platform platforms.Platform, sizeLimit int) error {
	en, err := schedule.Run(args, platform)
	switch {
	case errors.Is(err, schedule.ErrNothingToSchedule):
		colour.Infoln("Nothing to be scheduled for", platform)
		return nil
	case errors.Is(err, schedule.ErrNothingQueued):
		colour.Infoln("Nothing queued for", platform)
		return nil
	case err != nil:
		return err
	}

	if args.ComposeMode {
		colour.Infoln("Not posting any entry in compose mode!")
		return nil
	}

	err = platform.Post(ctx, args, sizeLimit, en)
	if errors.Is(err, prompt.ErrRamdomOther) || errors.Is(err, prompt.ErrDeleted) {
		return runPlatform(ctx, args, platform, sizeLimit)
	}
	return err
}

func checkPauseStatus(args config.Args) error {
	// Check if posting is paused
	paused, err := args.Config.IsPaused()
	if err != nil {
		return fmt.Errorf("error checking pause status: %w", err)
	}
	if paused {
		colour.Infoln("Posting is paused until", args.Config.PauseEnd, "- skipping all posts")
		return nil
	}
	return nil
}

func handleComposeMode(args config.Args) error {
	entryPath := fmt.Sprintf("%s/%d.ask.txt", args.GosDir, time.Now().Unix())
	if err := prompt.EditFile(entryPath); err != nil {
		return err
	}
	return nil
}

func runQueueOperations(args config.Args) error {
	if err := queue.Run(args); err != nil {
		if !softError(err) {
			return err
		}
		colour.Infoln(err)
	}
	return nil
}

func checkRunInterval(args config.Args) error {
	now := time.Now().Unix()
	sinceLastRun := time.Duration(now-args.Config.LastRunEpoch) * time.Second
	if sinceLastRun < args.RunInterval {
		colour.Infoln("Run interval of", args.RunInterval, "with", sinceLastRun, "not yet reached. Not posting anything!")
		return nil
	}
	return nil
}

func postToPlatforms(ctx context.Context, args config.Args) error {
	for platformStr, sizeLimit := range args.Platforms {
		platform, err := platforms.New(platformStr)
		if err != nil {
			return err
		}
		if err := runPlatform(ctx, args, platform, sizeLimit); err != nil {
			if softError(err) {
				colour.Infoln(err)
				continue
			}
			return err
		}
	}
	return nil
}

func softError(err error) bool {
	return errors.Is(err, prompt.ErrAborted)
}