148 lines
3.2 KiB
Go
148 lines
3.2 KiB
Go
package client
|
|
|
|
import (
|
|
"fmt"
|
|
"io/ioutil"
|
|
"net/url"
|
|
"path"
|
|
"encoding/json"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
"github.com/spf13/viper"
|
|
resty "github.com/go-resty/resty/v2"
|
|
yaml "github.com/ghodss/yaml"
|
|
|
|
"strings"
|
|
)
|
|
|
|
var client *resty.Client
|
|
|
|
// Response is the default JSON response from the Home Assistant Supervisor
|
|
type Response struct {
|
|
Result string `json:"result"`
|
|
Message string `json:"message,omitempty"`
|
|
Data map[string]interface{} `json:"data,omitempty"`
|
|
}
|
|
|
|
// URLHelper returns a URL built from the arguments
|
|
func URLHelper(base, section, command string) (string, error) {
|
|
log.WithFields(log.Fields{
|
|
"base": base,
|
|
"section": section,
|
|
"command": command,
|
|
}).Debug("[GenerateURI]")
|
|
|
|
scheme := ""
|
|
if !strings.Contains(base, "://") {
|
|
scheme = "http://"
|
|
}
|
|
|
|
uri := fmt.Sprintf("%s%s/%s/%s",
|
|
scheme,
|
|
base,
|
|
section,
|
|
command,
|
|
)
|
|
|
|
var myurl, err = url.Parse(uri)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
myurl.Path = path.Clean(myurl.Path)
|
|
|
|
res, _ := url.PathUnescape(myurl.String())
|
|
log.WithFields(log.Fields{
|
|
"uri": uri,
|
|
"url": myurl,
|
|
"url(string)": res,
|
|
}).Debug("[GenerateURI] Result")
|
|
return res, nil
|
|
}
|
|
|
|
// GetJSONRequest returns a request prepared for default JSON resposes
|
|
func GetJSONRequest() *resty.Request {
|
|
request := GetRequest().
|
|
SetResult(Response{}).
|
|
SetError(Response{})
|
|
if RawJSON {
|
|
request.
|
|
SetDoNotParseResponse(true)
|
|
}
|
|
return request
|
|
}
|
|
|
|
// GetRequest returns a resty.Request object prepared for an API call
|
|
func GetRequest() *resty.Request {
|
|
apiToken := viper.GetString("api-token")
|
|
|
|
if client == nil {
|
|
client = resty.New()
|
|
// Registering Response Middleware
|
|
client.OnAfterResponse(func(c *resty.Client, resp *resty.Response) error {
|
|
// explore response object
|
|
log.WithFields(log.Fields{
|
|
"statuscode": resp.StatusCode(),
|
|
"status": resp.Status(),
|
|
"time": resp.Time(),
|
|
"received-at": resp.ReceivedAt(),
|
|
"headers": resp.Header(),
|
|
"request": resp.Request.RawRequest,
|
|
"body": resp,
|
|
}).Debug("Response")
|
|
|
|
return nil // if its success otherwise return error
|
|
})
|
|
}
|
|
|
|
return client.R().
|
|
SetHeader("Accept", "application/json").
|
|
SetAuthToken(apiToken)
|
|
}
|
|
|
|
// ShowJSONResponse formats a JSON response for human readers
|
|
func ShowJSONResponse(resp *resty.Response) (success bool) {
|
|
if RawJSON {
|
|
// when we are returning raw JSON, all handling is for the consumer of the JSON
|
|
success = true
|
|
body := resp.RawBody()
|
|
defer body.Close()
|
|
if b, err := ioutil.ReadAll(body); err == nil {
|
|
fmt.Print(string(b))
|
|
}
|
|
return
|
|
}
|
|
var data *Response
|
|
if resp.IsSuccess() {
|
|
data = resp.Result().(*Response)
|
|
} else {
|
|
data = resp.Error().(*Response)
|
|
}
|
|
if data.Result == "ok" {
|
|
success = true
|
|
if len(data.Data) == 0 {
|
|
fmt.Println("Command completed successfully.")
|
|
} else {
|
|
j, err := json.Marshal(data.Data)
|
|
if err != nil {
|
|
log.Fatalf("error: %v", err)
|
|
}
|
|
|
|
d, err := yaml.JSONToYAML(j)
|
|
if err != nil {
|
|
log.Fatalf("error: %v", err)
|
|
}
|
|
fmt.Print(string(d))
|
|
}
|
|
} else if data.Result == "error" {
|
|
fmt.Printf("Error: %s\n", data.Message)
|
|
} else {
|
|
d, err := yaml.Marshal(data)
|
|
if err != nil {
|
|
log.Fatalf("error: %v", err)
|
|
}
|
|
fmt.Print(string(d))
|
|
}
|
|
return
|
|
}
|