From 77d0699381994997dc9f69af94a554caa81a5960 Mon Sep 17 00:00:00 2001 From: Adrien Gallou Date: Sun, 26 Feb 2023 17:30:48 +0100 Subject: [PATCH] nettoyage / factorisation --- gotoggl/gotoggl.go | 152 +++------------------------------------------ 1 file changed, 9 insertions(+), 143 deletions(-) diff --git a/gotoggl/gotoggl.go b/gotoggl/gotoggl.go index 1045aa0..cda8fcf 100644 --- a/gotoggl/gotoggl.go +++ b/gotoggl/gotoggl.go @@ -7,7 +7,6 @@ import ( "io/ioutil" "log" "net/http" - "strconv" "time" "strings" "io" @@ -24,22 +23,6 @@ const ( UserAgent = "github.com/roessland/gotoggl" ) -// Duration encapsulates the standard Duration in an anonymous field. Toggl -// returns durations in seconds, but time.Duration uses nanoseconds. Therefore -// we have to implement a custom UnmarshalJSON. -type Duration struct{ time.Duration } - -// UnmarshalJSON loads a Toggl duration into a Go duration. Toggl durations are -// given in seconds. -func (d *Duration) UnmarshalJSON(data []byte) error { - seconds, err := strconv.ParseInt(string(data), 10, 64) - if err != nil { - fmt.Errorf("Couldn't unmarshal toggl.Duration: %v\n", err) - } - d.Duration = time.Duration(seconds * int64(time.Second)) - return nil -} - // TimeEntry contains the data returned for a single time entry. type TimeEntry struct { Description string @@ -54,7 +37,6 @@ type Me struct { DefaultWorkspaceId int `json:"default_workspace_id"` } - // TimeEntryResponse is a wrapper for the data returned by /time_entries type TimeEntryResponse struct { Data TimeEntry @@ -68,24 +50,11 @@ type TimeEntriesService struct { client *Client } -// Get returns details of a single time entry -func (tes *TimeEntriesService) Get(id int) (TimeEntry, error) { - panic("Get() Not yet implemented") - return TimeEntry{}, nil -} - -// Current returns running time entry -func (tes *TimeEntriesService) Current() (TimeEntry, error) { - panic("Current() not yet implemented") - return TimeEntry{}, nil -} - type searchRequest struct { EndDate string `json:"end_date"` StartDate string `json:"start_date"` } - type searchTimeEntry struct { Description string ProjectId int `json:"project_id"` @@ -105,8 +74,6 @@ type TagItem struct { Name string `json:"name"` } - - // Range returns time entries started in a specific time range. Only the first // 1000 found time entries are returned. There is no pagination. func (tes *TimeEntriesService) Range(start, end time.Time) ([]TimeEntry, error) { @@ -143,7 +110,7 @@ func (tes *TimeEntriesService) Range(start, end time.Time) ([]TimeEntry, error) // on recherche les time entries searchTimeEntries := []searchTimeEntry{} path := fmt.Sprintf("workspace/%d/search/time_entries", me.DefaultWorkspaceId) - err := tes.client.POST(path, strings.NewReader(string(s)), &searchTimeEntries) + err := tes.client.POSTOnV3(path, strings.NewReader(string(s)), &searchTimeEntries) if err != nil { return nil, fmt.Errorf("Couldn't get time entries: %v\n", err) } @@ -176,7 +143,7 @@ func (tes *TimeEntriesService) Range(start, end time.Time) ([]TimeEntry, error) panic(fmt.Sprintf("Name not found for tag id %d", tagId)) } - tags = append(tags, tagName) //TODO corriger + tags = append(tags, tagName) } te.Tags = tags @@ -186,21 +153,6 @@ func (tes *TimeEntriesService) Range(start, end time.Time) ([]TimeEntry, error) return timeEntries, nil - - - - -/* - timeEntries := []TimeEntry{} - t0 := start.Format(time.RFC3339) - t1 := end.Format(time.RFC3339) - path := fmt.Sprintf("me/time_entries?start_date=%s&end_date=%s", t0, t1) - err := tes.client.GET(path, &timeEntries) - if err != nil { - return nil, fmt.Errorf("Couldn't get time entries: %v\n", err) - } - return timeEntries, nil -*/ } type User struct { @@ -268,46 +220,20 @@ func NewClient(apiKey string) *Client { return c } -// GET does a GET operation to the main API (not the reports API) and -// unmarshals the result into the given interface. func (c *Client) GET(path string, response interface{}) error { - if len(path) > 0 && path[0] == '/' { - log.Print("Warning: Do not include / at the start of path") - } - req, _ := http.NewRequest("GET", TogglApi+path, nil) - req.SetBasicAuth(c.ApiKey, "api_token") - resp, err := c.client.Do(req) - if err != nil { - return fmt.Errorf("GET couldn't do request %v: %v\n", path, err) - } - defer func() { - resp.Body.Close() - }() - buf, err := ioutil.ReadAll(resp.Body) - if err != nil { - return fmt.Errorf("GET to %v couldn't read response body: %v\n", req.URL, err) - } - if len(buf) == 0 { - return fmt.Errorf("GET to %v response had length zero.\n", req.URL) - } - if err := json.Unmarshal(buf, &response); err != nil { - return fmt.Errorf("GET couldn't unmarshal response: %v (Response was %v)\n", err, string(buf)) - } - if resp.StatusCode < 200 || resp.StatusCode >= 400 { - return fmt.Errorf("GET got wrong status code %v\n", resp.Status) - } - return nil + return c.genericDoRequest("GET", TogglApi, path, nil, response) } -func (c *Client) POST(path string, body io.Reader, response interface{}) error { +func (c *Client) POSTOnV3(path string, body io.Reader, response interface{}) error { + return c.genericDoRequest("POST", "https://api.track.toggl.com/reports/api/v3/", path, body, response) +} + +func (c *Client) genericDoRequest(method string, endpoint string, path string, body io.Reader, response interface{}) error { if len(path) > 0 && path[0] == '/' { log.Print("Warning: Do not include / at the start of path") } -// url := TogglApi+path - url := "https://api.track.toggl.com/reports/api/v3/" + path -//log.Print(url) - req, _ := http.NewRequest("POST", url, body) + req, _ := http.NewRequest(method, endpoint + path, body) req.SetBasicAuth(c.ApiKey, "api_token") resp, err := c.client.Do(req) @@ -334,64 +260,4 @@ func (c *Client) POST(path string, body io.Reader, response interface{}) error { } -/* -type TogglTimeEntry struct { - Id int - Description string - WorkspaceId int `json:"wid"` - ProjectId int `json:"pid"` - Guid string - Billable bool - Start time.Time - Stop time.Time - Duration int - DurOnly bool - UserId int `json:"uid"` - CreatedWith string `json:"created_with"` - Tags []string - At string -} - -type TogglTimeEntryResponse struct { - Data TogglTimeEntry -} - -type TogglProject struct { - ID int - GUID string - WID int - CID int - Name string - Billable bool - IsPrivate bool `json:"is_private"` - Active bool - Template bool - At time.Time - CreatedAt time.Time `json:"created_at"` - Color string - AutoEstimates bool `json:"auto_estimates"` - ActualHours int `json:"actual_hours"` -} - -type TogglProjectResponse struct { - Data TogglProject -} - -type TogglProjectSummary struct { - Id int - // Items []??? - Time int // Duration in milliseconds - Title struct { - Client string - Color string - HexColor string `json:"hex_color"` - Project string - } - // TotalCurrencies []Currency `json:"total_currencies"` -} - -type TogglProjectSummariesResponse struct { - Data []TogglProjectSummary -} -*/