2019-02-13 14:05:59 +01:00
|
|
|
package koofrclient
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"net/http"
|
|
|
|
"net/url"
|
|
|
|
"path"
|
|
|
|
|
2019-07-28 19:47:38 +02:00
|
|
|
httpclient "github.com/koofr/go-httpclient"
|
2019-02-13 14:05:59 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
var ErrCannotOverwrite = fmt.Errorf("Can not overwrite (filter constraint fails)")
|
|
|
|
var ErrCannotRemove = fmt.Errorf("Can not remove (filter constraint fails)")
|
|
|
|
|
|
|
|
func (c *KoofrClient) FilesInfo(mountId string, path string) (info FileInfo, err error) {
|
|
|
|
params := url.Values{}
|
|
|
|
params.Set("path", path)
|
|
|
|
|
|
|
|
request := httpclient.RequestData{
|
|
|
|
Method: "GET",
|
|
|
|
Path: "/api/v2/mounts/" + mountId + "/files/info",
|
|
|
|
Params: params,
|
|
|
|
ExpectedStatus: []int{http.StatusOK},
|
|
|
|
RespEncoding: httpclient.EncodingJSON,
|
|
|
|
RespValue: &info,
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = c.Request(&request)
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *KoofrClient) FilesList(mountId string, basePath string) (files []FileInfo, err error) {
|
|
|
|
f := &struct {
|
|
|
|
Files *[]FileInfo
|
|
|
|
}{&files}
|
|
|
|
|
|
|
|
params := url.Values{}
|
|
|
|
params.Set("path", basePath)
|
|
|
|
|
|
|
|
request := httpclient.RequestData{
|
|
|
|
Method: "GET",
|
|
|
|
Path: "/api/v2/mounts/" + mountId + "/files/list",
|
|
|
|
Params: params,
|
|
|
|
ExpectedStatus: []int{http.StatusOK},
|
|
|
|
RespEncoding: httpclient.EncodingJSON,
|
|
|
|
RespValue: &f,
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = c.Request(&request)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
for i := range files {
|
|
|
|
files[i].Path = path.Join(basePath, files[i].Name)
|
|
|
|
}
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *KoofrClient) FilesTree(mountId string, path string) (tree FileTree, err error) {
|
|
|
|
params := url.Values{}
|
|
|
|
params.Set("path", path)
|
|
|
|
|
|
|
|
request := httpclient.RequestData{
|
|
|
|
Method: "GET",
|
|
|
|
Path: "/api/v2/mounts/" + mountId + "/files/tree",
|
|
|
|
Params: params,
|
|
|
|
ExpectedStatus: []int{http.StatusOK},
|
|
|
|
RespEncoding: httpclient.EncodingJSON,
|
|
|
|
RespValue: &tree,
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = c.Request(&request)
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *KoofrClient) FilesDelete(mountId string, path string) (err error) {
|
|
|
|
return c.filesDelete(mountId, path, nil)
|
|
|
|
}
|
|
|
|
|
2019-07-15 14:57:02 +02:00
|
|
|
func (c *KoofrClient) FilesDeleteWithOptions(mountId string, path string, deleteOptions *DeleteOptions) (err error) {
|
|
|
|
return c.filesDelete(mountId, path, deleteOptions)
|
2019-02-13 14:05:59 +01:00
|
|
|
}
|
|
|
|
|
2019-07-15 14:57:02 +02:00
|
|
|
func (c *KoofrClient) filesDelete(mountId string, path string, deleteOptions *DeleteOptions) (err error) {
|
2019-02-13 14:05:59 +01:00
|
|
|
params := url.Values{}
|
|
|
|
params.Set("path", path)
|
|
|
|
|
2019-07-15 14:57:02 +02:00
|
|
|
if deleteOptions != nil {
|
|
|
|
if deleteOptions.RemoveIfSize != nil {
|
|
|
|
params.Set("removeIfSize", fmt.Sprintf("%d", *deleteOptions.RemoveIfSize))
|
2019-02-13 14:05:59 +01:00
|
|
|
}
|
2019-07-15 14:57:02 +02:00
|
|
|
if deleteOptions.RemoveIfModified != nil {
|
|
|
|
params.Set("removeIfModified", fmt.Sprintf("%d", *deleteOptions.RemoveIfModified))
|
2019-02-13 14:05:59 +01:00
|
|
|
}
|
2019-07-15 14:57:02 +02:00
|
|
|
if deleteOptions.RemoveIfHash != nil {
|
|
|
|
params.Set("removeIfHash", fmt.Sprintf("%s", *deleteOptions.RemoveIfHash))
|
2019-02-13 14:05:59 +01:00
|
|
|
}
|
2019-07-15 14:57:02 +02:00
|
|
|
if deleteOptions.RemoveIfEmpty {
|
2019-02-13 14:05:59 +01:00
|
|
|
params.Set("removeIfEmpty", "")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
request := httpclient.RequestData{
|
|
|
|
Method: "DELETE",
|
|
|
|
Path: "/api/v2/mounts/" + mountId + "/files/remove",
|
|
|
|
Params: params,
|
|
|
|
ExpectedStatus: []int{http.StatusOK},
|
|
|
|
RespConsume: true,
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = c.Request(&request)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
switch err := err.(type) {
|
|
|
|
case httpclient.InvalidStatusError:
|
|
|
|
if err.Got == http.StatusConflict {
|
|
|
|
return ErrCannotRemove
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *KoofrClient) FilesNewFolder(mountId string, path string, name string) (err error) {
|
|
|
|
reqData := FolderCreate{name}
|
|
|
|
|
|
|
|
params := url.Values{}
|
|
|
|
params.Set("path", path)
|
|
|
|
|
|
|
|
request := httpclient.RequestData{
|
|
|
|
Method: "POST",
|
|
|
|
Path: "/api/v2/mounts/" + mountId + "/files/folder",
|
|
|
|
Params: params,
|
|
|
|
ExpectedStatus: []int{http.StatusOK, http.StatusCreated},
|
|
|
|
ReqEncoding: httpclient.EncodingJSON,
|
|
|
|
ReqValue: reqData,
|
|
|
|
RespConsume: true,
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = c.Request(&request)
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2019-07-15 14:57:02 +02:00
|
|
|
func (c *KoofrClient) FilesCopy(mountId string, path string, toMountId string, toPath string, options CopyOptions) (err error) {
|
|
|
|
reqData := FileCopy{toMountId, toPath, options.SetModified}
|
2019-02-13 14:05:59 +01:00
|
|
|
|
|
|
|
params := url.Values{}
|
|
|
|
params.Set("path", path)
|
|
|
|
|
|
|
|
request := httpclient.RequestData{
|
|
|
|
Method: "PUT",
|
|
|
|
Path: "/api/v2/mounts/" + mountId + "/files/copy",
|
|
|
|
Params: params,
|
|
|
|
ExpectedStatus: []int{http.StatusOK},
|
|
|
|
ReqEncoding: httpclient.EncodingJSON,
|
|
|
|
ReqValue: reqData,
|
|
|
|
RespConsume: true,
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = c.Request(&request)
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *KoofrClient) FilesMove(mountId string, path string, toMountId string, toPath string) (err error) {
|
|
|
|
reqData := FileMove{toMountId, toPath}
|
|
|
|
|
|
|
|
params := url.Values{}
|
|
|
|
params.Set("path", path)
|
|
|
|
|
|
|
|
request := httpclient.RequestData{
|
|
|
|
Method: "PUT",
|
|
|
|
Path: "/api/v2/mounts/" + mountId + "/files/move",
|
|
|
|
Params: params,
|
|
|
|
ExpectedStatus: []int{http.StatusOK},
|
|
|
|
ReqEncoding: httpclient.EncodingJSON,
|
|
|
|
ReqValue: reqData,
|
|
|
|
RespConsume: true,
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = c.Request(&request)
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *KoofrClient) FilesGetRange(mountId string, path string, span *FileSpan) (reader io.ReadCloser, err error) {
|
|
|
|
params := url.Values{}
|
|
|
|
params.Set("path", path)
|
|
|
|
|
|
|
|
request := httpclient.RequestData{
|
|
|
|
Method: "GET",
|
|
|
|
Path: "/content/api/v2/mounts/" + mountId + "/files/get",
|
|
|
|
Params: params,
|
|
|
|
Headers: make(http.Header),
|
|
|
|
ExpectedStatus: []int{http.StatusOK, http.StatusPartialContent},
|
|
|
|
}
|
|
|
|
|
|
|
|
if span != nil {
|
|
|
|
if span.End == -1 {
|
|
|
|
request.Headers.Set("Range", fmt.Sprintf("bytes=%d-", span.Start))
|
|
|
|
} else {
|
|
|
|
request.Headers.Set("Range", fmt.Sprintf("bytes=%d-%d", span.Start, span.End))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
res, err := c.Request(&request)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
reader = res.Body
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *KoofrClient) FilesGet(mountId string, path string) (reader io.ReadCloser, err error) {
|
|
|
|
return c.FilesGetRange(mountId, path, nil)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *KoofrClient) FilesPut(mountId string, path string, name string, reader io.Reader) (newName string, err error) {
|
2019-07-15 14:57:02 +02:00
|
|
|
info, err := c.FilesPutWithOptions(mountId, path, name, reader, nil)
|
2019-02-13 14:05:59 +01:00
|
|
|
return info.Name, err
|
|
|
|
}
|
|
|
|
|
2019-07-15 14:57:02 +02:00
|
|
|
func (c *KoofrClient) FilesPutWithOptions(mountId string, path string, name string, reader io.Reader, putOptions *PutOptions) (fileInfo *FileInfo, err error) {
|
2019-02-13 14:05:59 +01:00
|
|
|
params := url.Values{}
|
|
|
|
params.Set("path", path)
|
|
|
|
params.Set("filename", name)
|
|
|
|
params.Set("info", "true")
|
|
|
|
|
2019-07-15 14:57:02 +02:00
|
|
|
if putOptions != nil {
|
|
|
|
if putOptions.OverwriteIfSize != nil {
|
|
|
|
params.Set("overwriteIfSize", fmt.Sprintf("%d", *putOptions.OverwriteIfSize))
|
2019-02-13 14:05:59 +01:00
|
|
|
}
|
2019-07-15 14:57:02 +02:00
|
|
|
if putOptions.OverwriteIfModified != nil {
|
|
|
|
params.Set("overwriteIfModified", fmt.Sprintf("%d", *putOptions.OverwriteIfModified))
|
2019-02-13 14:05:59 +01:00
|
|
|
}
|
2019-07-15 14:57:02 +02:00
|
|
|
if putOptions.OverwriteIfHash != nil {
|
|
|
|
params.Set("overwriteIfHash", fmt.Sprintf("%s", *putOptions.OverwriteIfHash))
|
2019-02-13 14:05:59 +01:00
|
|
|
}
|
2019-07-15 14:57:02 +02:00
|
|
|
if putOptions.OverwriteIfHash != nil {
|
|
|
|
params.Set("overwriteIfHash", fmt.Sprintf("%s", *putOptions.OverwriteIfHash))
|
|
|
|
}
|
|
|
|
if putOptions.OverwriteIgnoreNonExisting {
|
2019-02-13 14:05:59 +01:00
|
|
|
params.Set("overwriteIgnoreNonexisting", "")
|
|
|
|
}
|
2019-07-15 14:57:02 +02:00
|
|
|
if putOptions.NoRename {
|
2019-02-13 14:05:59 +01:00
|
|
|
params.Set("autorename", "false")
|
|
|
|
}
|
2019-07-15 14:57:02 +02:00
|
|
|
if putOptions.ForceOverwrite {
|
2019-02-13 14:05:59 +01:00
|
|
|
params.Set("overwrite", "true")
|
|
|
|
}
|
2019-07-15 14:57:02 +02:00
|
|
|
if putOptions.SetModified != nil {
|
|
|
|
params.Set("modified", fmt.Sprintf("%d", *putOptions.SetModified))
|
|
|
|
}
|
2019-02-13 14:05:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
request := httpclient.RequestData{
|
|
|
|
Method: "POST",
|
|
|
|
Path: "/content/api/v2/mounts/" + mountId + "/files/put",
|
|
|
|
Params: params,
|
|
|
|
ExpectedStatus: []int{http.StatusOK},
|
|
|
|
RespEncoding: httpclient.EncodingJSON,
|
|
|
|
RespValue: &fileInfo,
|
|
|
|
}
|
|
|
|
|
|
|
|
err = request.UploadFile("file", "dummy", reader)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = c.Request(&request)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
switch err := err.(type) {
|
|
|
|
case httpclient.InvalidStatusError:
|
|
|
|
if err.Got == http.StatusConflict {
|
|
|
|
return nil, ErrCannotOverwrite
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|