-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 1ca1e17
Showing
18 changed files
with
1,433 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# Binaries for programs and plugins | ||
*.exe | ||
*.exe~ | ||
*.dll | ||
*.so | ||
*.dylib | ||
|
||
# Test binary, built with `go test -c` | ||
*.test | ||
|
||
# Output of the go coverage tool, specifically when used with LiteIDE | ||
*.out | ||
|
||
# Go workspace file | ||
go.work |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
# matata | ||
|
||
> **matata** is a unofficial api client written in go for the time tracking tool [Hakuna](https://www.hakuna.ch). | ||
## Table of content | ||
|
||
- [matata](#matata) | ||
- [Table of content](#table-of-content) | ||
- [Installation](#installation) | ||
- [Documentation](#documentation) | ||
- [ToDo](#todo) | ||
- [License](#license) | ||
|
||
## Installation | ||
|
||
```bash | ||
go get github.com/1H0/matata | ||
``` | ||
|
||
## Documentation | ||
|
||
[![Go Reference](https://pkg.go.dev/badge/github.com/1H0/matata.svg)](https://pkg.go.dev/github.com/1H0/matata) | ||
|
||
## ToDo | ||
|
||
- [ ] Testing | ||
- [ ] Documentation | ||
|
||
## License | ||
|
||
The *GNU GENERAL PUBLIC LICENSE* - see [`LICENSE`](./LICENSE) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package matata | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"net/http" | ||
) | ||
|
||
type AbsenceType struct { | ||
ID int `json:"id"` | ||
Name string `json:"name"` | ||
Archived bool `json:"archived"` | ||
GrantsWorkTime bool `json:"grants_work_time"` | ||
IsVacation bool `json:"is_vacation"` | ||
} | ||
|
||
// AbsenceTypeList represents a list of AbsenceType objects. | ||
type AbsenceTypeList []AbsenceType | ||
|
||
func (c *Client) GetAbsenceTypes(ctx context.Context) (*AbsenceTypeList, error) { | ||
|
||
req, err := http.NewRequest("GET", fmt.Sprintf("%s/absence_types", c.BaseURL), nil) | ||
|
||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
res := AbsenceTypeList{} | ||
if err := c.sendRequest(req, &res); err != nil { | ||
return nil, err | ||
} | ||
|
||
return &res, nil | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
package matata | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"net/http" | ||
"strconv" | ||
"time" | ||
) | ||
|
||
type AbsenceOptions struct { | ||
Year string | ||
} | ||
|
||
type Absence struct { | ||
ID int `json:"id"` | ||
StartDate string `json:"start_date"` | ||
EndDate string `json:"end_date"` | ||
FirstHalfDay bool `json:"first_half_day"` | ||
SecondHalfDay bool `json:"second_half_day"` | ||
IsRecurring bool `json:"is_recurring"` | ||
WeeklyRepeatInterval interface{} `json:"weekly_repeat_interval"` | ||
User User `json:"user"` | ||
Type AbsenceType `json:"absence_type"` | ||
} | ||
|
||
type AbsenceList []Absence | ||
|
||
func (c *Client) GetAbsences(ctx context.Context, options *AbsenceOptions) (*AbsenceList, error) { | ||
|
||
if options.Year == "" { | ||
options.Year = strconv.Itoa(time.Now().Year()) | ||
} | ||
|
||
req, err := http.NewRequest("GET", fmt.Sprintf("%s/absences?year=%s", c.BaseURL, options.Year), nil) | ||
|
||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
res := AbsenceList{} | ||
if err := c.sendRequest(req, &res); err != nil { | ||
return nil, err | ||
} | ||
|
||
return &res, nil | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package matata | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"net/http" | ||
) | ||
|
||
type Company struct { | ||
CompanyName string `json:"company_name"` | ||
DurationFormat string `json:"duration_format"` | ||
AbsenceRequestsEnabled bool `json:"absence_requests_enabled"` | ||
ProjectsEnabled bool `json:"projects_enabled"` | ||
GroupsEnabled bool `json:"groups_enabled"` | ||
} | ||
|
||
func (c *Client) GetCompany(ctx context.Context) (*Company, error) { | ||
|
||
req, err := http.NewRequest("GET", fmt.Sprintf("%s/company", c.BaseURL), nil) | ||
|
||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
res := Company{} | ||
if err := c.sendRequest(req, &res); err != nil { | ||
return nil, err | ||
} | ||
|
||
return &res, nil | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
module github.com/1H0/matata | ||
|
||
go 1.18 |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package matata | ||
|
||
import ( | ||
"context" | ||
"os" | ||
"testing" | ||
) | ||
|
||
func TestPong(t *testing.T) { | ||
c := NewClient(os.Getenv("HAKUNA_TENNANT"), os.Getenv("HAKUNA_TOKEN")) | ||
|
||
res, err := c.Ping(context.TODO()) | ||
|
||
if err != nil { | ||
t.Error(err) | ||
} | ||
|
||
if res.Pong.IsZero() { | ||
t.Error("No Pong came back") | ||
} | ||
|
||
} | ||
|
||
func TestGetAbsenceTypes(t *testing.T) { | ||
|
||
c := NewClient(os.Getenv("HAKUNA_TENNANT"), os.Getenv("HAKUNA_TOKEN")) | ||
|
||
res, err := c.GetAbsenceTypes(context.TODO()) | ||
if res == nil || err != nil { | ||
t.Error(err) | ||
} | ||
} | ||
|
||
func TestGetAbsences(t *testing.T) { | ||
|
||
c := NewClient(os.Getenv("HAKUNA_TENNANT"), os.Getenv("HAKUNA_TOKEN")) | ||
|
||
res, err := c.GetAbsences(context.TODO(), nil) | ||
if res == nil || err != nil { | ||
t.Error(err) | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
package matata | ||
|
||
import ( | ||
"encoding/json" | ||
"errors" | ||
"fmt" | ||
"log" | ||
"net/http" | ||
"time" | ||
) | ||
|
||
const ( | ||
baseURL = "hakuna.ch/api/v1" | ||
) | ||
|
||
type Client struct { | ||
BaseURL string | ||
Tennant string | ||
token string | ||
Client *http.Client | ||
} | ||
|
||
// TODO: Is a bit weird, since somethines you get a Full error object with status code and message, and other times you just get a json object with at error attribute containing a string | ||
type errorResponse struct { | ||
HTTPStatus int | ||
Status int `json:"status"` | ||
Message string `json:"message"` | ||
Error string `json:"error"` | ||
} | ||
|
||
func NewClient(tennant string, token string) *Client { | ||
|
||
if tennant == "" { | ||
log.Fatal("a tennant is required") | ||
} | ||
|
||
if token == "" { | ||
log.Fatal("a token is required") | ||
|
||
} | ||
|
||
return &Client{ | ||
BaseURL: "https://" + tennant + "." + baseURL, | ||
Tennant: tennant, | ||
token: token, | ||
Client: &http.Client{ | ||
Timeout: time.Minute, | ||
}, | ||
} | ||
} | ||
|
||
func (c *Client) sendRequest(req *http.Request, v interface{}) error { | ||
req.Header.Set("Content-Type", "application/json; charset=utf-8") | ||
req.Header.Set("X-Auth-Token", c.token) | ||
|
||
res, err := c.Client.Do(req) | ||
|
||
if err != nil { | ||
return err | ||
} | ||
|
||
defer res.Body.Close() | ||
|
||
if res.StatusCode < http.StatusOK || res.StatusCode >= http.StatusBadRequest { | ||
|
||
var errRes errorResponse | ||
if err = json.NewDecoder(res.Body).Decode(&errRes); err == nil { | ||
|
||
if errRes.Message == "" { | ||
return fmt.Errorf(fmt.Sprintf("%d - %s", res.StatusCode, http.StatusText(res.StatusCode))) | ||
} | ||
|
||
return errors.New(errRes.Message) | ||
} | ||
|
||
return fmt.Errorf("unknown error, status code: %d", res.StatusCode) | ||
} | ||
|
||
if res.StatusCode == http.StatusNoContent { | ||
return nil | ||
} | ||
|
||
if err = json.NewDecoder(res.Body).Decode(&v); err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package matata | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"net/http" | ||
) | ||
|
||
type UserStatus struct { | ||
User User `json:"user"` | ||
AbsentFirstHalfDay bool `json:"absent_first_half_day"` | ||
AbsentSecondHalfDay bool `json:"absent_second_half_day"` | ||
HasTimerRunning bool `json:"has_timer_running"` | ||
} | ||
|
||
type OrganizationStatusList []UserStatus | ||
|
||
func (c *Client) GetOrganizationStatus(ctx context.Context) (*OrganizationStatusList, error) { | ||
|
||
req, err := http.NewRequest("GET", fmt.Sprintf("%s/organization/status", c.BaseURL), nil) | ||
|
||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
res := OrganizationStatusList{} | ||
if err := c.sendRequest(req, &res); err != nil { | ||
return nil, err | ||
} | ||
|
||
return &res, nil | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package matata | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"net/http" | ||
) | ||
|
||
type Overview struct { | ||
Overtime string `json:"overtime"` | ||
OvertimeInSeconds int `json:"overtime_in_seconds"` | ||
Vacation struct { | ||
RedeemedDays float64 `json:"redeemed_days"` | ||
RemainingDays float64 `json:"remaining_days"` | ||
} `json:"vacation"` | ||
} | ||
|
||
func (c *Client) GetOverview(ctx context.Context) (*Overview, error) { | ||
req, err := http.NewRequest("GET", fmt.Sprintf("%s/overview", c.BaseURL), nil) | ||
|
||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
res := Overview{} | ||
if err := c.sendRequest(req, &res); err != nil { | ||
return nil, err | ||
} | ||
|
||
return &res, nil | ||
|
||
} |
Oops, something went wrong.