add rclone

master
bel 2019-12-29 14:22:49 -07:00
parent 67160f5060
commit 2d94f956a1
2 changed files with 135 additions and 0 deletions

View File

@ -156,6 +156,23 @@ func TestImplementations(t *testing.T) {
t.Log("$MINIO not set. Skipping")
}
f, err := ioutil.TempFile(os.TempDir(), "rclone.conf.*")
if err != nil {
t.Fatal(err)
}
defer os.Remove(f.Name())
f.Write([]byte(`
[local]
type = local
`))
f.Close()
rclone, err := NewRClone(f.Name(), "local:/tmp")
if err != nil {
t.Errorf("cannot make rclone: %v", err)
} else {
cases = append(cases, rclone)
}
validKey := "key"
validValue := []byte("value")

118
rclone.go Executable file
View File

@ -0,0 +1,118 @@
package storage
import (
"bytes"
"io/ioutil"
"os"
"path"
"time"
"github.com/ncw/rclone/fs"
"github.com/ncw/rclone/fs/config"
"github.com/ncw/rclone/fs/object"
_ "github.com/ncw/rclone/backend/drive"
_ "github.com/ncw/rclone/backend/local"
_ "github.com/ncw/rclone/backend/s3"
)
type RClone struct {
ns string
}
func NewRClone(rclone string, ns ...string) (*RClone, error) {
namespace := path.Join(ns...)
_, err := os.Stat(rclone)
if err == nil {
os.Setenv("RCLONE_CONFIG", rclone)
config.ConfigPath = rclone
config.LoadConfig()
}
return &RClone{
ns: namespace,
}, err
}
func (rc *RClone) Get(key string, ns ...string) ([]byte, error) {
namespace := resolveNamespace(ns)
namespace = path.Join(rc.ns, namespace)
key = path.Join(namespace, key)
f, err := fs.NewFs(path.Dir(key))
if err != nil {
return nil, err
}
obj, err := f.NewObject(path.Base(key))
if err != nil {
return nil, err
}
r, err := obj.Open()
if err != nil {
return nil, err
}
return ioutil.ReadAll(r)
}
func (rc *RClone) Set(key string, value []byte, ns ...string) error {
if len(value) == 0 {
return rc.Del(key, ns...)
}
namespace := resolveNamespace(ns)
namespace = path.Join(rc.ns, namespace)
key = path.Join(namespace, key)
f, err := fs.NewFs(path.Dir(key))
if err != nil {
return err
}
obj := object.NewStaticObjectInfo(path.Base(key), time.Now(), 0, true, nil, f)
_, err = f.Put(bytes.NewReader(value), obj)
return err
}
func (rc *RClone) Del(key string, ns ...string) error {
namespace := resolveNamespace(ns)
namespace = path.Join(rc.ns, namespace)
key = path.Join(namespace, key)
f, err := fs.NewFs(path.Dir(key))
if err != nil {
return err
}
obj, err := f.NewObject(path.Base(key))
if err == fs.ErrorObjectNotFound {
return nil
}
if err != nil {
return nil
}
return obj.Remove()
}
func (rc *RClone) Close() error {
return nil
}
func (rc *RClone) List(ns []string, limits ...string) ([]string, error) {
namespace := path.Join(resolveNamespace(ns))
namespace = path.Join(rc.ns, namespace)
limits = resolveLimits(limits)
f, err := fs.NewFs(namespace)
if err != nil {
return nil, err
}
entries, err := f.List("")
if err != nil {
return nil, err
}
names := make([]string, 0)
for _, entry := range entries {
name := entry.Remote()
if rc.inRange(name, limits[0], limits[1]) {
names = append(names, name)
}
}
return names, nil
}
func (rc *RClone) inRange(k, start, stop string) bool {
return k != "" && k >= start && k <= stop
}