rc: Add operations/fsinfo: Return information about the remote

This returns a information about the remote including Name, Root,
Hashes and optional Features.
This commit is contained in:
Nick Craig-Wood 2019-06-08 09:19:07 +01:00
parent e1cf551ded
commit 454dfd3c9e
4 changed files with 164 additions and 1 deletions

View File

@ -1750,3 +1750,40 @@ func DirMove(f fs.Fs, srcRemote, dstRemote string) (err error) {
return nil
}
// FsInfo provides information about a remote
type FsInfo struct {
// Name of the remote (as passed into NewFs)
Name string
// Root of the remote (as passed into NewFs)
Root string
// String returns a description of the FS
String string
// Precision of the ModTimes in this Fs in Nanoseconds
Precision time.Duration
// Returns the supported hash types of the filesystem
Hashes []string
// Features returns the optional features of this Fs
Features map[string]bool
}
// GetFsInfo gets the information (FsInfo) about a given Fs
func GetFsInfo(f fs.Fs) *FsInfo {
info := &FsInfo{
Name: f.Name(),
Root: f.Root(),
String: f.String(),
Precision: f.Precision(),
Hashes: make([]string, 0, 4),
Features: f.Features().Enabled(),
}
for _, hashType := range f.Hashes().Array() {
info.Hashes = append(info.Hashes, hashType.String())
}
return info
}

View File

@ -1182,3 +1182,23 @@ func TestDirMove(t *testing.T) {
)
}
func TestGetFsInfo(t *testing.T) {
r := fstest.NewRun(t)
defer r.Finalise()
f := r.Fremote
info := operations.GetFsInfo(f)
assert.Equal(t, f.Name(), info.Name)
assert.Equal(t, f.Root(), info.Root)
assert.Equal(t, f.String(), info.String)
assert.Equal(t, f.Precision(), info.Precision)
hashSet := hash.NewHashSet()
for _, hashName := range info.Hashes {
var ht hash.Type
require.NoError(t, ht.Set(hashName))
hashSet.Add(ht)
}
assert.Equal(t, f.Hashes(), hashSet)
assert.Equal(t, f.Features().Enabled(), info.Features)
}

View File

@ -68,9 +68,10 @@ func init() {
Help: `This takes the following parameters
- fs - a remote name string eg "drive:"
- remote - a path within that remote eg "dir"
The result is as returned from rclone about --json
See the [about command](/commands/rclone_size/) command for more information on the above.
`,
})
}
@ -290,3 +291,81 @@ func rcPublicLink(in rc.Params) (out rc.Params, err error) {
out["url"] = url
return out, nil
}
func init() {
rc.Add(rc.Call{
Path: "operations/fsinfo",
Fn: rcFsInfo,
Title: "Return information about the remote",
Help: `This takes the following parameters
- fs - a remote name string eg "drive:"
This returns info about the remote passed in;
` + "```" + `
{
// optional features and whether they are available or not
"Features": {
"About": true,
"BucketBased": false,
"CanHaveEmptyDirectories": true,
"CaseInsensitive": false,
"ChangeNotify": false,
"CleanUp": false,
"Copy": false,
"DirCacheFlush": false,
"DirMove": true,
"DuplicateFiles": false,
"GetTier": false,
"ListR": false,
"MergeDirs": false,
"Move": true,
"OpenWriterAt": true,
"PublicLink": false,
"Purge": true,
"PutStream": true,
"PutUnchecked": false,
"ReadMimeType": false,
"ServerSideAcrossConfigs": false,
"SetTier": false,
"SetWrapper": false,
"UnWrap": false,
"WrapFs": false,
"WriteMimeType": false
},
// Names of hashes available
"Hashes": [
"MD5",
"SHA-1",
"DropboxHash",
"QuickXorHash"
],
"Name": "local", // Name as created
"Precision": 1, // Precision of timestamps in ns
"Root": "/", // Path as created
"String": "Local file system at /" // how the remote will appear in logs
}
` + "```" + `
This command does not have a command line equivalent so use this instead:
rclone rc --loopback operations/fsinfo fs=remote:
`,
})
}
// Fsinfo the remote
func rcFsInfo(in rc.Params) (out rc.Params, err error) {
f, err := rc.GetFs(in)
if err != nil {
return nil, err
}
info := GetFsInfo(f)
err = rc.Reshape(&out, info)
if err != nil {
return nil, errors.Wrap(err, "fsinfo Reshape failed")
}
return out, nil
}

View File

@ -370,3 +370,30 @@ func TestRcPublicLink(t *testing.T) {
require.Error(t, err)
assert.Contains(t, err.Error(), "doesn't support public links")
}
// operations/fsinfo: Return information about the remote
func TestRcFsInfo(t *testing.T) {
r, call := rcNewRun(t, "operations/fsinfo")
defer r.Finalise()
in := rc.Params{
"fs": r.FremoteName,
}
got, err := call.Fn(in)
require.NoError(t, err)
want := operations.GetFsInfo(r.Fremote)
assert.Equal(t, want.Name, got["Name"])
assert.Equal(t, want.Root, got["Root"])
assert.Equal(t, want.String, got["String"])
assert.Equal(t, float64(want.Precision), got["Precision"])
var hashes []interface{}
for _, hash := range want.Hashes {
hashes = append(hashes, hash)
}
assert.Equal(t, hashes, got["Hashes"])
var features = map[string]interface{}{}
for k, v := range want.Features {
features[k] = v
}
assert.Equal(t, features, got["Features"])
}