Lightweight and easily self-hostable Git forge. git.poy.ooo
git-forge selfhosting homebrew
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113package hackatime
import ( "encoding/json" "errors" "farga/lib" "fmt" "io" "net/http" "net/url" "time")
type ProjectItem struct { Name string `json:"name"` TotalSeconds uint `json:"total_seconds"` PrettyTime string}
type ProjectResponse struct { Projects []ProjectItem `json:"projects"`}
type User struct { ID uint `json:"id"` SlackID string `json:"slack_id"` Emails []string `json:"emails"`}
// 5 second timeout fetch for API requests, authenticates itself with a Bearer.func fetch(url string, bearer string) ([]byte, error) { req, err := http.NewRequest("GET", url, nil) if err != nil { fmt.Println(err) return nil, err }
req.Header.Add("Accept", "application/json") req.Header.Add("Authorization", "Bearer "+bearer) // user's oauth secret
client := &http.Client{ Timeout: 5 * time.Second, // 5 second timeout }
res, err := client.Do(req)
if err != nil { return nil, err }
defer res.Body.Close()
if res.StatusCode != 200 { return nil, errors.New("Hackatime API returned non-ok status code: " + fmt.Sprint(res.StatusCode)) }
body, err := io.ReadAll(res.Body)
return body, err}
// get a user from their bearer/secret hackatime token.func UserInfo(bearer string) (*User, error) { requestUrl := "https://hackatime.hackclub.com/api/v1/authenticated/me"
body, err := fetch(requestUrl, bearer) if err != nil { return nil, err }
var user User err = json.Unmarshal(body, &user)
return &user, err}
// gets all projects from a given oauth tokenfunc Projects(bearer string) ([]ProjectItem, error) { requestUrl := "https://hackatime.hackclub.com/api/v1/authenticated/projects"
body, err := fetch(requestUrl, bearer) if err != nil { return nil, err }
var projects ProjectResponse err = json.Unmarshal(body, &projects)
return projects.Projects, err}
// gets a single project.func Project(bearer string, name string) (ProjectItem, error) { requestUrl := "https://hackatime.hackclub.com/api/v1/authenticated/projects?projects=" + url.QueryEscape(name) // urlencoded in case someone tries to be funny.
body, err := fetch(requestUrl, bearer) if err != nil { return ProjectItem{}, err }
var projects ProjectResponse err = json.Unmarshal(body, &projects)
// if no such project, if len(projects.Projects) == 0 { return ProjectItem{}, errors.New("Hackatime project not found.") // todo: }
project := projects.Projects[0] project.PrettyTime = lib.FormatTime(int(project.TotalSeconds)) return project, err}