41 Commits

Author SHA1 Message Date
paulo 6aae4a5cdb nats migration 2021-11-14 10:31:07 -03:00
paulo 429580c010 wip 2021-11-13 21:35:07 +00:00
paulo c79c476473 fronted + nats 2021-11-13 16:30:02 -03:00
paulo 581b4def8a nats migration 2021-11-11 11:07:20 -03:00
paulo 5b590ab31b start nats migration 2021-11-11 05:56:07 -03:00
paulo c80d8b1095 added res,setres - fix ScreenWait return (raw, not json) 2021-11-05 13:59:52 -03:00
paulo 9fcc1cccd7 added dataapi 2021-11-05 10:13:48 -03:00
paulo 56927666ef fixed prop name 2021-11-05 10:11:04 -03:00
paulo ac706b9d72 fixed prop name 2021-11-04 17:21:52 -03:00
paulo a010f26d67 fix ocr 2021-11-04 13:05:27 -03:00
paulo a1ee372710 fix url 2021-11-03 19:33:25 -03:00
paulo a58c2b340c fix url 2021-10-31 19:57:02 -03:00
paulo cfbfdd77d5 Fix getmenus 2021-10-31 19:56:25 -03:00
paulo e572aae2a2 Fix getmenus 2021-10-31 19:48:31 -03:00
paulo 74dc132b2b Add OCR 2021-10-31 06:37:05 -03:00
paulo a9dacee062 Added error 2021-10-16 08:50:00 -03:00
paulo 6eda8f5249 added pre-cmds 2021-10-16 06:30:29 -03:00
paulo c573402bc0 Adicionados dados para cron 2021-10-14 13:29:30 -03:00
paulo 84ddbfbe69 transform log in writer 2021-10-14 06:56:11 -03:00
paulo 9602c569ec transform log in writer 2021-10-14 06:24:39 -03:00
paulo a6a48c459b added global config 2021-10-11 19:08:32 -03:00
paulo d12b549846 added log history 2021-10-11 18:38:44 -03:00
paulo 392c7940af added getmyjson to replaycli 2021-10-11 18:21:47 -03:00
paulo f3abaa694d forgot tags on log - lame me. 2021-10-11 15:11:42 -03:00
paulo 2a9dd021e6 fix path 2021-10-11 15:05:01 -03:00
paulo 53a53bd1ca add err and stack to log 2021-10-11 14:58:09 -03:00
paulo 8fb8bb502e added log table 2021-10-11 14:53:32 -03:00
paulo d06e5bceae fix deps 2021-10-11 13:28:04 -03:00
paulo 3a7cad4f12 added configgetmap 2021-10-11 12:31:54 -03:00
paulo bf8aaa2ca0 separated httpcli from replaycli. Added config methods 2021-10-11 11:53:57 -03:00
paulo 4e142e5300 separated httpcli from replaycli. Added config methods 2021-10-11 11:53:44 -03:00
paulo 7d8e31240e added public prop 2021-10-10 13:50:12 -03:00
paulo 5ee19adae4 Update 'types/lib.go' 2021-10-10 16:34:33 +00:00
paulo 42df57854b fix requests 2021-10-10 13:15:15 -03:00
paulo e0a0904c90 fix queueadd 2021-10-10 06:05:27 -03:00
paulo 55bef831c2 Added env access to replaycli 2021-10-10 05:41:47 -03:00
paulo c4e964e115 closing now properly the connection 2021-10-07 07:48:15 +00:00
paulo 23d1d9dd1d added close 2021-10-07 04:32:21 -03:00
paulo 284cc4eb1a Merge pull request 'Ampliação da API Wingui' (#2) from samuel.miranda into master
Reviewed-on: https://gitea.digitalcircle.com.br:443/open/replaycli-go/pulls/2
2021-10-06 16:59:01 +00:00
samuel.miranda 2bdb994cab Remoção do OCR do processo Wingui 2021-10-06 13:56:21 -03:00
samuel.miranda 2a959b9938 Teste 2021-10-06 13:46:47 -03:00
21 changed files with 1122 additions and 421 deletions
+7 -10
View File
@@ -5,11 +5,6 @@ import (
)
type Cli struct {
cli *api.Cli
}
func (c *Cli) HttpCli() *api.Cli {
return c.cli
}
type Req struct {
@@ -19,7 +14,7 @@ type Req struct {
To int `json:"to"`
}
func (c *Cli) Recaptchav2(site string, data string) (string, error) {
func (c *Cli) Recaptchav2(site string, data string, copts ...*api.CallOpts) (string, error) {
ret := ""
req := &Req{
Site: site,
@@ -27,22 +22,24 @@ func (c *Cli) Recaptchav2(site string, data string) (string, error) {
Img: nil,
To: 300,
}
err := c.cli.HttpJsonPost("/ipc/anticaptcha/recaptchav2", req, &ret)
err := api.Call("anticaptcha.recaptchav2", req, &ret, copts...)
return ret, err
}
func (c *Cli) Image2text(site string, data []byte) (string, error) {
func (c *Cli) Image2text(site string, data []byte, copts ...*api.CallOpts) (string, error) {
ret := ""
req := &Req{
Site: site,
Img: data,
To: 300,
}
err := c.cli.HttpJsonPost("/ipc/anticaptcha/image2text", req, &ret)
err := api.Call("anticaptcha.image2text", req, &ret, copts...)
return ret, err
}
func NewCli() *Cli {
ret := &Cli{cli: api.NewCli()}
ret := &Cli{}
return ret
}
+38 -13
View File
@@ -6,45 +6,70 @@ import (
"go.digitalcircle.com.br/open/replaycli-go/api"
)
type Cli struct {
cli *api.Cli
type Req struct {
To int
Url string
Id string
Eval string
Title string
Msg map[string]interface{}
}
type Res struct {
Id string
TabMetadata []TabMetadata
Ret map[string]interface{}
Raw []byte
}
func (c *Cli) HttpCli() *api.Cli {
return c.cli
type TabMetadata struct {
Description string `json:"description"`
DevtoolsFrontendUrl string `json:"devtoolsFrontendUrl"`
Id string `json:"id"`
Title string `json:"title"`
Type string `json:"type"`
Url string `json:"url"`
WebSocketDebuggerUrl string `json:"webSocketDebuggerUrl"`
}
type Cli struct {
*api.ApiCli
}
//func (c *Cli) HttpCli() *httpcli.Cli {
// return c.ApiCli.HttpCli()
//}
func (c *Cli) Start(to int) error {
err := c.cli.HttpJsonGet(fmt.Sprintf("/ipc/chrome/start?to=%d", to), nil)
err := c.HttpCli().JsonGet(fmt.Sprintf("/ipc/chrome/start?to=%d", to), nil)
return err
}
func (c *Cli) StartHeadless() error {
err := c.cli.HttpJsonGet("/ipc/chrome/startHeadless", nil)
err := c.HttpCli().JsonGet("/ipc/chrome/startHeadless", nil)
return err
}
func (c *Cli) Stop() error {
err := c.cli.HttpJsonGet("/ipc/chrome/stop", nil)
err := c.HttpCli().JsonGet("/ipc/chrome/stop", nil)
return err
}
func (c *Cli) New(url string) (string, error) {
ret := ""
err := c.cli.HttpJsonGet(fmt.Sprintf("/ipc/chrome/new?url=%s", url), &ret)
err := c.HttpCli().JsonGet(fmt.Sprintf("/ipc/chrome/new?url=%s", url), &ret)
return ret, err
}
func (c *Cli) Close(id string) error {
err := c.cli.HttpJsonGet("/ipc/chrome/close/"+id, nil)
err := c.HttpCli().JsonGet("/ipc/chrome/close/"+id, nil)
return err
}
func (c *Cli) Eval(id string, s string) (map[string]interface{}, error) {
ret := make(map[string]interface{})
bs, err := c.cli.HttpRawPost("/ipc/chrome/eval/"+id, []byte(s))
bs, err := c.HttpCli().RawPost("/ipc/chrome/eval/"+id, []byte(s))
json.Unmarshal(bs, &ret)
return ret, err
}
func (c *Cli) Wait(id string, s string, to int) (string, error) {
ret := ""
bs, err := c.cli.HttpRawPost(fmt.Sprintf("/ipc/chrome/wait/%s?to=%d", id, to), []byte(s))
bs, err := c.HttpCli().RawPost(fmt.Sprintf("/ipc/chrome/wait/%s?to=%d", id, to), []byte(s))
json.Unmarshal(bs, &ret)
return ret, err
}
@@ -55,11 +80,11 @@ func (c *Cli) Send(id string, m string, ps map[string]interface{}) (string, erro
"method": m,
"params": ps,
}
err := c.cli.HttpJsonPost("/ipc/chrome/eval/"+id, in, &ret)
err := c.HttpCli().JsonPost("/ipc/chrome/eval/"+id, in, &ret)
return ret, err
}
func NewCli() *Cli {
ret := &Cli{cli: api.NewCli()}
ret := &Cli{ApiCli: api.NewApiCli()}
return ret
}
+19 -131
View File
@@ -1,144 +1,32 @@
package api
import (
"bytes"
"encoding/json"
"io"
"net/http"
"go.digitalcircle.com.br/open/httpcli"
"go.digitalcircle.com.br/open/replaycli-go/ipcmux"
"go.digitalcircle.com.br/open/replaycli-go/util"
"os"
"strings"
)
type Cli struct {
cli *http.Client
headers map[string]string
type ApiCli struct {
cli *httpcli.Cli
}
func (c *Cli) Addr() string {
ret := os.Getenv("REPLAY_ADDR")
if ret == "" {
ret = "https://localhost:8443"
} else if strings.HasPrefix(ret, ":") {
ret = "https://localhost" + ret
}
return ret
}
func (c *Cli) AddHeader(k string, v string) {
c.headers[k] = v
}
func (c *Cli) DelHeader(k string) {
delete(c.headers, k)
}
func (c *Cli) HttpDo(method string, strurl string, body []byte) (*http.Response, error) {
if !strings.HasPrefix(strurl, "http") {
addr := c.Addr()
if strings.HasSuffix(addr, "/") {
addr = addr[:len(addr)-1]
}
if !strings.HasPrefix(strurl, "") {
strurl = "/" + strurl
}
strurl = addr + strurl
}
req, err := http.NewRequest(method, strurl, bytes.NewReader(body))
if err != nil {
return nil, err
}
if c.headers != nil {
for k, v := range c.headers {
req.Header.Set(k, v)
}
}
if body != nil && len(body) > 0 {
req, err = http.NewRequest(method, strurl, io.NopCloser(bytes.NewReader(body)))
} else {
req, err = http.NewRequest(method, strurl, nil)
}
if err != nil {
return nil, err
}
req.Header.Set("X-API-KEY", apikey)
req.Header.Set("Content-Type", "application/json")
return c.cli.Do(req)
}
func (c *Cli) HttpDoJson(method string, strurl string, i interface{}, o interface{}) (err error) {
bs, err := json.Marshal(i)
if err != nil {
return err
}
res, err := c.HttpDo(method, strurl, bs)
if err != nil {
return
}
defer res.Body.Close()
if o != nil {
err = json.NewDecoder(res.Body).Decode(o)
}
return
}
func (c *Cli) HttpJsonGet(strurl string, o interface{}) error {
return c.HttpDoJson(http.MethodGet, strurl, nil, o)
}
func (c *Cli) HttpJsonDelete(strurl string, o interface{}) error {
return c.HttpDoJson(http.MethodDelete, strurl, nil, o)
}
func (c *Cli) HttpJsonHead(strurl string, o interface{}) error {
return c.HttpDoJson(http.MethodHead, strurl, nil, o)
}
func (c *Cli) HttpJsonPost(strurl string, i interface{}, o interface{}) error {
return c.HttpDoJson(http.MethodPost, strurl, i, o)
}
func (c *Cli) HttpJsonPut(strurl string, i interface{}, o interface{}) error {
return c.HttpDoJson(http.MethodPut, strurl, i, o)
}
func (c *Cli) HttpJsonPatch(strurl string, i interface{}, o interface{}) error {
return c.HttpDoJson(http.MethodPatch, strurl, i, o)
}
func (c *Cli) HttpRawGet(strurl string) ([]byte, error) {
res, err := c.HttpDo(http.MethodGet, strurl, nil)
if err != nil {
return nil, err
}
defer res.Body.Close()
bs, _ := io.ReadAll(res.Body)
return bs, nil
}
func (c *Cli) HttpRawDelete(strurl string) ([]byte, error) {
res, err := c.HttpDo(http.MethodDelete, strurl, nil)
if err != nil {
return nil, err
}
defer res.Body.Close()
bs, _ := io.ReadAll(res.Body)
return bs, nil
}
func (c *Cli) HttpRawPost(strurl string, i []byte) ([]byte, error) {
res, err := c.HttpDo(http.MethodPost, strurl, i)
if err != nil {
return nil, err
}
defer res.Body.Close()
bs, _ := io.ReadAll(res.Body)
return bs, nil
}
func (c *Cli) HttpRawPut(strurl string, i []byte) ([]byte, error) {
res, err := c.HttpDo(http.MethodPut, strurl, i)
if err != nil {
return nil, err
}
defer res.Body.Close()
bs, _ := io.ReadAll(res.Body)
return bs, nil
func (a *ApiCli) HttpCli() *httpcli.Cli {
return a.cli
}
func NewCli() *Cli {
func NewApiCli() *ApiCli {
ret := &ApiCli{cli: httpcli.C()}
ret.cli.SetBasePath(util.Addr())
apikey = os.Getenv("REPLAY_APIKEY")
ret := &Cli{
cli: &http.Client{},
headers: make(map[string]string),
}
ret.AddHeader("X-API-KEY", apikey)
ret.cli.AddHeader("X-API-KEY", apikey)
return ret
}
func NewApiIPCCli() *ApiCli {
ret := &ApiCli{cli: httpcli.NewCli()}
ret.cli.SetCli(ipcmux.NewClient())
apikey = os.Getenv("REPLAY_APIKEY")
ret.cli.AddHeader("X-API-KEY", apikey)
return ret
}
+45
View File
@@ -0,0 +1,45 @@
package dataapi
import (
"go.digitalcircle.com.br/open/httpcli"
)
type DataApiOp string
const (
RETRIEVE DataApiOp = "R"
CREATE DataApiOp = "C"
DELETE DataApiOp = "D"
UPDATE DataApiOp = "U"
)
type DataAPIRequest struct {
Col string `json:"col"`
Q string `json:"q"`
Op DataApiOp `json:"op"`
Id string `json:"id"`
Data map[string]interface{} `json:"data"`
}
type DataAPIResponse struct {
Msg string `json:"msg"`
Id string `json:"id"`
Data []interface{} `json:"data"`
}
type Cli struct {
Httpcli *httpcli.Cli
}
func (c *Cli) Do(request *DataAPIRequest) (response *DataAPIResponse, err error) {
response = &DataAPIResponse{}
err = c.Httpcli.JsonPost("/", request, response)
return
}
func NewCli(apikey string) *Cli {
ret := &Cli{Httpcli: httpcli.NewCli()}
ret.Httpcli.AddHeader("X-API-KEY", apikey)
ret.Httpcli.SetBasePath("https://dataapi.digitalcircle.com.br")
return ret
}
+82
View File
@@ -0,0 +1,82 @@
package dataapi_test
import (
"go.digitalcircle.com.br/open/replaycli-go/api/dataapi"
"log"
"testing"
)
func TestAPIRetrieve(t *testing.T) {
c := dataapi.NewCli("RnJpIDA1IE5vdiAyMDIxIDExOjE1OjIyIEFNIFVUQwo")
res, err := c.Do(&dataapi.DataAPIRequest{
Col: "C1",
Op: dataapi.RETRIEVE,
})
if err != nil {
t.Fatal(err.Error())
}
log.Printf("%#v", res)
}
func TestAPIRetrieveWQuery(t *testing.T) {
c := dataapi.NewCli("RnJpIDA1IE5vdiAyMDIxIDExOjE1OjIyIEFNIFVUQwo")
res, err := c.Do(&dataapi.DataAPIRequest{
Col: "C1",
Op: dataapi.RETRIEVE,
Q: "@[?ID==`2`]",
})
if err != nil {
t.Fatal(err.Error())
}
log.Printf("%#v", res)
}
func TestAPIUpdate(t *testing.T) {
c := dataapi.NewCli("RnJpIDA1IE5vdiAyMDIxIDExOjE1OjIyIEFNIFVUQwo")
res, err := c.Do(&dataapi.DataAPIRequest{
Col: "C1",
Op: dataapi.UPDATE,
Id: "2",
Data: map[string]interface{}{
"F2": "Novo Campo",
},
})
if err != nil {
t.Fatal(err.Error())
}
log.Printf("%#v", res)
}
func TestAPIDelete(t *testing.T) {
c := dataapi.NewCli("RnJpIDA1IE5vdiAyMDIxIDExOjE1OjIyIEFNIFVUQwo")
res, err := c.Do(&dataapi.DataAPIRequest{
Col: "C1",
Op: dataapi.DELETE,
Id: "2",
})
if err != nil {
t.Fatal(err.Error())
}
log.Printf("%#v", res)
}
func TestAPICreate(t *testing.T) {
c := dataapi.NewCli("RnJpIDA1IE5vdiAyMDIxIDExOjE1OjIyIEFNIFVUQwo")
res, err := c.Do(&dataapi.DataAPIRequest{
Col: "C1",
Op: dataapi.CREATE,
Data: map[string]interface{}{
"MSG": "OI LEO",
},
})
if err != nil {
t.Fatal(err.Error())
}
log.Printf("%#v", res)
}
+3 -6
View File
@@ -5,19 +5,16 @@ import (
)
type Cli struct {
cli *api.Cli
*api.ApiCli
}
func (c *Cli) HttpCli() *api.Cli {
return c.cli
}
func (c *Cli) New(i interface{}) (string, error) {
res := ""
err := c.cli.HttpJsonPost("/ipc/datasyncreportmgr/new", i, &res)
err := c.HttpCli().JsonPost("/ipc/datasyncreportmgr/new", i, &res)
return res, err
}
func NewCli() *Cli {
ret := &Cli{cli: api.NewCli()}
ret := &Cli{ApiCli: api.NewApiCli()}
return ret
}
+5 -9
View File
@@ -11,11 +11,7 @@ const (
)
type Cli struct {
cli *api.Cli
}
func (c *Cli) HttpCli() *api.Cli {
return c.cli
*api.ApiCli
}
type Req struct {
@@ -32,7 +28,7 @@ func (c *Cli) Read(fname string, sheet string) ([][]string, error) {
Sheet: sheet,
}
res := make([][]string, 0)
err := c.cli.HttpJsonPost("/ipc/excel/read", req, &res)
err := c.HttpCli().JsonPost("/ipc/excel/read", req, &res)
return res, err
}
func (c *Cli) Write(fname string, sheet string, cell string, val string, celtype string) error {
@@ -44,7 +40,7 @@ func (c *Cli) Write(fname string, sheet string, cell string, val string, celtype
Celtype: celtype,
}
res := ""
err := c.cli.HttpJsonPost("/ipc/excel/write", req, &res)
err := c.HttpCli().JsonPost("/ipc/excel/write", req, &res)
return err
}
@@ -54,11 +50,11 @@ func (c *Cli) New(fname string, sheet string) (string, error) {
Sheet: sheet,
}
res := ""
err := c.cli.HttpJsonPost("/ipc/excel/new", req, &res)
err := c.HttpCli().JsonPost("/ipc/excel/new", req, &res)
return res, err
}
func NewCli() *Cli {
ret := &Cli{cli: api.NewCli()}
ret := &Cli{ApiCli: api.NewApiCli()}
return ret
}
+29
View File
@@ -0,0 +1,29 @@
package frontend
import "go.digitalcircle.com.br/open/replaycli-go/api"
type Cli struct {
}
type HttpRes struct {
Headers map[string]string
Body []byte
}
type HttpReq struct {
Url string
Headers map[string]string
Body []byte
}
func (c *Cli) Get(req *HttpReq, copts ...*api.CallOpts) (*HttpRes, error) {
res := &HttpRes{}
//err := c.HttpCli().JsonPost("/ipc/ocr/", opts, res)
err := api.Call("frontend.handle", req, &res, copts...)
return res, err
}
func NewCli() *Cli {
ret := &Cli{}
return ret
}
+12
View File
@@ -0,0 +1,12 @@
package http
type HttpRes struct {
Headers map[string]string
Body []byte
}
type HttpReq struct {
Url string
Headers map[string]string
Body []byte
}
+145
View File
@@ -0,0 +1,145 @@
package api
import (
"encoding/json"
"errors"
"fmt"
"github.com/nats-io/nats.go"
"log"
"os"
"time"
)
var nc *nats.Conn
type CallOpts struct {
To int
}
func NC() (nc *nats.Conn, err error) {
if nc == nil {
apikey = os.Getenv("REPLAY_APIKEY")
if apikey == "" {
log.Printf("Connecting to NATS Server w/o TK.")
nc, err = nats.Connect(nats.DefaultURL)
} else {
log.Printf("Connecting to NATS Server w TK: " + apikey)
nc, err = nats.Connect(nats.DefaultURL, nats.Token(apikey))
}
if err != nil {
return nil, err
}
}
return nc, nil
}
func Call(s string, in interface{}, out interface{}, opts ...*CallOpts) error {
var err error
opt := &CallOpts{}
if opts != nil && len(opts) > 1 {
opt = opts[0]
}
if opt.To == 0 {
opt.To = 60
}
defer func() {
if nc != nil && err != nil {
err1 := nc.Publish("err", []byte(fmt.Sprintf("Error calling nats: %s: \nIN: %v\nOUT: %v", s, err.Error(), in, out)))
if err1 != nil {
log.Printf("Error calling nats: %s: \nIN: %v\nOUT: %v", s, err.Error(), in, out)
log.Printf("Inner error: %s", err1.Error())
}
} else if nc == nil && err != nil {
log.Printf("Error calling nats: %s: \nIN: %v\nOUT: %v\n(nc is nil)", s, err.Error(), in, out)
}
}()
if nc == nil {
apikey = os.Getenv("REPLAY_APIKEY")
if apikey == "" {
log.Printf("Connecting to NATS Server w/o TK.")
nc, err = nats.Connect(nats.DefaultURL)
} else {
log.Printf("Connecting to NATS Server w TK: " + apikey)
nc, err = nats.Connect(nats.DefaultURL, nats.Token(apikey))
}
if err != nil {
return err
}
}
var bs []byte
if in != nil {
bs, err = json.Marshal(in)
if err != nil {
return err
}
} else {
bs = []byte("{}")
}
msg, err := nc.Request(s, bs, time.Second+time.Duration(opt.To))
if err != nil {
return err
}
if out != nil {
err = json.Unmarshal(msg.Data, out)
if err != nil {
out = bs
return err
}
}
errstr := msg.Header.Get("ERR")
if errstr != "" {
return errors.New(errstr)
}
return nil
}
func Close() error {
return nc.Drain()
}
func Pub(s string, in interface{}) error {
var err error
defer func() {
if nc != nil && err != nil {
err1 := nc.Publish("err", []byte(fmt.Sprintf("Error calling nats: %s: \nIN: %v", s, err.Error(), in)))
if err1 != nil {
log.Printf("Error calling nats: %s: \nIN: %v", s, err.Error(), in)
log.Printf("Inner error: %s", err1.Error())
}
} else if nc == nil && err != nil {
log.Printf("Error calling nats: %s: \nIN: %v\n(nc is nil)", s, err.Error(), in)
}
}()
bs, err := json.Marshal(in)
if err != nil {
return err
}
err = nc.Publish(s, bs)
return err
}
func Init() error {
var err error
nc, err = NC()
if err != nil {
return err
}
nc.Subscribe("exit", func(msg *nats.Msg) {
log.Printf("Exit Required")
os.Exit(0)
})
return nil
}
func Err(e error) {
Pub("err", e.Error())
}
func Dbg(e string) {
Pub("dbg", e)
}
+171 -184
View File
@@ -1,197 +1,184 @@
package wingui
package ocr
import (
"fmt"
"encoding/xml"
"go.digitalcircle.com.br/open/replaycli-go/api"
"log"
)
const ScreenShot = "ss"
type AltoString struct {
Text string `xml:",chardata"`
ID string `xml:"ID,attr"`
HPOS int `xml:"HPOS,attr"`
VPOS int `xml:"VPOS,attr"`
WIDTH int `xml:"WIDTH,attr"`
HEIGHT int `xml:"HEIGHT,attr"`
WC float64 `xml:"WC,attr"`
CONTENT string `xml:"CONTENT,attr"`
AHPOS int `xml:"AHPOS,attr"`
AVPOS int `xml:"AVPOS,attr"`
AWIDTH int `xml:"AWIDTH,attr"`
AHEIGHT int `xml:"AHEIGHT,attr"`
}
func (a *AltoString) AbsCoords(q *Opts) {
nx := int(float64(a.HPOS)/q.Proportion) + q.X
ny := int(float64(a.VPOS)/q.Proportion) + q.Y
nw := int(float64(a.WIDTH) / q.Proportion)
nh := int(float64(a.HEIGHT) / q.Proportion)
log.Printf("Mapping: x: %v=>%v; y:%v=>%v; w:%v=>%v; h:%v=>%v;(Prop: %v,qx: %v, qy: %v)", a.HPOS, nx, a.VPOS, ny, a.WIDTH, nw, a.HEIGHT, nh, q.Proportion, q.X, q.Y)
a.AHPOS = nx
a.AVPOS = ny
a.AWIDTH = nw
a.AHEIGHT = nh
return
}
type AltoSP struct {
Text string `xml:",chardata"`
WIDTH int `xml:"WIDTH,attr"`
VPOS int `xml:"VPOS,attr"`
HPOS int `xml:"HPOS,attr"`
}
type AltoTextLine struct {
Text string `xml:",chardata"`
ID string `xml:"ID,attr"`
HPOS string `xml:"HPOS,attr"`
VPOS string `xml:"VPOS,attr"`
WIDTH string `xml:"WIDTH,attr"`
HEIGHT string `xml:"HEIGHT,attr"`
String []*AltoString `xml:"String"`
SP []*AltoSP `xml:"SP"`
}
type AltoTextBlock struct {
Text string `xml:",chardata"`
ID string `xml:"ID,attr"`
HPOS int `xml:"HPOS,attr"`
VPOS int `xml:"VPOS,attr"`
WIDTH int `xml:"WIDTH,attr"`
HEIGHT int `xml:"HEIGHT,attr"`
TextLine []*AltoTextLine `xml:"TextLine"`
}
type AltoComposedBlock struct {
Text string `xml:",chardata"`
ID string `xml:"ID,attr"`
HPOS int `xml:"HPOS,attr"`
VPOS int `xml:"VPOS,attr"`
WIDTH int `xml:"WIDTH,attr"`
HEIGHT int `xml:"HEIGHT,attr"`
TextBlock []*AltoTextBlock `xml:"TextBlock"`
}
type AltoPrintSpace struct {
Text string `xml:",chardata"`
HPOS int `xml:"HPOS,attr"`
VPOS int `xml:"VPOS,attr"`
WIDTH int `xml:"WIDTH,attr"`
HEIGHT int `xml:"HEIGHT,attr"`
ComposedBlock []*AltoComposedBlock `xml:"ComposedBlock"`
}
type AltoPage struct {
Text string `xml:",chardata"`
WIDTH int `xml:"WIDTH,attr"`
HEIGHT int `xml:"HEIGHT,attr"`
PHYSICALIMGNR string `xml:"PHYSICAL_IMG_NR,attr"`
ID string `xml:"ID,attr"`
PrintSpace *AltoPrintSpace `xml:"PrintSpace"`
}
type AltoDescription struct {
Text string `xml:",chardata"`
MeasurementUnit string `xml:"MeasurementUnit"`
SourceImageInformation struct {
Text string `xml:",chardata"`
FileName string `xml:"fileName"`
} `xml:"sourceImageInformation"`
OCRProcessing *struct {
Text string `xml:",chardata"`
ID string `xml:"ID,attr"`
OcrProcessingStep struct {
Text string `xml:",chardata"`
ProcessingSoftware struct {
Text string `xml:",chardata"`
SoftwareName string `xml:"softwareName"`
} `xml:"processingSoftware"`
} `xml:"ocrProcessingStep"`
} `xml:"OCRProcessing"`
}
type AltoLayout struct {
Text string `xml:",chardata"`
Page *AltoPage `xml:"Page"`
}
type Alto struct {
XMLName xml.Name `xml:"alto"`
Text string `xml:",chardata"`
Xmlns string `xml:"xmlns,attr"`
Xlink string `xml:"xlink,attr"`
Xsi string `xml:"xsi,attr"`
SchemaLocation string `xml:"schemaLocation,attr"`
Description *AltoDescription `xml:"Description"`
Layout *AltoLayout `xml:"Layout"`
}
func (a *Alto) Strings() []*AltoString {
ret := make([]*AltoString, 0)
for _, v := range a.Layout.Page.PrintSpace.ComposedBlock {
for _, v1 := range v.TextBlock {
for _, v2 := range v1.TextLine {
for _, v3 := range v2.String {
ret = append(ret, v3)
}
}
}
}
return ret
}
func (a *Alto) CalcAbsolute(q *Opts) {
for _, v := range a.Layout.Page.PrintSpace.ComposedBlock {
for _, v1 := range v.TextBlock {
for _, v2 := range v1.TextLine {
for _, v3 := range v2.String {
v3.AbsCoords(q)
}
}
}
}
}
type Opts struct {
Ver string `json:"ver,omitempty"`
X int `json:"x"`
Y int `json:"y"`
H int `json:"h"`
W int `json:"w"`
Blur float64 `json:"blur"`
Sharpen float64 `json:"sharpen"`
Resizew int `json:"resizew"`
Resizeh int `json:"resizeh"`
Lang string `json:"lang"`
Tempfile string `json:"tempfile"`
Dispid int `json:"d"`
Gray bool `json:"gray"`
Src string `json:"src"`
Bytes []byte `json:"bytes"`
AddRects bool `json:"add_rects"`
Proportion float64 `json:"proportion"`
Encoding string `json:"encoding"`
Absolute bool `json:"absolute"`
}
type Cli struct {
cli *api.Cli
//*api.ApiCli
}
func (c *Cli) HttpCli() *api.Cli {
return c.cli
}
func (c *Cli) Ocr_screen(l string) (map[string]interface{}, error) {
d := 0
ret := make(map[string]interface{})
err := c.cli.HttpJsonGet(fmt.Sprintf("/ipc/ocr/screen?l=%s&d=%d", l, d), &ret)
return ret, err
}
func (c *Cli) ClipRead() (string, error) {
ret := ""
err := c.cli.HttpJsonGet(fmt.Sprintf("/ipc/wingui/clip/read"), &ret)
return ret, err
}
func (c *Cli) ClipWrite(site string) error {
err := c.cli.HttpJsonGet(fmt.Sprintf("/ipc/wingui/clip/write?str=%s", site), nil)
return err
}
func (c *Cli) MouseClick() error {
err := c.cli.HttpJsonGet(fmt.Sprintf("/ipc/wingui/mouse/click"), nil)
return err
}
func (c *Cli) MouseMove(x, y int) error {
err := c.cli.HttpJsonGet(fmt.Sprintf("/ipc/wingui/mouse/move?x=%d&y=%d", x, y), nil)
return err
}
func (c *Cli) MouseMoveRelative(x, y int) error {
err := c.cli.HttpJsonGet(fmt.Sprintf("/ipc/wingui/mouse/moverelative?x=%d&y=%d", x, y), nil)
return err
}
func (c *Cli) MouseClickRelative(x, y int) error {
err := c.cli.HttpJsonGet(fmt.Sprintf("/ipc/wingui/mouse/clickatrelative?x=%d&y=%d", x, y), nil)
return err
}
func (c *Cli) MouseClickAt(x, y int) error {
err := c.cli.HttpJsonGet(fmt.Sprintf("/ipc/wingui/mouse/clickat?x=%d&y=%d", x, y), nil)
return err
}
func (c *Cli) ScreenClick(f string) error {
err := c.cli.HttpJsonGet(fmt.Sprintf("/ipc/wingui/screen/click?f=%s", f), nil)
return err
}
func (c *Cli) ScreenClickCenter(f string) error {
err := c.cli.HttpJsonGet(fmt.Sprintf("/ipc/wingui/screen/clickcenter?f=%s", f), nil)
return err
}
func (c *Cli) ScreenFind(f string) (ret map[string]interface{}, err error) {
ret = make(map[string]interface{})
err = c.cli.HttpJsonGet(fmt.Sprintf("/ipc/wingui/screen/find?f=%s", f), &ret)
return
}
func (c *Cli) KBTap(t string) (map[string]interface{}, error) {
/*Envia uma tecla ou teclas para serem clicadas no componente com foco onde o robo é executado
Em caso de teclas alteradoras, elas devem ser sempre posicionadas apos a tecla alvo.
Dessa forma, para enviar ALT+d, vc envia o string "d,alt". Para enviar C maiusculo, vc utiiliza
"c,shift".
Referencia das teclas e respectivos strings:
"`": 41,
"1": 2,
"2": 3,
"3": 4,
"4": 5,
"5": 6,
"6": 7,
"7": 8,
"8": 9,
"9": 10,
"0": 11,
"-": 12,
"+": 13,
//
"q": 16,
"w": 17,
"e": 18,
"r": 19,
"t": 20,
"y": 21,
"u": 22,
"i": 23,
"o": 24,
"p": 25,
"[": 26,
"]": 27,
"\\": 43,
//
"a": 30,
"s": 31,
"d": 32,
"f": 33,
"g": 34,
"h": 35,
"j": 36,
"k": 37,
"l": 38,
";": 39,
"'": 40,
//
"z": 44,
"x": 45,
"c": 46,
"v": 47,
"b": 48,
"n": 49,
"m": 50,
",": 51,
".": 52,
"/": 53,
//
"f1": 59,
"f2": 60,
"f3": 61,
"f4": 62,
"f5": 63,
"f6": 64,
"f7": 65,
"f8": 66,
"f9": 67,
"f10": 68,
"f11": 69,
"f12": 70,
// more
"esc": 1,
"delete": 14,
"tab": 15,
"ctrl": 29,
"control": 29,
"alt": 56,
"space": 57,
"shift": 42,
"rshift": 54,
"enter": 28,
//
"cmd": 3675,
"command": 3675,
"rcmd": 3676,
"ralt": 3640,
//
"up": 57416,
"down": 57424,
"left": 57419,
"right": 57421,
*/
ret := make(map[string]interface{})
err := c.cli.HttpJsonGet(fmt.Sprintf("/ipc/wingui/kb/tap?str=%s", t), &ret)
return ret, err
}
func (c *Cli) KBType(t string) (map[string]interface{}, error) {
/* Semelhante a tap, mas envia textos completos.
***ATENCAO*** Esse metodo usa urlencoding, dessa forma caracteres serao codificados para envio. # virará %23
por exemplo. Ao chegar no robo passrão pelo decoding análogo. */
ret := make(map[string]interface{})
err := c.cli.HttpJsonGet(fmt.Sprintf("/ipc/wingui/kb/type?str=%s", t), &ret)
return ret, err
}
func (c *Cli) ScreenWait(f string, m int) (ret map[string]interface{}, err error) {
ret = make(map[string]interface{})
err = c.cli.HttpJsonGet(fmt.Sprintf("/ipc/wingui/screen/wait?f=%s&m=%d", f, m), &ret)
return
}
func (c *Cli) ScreenWaitClick(f string, m int) (ret map[string]interface{}, err error) {
ret = make(map[string]interface{})
err = c.cli.HttpJsonGet(fmt.Sprintf("/ipc/wingui/screen/waitclick?f=%s&m=%d", f, m), &ret)
return
}
func (c *Cli) ScreenWaitClickCenter(f string, m int) (ret map[string]interface{}, err error) {
ret = make(map[string]interface{})
err = c.cli.HttpJsonGet(fmt.Sprintf("/ipc/wingui/screen/waitclickcenter?f=%s&m=%d", f, m), &ret)
return
func (c *Cli) OCR(opts *Opts, copts ...*api.CallOpts) (*Alto, error) {
res := &Alto{}
err := api.Call("ocr.ocr", opts, &res, copts...)
return res, err
}
func NewCli() *Cli {
ret := &Cli{cli: api.NewCli()}
ret := &Cli{}
return ret
}
+27
View File
@@ -0,0 +1,27 @@
package ocr_test
import (
"go.digitalcircle.com.br/open/replaycli-go/api/ocr"
"log"
"testing"
)
func TestCli_OCR(t *testing.T) {
c := ocr.NewCli()
a, err := c.OCR(&ocr.Opts{
X: 0,
Y: 0,
H: 400,
W: 400,
Resizew: 1200,
Sharpen: 1,
Tempfile: "some_test.jpg",
Src: "ss",
AddRects: true,
Gray: true,
})
if err != nil {
t.Fatal(err.Error())
}
log.Printf("#%v", a)
}
+103 -17
View File
@@ -1,8 +1,11 @@
package replay
import (
"encoding/json"
"fmt"
"os"
"runtime"
"time"
"go.digitalcircle.com.br/open/replaycli-go/api"
"go.digitalcircle.com.br/open/replaycli-go/types"
@@ -10,63 +13,146 @@ import (
)
type Cli struct {
cli *api.Cli
*api.ApiCli
}
func (c *Cli) HttpCli() *api.Cli {
return c.cli
func (c *Cli) Log(l *types.Log) error {
l.Alias = c.ReplayEnvAlias()
l.Dtlogend = time.Now()
return c.HttpCli().JsonPost("/api/v1/log/add", l, nil)
}
func (c *Cli) NewLog() *types.Log {
ret := &types.Log{}
ret.Alias = c.ReplayEnvAlias()
ret.Dtlog = time.Now()
return ret
}
func (c *Cli) ReplayEnvQueueId() string {
return os.Getenv("REPLAY_QUEUEID")
}
func (c *Cli) ReplayEnvAlias() string {
return os.Getenv("REPLAY_ALIAS")
}
func (c *Cli) ReplayEnvFeatureDir() string {
return os.Getenv("REPLAY_FEATUREDIR")
}
func (c *Cli) ReplayEnvRoot() string {
return os.Getenv("REPLAY_ROOT")
}
func (c *Cli) ReplayEnvAddr() string {
return os.Getenv("REPLAY_ADDR")
}
func (c *Cli) ReplayEnvHomeDir() string {
return os.Getenv("REPLAY_HOMEDIR")
}
func (c *Cli) ReplayEnvRepo() string {
return os.Getenv("REPLAY_REPO")
}
func (c *Cli) ReplayEnvVer() string {
return os.Getenv("REPLAY_VER")
}
func (c *Cli) ReplayEnvRepoDir() string {
return os.Getenv("REPLAY_REPODIR")
}
func (c *Cli) ReplayEnvDataDir() string {
return os.Getenv("REPLAY_DATADIR")
}
func (c *Cli) ReplayEnvInstanceAlias() string {
return os.Getenv("REPLAY_INSTANCE_ALIAS")
}
func (c *Cli) ReplayEnvApiKey() string {
return os.Getenv("REPLAY_APIKEY")
}
func (c *Cli) OpenApp(id uint) error {
err := c.cli.HttpJsonGet(fmt.Sprintf("/api/v1/app/run/%d", id), nil)
err := c.HttpCli().JsonGet(fmt.Sprintf("/api/v1/app/run/%d", id), nil)
return err
}
func (c *Cli) ConfigGet(k string) (ret string, err error) {
err = c.cli.HttpJsonGet("/api/v1/config/byrepo/"+util.Repo()+"/"+k, &ret)
err = c.HttpCli().JsonGet("/api/v1/config/byrepo/"+util.Repo()+"/"+k, &ret)
return
}
func (c *Cli) ConfigGetGlobal(k string) (ret string, err error) {
err = c.HttpCli().JsonGet("/api/v1/config/global/"+k, &ret)
return
}
func (c *Cli) ConfigGetAll() (ret []types.Config, err error) {
ret = make([]types.Config, 0)
err = c.cli.HttpJsonGet("/api/v1/config/byrepo/"+util.Repo(), &ret)
err = c.HttpCli().JsonGet("/api/v1/config/byrepo/"+util.Repo(), &ret)
return
}
func (c *Cli) ConfigGetMap() (ret map[string]types.Config, err error) {
cfgs, err := c.ConfigGetAll()
if err != nil {
return
}
ret = make(map[string]types.Config)
for _, v := range cfgs {
ret[v.K] = v
}
return
}
func (c *Cli) CronReload() error {
return c.cli.HttpJsonGet("/ipc/cron/reload", nil)
return c.HttpCli().JsonGet("/ipc/cron/reload", nil)
}
func (c *Cli) Exit() error {
err := c.cli.HttpJsonGet("/api/v1/exit", nil)
err := c.HttpCli().JsonGet("/api/v1/exit", nil)
return err
}
func (c *Cli) MenuGetAllEnabled() (ret []types.Menu, err error) {
ret = make([]types.Menu, 0)
err = c.cli.HttpJsonGet("/api/v1/menu/enabled", nil)
err = c.HttpCli().JsonGet("/api/v1/menu/enabled", &ret)
return ret, err
}
func (c *Cli) QueueAdd(job string, bs []byte) error {
return c.cli.HttpJsonGet("/api/v1/queue/add/"+job, bs)
_, err := c.HttpCli().RawPost("/api/v1/queue/add/"+job, bs)
return err
}
func (c *Cli) QueueGetData(id string) (ret []byte, err error) {
ret, err = c.cli.HttpRawGet("/api/v1/queue/getrequest/" + id)
ret, err = c.HttpCli().RawGet("/api/v1/queue/getrequest/" + id)
return
}
func (c *Cli) QueueGetMyData() ([]byte, error) {
return c.QueueGetData(os.Getenv("REPLAY_QUEUEID"))
}
func (c *Cli) QueueGetMyJson(i interface{}) error {
bs, err := c.QueueGetData(os.Getenv("REPLAY_QUEUEID"))
if err != nil {
return err
}
err = json.Unmarshal(bs, i)
return err
}
func (c *Cli) QueueAbort() error {
return c.cli.HttpJsonGet("/api/v1/queue/abort", nil)
return c.HttpCli().JsonGet("/api/v1/queue/abort", nil)
}
func (c *Cli) QueueEnqueue(id uint) error {
return c.cli.HttpJsonGet(fmt.Sprintf("/api/v1/robots/op/enqueue/%d", id), nil)
return c.HttpCli().JsonGet(fmt.Sprintf("/api/v1/robots/op/enqueue/%d", id), nil)
}
func (c *Cli) ServiceStopAll() error {
return c.cli.HttpJsonGet("/api/v1/service/op/stopall", nil)
return c.HttpCli().JsonGet("/api/v1/service/op/stopall", nil)
}
func (c *Cli) Err(err string, desc string) error {
bs := make([]byte, 4096)
n := runtime.Stack(bs, false)
cd, _ := c.QueueGetMyData()
e := &types.Error{
Feature: c.ReplayEnvAlias(),
Err: err,
When: time.Time{},
Stack: string(bs[:n]),
InputData: string(cd),
Details: desc,
}
return c.HttpCli().JsonPost("/api/v1/err", e, nil)
}
type SQLReturn struct {
@@ -79,11 +165,11 @@ func (c *Cli) SQL(s string) (*SQLReturn, error) {
Sql string `json:"sql"`
}{s}
out := &SQLReturn{}
err := c.cli.HttpJsonPost("/api/v1/sql", in, &out)
err := c.HttpCli().JsonPost("/api/v1/sql", in, &out)
return out, err
}
func NewCli() *Cli {
ret := &Cli{cli: api.NewCli()}
ret := &Cli{ApiCli: api.NewApiCli()}
return ret
}
+62 -38
View File
@@ -7,62 +7,57 @@ import (
)
type Cli struct {
cli *api.Cli
*api.ApiCli
}
func (c *Cli) HttpCli() *api.Cli {
return c.cli
}
//func (c *Cli) HttpCli() *api.Cli {
// return c.cli
//}
func (c *Cli) ClipRead() (string, error) {
ret := ""
err := c.cli.HttpJsonGet(fmt.Sprintf("/ipc/wingui/clip/read"), &ret)
err := api.Call("wingui.clip.read", nil, &ret)
//err := c.HttpCli().JsonGet(fmt.Sprintf("/ipc/wingui/clip/read"), &ret)
return ret, err
}
func (c *Cli) ClipWrite(site string) error {
err := c.cli.HttpJsonGet(fmt.Sprintf("/ipc/wingui/clip/write?str=%s", site), nil)
func (c *Cli) ClipWrite(in string) error {
var out interface{}
err := api.Call("wingui.clip.read", in, &out)
//err := c.HttpCli().JsonGet(fmt.Sprintf("/ipc/wingui/clip/write?str=%s", site), nil)
return err
}
func (c *Cli) Ocr_screen(l string) (map[string]interface{}, error) {
d := 0
ret := make(map[string]interface{})
err := c.cli.HttpJsonGet(fmt.Sprintf("/ipc/ocr/screen?l=%s&d=%d", l, d), &ret)
return ret, err
}
func (c *Cli) MouseClick() error {
err := c.cli.HttpJsonGet(fmt.Sprintf("/ipc/wingui/mouse/click"), nil)
err := c.HttpCli().JsonGet(fmt.Sprintf("/ipc/wingui/mouse/click"), nil)
return err
}
func (c *Cli) MouseMove(x, y int) error {
err := c.cli.HttpJsonGet(fmt.Sprintf("/ipc/wingui/mouse/move?x=%d&y=%d", x, y), nil)
err := c.HttpCli().JsonGet(fmt.Sprintf("/ipc/wingui/mouse/move?x=%d&y=%d", x, y), nil)
return err
}
func (c *Cli) MouseMoveRelative(x, y int) error {
err := c.cli.HttpJsonGet(fmt.Sprintf("/ipc/wingui/mouse/moverelative?x=%d&y=%d", x, y), nil)
err := c.HttpCli().JsonGet(fmt.Sprintf("/ipc/wingui/mouse/moverelative?x=%d&y=%d", x, y), nil)
return err
}
func (c *Cli) MouseClickRelative(x, y int) error {
err := c.cli.HttpJsonGet(fmt.Sprintf("/ipc/wingui/mouse/clickatrelative?x=%d&y=%d", x, y), nil)
err := c.HttpCli().JsonGet(fmt.Sprintf("/ipc/wingui/mouse/clickatrelative?x=%d&y=%d", x, y), nil)
return err
}
func (c *Cli) MouseClickAt(x, y int) error {
err := c.cli.HttpJsonGet(fmt.Sprintf("/ipc/wingui/mouse/clickat?x=%d&y=%d", x, y), nil)
err := c.HttpCli().JsonGet(fmt.Sprintf("/ipc/wingui/mouse/clickat?x=%d&y=%d", x, y), nil)
return err
}
func (c *Cli) ScreenClick(f string) error {
err := c.cli.HttpJsonGet(fmt.Sprintf("/ipc/wingui/screen/click?f=%s", f), nil)
err := c.HttpCli().JsonGet(fmt.Sprintf("/ipc/wingui/screen/click?f=%s", f), nil)
return err
}
func (c *Cli) ScreenClickCenter(f string) error {
err := c.cli.HttpJsonGet(fmt.Sprintf("/ipc/wingui/screen/clickcenter?f=%s", f), nil)
err := c.HttpCli().JsonGet(fmt.Sprintf("/ipc/wingui/screen/clickcenter?f=%s", f), nil)
return err
}
func (c *Cli) ScreenFind(f string) (ret map[string]interface{}, err error) {
ret = make(map[string]interface{})
err = c.cli.HttpJsonGet(fmt.Sprintf("/ipc/wingui/screen/find?f=%s", f), &ret)
err = c.HttpCli().JsonGet(fmt.Sprintf("/ipc/wingui/screen/find?f=%s", f), &ret)
return
}
@@ -161,7 +156,7 @@ func (c *Cli) KBTap(t string) (map[string]interface{}, error) {
*/
ret := make(map[string]interface{})
err := c.cli.HttpJsonGet(fmt.Sprintf("/ipc/wingui/kb/tap?str=%s", t), &ret)
err := c.HttpCli().JsonGet(fmt.Sprintf("/ipc/wingui/kb/tap?str=%s", t), &ret)
return ret, err
}
@@ -171,27 +166,56 @@ func (c *Cli) KBType(t string) (map[string]interface{}, error) {
por exemplo. Ao chegar no robo passrão pelo decoding análogo. */
ret := make(map[string]interface{})
err := c.cli.HttpJsonGet(fmt.Sprintf("/ipc/wingui/kb/type?str=%s", t), &ret)
err := c.HttpCli().JsonGet(fmt.Sprintf("/ipc/wingui/kb/type?str=%s", t), &ret)
return ret, err
}
func (c *Cli) ScreenWait(f string, m int) (ret map[string]interface{}, err error) {
ret = make(map[string]interface{})
err = c.cli.HttpJsonGet(fmt.Sprintf("/ipc/wingui/screen/wait?f=%s&m=%d", f, m), &ret)
return
func (c *Cli) ScreenWait(f string, m int) ([]byte, error) {
url := fmt.Sprintf("/ipc/wingui/screen/wait?f=%s&m=%d", f, m)
ret, err := c.HttpCli().RawGet(url)
if err != nil {
fmt.Printf(err.Error())
}
fmt.Println(ret)
return ret, err
}
func (c *Cli) ScreenWaitClick(f string, m int) (ret map[string]interface{}, err error) {
ret = make(map[string]interface{})
err = c.cli.HttpJsonGet(fmt.Sprintf("/ipc/wingui/screen/waitclick?f=%s&m=%d", f, m), &ret)
return
func (c *Cli) ScreenWaitClick(f string, m int) ([]byte, error) {
url := fmt.Sprintf("/ipc/wingui/screen/waitclick?f=%s&m=%d", f, m)
ret, err := c.HttpCli().RawGet(url)
if err != nil {
fmt.Printf(err.Error())
}
fmt.Println(ret)
return ret, err
}
func (c *Cli) ScreenWaitClickCenter(f string, m int) (ret map[string]interface{}, err error) {
ret = make(map[string]interface{})
err = c.cli.HttpJsonGet(fmt.Sprintf("/ipc/wingui/screen/waitclickcenter?f=%s&m=%d", f, m), &ret)
return
func (c *Cli) ScreenWaitClickCenter(f string, m int) ([]byte, error) {
url := fmt.Sprintf("/ipc/wingui/screen/waitclickcenter?f=%s&m=%d", f, m)
ret, err := c.HttpCli().RawGet(url)
if err != nil {
fmt.Printf(err.Error())
}
fmt.Println(ret)
return ret, err
}
func (c *Cli) ScreenRes() ([]byte, error) {
url := fmt.Sprintf("/ipc/wingui/screen/res")
ret, err := c.HttpCli().RawGet(url)
if err != nil {
fmt.Printf(err.Error())
}
return ret, err
}
func (c *Cli) ScreenSetRes(x, y, cor int) error {
err := c.HttpCli().JsonGet(fmt.Sprintf("/ipc/wingui/screen/setres?x=%d&y=%d&c=%d", x, y, cor), nil)
return err
}
func NewCli() *Cli {
ret := &Cli{cli: api.NewCli()}
ret := &Cli{ApiCli: api.NewApiCli()}
return ret
}
+1
View File
@@ -75,4 +75,5 @@ const (
ENV_REPLAY_ALIAS = "REPLAY_ALIAS"
ENV_REPLAY_VER = "REPLAY_VER"
ENV_REPLAY_QUEUEID = "REPLAY_QUEUEID"
ENV_REPLAY_PRECMDS = "REPLAY_PRECMDS"
)
+17 -2
View File
@@ -2,9 +2,24 @@ module go.digitalcircle.com.br/open/replaycli-go
go 1.17
//replace (
// go.digitalcircle.com.br/open/httpcli => ../httpcli
//)
require (
github.com/Microsoft/go-winio v0.5.0
github.com/Microsoft/go-winio v0.5.1
github.com/gorilla/websocket v1.4.2
github.com/mitchellh/go-ps v1.0.0
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6 // indirect
github.com/nats-io/nats.go v1.13.1-0.20211018182449-f2416a8b1483
go.digitalcircle.com.br/open/httpcli v0.0.0-20211031093505-ecf33aed8afb
golang.org/x/sys v0.0.0-20211031064116-611d5d643895 // indirect
)
require (
github.com/golang/protobuf v1.5.2 // indirect
github.com/nats-io/nats-server/v2 v2.6.4 // indirect
github.com/nats-io/nkeys v0.3.0 // indirect
github.com/nats-io/nuid v1.0.1 // indirect
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e // indirect
golang.org/x/mod v0.5.1 // indirect
google.golang.org/protobuf v1.27.1 // indirect
)
+59 -6
View File
@@ -1,17 +1,70 @@
github.com/Microsoft/go-winio v0.5.0 h1:Elr9Wn+sGKPlkaBvwu4mTrxtmOp3F3yV9qhaHbXGjwU=
github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
github.com/Microsoft/go-winio v0.5.1 h1:aPJp2QD7OOrhO5tQXqQoGSJc+DjDtWTGLOmNyAm6FgY=
github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/klauspost/compress v1.13.4 h1:0zhec2I8zGnjWcKyLl6i3gPqKANCCn5e9xmviEEeX6s=
github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
github.com/minio/highwayhash v1.0.1 h1:dZ6IIu8Z14VlC0VpfKofAhCy74wu/Qb5gcn52yWoz/0=
github.com/minio/highwayhash v1.0.1/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY=
github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc=
github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg=
github.com/nats-io/jwt/v2 v2.1.0 h1:1UbfD5g1xTdWmSeRV8bh/7u+utTiBsRtWhLl1PixZp4=
github.com/nats-io/jwt/v2 v2.1.0/go.mod h1:0tqz9Hlu6bCBFLWAASKhE5vUA4c24L9KPUUgvwumE/k=
github.com/nats-io/nats-server/v2 v2.6.4 h1:WjR1ylV/5Urth88K8U78wEEnWFYEJ9DNM0Q5DTlTx0g=
github.com/nats-io/nats-server/v2 v2.6.4/go.mod h1:LlMieumxNUnCloOTVFv7Wog0YnasScxARUMXVXv9/+M=
github.com/nats-io/nats.go v1.13.1-0.20211018182449-f2416a8b1483 h1:GMx3ZOcMEVM5qnUItQ4eJyQ6ycwmIEB/VC/UxvdevE0=
github.com/nats-io/nats.go v1.13.1-0.20211018182449-f2416a8b1483/go.mod h1:BPko4oXsySz4aSWeFgOHLZs3G4Jq4ZAyE6/zMCxRT6w=
github.com/nats-io/nkeys v0.3.0 h1:cgM5tL53EvYRU+2YLXIK0G2mJtK12Ft9oeooSZMA2G8=
github.com/nats-io/nkeys v0.3.0/go.mod h1:gvUNGjVcM2IPr5rCsRsC6Wb3Hr2CQAm08dsxtV6A5y4=
github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
go.digitalcircle.com.br/open/httpcli v0.0.0-20211031093505-ecf33aed8afb h1:gv0FO26InL2ctmhCqthsOFEooi0FvA1rFT6VXzgveJE=
go.digitalcircle.com.br/open/httpcli v0.0.0-20211031093505-ecf33aed8afb/go.mod h1:e/6vw7F4vgfs+ThQoLeBbYCYLTH1b5thzFwkFixi+oA=
golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e h1:gsTQYXdTw2Gq7RBsWvlQ91b+aEQ6bXFUngBGuR8sPpI=
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210921065528-437939a70204 h1:JJhkWtBuTQKyz2bd5WG9H8iUsJRU3En/KRfN8B2RnDs=
golang.org/x/sys v0.0.0-20210921065528-437939a70204/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6 h1:foEbQz/B0Oz6YIqu/69kfXPYeFQAuuMYFkjaqXzl5Wo=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211031064116-611d5d643895 h1:iaNpwpnrgL5jzWS0vCNnfa8HqzxveCFpFx3uC/X4Tps=
golang.org/x/sys v0.0.0-20211031064116-611d5d643895/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1 h1:NusfzzA6yGQ+ua51ck7E3omNUX/JuqbFSaRGqU8CcLI=
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
+12 -1
View File
@@ -56,7 +56,7 @@ func (p *PSCli) GetConn() *websocket.Conn {
p.con = con
p.con.SetCloseHandler(func(code int, text string) error {
log.Printf("Connection closed: %d: %s", code, text)
p.con = nil
p.Close()
return nil
})
break
@@ -95,6 +95,17 @@ func (p *PSCli) Read(i interface{}) error {
return json.Unmarshal(bs, i)
}
func (p *PSCli) Close() error {
if !p.closed {
p.closed = true
if p.ch != nil {
close(p.ch)
}
return p.con.Close()
}
return nil
}
func NewCli(q string) (*PSCli, error) {
ret := &PSCli{}
ret.q = q
+154
View File
@@ -0,0 +1,154 @@
package svc
import (
"encoding/json"
"errors"
"fmt"
"github.com/nats-io/nats.go"
"log"
"os"
"reflect"
"strings"
"time"
"unicode"
)
var nc *nats.Conn
var compname string
func Init(s string) error {
var err error
compname = s
var apikey string
if nc == nil {
apikey = os.Getenv("REPLAY_APIKEY")
if apikey == "" {
log.Printf("Connecting to NATS Server w/o TK.")
nc, err = nats.Connect(nats.DefaultURL, nats.Name(compname))
} else {
log.Printf("Connecting to NATS Server w TK: " + apikey)
nc, err = nats.Connect(nats.DefaultURL, nats.Name(compname), nats.Token(apikey))
}
if err != nil {
return err
}
}
return err
}
func Close() error {
err := nc.Drain()
chEnd <- struct{}{}
return err
}
var chEnd chan struct{}
func Serve() {
chEnd = make(chan struct{})
<-chEnd
}
func NormalizeName(s string) string {
sb := strings.Builder{}
for i, v := range s {
if unicode.IsUpper(v) && i != 0 {
sb.WriteString(".")
}
sb.WriteRune(unicode.ToLower(v))
}
return sb.String()
}
func Register(h interface{}) {
var err error
tp := reflect.TypeOf(h)
for i := 0; i < tp.NumMethod(); i++ {
mtd := tp.Method(i)
mtdt := mtd.Type
intp := mtdt.In(1)
isPtr := false
if intp.Kind() == reflect.Ptr {
isPtr = true
intp = intp.Elem()
}
mn := NormalizeName(compname) + "." + NormalizeName(mtd.Name)
err = nc.Publish("sub", []byte(mn))
if err != nil {
log.Printf(err.Error())
}
_, err = nc.Subscribe(mn, func(msg *nats.Msg) {
ni := reflect.New(intp).Interface()
var err error
if intp.Kind() == reflect.Ptr {
err = json.Unmarshal(msg.Data, ni)
} else {
err = json.Unmarshal(msg.Data, &ni)
}
if err != nil {
log.Printf(err.Error())
}
var rawret []reflect.Value
if isPtr {
rawret = mtd.Func.Call([]reflect.Value{reflect.ValueOf(h), reflect.ValueOf(ni)})
} else {
rawret = mtd.Func.Call([]reflect.Value{reflect.ValueOf(h), reflect.ValueOf(ni).Elem()})
}
ret := rawret[0].Interface()
err1 := rawret[1].Interface()
//if err1 != nil {
// log.Printf(err1.(error).Error())
//}
var bs []byte
rmsg := &nats.Msg{}
rmsg.Data = bs
bs, err = json.Marshal(ret)
if err1 != nil {
rmsg.Header = nats.Header{}
rmsg.Header.Set("ERR", fmt.Sprintf("%#v", err1))
}
if err != nil {
log.Printf(err.Error())
}
rmsg.Data = bs
err = msg.RespondMsg(rmsg)
if err != nil {
log.Printf(err.Error())
}
})
if err != nil {
log.Printf(err.Error())
}
if err != nil {
nc.Publish("err", []byte(err.Error()))
}
}
}
func Nc() *nats.Conn {
return nc
}
func Call(s string, in interface{}, out interface{}) error {
bs, err := json.Marshal(in)
if err != nil {
return err
}
msg, err := nc.Request(s, bs, time.Minute)
if err != nil {
return err
}
err = json.Unmarshal(msg.Data, out)
if err != nil {
return err
}
errstr := msg.Header.Get("ERR")
if errstr != "" {
return errors.New(errstr)
}
return nil
}
+101 -4
View File
@@ -1,6 +1,10 @@
package types
import (
"encoding/json"
"fmt"
"os"
"strconv"
"time"
)
@@ -66,6 +70,7 @@ type Service struct {
Pid int `json:"pid" yaml:"-"`
Hostname string `json:"hostname" yaml:"hostname"`
Gui bool `json:"gui" yaml:"gui"`
Public bool `json:"public" yaml:"public"`
}
type Runtime struct {
@@ -106,6 +111,7 @@ type ReplayDescriptor struct {
Hostname string `json:"hostname" yaml:"hostname"`
Ipcid string `json:"ipcid"`
Gui bool `json:"gui" yaml:"gui"`
Public bool `json:"public" yaml:"public"`
Link string `json:"link" yaml:"link"` //This prop allows redirect of repos
}
@@ -138,6 +144,55 @@ type Config struct {
Repo uint `json:"repo"`
}
func (c *Config) AsInt64() int64 {
i, err := strconv.ParseInt(c.V, 10, 64)
if err != nil {
return 0
}
return i
}
func (c *Config) AsInt32() int32 {
i, err := strconv.ParseInt(c.V, 10, 32)
if err != nil {
return 0
}
return int32(i)
}
func (c *Config) AsUint() uint {
i, err := strconv.ParseInt(c.V, 10, 32)
if err != nil {
return 0
}
return uint(i)
}
func (c *Config) AsInt() int {
i, err := strconv.ParseInt(c.V, 10, 16)
if err != nil {
return 0
}
return int(i)
}
func (c *Config) AsFloat64() float64 {
i, err := strconv.ParseFloat(c.V, 64)
if err != nil {
return 0
}
return i
}
func (c *Config) AsFloat32() float32 {
i, err := strconv.ParseFloat(c.V, 32)
if err != nil {
return 0
}
return float32(i)
}
func (c *Config) AsBool() bool {
return c.V == "true" || c.V == "1" || c.V == "t"
}
func (c *Config) AsJson(i interface{}) error {
return json.Unmarshal([]byte(c.V), i)
}
type Credentials struct {
Model
Name string `json:"name"`
@@ -148,7 +203,38 @@ type Credentials struct {
type Log struct {
Model
Log []byte
Alias string `json:"alias,omitempty"`
Title string `json:"title,omitempty"`
Tags string `json:"tags,omitempty"`
Dtlog time.Time `json:"dtlog"`
Dtlogend time.Time `json:"dtlogend"`
Data []byte `json:"data,omitempty"`
Err string `json:"err,omitempty"`
History string `json:"history,omitempty"`
}
func (l *Log) Write(p []byte) (n int, err error) {
os.Stdout.Write([]byte(fmt.Sprintf("- %s\n", string(p))))
l.AddHistory(string(p))
return len(p), nil
}
func (l *Log) AddHistory(s string) {
s = fmt.Sprintf("* %s: %s", time.Now().Format("02/01/06 - 15:04:05"), s)
if l.History == "" {
l.History = s
} else {
l.History = l.History + "\n" + s
}
}
type LogQuery struct {
From time.Time `json:"from"`
Until time.Time `json:"until"`
Limit int `json:"limit"`
Title string `json:"title"`
Alias string `json:"alias"`
Tags string `json:"tags"`
}
type Job struct {
@@ -215,9 +301,11 @@ type Options struct {
type Cron struct {
Model
Cron string `json:"cron"`
JobCode uint `json:"job"`
Enabled *bool `json:"enabled"`
Cron string `json:"cron"`
JobCode uint `json:"job"`
Enabled *bool `json:"enabled"`
Data string `json:"data"`
Comments string `json:"comments"`
}
//type Resource struct {
@@ -338,6 +426,15 @@ type Series struct {
Year int `json:"year"`
}
type Error struct {
Feature string `json:"feature,omitempty"`
When time.Time `json:"when"`
Err string `json:"err,omitempty"`
Stack string `json:"stack,omitempty"`
InputData string `json:"input_data,omitempty"`
Details string `json:"details,omitempty"`
}
func (s *Series) SetTime(t time.Time) {
s.When = t
s.Day = t.Day()
+30
View File
@@ -0,0 +1,30 @@
package ver
import (
"golang.org/x/mod/semver"
"log"
"os"
)
var Ver string
func EnsureVer(v string) {
build := os.Getenv("BUILD_VER")
if build == "" {
log.Printf("No BUILD_VER found - skipping verification")
return
}
if semver.Compare(build, v) < 0 {
log.Printf("Replay version is %s, lower than required. Should be minimum %s - aborting", build, v)
os.Exit(0)
}
if semver.Major(build) != semver.Major(v) {
log.Printf("Replay major version is %s, different from feature requirement: %s - aborting", build, v)
}
}
func Get() string {
if Ver == "" {
Ver = os.Getenv("BUILD_VER")
}
return Ver
}