oh-my-posh/src/segment_nightscout.go
2021-11-26 11:11:07 +01:00

155 lines
3.6 KiB
Go

package main
import (
"encoding/json"
"errors"
"time"
)
// segment struct, makes templating easier
type nightscout struct {
props properties
env environmentInfo
NightscoutData
TrendIcon string
}
const (
// Your complete Nightscout URL and APIKey like this
URL Property = "url"
DoubleUpIcon Property = "doubleup_icon"
SingleUpIcon Property = "singleup_icon"
FortyFiveUpIcon Property = "fortyfiveup_icon"
FlatIcon Property = "flat_icon"
FortyFiveDownIcon Property = "fortyfivedown_icon"
SingleDownIcon Property = "singledown_icon"
DoubleDownIcon Property = "doubledown_icon"
NSCacheTimeout Property = "cache_timeout"
)
// NightscoutData struct contains the API data
type NightscoutData struct {
ID string `json:"_id"`
Sgv int `json:"sgv"`
Date int64 `json:"date"`
DateString time.Time `json:"dateString"`
Trend int `json:"trend"`
Direction string `json:"direction"`
Device string `json:"device"`
Type string `json:"type"`
UtcOffset int `json:"utcOffset"`
SysTime time.Time `json:"sysTime"`
Mills int64 `json:"mills"`
}
func (ns *nightscout) enabled() bool {
data, err := ns.getResult()
if err != nil {
return false
}
ns.NightscoutData = *data
ns.TrendIcon = ns.getTrendIcon()
return true
}
func (ns *nightscout) getTrendIcon() string {
switch ns.Direction {
case "DoubleUp":
return ns.props.getString(DoubleUpIcon, "↑↑")
case "SingleUp":
return ns.props.getString(SingleUpIcon, "↑")
case "FortyFiveUp":
return ns.props.getString(FortyFiveUpIcon, "↗")
case "Flat":
return ns.props.getString(FlatIcon, "→")
case "FortyFiveDown":
return ns.props.getString(FortyFiveDownIcon, "↘")
case "SingleDown":
return ns.props.getString(SingleDownIcon, "↓")
case "DoubleDown":
return ns.props.getString(DoubleDownIcon, "↓↓")
default:
return ""
}
}
func (ns *nightscout) string() string {
segmentTemplate := ns.props.getString(SegmentTemplate, "{{.Sgv}}")
template := &textTemplate{
Template: segmentTemplate,
Context: ns,
Env: ns.env,
}
text, err := template.render()
if err != nil {
return err.Error()
}
return text
}
func (ns *nightscout) getResult() (*NightscoutData, error) {
parseSingleElement := func(data []byte) (*NightscoutData, error) {
var result []*NightscoutData
err := json.Unmarshal(data, &result)
if err != nil {
return nil, err
}
if len(result) == 0 {
return nil, errors.New("no elements in the array")
}
return result[0], nil
}
getCacheValue := func(key string) (*NightscoutData, error) {
val, found := ns.env.cache().get(key)
// we got something from the cache
if found {
if data, err := parseSingleElement([]byte(val)); err == nil {
return data, nil
}
}
return nil, errors.New("no data in cache")
}
url := ns.props.getString(URL, "")
httpTimeout := ns.props.getInt(HTTPTimeout, DefaultHTTPTimeout)
// natural and understood NS timeout is 5, anything else is unusual
cacheTimeout := ns.props.getInt(NSCacheTimeout, 5)
if cacheTimeout > 0 {
if data, err := getCacheValue(url); err == nil {
return data, nil
}
}
body, err := ns.env.doGet(url, httpTimeout)
if err != nil {
return nil, err
}
var arr []*NightscoutData
err = json.Unmarshal(body, &arr)
if err != nil {
return nil, err
}
data, err := parseSingleElement(body)
if err != nil {
return nil, err
}
if cacheTimeout > 0 {
// persist new sugars in cache
ns.env.cache().set(url, string(body), cacheTimeout)
}
return data, nil
}
func (ns *nightscout) init(props properties, env environmentInfo) {
ns.props = props
ns.env = env
}