StatJSON returns a single JSON stat entry for the fsrc, remote path The item returned may be nil if it is not found or excluded with DirsOnly/FilesOnly
(ctx context.Context, fsrc fs.Fs, remote string, opt *ListJSONOpt)
| 270 | // |
| 271 | // The item returned may be nil if it is not found or excluded with DirsOnly/FilesOnly |
| 272 | func StatJSON(ctx context.Context, fsrc fs.Fs, remote string, opt *ListJSONOpt) (item *ListJSONItem, err error) { |
| 273 | // FIXME this could me more efficient we had a new primitive |
| 274 | // NewDirEntry() which returned an Object or a Directory |
| 275 | lj, err := newListJSON(ctx, fsrc, remote, opt) |
| 276 | if err != nil { |
| 277 | return nil, err |
| 278 | } |
| 279 | |
| 280 | // Root is always a directory. When we have a NewDirEntry |
| 281 | // primitive we need to call it, but for now this will do. |
| 282 | if remote == "" { |
| 283 | if !lj.dirs { |
| 284 | return nil, nil |
| 285 | } |
| 286 | // Check the root directory exists |
| 287 | entries, err := fsrc.List(ctx, "") |
| 288 | accounting.Stats(ctx).Listed(int64(len(entries))) |
| 289 | if err != nil { |
| 290 | return nil, err |
| 291 | } |
| 292 | return lj.entry(ctx, fs.NewDir("", time.Now())) |
| 293 | } |
| 294 | |
| 295 | // Could be a file or a directory here |
| 296 | if lj.files && !strings.HasSuffix(remote, "/") { |
| 297 | // NewObject can return the sentinel errors ErrorObjectNotFound or ErrorIsDir |
| 298 | // ErrorObjectNotFound can mean the source is a directory or not found |
| 299 | obj, err := fsrc.NewObject(ctx, remote) |
| 300 | if err == fs.ErrorObjectNotFound { |
| 301 | if !lj.dirs { |
| 302 | return nil, nil |
| 303 | } |
| 304 | } else if err == fs.ErrorIsDir { |
| 305 | if !lj.dirs { |
| 306 | return nil, nil |
| 307 | } |
| 308 | // This could return a made up ListJSONItem here |
| 309 | // but that wouldn't have the IDs etc in |
| 310 | } else if err != nil { |
| 311 | if !lj.dirs { |
| 312 | return nil, err |
| 313 | } |
| 314 | } else { |
| 315 | return lj.entry(ctx, obj) |
| 316 | } |
| 317 | } |
| 318 | // Must be a directory here |
| 319 | // |
| 320 | // Remove trailing / as rclone listings won't have them |
| 321 | remote = strings.TrimRight(remote, "/") |
| 322 | parent := path.Dir(remote) |
| 323 | if parent == "." || parent == "/" { |
| 324 | parent = "" |
| 325 | } |
| 326 | entries, err := fsrc.List(ctx, parent) |
| 327 | accounting.Stats(ctx).Listed(int64(len(entries))) |
| 328 | if err == fs.ErrorDirNotFound { |
| 329 | return nil, nil |
searching dependent graphs…