1// Utilities for accessing the Fs cache 2 3package rc 4 5import ( 6 "context" 7 "errors" 8 9 "github.com/rclone/rclone/fs" 10 "github.com/rclone/rclone/fs/cache" 11 "github.com/rclone/rclone/fs/config/configmap" 12) 13 14// GetFsNamed gets an fs.Fs named fsName either from the cache or creates it afresh 15func GetFsNamed(ctx context.Context, in Params, fsName string) (f fs.Fs, err error) { 16 fsString, err := in.GetString(fsName) 17 if err != nil { 18 if !IsErrParamInvalid(err) { 19 return nil, err 20 } 21 fsString, err = getConfigMap(in, fsName) 22 if err != nil { 23 return nil, err 24 } 25 } 26 return cache.Get(ctx, fsString) 27} 28 29// getConfigMap gets the config as a map from in and converts it to a 30// config string 31// 32// It uses the special parameters _name to name the remote and _root 33// to make the root of the remote. 34func getConfigMap(in Params, fsName string) (fsString string, err error) { 35 var m configmap.Simple 36 err = in.GetStruct(fsName, &m) 37 if err != nil { 38 return fsString, err 39 } 40 pop := func(key string) string { 41 value := m[key] 42 delete(m, key) 43 return value 44 } 45 Type := pop("type") 46 name := pop("_name") 47 root := pop("_root") 48 if name != "" { 49 fsString = name 50 } else if Type != "" { 51 fsString = ":" + Type 52 } else { 53 return fsString, errors.New(`couldn't find "type" or "_name" in JSON config definition`) 54 } 55 config := m.String() 56 if config != "" { 57 fsString += "," 58 fsString += config 59 } 60 fsString += ":" 61 fsString += root 62 return fsString, nil 63} 64 65// GetFs gets an fs.Fs named "fs" either from the cache or creates it afresh 66func GetFs(ctx context.Context, in Params) (f fs.Fs, err error) { 67 return GetFsNamed(ctx, in, "fs") 68} 69 70// GetFsAndRemoteNamed gets the fsName parameter from in, makes a 71// remote or fetches it from the cache then gets the remoteName 72// parameter from in too. 73func GetFsAndRemoteNamed(ctx context.Context, in Params, fsName, remoteName string) (f fs.Fs, remote string, err error) { 74 remote, err = in.GetString(remoteName) 75 if err != nil { 76 return 77 } 78 f, err = GetFsNamed(ctx, in, fsName) 79 return 80 81} 82 83// GetFsAndRemote gets the `fs` parameter from in, makes a remote or 84// fetches it from the cache then gets the `remote` parameter from in 85// too. 86func GetFsAndRemote(ctx context.Context, in Params) (f fs.Fs, remote string, err error) { 87 return GetFsAndRemoteNamed(ctx, in, "fs", "remote") 88} 89 90func init() { 91 Add(Call{ 92 Path: "fscache/clear", 93 Fn: rcCacheClear, 94 Title: "Clear the Fs cache.", 95 AuthRequired: true, 96 Help: ` 97This clears the fs cache. This is where remotes created from backends 98are cached for a short while to make repeated rc calls more efficient. 99 100If you change the parameters of a backend then you may want to call 101this to clear an existing remote out of the cache before re-creating 102it. 103`, 104 }) 105} 106 107// Clear the fs cache 108func rcCacheClear(ctx context.Context, in Params) (out Params, err error) { 109 cache.Clear() 110 return nil, nil 111} 112 113func init() { 114 Add(Call{ 115 Path: "fscache/entries", 116 Fn: rcCacheEntries, 117 Title: "Returns the number of entries in the fs cache.", 118 AuthRequired: true, 119 Help: ` 120This returns the number of entries in the fs cache. 121 122Returns 123- entries - number of items in the cache 124`, 125 }) 126} 127 128// Return the Entries the fs cache 129func rcCacheEntries(ctx context.Context, in Params) (out Params, err error) { 130 return Params{ 131 "entries": cache.Entries(), 132 }, nil 133} 134