new api organization

This commit is contained in:
2024-09-24 16:43:53 -05:00
parent 2ff320038d
commit 5a9995a724
6 changed files with 175 additions and 63 deletions

54
internal/api/activity.go Normal file
View File

@@ -0,0 +1,54 @@
package api
import (
"encoding/json"
"io"
"net/http"
"net/url"
"time"
)
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 (sc *SyncClient) RecentlyCompleted() (*ActivityLog, error) {
params := url.Values{"event_type": {"completed"}}
req, err := http.NewRequest("GET", API_BASE_URL+"/activity/get?"+params.Encode(), 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
}

View File

@@ -1,45 +0,0 @@
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
}

8
internal/api/helpers.go Normal file
View File

@@ -0,0 +1,8 @@
package api
import "net/http"
// applyAuthorization sets the Authorization header with the API token.
func (sc *SyncClient) applyAuthorization(req *http.Request) {
req.Header.Set("Authorization", "Bearer "+sc.ApiToken)
}

23
internal/api/resource.go Normal file
View File

@@ -0,0 +1,23 @@
package api
type ResourceType string
const (
Labels ResourceType = "labels"
Projects ResourceType = "projects"
Items ResourceType = "items"
Notes ResourceType = "notes"
Sections ResourceType = "sections"
Filters ResourceType = "filters"
Reminders ResourceType = "reminders"
RemindersLocation ResourceType = "reminders_location"
Locations ResourceType = "locations"
User ResourceType = "user"
LiveNotifications ResourceType = "live_notifications"
Collaborators ResourceType = "collaborators"
UserSettings ResourceType = "user_settings"
NotificationSettings ResourceType = "notification_settings"
UserPlanLimits ResourceType = "user_plan_limits"
CompletedInfo ResourceType = "completed_info"
Stats ResourceType = "stats"
)

View File

@@ -1 +1,28 @@
package api
type ClientState struct {
// Items map[string]Item
}
type Changes struct {
Added []string
Updated []string
Deleted []string
}
// sync synchronizes the client's state with the server. If the full parameter is set to true,
// a full synchronization is performed, otherwise, a partial synchronization is done.
// This strongly mutates the client's state.
//
// Parameters:
//
// full - a boolean indicating whether to perform a full synchronization.
//
// Returns:
//
// int - the number of changes synchronized.
// *Changes - a pointer to a Changes struct containing the details of the changes.
// error - an error object if an error occurred during synchronization, otherwise nil.
func (sc *SyncClient) sync(full bool) (int, *Changes, error) {
return 0, nil, nil
}

View File

@@ -1,16 +1,47 @@
package api
import (
"fmt"
"net/http"
"net/url"
"runtime"
"runtime/debug"
"time"
)
var (
userAgent string
)
func init() {
revision := "unknown"
version := "v0.0.0"
if info, ok := debug.ReadBuildInfo(); ok {
if info.Main.Version != "(devel)" {
version = info.Main.Version
revision = info.Main.Sum
} else {
fmt.Println("WARN : Inaccurate version information")
}
}
userAgent = fmt.Sprintf("todoist-late-reset/%v (%v; revision %v)", version, runtime.GOOS, revision)
fmt.Println(userAgent)
}
// SyncClient represents a client for synchronizing data with the Todoist API.
// It holds the HTTP client, synchronization tokens, timestamps of the last syncs,
// and the types of resources to be synchronized.
type SyncClient struct {
Http *http.Client
SyncToken string
ApiToken string
// LastSync is the timestamp of the last synchronization, full or incremental.
LastSync time.Time
// LastFullSync is the timestamp of the last full synchronization.
LastFullSync time.Time
// RequireFullSync indicates that client state has changed that a full sync is warranted.
RequireFullSync bool
ResourceTypes map[ResourceType]bool
}
func NewSyncClient(apiToken string) *SyncClient {
@@ -21,22 +52,36 @@ func NewSyncClient(apiToken string) *SyncClient {
}
}
type SyncResponse struct {
// UseResources marks the resource types to be synchronized.
func (sc *SyncClient) UseResources(resourceTypes ...ResourceType) {
for _, resourceType := range resourceTypes {
if resourceType != Items {
// Log a warning or handle the case where the resource type is not implemented
fmt.Printf("WARN : Resource type %v not implemented\n", resourceType)
continue
}
type ActivityLog struct {
Count int `json:"count"`
Events []Event `json:"events"`
if sc.ResourceTypes[resourceType] == false {
sc.ResourceTypes[resourceType] = true
// Incremental sync may not contain all necessary data, so require a full sync.
sc.RequireFullSync = true
}
}
}
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"`
// get performs a GET request to the Todoist API, building a request with the given path and parameters.
// It will also apply Authorization, Content-Type, Accept, and User-Agent headers.
func (sc *SyncClient) get(path string, params url.Values) (*http.Response, error) {
req, err := http.NewRequest("GET", API_BASE_URL+path+"?"+params.Encode(), nil)
if err != nil {
return nil, err
}
req.Header.Set("Authorization", "Bearer "+sc.ApiToken)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Accept", "application/json")
req.Header.Set("User-Agent", userAgent)
return sc.Http.Do(req)
}