Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev #44

Merged
merged 17 commits into from
Mar 17, 2022
Merged

Dev #44

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 94 additions & 20 deletions app.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ type AppError struct {
Errors string `json:"errors"` // Error Description.
}

type AppFormFields struct {
Properties interface{} `json:"properties"`
}

func (e *AppError) Error() string {
if len(e.Message) == 0 {
return "HTTP error: " + e.HttpStatus
Expand All @@ -57,6 +61,7 @@ func (e *AppError) Error() string {
type UpdateKeyField interface {
JSONValue() interface{}
}

type UpdateKey struct {
FieldCode string
Field UpdateKeyField
Expand Down Expand Up @@ -89,7 +94,7 @@ func (f UpdateKey) MarshalJSON() ([]byte, error) {
//
// func handler(w http.ResponseWriter, r *http.Request) {
// c := appengine.NewContext(r)
// app := &kintone.App{urlfetch.Client(c)}
// app := &kintone.App{Client: urlfetch.Client(c)}
// ...
// }
//
Expand All @@ -104,7 +109,7 @@ func (f UpdateKey) MarshalJSON() ([]byte, error) {
// func main() {
// proxyURL, _ := url.Parse("https://proxy.example.com")
// transport := &http.Transport{Proxy: http.ProxyURL(proxyURL)}
// client := &http.Client(Transport: transport)
// client := &http.Client{Transport: transport}
// app := &kintone.App{Client: client}
// ...
// }
Expand Down Expand Up @@ -181,6 +186,7 @@ func (app *App) createUrl(api string, query string) url.URL {
}
return resultUrl
}

func (app *App) setAuth(request *http.Request) {
if app.basicAuth {
request.SetBasicAuth(app.basicAuthUser, app.basicAuthPassword)
Expand All @@ -196,7 +202,7 @@ func (app *App) setAuth(request *http.Request) {
}
}

//NewRequest create a request connect to kintone api.
// NewRequest create a request connect to kintone api.
func (app *App) NewRequest(method, url string, body io.Reader) (*http.Request, error) {
bodyData := io.Reader(nil)
if body != nil {
Expand Down Expand Up @@ -321,18 +327,18 @@ func parseResponse(resp *http.Response) ([]byte, error) {
}
}

//Get other than the Errors property
// Get other than the Errors property
var ae AppError
json.Unmarshal(body, &ae)
ae.HttpStatus = resp.Status
ae.HttpStatusCode = resp.StatusCode

//Get the Errors property
// Get the Errors property
var errors interface{}
json.Unmarshal(body, &errors)
msg := errors.(map[string]interface{})
v, ok := msg["errors"]
//If the Errors property exists
// If the Errors property exists
if ok {
result, err := json.Marshal(v)
if err != nil {
Expand Down Expand Up @@ -460,7 +466,7 @@ func isAllowedLang(allowedLangs []string, lang string) bool {
func (app *App) GetProcess(lang string) (process *Process, err error) {
type request_body struct {
App uint64 `json:"app,string"`
lang string `json:"lang,string"`
Lang string `json:"lang,string"`
}
if app.User == "" || app.Password == "" {
err = errors.New("This API only supports password authentication")
Expand Down Expand Up @@ -552,7 +558,7 @@ func escapeQuotes(s string) string {
//
// If successfully uploaded, the key string of the uploaded file is returned.
func (app *App) Upload(fileName, contentType string, data io.Reader) (key string, err error) {
f, err := ioutil.TempFile("", "hoge")
f, err := ioutil.TempFile("", "go-kintone-")
if err != nil {
return
}
Expand Down Expand Up @@ -1015,10 +1021,80 @@ func (fi *FieldInfo) UnmarshalJSON(data []byte) error {
t.MaxValue, t.MinValue, t.MaxLength, t.MinLength,
t.Default, t.DefaultTime, t.Options, t.Expression,
(t.Separator == "true"),
t.Medium, t.Format, t.Fields}
t.Medium, t.Format, t.Fields,
}
return nil
}

// Decode JSON from app/form/fields.json
func decodeFieldInfo(t AppFormFields, ret map[string]*FieldInfo) {
itemsMap := t.Properties.(map[string]interface{})
for k, v := range itemsMap {
fi := FieldInfo{}
for l, w := range v.(map[string]interface{}) {
switch l {
case "label":
fi.Label = w.(string)
case "code":
fi.Code = w.(string)
case "type":
fi.Type = w.(string)
case "noLabel":
fi.NoLabel = w.(bool)
case "required":
fi.Required = w.(bool)
case "unique":
fi.Unique = w.(bool)
case "maxValue":
fi.MaxValue = w
case "minValue":
fi.MaxValue = w
case "maxLength":
fi.MaxLength = w
case "minLength":
fi.MinLength = w
case "defaultValue":
fi.Default = w
case "defaultNowValue":
fi.DefaultTime = w
case "options":
var sa []string
for _, x := range w.(map[string]interface{}) {
sa = append(sa, x.(map[string]interface{})["label"].(string))
}
fi.Options = sa
case "expression":
fi.Expression = w.(string)
case "digit":
fi.Separator = w.(bool)
case "protocol":
fi.Medium = w.(string)
case "format":
fi.Format = w.(string)
case "fields":
ret := make(map[string]*FieldInfo)
var y AppFormFields
y.Properties = w
decodeFieldInfo(y, ret)
var sb []FieldInfo
for z, _ := range ret {
sb = append(sb, *ret[z])
}
fi.Fields = sb
default: break;
}
}
switch fi.Type {
case "GROUP":
// Do not add to []FieldInfo
case "REFERENCE_TABLE":
// Do not add to []FieldInfo
default:
ret[k] = &fi
}
}
}

// Fields returns the meta data of the fields in this application.
//
// If successful, a mapping between field codes and FieldInfo is returned.
Expand All @@ -1027,7 +1103,7 @@ func (app *App) Fields() (map[string]*FieldInfo, error) {
App uint64 `json:"app,string"`
}
data, _ := json.Marshal(request_body{app.AppId})
req, err := app.newRequest("GET", "form", bytes.NewReader(data))
req, err := app.newRequest("GET", "app/form/fields", bytes.NewReader(data))
if err != nil {
return nil, err
}
Expand All @@ -1040,23 +1116,18 @@ func (app *App) Fields() (map[string]*FieldInfo, error) {
return nil, err
}

var t struct {
Properties []FieldInfo `json:"properties"`
}
var t AppFormFields
err = json.Unmarshal(body, &t)
if err != nil {
return nil, ErrInvalidResponse
}

ret := make(map[string]*FieldInfo)
for i, _ := range t.Properties {
fi := &(t.Properties[i])
ret[fi.Code] = fi
}
decodeFieldInfo(t, ret)
return ret, nil
}

//CreateCursor return the meta data of the Cursor in this application
// CreateCursor return the meta data of the Cursor in this application
func (app *App) CreateCursor(fields []string, query string, size uint64) (*Cursor, error) {
type cursor struct {
App uint64 `json:"app"`
Expand All @@ -1080,6 +1151,9 @@ func (app *App) CreateCursor(fields []string, query string, size uint64) (*Curso
return nil, err
}
result, err := decodeCursor(body)
if err != nil {
return nil, err
}
return result, nil
}

Expand Down Expand Up @@ -1112,8 +1186,8 @@ func (app *App) DeleteCursor(id string) error {
return nil
}

//Using Cursor Id to get all records
//GetRecordsByCursor return the meta data of the Record in this application
// Using Cursor Id to get all records
// GetRecordsByCursor return the meta data of the Record in this application
func (app *App) GetRecordsByCursor(id string) (*GetRecordsCursorResponse, error) {
url := app.createUrl("records/cursor", "id="+id)
request, err := app.NewRequest("GET", url.String(), nil)
Expand Down
7 changes: 4 additions & 3 deletions app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ const (
func createServerTest(mux *http.ServeMux) (*httptest.Server, error) {
ts := httptest.NewUnstartedServer(mux)
listen, err := net.Listen("tcp", KINTONE_DOMAIN)

if err != nil {
return nil, err
}
Expand Down Expand Up @@ -207,6 +206,7 @@ func newApp() *App {
AppId: KINTONE_APP_ID,
}
}

func newAppWithGuest() *App {
return &App{
Domain: KINTONE_DOMAIN,
Expand All @@ -216,6 +216,7 @@ func newAppWithGuest() *App {
GuestSpaceId: KINTONE_GUEST_SPACE_ID,
}
}

func newAppWithToken() *App {
return &App{
AppId: KINTONE_APP_ID,
Expand Down Expand Up @@ -259,6 +260,7 @@ func TestAddRecord(t *testing.T) {
t.Log(ids)
}
}

func TestGetRecord(t *testing.T) {
testData := GetTestDataGetRecord()
testDataRecords := GetTestDataGetRecords()
Expand Down Expand Up @@ -298,8 +300,8 @@ func TestGetRecord(t *testing.T) {
} else {
t.Log(len(recs))
}

}

func TestUpdateRecord(t *testing.T) {
testData := GetTestDataGetRecord()
testDataRecords := GetTestDataGetRecords()
Expand Down Expand Up @@ -359,7 +361,6 @@ func TestGetRecordsByCursor(t *testing.T) {
if err != nil {
t.Errorf("TestGetCursor is failed: %v", err)
}

}

func TestDeleteCursor(t *testing.T) {
Expand Down
7 changes: 5 additions & 2 deletions app_test_json.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ func GetTestDataDeleteRecords() *TestData {
output: `{}`,
}
}

func GetTestDataGetRecord() *TestData {
return &TestData{
input: []interface{}{1, true},
Expand Down Expand Up @@ -289,6 +290,7 @@ func GetDataTestDeleteRecordComment() *TestData {
output: `{}`,
}
}

func GetTestDataAddRecord() *TestData {
return &TestData{
output: `{
Expand Down Expand Up @@ -324,6 +326,7 @@ func GetDataTestAddRecord() *TestData {
}`,
}
}

func getDataTestCreateCursor() *TestData {
return &TestData{
output: `
Expand All @@ -332,10 +335,9 @@ func getDataTestCreateCursor() *TestData {
"totalCount": 123456
}`,
}

}
func GetDataTestGetRecordsByCursor() *TestData {

func GetDataTestGetRecordsByCursor() *TestData {
return &TestData{
input: []interface{}{"9a9716fe-1394-4677-a1c7-2199a5d28215"},
output: `
Expand Down Expand Up @@ -384,6 +386,7 @@ func GetTestDataAddRecordComment() *TestData {
output: `{"id": "4"}`,
}
}

func GetTestDataUpdateRecordByKey() *TestData {
return &TestData{
input: []interface{}{2, "key", true},
Expand Down
6 changes: 4 additions & 2 deletions cursor.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,26 @@ import (
"encoding/json"
)

//Object Cursor structure
// Object Cursor structure
type Cursor struct {
Id string `json:"id"`
TotalCount string `json:"totalCount"`
}

type GetRecordsCursorResponse struct {
Records []*Record `json:"records"`
Next bool `json:"next"`
}

//decodeCursor decodes JSON response for cursor api
// decodeCursor decodes JSON response for cursor api
func decodeCursor(b []byte) (c *Cursor, err error) {
err = json.Unmarshal(b, &c)
if err != nil {
return nil, err
}
return c, nil
}

func DecodeGetRecordsCursorResponse(b []byte) (rc *GetRecordsCursorResponse, err error) {
var t struct {
Next bool `json:"next"`
Expand Down
8 changes: 4 additions & 4 deletions doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ See https://developer.kintone.io for API specs.
)
...
app := &kintone.App{
"example.cybozu.com",
"user1",
"password",
25,
Domain: "example.cybozu.com",
User: "user1",
Password: "password",
AppId: 25,
}

To retrieve 3 records from a kintone app (id=25):
Expand Down
Loading