141 lines
3.1 KiB
Go
141 lines
3.1 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"encoding/json"
|
|
"fmt"
|
|
"html"
|
|
"io/ioutil"
|
|
"net/http"
|
|
"os"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
type togglCurrentResponse struct {
|
|
WorkspaceID int `json:"workspace_id"`
|
|
ProjectID int `json:"project_id"`
|
|
Start string `json:"start"`
|
|
}
|
|
|
|
type togglProjectResponse struct {
|
|
Name string `json:"name"`
|
|
}
|
|
|
|
const (
|
|
TOGGL_CURRENT_URI = "https://api.track.toggl.com/api/v9/me/time_entries/current"
|
|
TOGGL_PROJECT_URI = "https://api.track.toggl.com/api/v9/workspaces/%d/projects/%d"
|
|
TOGGL_API_KEY_VAR = "TOGGL_API_TOKEN"
|
|
TOGGL_API_KEY_FILE = ".config/toggl-api-token"
|
|
)
|
|
|
|
var TOGGL_API_TOKEN = ""
|
|
|
|
func load_toggl_api_key() (string, error) {
|
|
token := os.Getenv(TOGGL_API_TOKEN)
|
|
if token != "" {
|
|
return token, nil
|
|
}
|
|
|
|
home, err := os.UserHomeDir()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
key, err := ioutil.ReadFile(home + "/" + TOGGL_API_KEY_FILE)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return strings.ReplaceAll(string(key), "\n", ""), nil
|
|
}
|
|
|
|
func toggl_basic_auth() string {
|
|
auth := TOGGL_API_TOKEN + ":api_token"
|
|
return "Basic " + base64.StdEncoding.EncodeToString([]byte(auth))
|
|
}
|
|
|
|
func get_current_toggl_project() string {
|
|
if TOGGL_API_TOKEN == "" {
|
|
token, err := load_toggl_api_key()
|
|
if err != nil {
|
|
return "toggl token error"
|
|
}
|
|
TOGGL_API_TOKEN = token
|
|
}
|
|
|
|
client := &http.Client{}
|
|
|
|
currentRequest, err := http.NewRequest("GET", TOGGL_CURRENT_URI, nil)
|
|
if err != nil {
|
|
return "toggl create currentRequest error"
|
|
}
|
|
|
|
currentRequest.Header.Add("Authorization", toggl_basic_auth())
|
|
|
|
resp, err := client.Do(currentRequest)
|
|
if err != nil {
|
|
return "toggl currentRequest error"
|
|
}
|
|
|
|
body, err := ioutil.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return "toggl currentRequest body error"
|
|
}
|
|
|
|
if string(body) == "null" {
|
|
return "<span foreground=\"white\" background=\"red\"> TOGGL NOT TRACKING </span>"
|
|
}
|
|
|
|
var currentJson togglCurrentResponse
|
|
err = json.Unmarshal(body, ¤tJson)
|
|
if err != nil {
|
|
return "toggl currentResponse unmarshal error"
|
|
}
|
|
|
|
if currentJson.ProjectID == 0 {
|
|
return get_toggl_time_elapsed(currentJson.Start)
|
|
}
|
|
|
|
projectRequest, err := http.NewRequest("GET", fmt.Sprintf(TOGGL_PROJECT_URI, currentJson.WorkspaceID, currentJson.ProjectID), nil)
|
|
if err != nil {
|
|
return "toggl create projectRequest error"
|
|
}
|
|
|
|
projectRequest.Header.Add("Authorization", toggl_basic_auth())
|
|
|
|
resp, err = client.Do(projectRequest)
|
|
if err != nil {
|
|
return "toggl projectRequest error"
|
|
}
|
|
|
|
body, err = ioutil.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return "toggl projectRequest body error"
|
|
}
|
|
|
|
var projectJson togglProjectResponse
|
|
err = json.Unmarshal(body, &projectJson)
|
|
if err != nil {
|
|
return "toggl projectResponse unmarshal error"
|
|
}
|
|
|
|
return fmt.Sprintf("%s - %s", html.EscapeString(projectJson.Name), get_toggl_time_elapsed(currentJson.Start))
|
|
}
|
|
|
|
func get_toggl_time_elapsed(start string) string {
|
|
t, err := time.Parse(time.RFC3339, start)
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
|
|
elapsed := time.Since(t)
|
|
hours := int(elapsed.Hours())
|
|
minutes := int(elapsed.Minutes()) % 60
|
|
|
|
if hours == 0 {
|
|
return fmt.Sprintf("%d min", minutes)
|
|
}
|
|
return fmt.Sprintf("%d h %d min", hours, minutes)
|
|
}
|