Skip to content

Commit

Permalink
Implementation of basic mechanics
Browse files Browse the repository at this point in the history
  • Loading branch information
markus621 committed Jan 22, 2021
1 parent 342ae18 commit c13614b
Show file tree
Hide file tree
Showing 13 changed files with 1,270 additions and 432 deletions.
143 changes: 132 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,14 @@ Unofficial golang client for smartcat.com
[![Go Report Card](https://goreportcard.com/badge/github.com/markus621/go-smartcat-client)](https://goreportcard.com/report/github.com/markus621/go-smartcat-client)
[![Build Status](https://travis-ci.com/markus621/go-smartcat-client.svg?branch=master)](https://travis-ci.com/markus621/go-smartcat-client)

## Official documentation

[Swagger 2.0](https://smartcat.com/api/swagger/docs/v1) + [Swagger UI](https://smartcat.com/api/methods/)

# Example

### _Create project and upload documents_

```go
package main

Expand All @@ -18,6 +24,7 @@ import (
cli "github.com/markus621/go-smartcat-client"
)

//nolint: errcheck
func main() {

conf := cli.Config{
Expand All @@ -29,16 +36,130 @@ func main() {
client := cli.NewClient(conf)
client.Debug(true, os.Stdout)

_, _ = client.GetAccount()
_, _ = client.GetAccountMTEngines()
_, _ = client.SetCallback(cli.Callback{
URL: "https://demo.example/callback",
AdditionalHeaders: []cli.AdditionalHeader{
{Name: "x-header", Value: "demo"},
},
})
_, _ = client.GetCallback()
_ = client.DelCallback()
_, _ = client.GetCallbackLastErrors(10)
project, err := client.CreateProject(cli.NewProject{
Name: "TS-10",
Description: "Перевод с русского на английский",
SourceLanguage: "en-US",
TargetLanguages: []string{"ru", "id"},
AssignToVendor: false,
UseMT: false,
Pretranslate: false,
UseTranslationMemory: false,
AutoPropagateRepetitions: false,
WorkflowStages: []string{"translation"},
IsForTesting: false,
})
if err != nil {
panic(err)
}

form := cli.NewForm()
form.AddFile("base1.json", []byte(`{"main":"hello world"}`))
form.AddFile("base2.json", []byte(`{"main2":"hello my world"}`))

docs, err := client.CreateDocument(project.ID, form)
if err != nil {
panic(err)
}

fmt.Println("Create new docs")
for _, doc := range docs {
fmt.Println(doc.Status, doc.Name)
for _, ws := range doc.WorkflowStages {
fmt.Println(ws.Status, ws.Progress)
}
}

fmt.Println("Get status all docs")
project, err = client.GetProject(project.ID)
if err != nil {
panic(err)
}

for _, doc := range project.Documents {
fmt.Println(doc.Status, doc.Name)
for _, ws := range doc.WorkflowStages {
fmt.Println(ws.Status, ws.Progress)
}
}

}

```

### _Get all documents and export_
```go
import (
"archive/zip"
"bytes"
"fmt"
"io/ioutil"
"os"
"time"

cli "github.com/markus621/go-smartcat-client"
)

//nolint: errcheck
func main() {

conf := cli.Config{
AccountID: os.Getenv(`SMARTCAT_ACCOUNT_ID`),
AuthKey: os.Getenv(`SMARTCAT_AUTH_KEY`),
URL: cli.HostURL,
}

client := cli.NewClient(conf)
client.Debug(true, os.Stdout)

list, err := client.ListProject()
if err != nil {
panic(err)
}

ids := make([]string, 0)
for _, project := range list {
fmt.Println(project.ID, project.Name, project.Status)
for _, doc := range project.Documents {
fmt.Println(doc.ID, doc.Name, doc.Status, doc.SourceLanguage, doc.TargetLanguage, doc.WorkflowStages[0].Progress)

if doc.WorkflowStages[0].Progress == 100 {
ids = append(ids, doc.ID)
}
}
}

task, err := client.ExportDocument(ids)
if err != nil {
panic(err)
}

<-time.After(3 * time.Second)

data, err := client.ExportDocumentByTaskID(task.ID)
if err != nil {
panic(err)
}

// as text file if one document
if len(ids) == 1 {
fmt.Println(string(data))
os.Exit(0)
}

// as zip file if many documents
z, err := zip.NewReader(bytes.NewReader(data), int64(len(data)))
if err != nil {
panic(err)
}
for _, f := range z.File {
reader, err := f.Open()
if err != nil {
panic(err)
}
b, err := ioutil.ReadAll(reader)
fmt.Println(f.Name, string(b), err)
}
}

```
8 changes: 4 additions & 4 deletions account.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@ type (
)

//GetAccount Receiving the account details
func (v *Client) GetAccount() (out Account, err error) {
_, err = v.call(http.MethodGet, uriAccount, nil, &out)
func (c *Client) GetAccount() (out Account, err error) {
_, err = c.json(http.MethodGet, uriAccount, nil, &out)
return
}

//GetAccountMTEngines Receiving MT engines available for the account
func (v *Client) GetAccountMTEngines() (out AccountMTEngines, err error) {
_, err = v.call(http.MethodGet, uriAccountMTEngines, nil, &out)
func (c *Client) GetAccountMTEngines() (out AccountMTEngines, err error) {
_, err = c.json(http.MethodGet, uriAccountMTEngines, nil, &out)
return
}
16 changes: 8 additions & 8 deletions callback.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,25 +38,25 @@ type (
)

//DelCallback Resetting the configuration of notifications reception
func (v *Client) DelCallback() (err error) {
_, err = v.call(http.MethodDelete, uriCallback, nil, nil)
func (c *Client) DelCallback() (err error) {
_, err = c.json(http.MethodDelete, uriCallback, nil, nil)
return
}

//GetCallback Reading configurations of notifications reception of the account
func (v *Client) GetCallback() (out Callback, err error) {
_, err = v.call(http.MethodGet, uriCallback, nil, &out)
func (c *Client) GetCallback() (out Callback, err error) {
_, err = c.json(http.MethodGet, uriCallback, nil, &out)
return
}

//SetCallback Setting configurations of notifications reception of the account
func (v *Client) SetCallback(in Callback) (out Callback, err error) {
_, err = v.call(http.MethodPost, uriCallback, &in, &out)
func (c *Client) SetCallback(in Callback) (out Callback, err error) {
_, err = c.json(http.MethodPost, uriCallback, &in, &out)
return
}

//GetCallbackLastErrors Reading the recent sending errors
func (v *Client) GetCallbackLastErrors(limit int) (out LastErrors, err error) {
_, err = v.call(http.MethodGet, fmt.Sprintf("%s?limit=%d", uriCallbackLastErrors, limit), nil, &out)
func (c *Client) GetCallbackLastErrors(limit int) (out LastErrors, err error) {
_, err = c.json(http.MethodGet, fmt.Sprintf("%s?limit=%d", uriCallbackLastErrors, limit), nil, &out)
return
}
99 changes: 62 additions & 37 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
)

const (
userAgent = "go-smartcat-client"
userAgent = `go-smartcat-client`
)

type (
Expand Down Expand Up @@ -54,83 +54,108 @@ func NewCustomClient(c Config, cli *http.Client) *Client {
}

//Debug enable logging of responses
func (v *Client) Debug(is bool, w io.Writer) {
v.debug, v.writer = is, w
func (c *Client) Debug(is bool, w io.Writer) {
c.debug, c.writer = is, w
}

func (v *Client) call(method, path string, req json.Marshaler, resp json.Unmarshaler) (int, error) {
var (
body []byte
err error
)
func (c *Client) raw(method, path string, req []byte) (code int, body []byte, err error) {
code, body, err = c.call(method, path, body, `application/json`)
return
}

func (c *Client) json(method, path string, req json.Marshaler, resp json.Unmarshaler) (code int, err error) {
var body []byte
if req != nil {
body, err = req.MarshalJSON()
if err != nil {
return 0, errors.Wrap(err, "marshal request")
}
}
code, body, err = c.call(method, path, body, `application/json`)
if err != nil {
return
}
err = json.Unmarshal(body, &resp)
return
}

func (c *Client) form(method, path string, fields *Form, resp json.Unmarshaler) (code int, err error) {
if fields == nil {
err = ErrEmptyRequest
return
}
var body []byte
code, body, err = c.call(method, path, fields.Bytes(), fields.GetContentType())
if err != nil {
return
}
err = json.Unmarshal(body, &resp)
return
}

creq, err := http.NewRequest(method, v.conf.URL+path, bytes.NewReader(body))
func (c *Client) call(method, path string, body []byte, contentType string) (int, []byte, error) {
creq, err := http.NewRequest(method, c.conf.URL+path, bytes.NewReader(body))
c.requestDebug(method, path, body, err)
if err != nil {
return 0, errors.Wrap(err, "create request")
return 0, nil, errors.Wrap(err, "create request")
}

creq.Header.Set("User-Agent", userAgent)
creq.Header.Set("Connection", "keep-alive")
creq.Header.Set("Accept", "*/*")
creq.Header.Set("Content-Type", "application/json")
creq.Header.Set("Authorization", v.conf.AuthToken())
creq.Header.Set("Content-Type", contentType)
creq.Header.Set("Authorization", c.conf.AuthToken())

cresp, err := v.cli.Do(creq)
cresp, err := c.cli.Do(creq)
if err != nil {
return 0, errors.Wrap(err, "make request")
return 0, nil, errors.Wrap(err, "make request")
}

code := cresp.StatusCode
switch code {
case 200:
body, err = v.readBody(cresp.Body, resp)
body, err = c.read(cresp.Body)
case 204:
case 404:
case 404, 415:
body, err = nil, errors.New(cresp.Status)
case 400, 401, 403, 202:
msg := ErrorResponse{}
body, err = v.readBody(cresp.Body, &msg)
if err != nil {
err = ErrorResponse{Message: string(body)}
}
default:
var raw json.RawMessage
body, err = v.readBody(cresp.Body, &raw)
msg := ErrorResponse{}
body, err = c.read(cresp.Body)
if err == nil {
err = ErrUnknown
if err = json.Unmarshal(body, &msg); err != nil {
err = ErrorResponse{Message: string(body)}
} else {
err = msg
}
}
}

v.writeDebug(code, method, path, body, err)
c.responseDebug(code, err, body)

switch err {
case nil:
return code, nil
return code, body, nil
case io.EOF:
return code, errors.New(cresp.Status)
return code, body, errors.New(cresp.Status)
default:
return code, errors.Wrap(err, "unmarshal response")
return code, body, err
}
}

func (v *Client) readBody(rc io.ReadCloser, resp json.Unmarshaler) (b []byte, err error) {
func (c *Client) read(rc io.ReadCloser) (b []byte, err error) {
defer rc.Close()
b, err = ioutil.ReadAll(rc)
if err != nil || resp == nil {
return
}
err = resp.UnmarshalJSON(b)
return
}

func (v *Client) writeDebug(code int, method, path string, body []byte, err error) {
if v.debug {
fmt.Fprintf(v.writer, "[%d] %s:%s err: %+v raw:%s \n", code, method, path, err, body)
func (c *Client) requestDebug(method, path string, body []byte, err error) {
if c.debug {
fmt.Fprintf(c.writer, "REQ: %s:%s err: %v raw:%s \n", method, path, err, body)
}
}

func (c *Client) responseDebug(code int, err error, body []byte) {
if c.debug {
fmt.Fprintf(c.writer, "RES: [%d] err: %v raw:%s \n", code, err, body)
}
}

0 comments on commit c13614b

Please sign in to comment.