diff --git a/api.go b/api.go deleted file mode 100644 index 27cc4dc..0000000 --- a/api.go +++ /dev/null @@ -1,72 +0,0 @@ -package main - -import ( - "encoding/json" - "io" - "net/http" - "net/url" - "time" -) - -var ( - syncToken string -) - -type ActivityLog struct { - Count int `json:"count"` - Events []Event `json:"events"` -} - -type Event struct { - EventDate time.Time `json:"event_date"` - EventType string `json:"event_type"` - ExtraData map[string]any `json:"extra_data"` - ExtraDataID int64 `json:"extra_data_id"` - ID int64 `json:"id"` - - InitiatorID *int64 `json:"initiator_id"` - ObjectID string `json:"object_id"` - ObjectType string `json:"object_type"` -} - -func getRecentlyCompleted() (*ActivityLog, error) { - baseURL := "https://api.todoist.com/sync/v9/activity/get" - params := url.Values{} - params.Add("event_type", "completed") - - fullURL := baseURL + "?" + params.Encode() - - req, err := http.NewRequest("GET", fullURL, nil) - if err != nil { - return nil, err - } - - req.Header.Set("Authorization", "Bearer "+todoistApiToken) - - resp, err := client.Do(req) - if err != nil { - return nil, err - } - defer resp.Body.Close() - - body, err := io.ReadAll(resp.Body) - if err != nil { - return nil, err - } - - var activityLog *ActivityLog - if err := json.Unmarshal(body, &activityLog); err != nil { - return nil, err - } - - return activityLog, nil -} - -// $ curl https://api.todoist.com/sync/v9/sync \ -// -H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \ -// -d sync_token='*' \ -// -d resource_types='["all"]' - -func synchronize() { - -} diff --git a/cmd/develop/main.go b/cmd/develop/main.go new file mode 100644 index 0000000..e69de29 diff --git a/main.go b/cmd/main/main.go similarity index 76% rename from main.go rename to cmd/main/main.go index d5a2a21..b5fa188 100644 --- a/main.go +++ b/cmd/main/main.go @@ -7,7 +7,7 @@ package main import ( "fmt" - "net/http" + "internal/api" "os" "os/signal" "syscall" @@ -19,11 +19,10 @@ import ( ) var ( - todoistApiToken string - redisURL string - cronSchedule string - tzLocation *time.Location - client = &http.Client{} + client *api.SyncClient + redisURL string + cronSchedule string + tzLocation *time.Location ) func init() { @@ -41,31 +40,31 @@ func init() { } } +// primary is the main function that will be run by the scheduler func primary() error { - log, err := getRecentlyCompleted() + // Get recently completed tasks + + log, err := client.RecentlyCompleted() if err != nil { - fmt.Println("Error getting recently completed tasks:", err) + fmt.Println("Error fetching recently completed tasks:", err) return err } - now := time.Now().In(tzLocation) - startTime := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, tzLocation) - endTime := startTime.Add(3 * time.Hour) - for _, event := range log.Events { - if event.EventDate.After(startTime) && event.EventDate.Before(endTime) { - fmt.Printf("%s - %s\n", event.EventDate.In(tzLocation).Format("Monday, January 2, 3:04 PM MST"), event.ExtraData["content"]) - } + // if event.EventDate.In(tzLocation).Hour() >= 1 && event.EventDate.In(tzLocation).Hour() < 3 { + fmt.Printf("Task completed: %s at %s\n", event.ExtraData["content"], event.EventDate.In(tzLocation).Format("Monday, January 2, 3:04 PM MST")) + // } } return nil } func main() { - todoistApiToken = os.Getenv("TODOIST_API_KEY") redisURL = os.Getenv("REDIS_URL") cronSchedule = os.Getenv("CRON_SCHEDULE") + client = api.NewSyncClient(os.Getenv("TODOIST_API_KEY")) + // opt, _ := redis.ParseURL(redisURL) // client := redis.NewClient(opt) @@ -97,7 +96,7 @@ func main() { durationUntilNextRun := time.Until(nextRun).Seconds() fmt.Printf("startup: next run in %.2f seconds: %v\n", durationUntilNextRun, nextRun.Format(time.RFC3339)) - if durationUntilNextRun > 1 { + if durationUntilNextRun > 60 { // Run the job immediately err = j.RunNow() fmt.Println("startup: running job immediately") @@ -118,6 +117,7 @@ func main() { fmt.Println("Gracefully shutting down, received signal:", closingSignal.String()) err = s.Shutdown() if err != nil { - // handle error + fmt.Println("Error shutting down scheduler:", err) + os.Exit(1) } } diff --git a/go.mod b/go.mod index 6d90d19..0f8fd91 100644 --- a/go.mod +++ b/go.mod @@ -13,3 +13,7 @@ require ( github.com/robfig/cron/v3 v3.0.1 // indirect golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 // indirect ) + + +require internal/api v1.0.0 +replace internal/api => ./internal/api \ No newline at end of file diff --git a/internal/api/commands.go b/internal/api/commands.go new file mode 100644 index 0000000..d129c27 --- /dev/null +++ b/internal/api/commands.go @@ -0,0 +1,45 @@ +package api + +import ( + "encoding/json" + "io" + "net/http" + "net/url" +) + +func (sc *SyncClient) RecentlyCompleted() (*ActivityLog, error) { + baseURL := API_BASE_URL + "/activity/get" + params := url.Values{} + params.Add("event_type", "completed") + + fullURL := baseURL + "?" + params.Encode() + + req, err := http.NewRequest("GET", fullURL, nil) + if err != nil { + return nil, err + } + + req.Header.Set("Authorization", "Bearer "+sc.ApiToken) + + resp, err := sc.Http.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + var activityLog *ActivityLog + if err := json.Unmarshal(body, &activityLog); err != nil { + return nil, err + } + + return activityLog, nil +} + +func (sc *SyncClient) sync() { + // Implementation for synchronize function +} diff --git a/internal/api/constants.go b/internal/api/constants.go new file mode 100644 index 0000000..5cd6b2d --- /dev/null +++ b/internal/api/constants.go @@ -0,0 +1,5 @@ +package api + +var ( + API_BASE_URL = "https://api.todoist.com/sync/v9" +) diff --git a/internal/api/go.mod b/internal/api/go.mod new file mode 100644 index 0000000..22d8729 --- /dev/null +++ b/internal/api/go.mod @@ -0,0 +1,4 @@ +module api + +go 1.22.3 + diff --git a/internal/api/sync.go b/internal/api/sync.go new file mode 100644 index 0000000..778f64e --- /dev/null +++ b/internal/api/sync.go @@ -0,0 +1 @@ +package api diff --git a/internal/api/types.go b/internal/api/types.go new file mode 100644 index 0000000..23c541b --- /dev/null +++ b/internal/api/types.go @@ -0,0 +1,42 @@ +package api + +import ( + "net/http" + "time" +) + +type SyncClient struct { + Http *http.Client + SyncToken string + ApiToken string + LastSync time.Time + LastFullSync time.Time +} + +func NewSyncClient(apiToken string) *SyncClient { + return &SyncClient{ + Http: &http.Client{}, + ApiToken: apiToken, + SyncToken: "*", + } +} + +type SyncResponse struct { +} + +type ActivityLog struct { + Count int `json:"count"` + Events []Event `json:"events"` +} + +type Event struct { + EventDate time.Time `json:"event_date"` + EventType string `json:"event_type"` + ExtraData map[string]any `json:"extra_data"` + ExtraDataID int64 `json:"extra_data_id"` + ID int64 `json:"id"` + + InitiatorID *int64 `json:"initiator_id"` + ObjectID string `json:"object_id"` + ObjectType string `json:"object_type"` +}