package rclone import ( "bytes" "errors" "io" "io/ioutil" "local/storage/resolve" "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/crypt" _ "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) { r, err := rc.GetStream(key, ns...) if err != nil { return nil, err } return ioutil.ReadAll(r) } func (rc *RClone) GetStream(key string, ns ...string) (io.Reader, error) { namespace := rc.ns if len(ns) > 0 { namespace = path.Join(rc.ns, resolve.Namespace(ns)) } 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 } return obj.Open() } func (rc *RClone) Set(key string, value []byte, ns ...string) error { if len(value) == 0 { return rc.Del(key, ns...) } return rc.SetStream(key, bytes.NewReader(value), ns...) } func (rc *RClone) SetStream(key string, r io.Reader, ns ...string) error { namespace := rc.ns if len(ns) > 0 { namespace = path.Join(rc.ns, resolve.Namespace(ns)) } 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(r, obj) return err } func (rc *RClone) Del(key string, ns ...string) error { namespace := rc.ns if len(ns) > 0 { namespace = path.Join(rc.ns, resolve.Namespace(ns)) } 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) Namespaces() ([][]string, error) { return nil, errors.New("not impl") } func (rc *RClone) List(ns []string, limits ...string) ([]string, error) { namespace := rc.ns if len(ns) > 0 { namespace = path.Join(rc.ns, resolve.Namespace(ns)) } limits = resolve.Limits(limits) f, err := fs.NewFs(namespace) if err != nil { return nil, err } entries, err := f.List("") if err != nil { return nil, nil // errs on does not exit 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 }