Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Uwe Steinmann committed Apr 3, 2023
0 parents commit a4f784f
Show file tree
Hide file tree
Showing 19 changed files with 764 additions and 0 deletions.
22 changes: 22 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
PKGNAME=golang-seeddms-seeddms-apiclient
VERSION=0.0.2

test:
go test -v .

build:
go build seeddms.org/seeddms/apiclient

dist:
rm -rf ${PKGNAME}-${VERSION}
mkdir ${PKGNAME}-${VERSION}
cp -r *.go Makefile go.mod go.sum ${PKGNAME}-${VERSION}
mkdir -p ${PKGNAME}-${VERSION}/testdata/fixtures
cp testdata/fixtures/*.json ${PKGNAME}-${VERSION}/testdata/fixtures
tar czvf ${PKGNAME}-${VERSION}.tar.gz ${PKGNAME}-${VERSION}
rm -rf ${PKGNAME}-${VERSION}

debian: dist
mv ${PKGNAME}-${VERSION}.tar.gz ../${PKGNAME}_${VERSION}.orig.tar.gz
debuild

215 changes: 215 additions & 0 deletions apiclient.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
package apiclient

import (
"net/http"
"net/http/cookiejar"
// "net/url"
"fmt"
"time"
"io"
"io/ioutil"
// "os"
"log"
"encoding/json"
)

type Client struct {
BaseURL string
username string
password string
ApiKey string
HTTPClient *http.Client
StatusCode int
ErrorMsg string
}

type Attribute struct {
Id int
Name string
Value string
}

type Object struct {
Id int
Objtype string `json:"type"`
Name string
Comment string
Date string
}

type Folder struct {
Id int
Objtype string `json:"type"`
Name string
Comment string
Date string
Attributes []Attribute
}

type Document struct {
Id int
Objtype string `json:"type"`
Name string
Comment string
Keywords string
Date string
Mimetype string
Filetype string
Origfilename string
Islocked bool
Expires string
Version int
VersionComment string `json:"version_comment"`
VersionDate string `json:"version_date"`
Size int
Attributes []Attribute
VersionAttributes []Attribute `json:"version_attributes"`
}

type Group struct {
Id int
Objtype string `json:"type"`
Name string
Comment string
}

type Role struct {
Id int
Name string
}

type User struct {
Id int
Objtype string `json:"type"`
Name string
Comment string
Login string
Email string
Language string
Theme string
Role Role
Hidden bool
Disabled bool
Isguest bool
Isadmin bool
Groups []Group
}

type Statstotal struct {
Docstotal int
Folderstotal int
Userstotal int
}

type errorResponse struct {
Success bool
Message string
Data string
}

type successResponse struct {
success bool
message string
data interface{}
}

func Connect(baseurl string, apikey string) *Client {
jar, err := cookiejar.New(nil)
if err != nil {
log.Fatalf("Got error while creating cookie jar %s", err.Error())
}
return &Client{
BaseURL: baseurl,
ApiKey: apikey,
HTTPClient: &http.Client{
Timeout: time.Minute,
Jar: jar,
},
}
}

func (c *Client) getBody(url string) (io.Reader, error) {
req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
return nil, err
}

if c.ApiKey != "" {
req.Header.Set("Authorization", fmt.Sprintf("%s", c.ApiKey))
}

res, err := c.HTTPClient.Do(req)
if err != nil {
return nil, err
}

c.StatusCode = res.StatusCode
if res.StatusCode < http.StatusOK || res.StatusCode >= http.StatusBadRequest {
var errRes errorResponse
if err = json.NewDecoder(res.Body).Decode(&errRes); err == nil {
c.ErrorMsg = errRes.Message
return nil, fmt.Errorf(errRes.Message)
}

return nil, fmt.Errorf("unknown error, status code: %d", res.StatusCode)
}

return res.Body, nil
}

func (c *Client) sendRequest(req *http.Request, target interface{}) error {
if req.Header.Get("Content-Type") == "" {
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
}
req.Header.Set("Accept", "application/json; charset=utf-8")
if c.ApiKey != "" {
req.Header.Set("Authorization", fmt.Sprintf("%s", c.ApiKey))
}

// urlObj, _ := url.Parse(c.BaseURL)
// fmt.Print(c.HTTPClient.Jar.Cookies(urlObj))

res, err := c.HTTPClient.Do(req)
if err != nil {
return err
}

defer res.Body.Close()

c.StatusCode = res.StatusCode
if res.StatusCode < http.StatusOK || res.StatusCode >= http.StatusBadRequest {
var errRes errorResponse
if err = json.NewDecoder(res.Body).Decode(&errRes); err == nil {
c.ErrorMsg = errRes.Message
return fmt.Errorf(errRes.Message)
}

return fmt.Errorf("unknown error, status code: %d", res.StatusCode)
}

if false {
// since goland 1.16 io.ReadAll should be used
bodyBytes, err := ioutil.ReadAll(res.Body)
if err == nil {
jsonerr := json.Unmarshal([]byte(bodyBytes), target)
//fmt.Printf("%+v", target)
return jsonerr
} else {
//fmt.Print(err)
return err
}
} else {
// For some reason reading from the io stream didn't work because 'success'
// was an unknown field
//io.Copy(os.Stdout, res.Body)
decoder := json.NewDecoder(res.Body)
// Children() returns both, folders and documents and they have different
// structs. That's why the json is mapped on the struct Object which just
// contains the fields common to both folders and documents. But that
// requires to allow unknows fields.
// decoder.DisallowUnknownFields()
return decoder.Decode(target)
}
}


27 changes: 27 additions & 0 deletions children.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package apiclient

import (
"fmt"
"net/http"
)

type childrenResponse struct {
Success bool `json:"success"`
Message string `json:"message"`
Data []Object
}

func (c *Client) Children(id int) (*childrenResponse, error) {
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s/folder/%d/children", c.BaseURL, id), nil)
if err != nil {
return nil, err
}

res := childrenResponse{}
if err := c.sendRequest(req, &res); err != nil {
return nil, err
}

return &res, nil
}

32 changes: 32 additions & 0 deletions children_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package apiclient

import (
"testing"
"github.com/stretchr/testify/assert"
"fmt"
"net/http"
)

func TestChildren(t *testing.T) {
// Create the test server and shut it down when the test ends
c, teardown := setupTestServer()
defer teardown()

// Add restapi endpoint to retrieve the children of a folder
mux.HandleFunc("/folder/1/children", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
// ... return the JSON
fmt.Fprint(w, fixture("children.json"))
})

c.Login("admin", "admin")

res, err := c.Children(1)

assert.Nil(t, err, "expecting nil error")
assert.NotNil(t, res, "expecting non-nil result")
assert.NotNil(t, res.Data, "expecting array of objects")
}


18 changes: 18 additions & 0 deletions content.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package apiclient

import (
"fmt"
"io"
)

func (c *Client) Content(id int) (io.Reader, error) {
body, err := c.getBody(fmt.Sprintf("%s/document/%d/content", c.BaseURL, id))
if err != nil {
return nil, err
}

//defer body.Close()

return body, nil
}

28 changes: 28 additions & 0 deletions document.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package apiclient

import (
"fmt"
"net/http"
)

type documentResponse struct {
Success bool `json:"success"`
Message string `json:"message"`
Data Document
}

func (c *Client) Document(id int) (*documentResponse, error) {
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s/document/%d", c.BaseURL, id), nil)
if err != nil {
return nil, err
}

res := documentResponse{}
if err := c.sendRequest(req, &res); err != nil {
return nil, err
}

return &res, nil
}


32 changes: 32 additions & 0 deletions document_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package apiclient

import (
"testing"
"github.com/stretchr/testify/assert"
"fmt"
"net/http"
)

func TestDocument(t *testing.T) {
// Create the test server and shut it down when the test ends
c, teardown := setupTestServer()
defer teardown()

// Add restapi endpoint to retrieve a document
mux.HandleFunc("/document/22545", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
// ... return the JSON
fmt.Fprint(w, fixture("document.json"))
})

c.Login("admin", "admin")

res, err := c.Document(22545)

assert.Nil(t, err, "expecting nil error")
assert.NotNil(t, res, "expecting non-nil result")
assert.Equal(t, 22545, res.Data.Id, "expecting id=22545 as we asked for it")
}


Loading

0 comments on commit a4f784f

Please sign in to comment.