diff options
Diffstat (limited to 'main.go')
| -rw-r--r-- | main.go | 95 |
1 files changed, 54 insertions, 41 deletions
@@ -26,6 +26,8 @@ type InputLine struct { type TaskAddingJob struct { Schedule cron.Schedule Task cron.Job + EntryID cron.EntryID // this doesn't fit super well, but we'll figure that out soon I guess + Delete bool } type Task struct { @@ -39,7 +41,7 @@ func (t Task) Run() { } } -var lastSeenInput = map[InputLine]TaskAddingJob{} +var jobsFromInput = map[InputLine]TaskAddingJob{} var todoistToken string var httpClient = http.Client{ Timeout: 10 * time.Second, @@ -57,25 +59,36 @@ func main() { log.Printf("Started watching '%s'", p) c := cron.New() + c.Start() for { - input, err := readInput(p) + err = readInput(p) if err != nil { log.Printf("Error reading input: %s", err) continue } - if inputChanged(lastSeenInput, input) { - log.Print("Updating task list") - lastSeenInput = input - c.Stop() - c := cron.New() - addJobs(c, input) - c.Start() - log.Print("Done updating task list") + for inputLine, taskAddingJob := range jobsFromInput { + if jobsFromInput[inputLine].EntryID == 0 { + taskAddingJob.EntryID = c.Schedule( + jobsFromInput[inputLine].Schedule, + jobsFromInput[inputLine].Task, + ) + jobsFromInput[inputLine] = taskAddingJob + + log.Printf( + "Added '%s' with recurrence '%s'", + inputLine.RawTask, + inputLine.RawSchedule, + ) + } else if taskAddingJob.Delete { + c.Remove(taskAddingJob.EntryID) + delete(jobsFromInput, inputLine) + log.Printf("Removed '%s'", inputLine.RawTask) + } } - time.Sleep(time.Minute) // re-read the input file every minute + time.Sleep(time.Minute) } } @@ -108,15 +121,19 @@ func inputFilePath() (string, error) { var inputFileRe = regexp.MustCompile(`([^\s]+\s+[^\s]+\s+[^\s]+\s+[^\s]+\s+[^\s]+)\s+(.*)`) -func readInput(p string) (map[InputLine]TaskAddingJob, error) { - input := map[InputLine]TaskAddingJob{} - +func readInput(p string) error { f, err := os.Open(p) if err != nil { - return nil, fmt.Errorf("opening '%s': %w", p, err) + return fmt.Errorf("opening '%s': %w", p, err) } defer f.Close() + previousInput := map[InputLine]struct{}{} + for k := range jobsFromInput { + previousInput[k] = struct{}{} + } + currentInput := map[InputLine]struct{}{} + scanner := bufio.NewScanner(f) for scanner.Scan() { line := strings.TrimSpace(scanner.Text()) @@ -135,38 +152,41 @@ func readInput(p string) (map[InputLine]TaskAddingJob, error) { RawTask: matches[2], } + currentInput[inputLine] = struct{}{} + if _, ok := previousInput[inputLine]; ok { + continue + } + schedule, err := cron.ParseStandard(inputLine.RawSchedule) if err != nil { - log.Printf("Failed to add '%s' with recurrence '%s': %s", inputLine.RawTask, inputLine.RawSchedule, err) + log.Printf( + "Failed to add '%s' with recurrence '%s': %s", + inputLine.RawTask, + inputLine.RawSchedule, + err, + ) continue } - job := Task{Name: inputLine.RawTask} - taskAddingJob := TaskAddingJob{ + jobsFromInput[inputLine] = TaskAddingJob{ Schedule: schedule, - Task: job, + Task: Task{Name: inputLine.RawTask}, } - - input[inputLine] = taskAddingJob } - if err := scanner.Err(); err != nil { - return nil, fmt.Errorf("scanning: %w", err) + return fmt.Errorf("scanning: %w", err) } - return input, nil -} - -func inputChanged(old, new map[InputLine]TaskAddingJob) bool { - if len(new) != len(old) { - return true - } - for k := range old { - if _, ok := new[k]; !ok { - return true + // Mark stuff that we previously saw, but is now missing, for pruning. + for k := range previousInput { + if _, ok := currentInput[k]; !ok { + v := jobsFromInput[k] + v.Delete = true + jobsFromInput[k] = v } } - return false + + return nil } func createTask(task string) error { @@ -198,10 +218,3 @@ func createTask(task string) error { log.Printf("Created task '%s'", task) return nil } - -func addJobs(c *cron.Cron, tasks map[InputLine]TaskAddingJob) { - for _, task := range tasks { - _ = c.Schedule(task.Schedule, task.Task) - } - log.Printf("Added %d jobs", len(tasks)) -} |
