mirror of
				https://github.com/rclone/rclone.git
				synced 2025-10-30 23:17:59 +02:00 
			
		
		
		
	Create fs.Directory interface and use it everywhere
This commit is contained in:
		| @@ -426,12 +426,8 @@ func (f *Fs) List(dir string) (entries fs.DirEntries, err error) { | |||||||
| 			case folderKind: | 			case folderKind: | ||||||
| 				// cache the directory ID for later lookups | 				// cache the directory ID for later lookups | ||||||
| 				f.dirCache.Put(remote, *node.Id) | 				f.dirCache.Put(remote, *node.Id) | ||||||
| 				d := &fs.Dir{ | 				when, _ := time.Parse(timeFormat, *node.ModifiedDate) // FIXME | ||||||
| 					Name:  remote, | 				d := fs.NewDir(remote, when) | ||||||
| 					Bytes: -1, |  | ||||||
| 					Count: -1, |  | ||||||
| 				} |  | ||||||
| 				d.When, _ = time.Parse(timeFormat, *node.ModifiedDate) // FIXME |  | ||||||
| 				entries = append(entries, d) | 				entries = append(entries, d) | ||||||
| 			case fileKind: | 			case fileKind: | ||||||
| 				o, err := f.newObjectWithInfo(remote, node) | 				o, err := f.newObjectWithInfo(remote, node) | ||||||
|   | |||||||
							
								
								
									
										12
									
								
								b2/b2.go
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								b2/b2.go
									
									
									
									
									
								
							| @@ -521,11 +521,7 @@ func (f *Fs) list(dir string, recurse bool, prefix string, limit int, hidden boo | |||||||
| // Convert a list item into a DirEntry | // Convert a list item into a DirEntry | ||||||
| func (f *Fs) itemToDirEntry(remote string, object *api.File, isDirectory bool, last *string) (fs.DirEntry, error) { | func (f *Fs) itemToDirEntry(remote string, object *api.File, isDirectory bool, last *string) (fs.DirEntry, error) { | ||||||
| 	if isDirectory { | 	if isDirectory { | ||||||
| 		d := &fs.Dir{ | 		d := fs.NewDir(remote, time.Time{}) | ||||||
| 			Name:  remote, |  | ||||||
| 			Bytes: -1, |  | ||||||
| 			Count: -1, |  | ||||||
| 		} |  | ||||||
| 		return d, nil | 		return d, nil | ||||||
| 	} | 	} | ||||||
| 	if remote == *last { | 	if remote == *last { | ||||||
| @@ -569,11 +565,7 @@ func (f *Fs) listBuckets(dir string) (entries fs.DirEntries, err error) { | |||||||
| 		return nil, fs.ErrorListBucketRequired | 		return nil, fs.ErrorListBucketRequired | ||||||
| 	} | 	} | ||||||
| 	err = f.listBucketsToFn(func(bucket *api.Bucket) error { | 	err = f.listBucketsToFn(func(bucket *api.Bucket) error { | ||||||
| 		d := &fs.Dir{ | 		d := fs.NewDir(bucket.Name, time.Time{}) | ||||||
| 			Name:  bucket.Name, |  | ||||||
| 			Bytes: -1, |  | ||||||
| 			Count: -1, |  | ||||||
| 		} |  | ||||||
| 		entries = append(entries, d) | 		entries = append(entries, d) | ||||||
| 		return nil | 		return nil | ||||||
| 	}) | 	}) | ||||||
|   | |||||||
| @@ -32,7 +32,7 @@ var commandDefintion = &cobra.Command{ | |||||||
| 					return nil | 					return nil | ||||||
| 				} | 				} | ||||||
| 				for _, entry := range entries { | 				for _, entry := range entries { | ||||||
| 					_, isDir := entry.(*fs.Dir) | 					_, isDir := entry.(fs.Directory) | ||||||
| 					if isDir { | 					if isDir { | ||||||
| 						fmt.Println(entry.Remote() + "/") | 						fmt.Println(entry.Remote() + "/") | ||||||
| 					} else { | 					} else { | ||||||
|   | |||||||
| @@ -99,7 +99,7 @@ can be processed line by line as each item is written one to a line. | |||||||
| 						item.ModTime = Timestamp(entry.ModTime()) | 						item.ModTime = Timestamp(entry.ModTime()) | ||||||
| 					} | 					} | ||||||
| 					switch x := entry.(type) { | 					switch x := entry.(type) { | ||||||
| 					case *fs.Dir: | 					case fs.Directory: | ||||||
| 						item.IsDir = true | 						item.IsDir = true | ||||||
| 					case fs.Object: | 					case fs.Object: | ||||||
| 						item.IsDir = false | 						item.IsDir = false | ||||||
|   | |||||||
| @@ -118,7 +118,7 @@ func (d *Dir) ReadDirAll(ctx context.Context) (dirents []fuse.Dirent, err error) | |||||||
| 				Type: fuse.DT_File, | 				Type: fuse.DT_File, | ||||||
| 				Name: path.Base(x.Remote()), | 				Name: path.Base(x.Remote()), | ||||||
| 			} | 			} | ||||||
| 		case *fs.Dir: | 		case fs.Directory: | ||||||
| 			dirent = fuse.Dirent{ | 			dirent = fuse.Dirent{ | ||||||
| 				// Inode FIXME ??? | 				// Inode FIXME ??? | ||||||
| 				Type: fuse.DT_Dir, | 				Type: fuse.DT_Dir, | ||||||
|   | |||||||
| @@ -32,12 +32,12 @@ type Dir struct { | |||||||
| 	items   map[string]*DirEntry | 	items   map[string]*DirEntry | ||||||
| } | } | ||||||
|  |  | ||||||
| func newDir(fsys *FS, f fs.Fs, fsDir *fs.Dir) *Dir { | func newDir(fsys *FS, f fs.Fs, fsDir fs.Directory) *Dir { | ||||||
| 	return &Dir{ | 	return &Dir{ | ||||||
| 		fsys:    fsys, | 		fsys:    fsys, | ||||||
| 		f:       f, | 		f:       f, | ||||||
| 		path:    fsDir.Name, | 		path:    fsDir.Remote(), | ||||||
| 		modTime: fsDir.When, | 		modTime: fsDir.ModTime(), | ||||||
| 		inode:   NewInode(), | 		inode:   NewInode(), | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @@ -113,10 +113,10 @@ func (d *Dir) walk(absPath string, fun func(*Dir)) { | |||||||
| // | // | ||||||
| // Reset the directory to new state, discarding all the objects and | // Reset the directory to new state, discarding all the objects and | ||||||
| // reading everything again | // reading everything again | ||||||
| func (d *Dir) rename(newParent *Dir, fsDir *fs.Dir) { | func (d *Dir) rename(newParent *Dir, fsDir fs.Directory) { | ||||||
| 	d.ForgetAll() | 	d.ForgetAll() | ||||||
| 	d.path = fsDir.Name | 	d.path = fsDir.Remote() | ||||||
| 	d.modTime = fsDir.When | 	d.modTime = fsDir.ModTime() | ||||||
| 	d.read = time.Time{} | 	d.read = time.Time{} | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -180,12 +180,12 @@ func (d *Dir) readDir() error { | |||||||
| 				Obj:  obj, | 				Obj:  obj, | ||||||
| 				Node: nil, | 				Node: nil, | ||||||
| 			} | 			} | ||||||
| 		case *fs.Dir: | 		case fs.Directory: | ||||||
| 			dir := item | 			dir := item | ||||||
| 			name := path.Base(dir.Remote()) | 			name := path.Base(dir.Remote()) | ||||||
| 			// Use old dir value if it exists | 			// Use old dir value if it exists | ||||||
| 			if oldItem, ok := oldItems[name]; ok { | 			if oldItem, ok := oldItems[name]; ok { | ||||||
| 				if _, ok := oldItem.Obj.(*fs.Dir); ok { | 				if _, ok := oldItem.Obj.(fs.Directory); ok { | ||||||
| 					d.items[name] = oldItem | 					d.items[name] = oldItem | ||||||
| 					continue | 					continue | ||||||
| 				} | 				} | ||||||
| @@ -262,7 +262,7 @@ func (d *Dir) lookupNode(leaf string) (item *DirEntry, err error) { | |||||||
| 	switch x := item.Obj.(type) { | 	switch x := item.Obj.(type) { | ||||||
| 	case fs.Object: | 	case fs.Object: | ||||||
| 		node, err = newFile(d, x, leaf), nil | 		node, err = newFile(d, x, leaf), nil | ||||||
| 	case *fs.Dir: | 	case fs.Directory: | ||||||
| 		node, err = newDir(d.fsys, d.f, x), nil | 		node, err = newDir(d.fsys, d.f, x), nil | ||||||
| 	default: | 	default: | ||||||
| 		err = errors.Errorf("unknown type %T", item) | 		err = errors.Errorf("unknown type %T", item) | ||||||
| @@ -342,10 +342,7 @@ func (d *Dir) Mkdir(name string) (*Dir, error) { | |||||||
| 		fs.Errorf(path, "Dir.Mkdir failed to create directory: %v", err) | 		fs.Errorf(path, "Dir.Mkdir failed to create directory: %v", err) | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| 	fsDir := &fs.Dir{ | 	fsDir := fs.NewDir(path, time.Now()) | ||||||
| 		Name: path, |  | ||||||
| 		When: time.Now(), |  | ||||||
| 	} |  | ||||||
| 	dir := newDir(d.fsys, d.f, fsDir) | 	dir := newDir(d.fsys, d.f, fsDir) | ||||||
| 	d.addObject(fsDir, dir) | 	d.addObject(fsDir, dir) | ||||||
| 	// fs.Debugf(path, "Dir.Mkdir OK") | 	// fs.Debugf(path, "Dir.Mkdir OK") | ||||||
| @@ -373,7 +370,7 @@ func (d *Dir) Remove(name string) error { | |||||||
| 			fs.Errorf(path, "Dir.Remove file error: %v", err) | 			fs.Errorf(path, "Dir.Remove file error: %v", err) | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| 	case *fs.Dir: | 	case fs.Directory: | ||||||
| 		// Check directory is empty first | 		// Check directory is empty first | ||||||
| 		dir := item.Node.(*Dir) | 		dir := item.Node.(*Dir) | ||||||
| 		empty, err := dir.isEmpty() | 		empty, err := dir.isEmpty() | ||||||
| @@ -440,23 +437,21 @@ func (d *Dir) Rename(oldName, newName string, destDir *Dir) error { | |||||||
| 				oldFile.rename(destDir, newObject) | 				oldFile.rename(destDir, newObject) | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	case *fs.Dir: | 	case fs.Directory: | ||||||
| 		doDirMove := d.f.Features().DirMove | 		doDirMove := d.f.Features().DirMove | ||||||
| 		if doDirMove == nil { | 		if doDirMove == nil { | ||||||
| 			err := errors.Errorf("Fs %q can't rename directories (no DirMove)", d.f) | 			err := errors.Errorf("Fs %q can't rename directories (no DirMove)", d.f) | ||||||
| 			fs.Errorf(oldPath, "Dir.Rename error: %v", err) | 			fs.Errorf(oldPath, "Dir.Rename error: %v", err) | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| 		srcRemote := x.Name | 		srcRemote := x.Remote() | ||||||
| 		dstRemote := newPath | 		dstRemote := newPath | ||||||
| 		err = doDirMove(d.f, srcRemote, dstRemote) | 		err = doDirMove(d.f, srcRemote, dstRemote) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			fs.Errorf(oldPath, "Dir.Rename error: %v", err) | 			fs.Errorf(oldPath, "Dir.Rename error: %v", err) | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| 		newDir := new(fs.Dir) | 		newDir := fs.NewDirCopy(x).SetRemote(newPath) | ||||||
| 		*newDir = *x |  | ||||||
| 		newDir.Name = newPath |  | ||||||
| 		newObj = newDir | 		newObj = newDir | ||||||
| 		// Update the node with the new details | 		// Update the node with the new details | ||||||
| 		if oldNode != nil { | 		if oldNode != nil { | ||||||
|   | |||||||
| @@ -45,10 +45,7 @@ type FS struct { | |||||||
|  |  | ||||||
| // NewFS creates a new filing system and root directory | // NewFS creates a new filing system and root directory | ||||||
| func NewFS(f fs.Fs) *FS { | func NewFS(f fs.Fs) *FS { | ||||||
| 	fsDir := &fs.Dir{ | 	fsDir := fs.NewDir("", time.Now()) | ||||||
| 		Name: "", |  | ||||||
| 		When: time.Now(), |  | ||||||
| 	} |  | ||||||
| 	fsys := &FS{ | 	fsys := &FS{ | ||||||
| 		f: f, | 		f: f, | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -80,7 +80,7 @@ func (d *Dir) Entries() fs.DirEntries { | |||||||
| // Call with d.mu held | // Call with d.mu held | ||||||
| func (d *Dir) getDir(i int) (subDir *Dir, isDir bool) { | func (d *Dir) getDir(i int) (subDir *Dir, isDir bool) { | ||||||
| 	obj := d.entries[i] | 	obj := d.entries[i] | ||||||
| 	dir, ok := obj.(*fs.Dir) | 	dir, ok := obj.(fs.Directory) | ||||||
| 	if !ok { | 	if !ok { | ||||||
| 		return nil, false | 		return nil, false | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -157,8 +157,8 @@ func (f *Fs) add(entries *fs.DirEntries, obj fs.Object) { | |||||||
| } | } | ||||||
|  |  | ||||||
| // Encrypt an directory file name to entries. | // Encrypt an directory file name to entries. | ||||||
| func (f *Fs) addDir(entries *fs.DirEntries, dir *fs.Dir) { | func (f *Fs) addDir(entries *fs.DirEntries, dir fs.Directory) { | ||||||
| 	remote := dir.Name | 	remote := dir.Remote() | ||||||
| 	decryptedRemote, err := f.cipher.DecryptDirName(remote) | 	decryptedRemote, err := f.cipher.DecryptDirName(remote) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		fs.Debugf(remote, "Skipping undecryptable dir name: %v", err) | 		fs.Debugf(remote, "Skipping undecryptable dir name: %v", err) | ||||||
| @@ -177,7 +177,7 @@ func (f *Fs) encryptEntries(entries fs.DirEntries) (newEntries fs.DirEntries, er | |||||||
| 		switch x := entry.(type) { | 		switch x := entry.(type) { | ||||||
| 		case fs.Object: | 		case fs.Object: | ||||||
| 			f.add(&newEntries, x) | 			f.add(&newEntries, x) | ||||||
| 		case *fs.Dir: | 		case fs.Directory: | ||||||
| 			f.addDir(&newEntries, x) | 			f.addDir(&newEntries, x) | ||||||
| 		default: | 		default: | ||||||
| 			return nil, errors.Errorf("Unknown object type %T", entry) | 			return nil, errors.Errorf("Unknown object type %T", entry) | ||||||
| @@ -545,16 +545,16 @@ func (o *Object) Update(in io.Reader, src fs.ObjectInfo, options ...fs.OpenOptio | |||||||
| } | } | ||||||
|  |  | ||||||
| // newDir returns a dir with the Name decrypted | // newDir returns a dir with the Name decrypted | ||||||
| func (f *Fs) newDir(dir *fs.Dir) *fs.Dir { | func (f *Fs) newDir(dir fs.Directory) fs.Directory { | ||||||
| 	new := *dir | 	new := fs.NewDirCopy(dir) | ||||||
| 	remote := dir.Name | 	remote := dir.Remote() | ||||||
| 	decryptedRemote, err := f.cipher.DecryptDirName(remote) | 	decryptedRemote, err := f.cipher.DecryptDirName(remote) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		fs.Debugf(remote, "Undecryptable dir name: %v", err) | 		fs.Debugf(remote, "Undecryptable dir name: %v", err) | ||||||
| 	} else { | 	} else { | ||||||
| 		new.Name = decryptedRemote | 		new.SetRemote(decryptedRemote) | ||||||
| 	} | 	} | ||||||
| 	return &new | 	return new | ||||||
| } | } | ||||||
|  |  | ||||||
| // ObjectInfo describes a wrapped fs.ObjectInfo for being the source | // ObjectInfo describes a wrapped fs.ObjectInfo for being the source | ||||||
|   | |||||||
| @@ -586,12 +586,8 @@ func (f *Fs) List(dir string) (entries fs.DirEntries, err error) { | |||||||
| 		case item.MimeType == driveFolderType: | 		case item.MimeType == driveFolderType: | ||||||
| 			// cache the directory ID for later lookups | 			// cache the directory ID for later lookups | ||||||
| 			f.dirCache.Put(remote, item.Id) | 			f.dirCache.Put(remote, item.Id) | ||||||
| 			d := &fs.Dir{ | 			when, _ := time.Parse(timeFormatIn, item.ModifiedDate) | ||||||
| 				Name:  remote, | 			d := fs.NewDir(remote, when) | ||||||
| 				Bytes: -1, |  | ||||||
| 				Count: -1, |  | ||||||
| 			} |  | ||||||
| 			d.When, _ = time.Parse(timeFormatIn, item.ModifiedDate) |  | ||||||
| 			entries = append(entries, d) | 			entries = append(entries, d) | ||||||
| 		case item.Md5Checksum != "" || item.FileSize > 0: | 		case item.Md5Checksum != "" || item.FileSize > 0: | ||||||
| 			// If item has MD5 sum or a length it is a file stored on drive | 			// If item has MD5 sum or a length it is a file stored on drive | ||||||
|   | |||||||
| @@ -392,13 +392,7 @@ func (f *Fs) List(dir string) (entries fs.DirEntries, err error) { | |||||||
| 				} | 				} | ||||||
| 				name = strings.Trim(name, "/") | 				name = strings.Trim(name, "/") | ||||||
| 				if name != "" && name != dir { | 				if name != "" && name != dir { | ||||||
| 					d := &fs.Dir{ | 					d := fs.NewDir(name, time.Now()) | ||||||
| 						Name: name, |  | ||||||
| 						When: time.Now(), |  | ||||||
| 						//When:  folderInfo.ClientMtime, |  | ||||||
| 						//Bytes: folderInfo.Bytes, |  | ||||||
| 						//Count: -1, |  | ||||||
| 					} |  | ||||||
| 					entries = append(entries, d) | 					entries = append(entries, d) | ||||||
| 				} | 				} | ||||||
| 			} else if fileInfo != nil { | 			} else if fileInfo != nil { | ||||||
|   | |||||||
							
								
								
									
										85
									
								
								fs/dir.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								fs/dir.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,85 @@ | |||||||
|  | package fs | ||||||
|  |  | ||||||
|  | import "time" | ||||||
|  |  | ||||||
|  | // Dir describes an unspecialized directory for directory/container/bucket lists | ||||||
|  | type Dir struct { | ||||||
|  | 	remote  string    // name of the directory | ||||||
|  | 	modTime time.Time // modification or creation time - IsZero for unknown | ||||||
|  | 	size    int64     // size of directory and contents or -1 if unknown | ||||||
|  | 	items   int64     // number of objects or -1 for unknown | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // NewDir creates an unspecialized Directory object | ||||||
|  | func NewDir(remote string, modTime time.Time) *Dir { | ||||||
|  | 	return &Dir{ | ||||||
|  | 		remote:  remote, | ||||||
|  | 		modTime: modTime, | ||||||
|  | 		size:    -1, | ||||||
|  | 		items:   -1, | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // NewDirCopy creates an unspecialized copy of the Directory object passed in | ||||||
|  | func NewDirCopy(d Directory) *Dir { | ||||||
|  | 	return &Dir{ | ||||||
|  | 		remote:  d.Remote(), | ||||||
|  | 		modTime: d.ModTime(), | ||||||
|  | 		size:    d.Size(), | ||||||
|  | 		items:   d.Items(), | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // String returns the name | ||||||
|  | func (d *Dir) String() string { | ||||||
|  | 	return d.remote | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Remote returns the remote path | ||||||
|  | func (d *Dir) Remote() string { | ||||||
|  | 	return d.remote | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // SetRemote sets the remote | ||||||
|  | func (d *Dir) SetRemote(remote string) *Dir { | ||||||
|  | 	d.remote = remote | ||||||
|  | 	return d | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ModTime returns the modification date of the file | ||||||
|  | // It should return a best guess if one isn't available | ||||||
|  | func (d *Dir) ModTime() time.Time { | ||||||
|  | 	if !d.modTime.IsZero() { | ||||||
|  | 		return d.modTime | ||||||
|  | 	} | ||||||
|  | 	return time.Now() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Size returns the size of the file | ||||||
|  | func (d *Dir) Size() int64 { | ||||||
|  | 	return d.size | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // SetSize sets the size of the directory | ||||||
|  | func (d *Dir) SetSize(size int64) *Dir { | ||||||
|  | 	d.size = size | ||||||
|  | 	return d | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Items returns the count of items in this directory or this | ||||||
|  | // directory and subdirectories if known, -1 for unknown | ||||||
|  | func (d *Dir) Items() int64 { | ||||||
|  | 	return d.items | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // SetItems sets the number of items in the directory | ||||||
|  | func (d *Dir) SetItems(items int64) *Dir { | ||||||
|  | 	d.items = items | ||||||
|  | 	return d | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Check interfaces | ||||||
|  | var ( | ||||||
|  | 	_ DirEntry  = (*Dir)(nil) | ||||||
|  | 	_ Directory = (*Dir)(nil) | ||||||
|  | ) | ||||||
							
								
								
									
										91
									
								
								fs/fs.go
									
									
									
									
									
								
							
							
						
						
									
										91
									
								
								fs/fs.go
									
									
									
									
									
								
							| @@ -209,6 +209,15 @@ type DirEntry interface { | |||||||
| 	Size() int64 | 	Size() int64 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // Directory is a filesystem like directory provided by an Fs | ||||||
|  | type Directory interface { | ||||||
|  | 	DirEntry | ||||||
|  |  | ||||||
|  | 	// Items returns the count of items in this directory or this | ||||||
|  | 	// directory and subdirectories if known, -1 for unknown | ||||||
|  | 	Items() int64 | ||||||
|  | } | ||||||
|  |  | ||||||
| // MimeTyper is an optional interface for Object | // MimeTyper is an optional interface for Object | ||||||
| type MimeTyper interface { | type MimeTyper interface { | ||||||
| 	// MimeType returns the content type of the Object if | 	// MimeType returns the content type of the Object if | ||||||
| @@ -544,41 +553,6 @@ type ObjectPair struct { | |||||||
| // ObjectPairChan is a channel of ObjectPair | // ObjectPairChan is a channel of ObjectPair | ||||||
| type ObjectPairChan chan ObjectPair | type ObjectPairChan chan ObjectPair | ||||||
|  |  | ||||||
| // Dir describes a directory for directory/container/bucket lists |  | ||||||
| type Dir struct { |  | ||||||
| 	Name  string    // name of the directory |  | ||||||
| 	When  time.Time // modification or creation time - IsZero for unknown |  | ||||||
| 	Bytes int64     // size of directory and contents -1 for unknown |  | ||||||
| 	Count int64     // number of objects -1 for unknown |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // String returns the name |  | ||||||
| func (d *Dir) String() string { |  | ||||||
| 	return d.Name |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Remote returns the remote path |  | ||||||
| func (d *Dir) Remote() string { |  | ||||||
| 	return d.Name |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ModTime returns the modification date of the file |  | ||||||
| // It should return a best guess if one isn't available |  | ||||||
| func (d *Dir) ModTime() time.Time { |  | ||||||
| 	if !d.When.IsZero() { |  | ||||||
| 		return d.When |  | ||||||
| 	} |  | ||||||
| 	return time.Now() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Size returns the size of the file |  | ||||||
| func (d *Dir) Size() int64 { |  | ||||||
| 	return d.Bytes |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Check interface |  | ||||||
| var _ DirEntry = (*Dir)(nil) |  | ||||||
|  |  | ||||||
| // Find looks for an Info object for the name passed in | // Find looks for an Info object for the name passed in | ||||||
| // | // | ||||||
| // Services are looked up in the config file | // Services are looked up in the config file | ||||||
| @@ -651,50 +625,3 @@ func CheckClose(c io.Closer, err *error) { | |||||||
| 		*err = cerr | 		*err = cerr | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| // NewStaticObjectInfo returns a static ObjectInfo |  | ||||||
| // If hashes is nil and fs is not nil, the hash map will be replaced with |  | ||||||
| // empty hashes of the types supported by the fs. |  | ||||||
| func NewStaticObjectInfo(remote string, modTime time.Time, size int64, storable bool, hashes map[HashType]string, fs Info) ObjectInfo { |  | ||||||
| 	info := &staticObjectInfo{ |  | ||||||
| 		remote:   remote, |  | ||||||
| 		modTime:  modTime, |  | ||||||
| 		size:     size, |  | ||||||
| 		storable: storable, |  | ||||||
| 		hashes:   hashes, |  | ||||||
| 		fs:       fs, |  | ||||||
| 	} |  | ||||||
| 	if fs != nil && hashes == nil { |  | ||||||
| 		set := fs.Hashes().Array() |  | ||||||
| 		info.hashes = make(map[HashType]string) |  | ||||||
| 		for _, ht := range set { |  | ||||||
| 			info.hashes[ht] = "" |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return info |  | ||||||
| } |  | ||||||
|  |  | ||||||
| type staticObjectInfo struct { |  | ||||||
| 	remote   string |  | ||||||
| 	modTime  time.Time |  | ||||||
| 	size     int64 |  | ||||||
| 	storable bool |  | ||||||
| 	hashes   map[HashType]string |  | ||||||
| 	fs       Info |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (i *staticObjectInfo) Fs() Info           { return i.fs } |  | ||||||
| func (i *staticObjectInfo) Remote() string     { return i.remote } |  | ||||||
| func (i *staticObjectInfo) String() string     { return i.remote } |  | ||||||
| func (i *staticObjectInfo) ModTime() time.Time { return i.modTime } |  | ||||||
| func (i *staticObjectInfo) Size() int64        { return i.size } |  | ||||||
| func (i *staticObjectInfo) Storable() bool     { return i.storable } |  | ||||||
| func (i *staticObjectInfo) Hash(h HashType) (string, error) { |  | ||||||
| 	if len(i.hashes) == 0 { |  | ||||||
| 		return "", ErrHashUnsupported |  | ||||||
| 	} |  | ||||||
| 	if hash, ok := i.hashes[h]; ok { |  | ||||||
| 		return hash, nil |  | ||||||
| 	} |  | ||||||
| 	return "", ErrHashUnsupported |  | ||||||
| } |  | ||||||
|   | |||||||
							
								
								
									
										50
									
								
								fs/object.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								fs/object.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,50 @@ | |||||||
|  | package fs | ||||||
|  |  | ||||||
|  | import "time" | ||||||
|  |  | ||||||
|  | // NewStaticObjectInfo returns a static ObjectInfo | ||||||
|  | // If hashes is nil and fs is not nil, the hash map will be replaced with | ||||||
|  | // empty hashes of the types supported by the fs. | ||||||
|  | func NewStaticObjectInfo(remote string, modTime time.Time, size int64, storable bool, hashes map[HashType]string, fs Info) ObjectInfo { | ||||||
|  | 	info := &staticObjectInfo{ | ||||||
|  | 		remote:   remote, | ||||||
|  | 		modTime:  modTime, | ||||||
|  | 		size:     size, | ||||||
|  | 		storable: storable, | ||||||
|  | 		hashes:   hashes, | ||||||
|  | 		fs:       fs, | ||||||
|  | 	} | ||||||
|  | 	if fs != nil && hashes == nil { | ||||||
|  | 		set := fs.Hashes().Array() | ||||||
|  | 		info.hashes = make(map[HashType]string) | ||||||
|  | 		for _, ht := range set { | ||||||
|  | 			info.hashes[ht] = "" | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return info | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type staticObjectInfo struct { | ||||||
|  | 	remote   string | ||||||
|  | 	modTime  time.Time | ||||||
|  | 	size     int64 | ||||||
|  | 	storable bool | ||||||
|  | 	hashes   map[HashType]string | ||||||
|  | 	fs       Info | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (i *staticObjectInfo) Fs() Info           { return i.fs } | ||||||
|  | func (i *staticObjectInfo) Remote() string     { return i.remote } | ||||||
|  | func (i *staticObjectInfo) String() string     { return i.remote } | ||||||
|  | func (i *staticObjectInfo) ModTime() time.Time { return i.modTime } | ||||||
|  | func (i *staticObjectInfo) Size() int64        { return i.size } | ||||||
|  | func (i *staticObjectInfo) Storable() bool     { return i.storable } | ||||||
|  | func (i *staticObjectInfo) Hash(h HashType) (string, error) { | ||||||
|  | 	if len(i.hashes) == 0 { | ||||||
|  | 		return "", ErrHashUnsupported | ||||||
|  | 	} | ||||||
|  | 	if hash, ok := i.hashes[h]; ok { | ||||||
|  | 		return hash, nil | ||||||
|  | 	} | ||||||
|  | 	return "", ErrHashUnsupported | ||||||
|  | } | ||||||
| @@ -566,20 +566,20 @@ func (ds DirEntries) ForObjectError(fn func(o Object) error) error { | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| // ForDir runs the function supplied on every object in the entries | // ForDir runs the function supplied on every Directory in the entries | ||||||
| func (ds DirEntries) ForDir(fn func(dir *Dir)) { | func (ds DirEntries) ForDir(fn func(dir Directory)) { | ||||||
| 	for _, entry := range ds { | 	for _, entry := range ds { | ||||||
| 		dir, ok := entry.(*Dir) | 		dir, ok := entry.(Directory) | ||||||
| 		if ok { | 		if ok { | ||||||
| 			fn(dir) | 			fn(dir) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| // ForDirError runs the function supplied on every object in the entries | // ForDirError runs the function supplied on every Directory in the entries | ||||||
| func (ds DirEntries) ForDirError(fn func(dir *Dir) error) error { | func (ds DirEntries) ForDirError(fn func(dir Directory) error) error { | ||||||
| 	for _, entry := range ds { | 	for _, entry := range ds { | ||||||
| 		dir, ok := entry.(*Dir) | 		dir, ok := entry.(Directory) | ||||||
| 		if ok { | 		if ok { | ||||||
| 			err := fn(dir) | 			err := fn(dir) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| @@ -617,7 +617,7 @@ func ListDirSorted(fs Fs, includeAll bool, dir string) (entries DirEntries, err | |||||||
| 				} else { | 				} else { | ||||||
| 					Debugf(x, "Excluded from sync (and deletion)") | 					Debugf(x, "Excluded from sync (and deletion)") | ||||||
| 				} | 				} | ||||||
| 			case *Dir: | 			case Directory: | ||||||
| 				if Config.Filter.IncludeDirectory(x.Remote()) { | 				if Config.Filter.IncludeDirectory(x.Remote()) { | ||||||
| 					newEntries = append(newEntries, entry) | 					newEntries = append(newEntries, entry) | ||||||
| 				} else { | 				} else { | ||||||
| @@ -1052,9 +1052,9 @@ func ListDir(f Fs, w io.Writer) error { | |||||||
| 			// FIXME count errors and carry on for listing | 			// FIXME count errors and carry on for listing | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| 		entries.ForDir(func(dir *Dir) { | 		entries.ForDir(func(dir Directory) { | ||||||
| 			if dir != nil { | 			if dir != nil { | ||||||
| 				syncFprintf(w, "%12d %13s %9d %s\n", dir.Bytes, dir.When.Format("2006-01-02 15:04:05"), dir.Count, dir.Name) | 				syncFprintf(w, "%12d %13s %9d %s\n", dir.Size(), dir.ModTime().Format("2006-01-02 15:04:05"), dir.Items(), dir.Remote()) | ||||||
| 			} | 			} | ||||||
| 		}) | 		}) | ||||||
| 		return nil | 		return nil | ||||||
| @@ -1478,9 +1478,9 @@ func Rmdirs(f Fs, dir string) error { | |||||||
| 		} | 		} | ||||||
| 		for _, entry := range entries { | 		for _, entry := range entries { | ||||||
| 			switch x := entry.(type) { | 			switch x := entry.(type) { | ||||||
| 			case *Dir: | 			case Directory: | ||||||
| 				// add a new directory as empty | 				// add a new directory as empty | ||||||
| 				dir := x.Name | 				dir := x.Remote() | ||||||
| 				_, found := dirEmpty[dir] | 				_, found := dirEmpty[dir] | ||||||
| 				if !found { | 				if !found { | ||||||
| 					dirEmpty[dir] = true | 					dirEmpty[dir] = true | ||||||
|   | |||||||
| @@ -172,7 +172,7 @@ func NewRun(t *testing.T) *Run { | |||||||
| 						if err != nil { | 						if err != nil { | ||||||
| 							t.Errorf("Error removing file %q: %v", x.Remote(), err) | 							t.Errorf("Error removing file %q: %v", x.Remote(), err) | ||||||
| 						} | 						} | ||||||
| 					case *fs.Dir: | 					case fs.Directory: | ||||||
| 						toDelete = append(toDelete, x.Remote()) | 						toDelete = append(toDelete, x.Remote()) | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| @@ -959,7 +959,7 @@ func TestListDirSorted(t *testing.T) { | |||||||
| 		name := item.Remote() | 		name := item.Remote() | ||||||
| 		switch item.(type) { | 		switch item.(type) { | ||||||
| 		case fs.Object: | 		case fs.Object: | ||||||
| 		case *fs.Dir: | 		case fs.Directory: | ||||||
| 			name += "/" | 			name += "/" | ||||||
| 		default: | 		default: | ||||||
| 			t.Fatalf("Unknown type %+v", item) | 			t.Fatalf("Unknown type %+v", item) | ||||||
|   | |||||||
| @@ -755,7 +755,7 @@ func (s *syncCopyMove) dstOnly(dst DirEntry, job listDirJob, jobs *[]listDirJob) | |||||||
| 		default: | 		default: | ||||||
| 			panic(fmt.Sprintf("unexpected delete mode %d", s.deleteMode)) | 			panic(fmt.Sprintf("unexpected delete mode %d", s.deleteMode)) | ||||||
| 		} | 		} | ||||||
| 	case *Dir: | 	case Directory: | ||||||
| 		// Do the same thing to the entire contents of the directory | 		// Do the same thing to the entire contents of the directory | ||||||
| 		if job.dstDepth > 0 { | 		if job.dstDepth > 0 { | ||||||
| 			*jobs = append(*jobs, listDirJob{ | 			*jobs = append(*jobs, listDirJob{ | ||||||
| @@ -784,7 +784,7 @@ func (s *syncCopyMove) srcOnly(src DirEntry, job listDirJob, jobs *[]listDirJob) | |||||||
| 			// No need to check since doesn't exist | 			// No need to check since doesn't exist | ||||||
| 			s.toBeUploaded <- ObjectPair{x, nil} | 			s.toBeUploaded <- ObjectPair{x, nil} | ||||||
| 		} | 		} | ||||||
| 	case *Dir: | 	case Directory: | ||||||
| 		// Do the same thing to the entire contents of the directory | 		// Do the same thing to the entire contents of the directory | ||||||
| 		if job.srcDepth > 0 { | 		if job.srcDepth > 0 { | ||||||
| 			*jobs = append(*jobs, listDirJob{ | 			*jobs = append(*jobs, listDirJob{ | ||||||
| @@ -814,9 +814,9 @@ func (s *syncCopyMove) transfer(dst, src DirEntry, job listDirJob, jobs *[]listD | |||||||
| 			Errorf(dst, "%v", err) | 			Errorf(dst, "%v", err) | ||||||
| 			s.processError(err) | 			s.processError(err) | ||||||
| 		} | 		} | ||||||
| 	case *Dir: | 	case Directory: | ||||||
| 		// Do the same thing to the entire contents of the directory | 		// Do the same thing to the entire contents of the directory | ||||||
| 		_, ok := dst.(*Dir) | 		_, ok := dst.(Directory) | ||||||
| 		if ok { | 		if ok { | ||||||
| 			if job.srcDepth > 0 && job.dstDepth > 0 { | 			if job.srcDepth > 0 && job.dstDepth > 0 { | ||||||
| 				*jobs = append(*jobs, listDirJob{ | 				*jobs = append(*jobs, listDirJob{ | ||||||
|   | |||||||
							
								
								
									
										15
									
								
								fs/walk.go
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								fs/walk.go
									
									
									
									
									
								
							| @@ -9,6 +9,7 @@ import ( | |||||||
| 	"sort" | 	"sort" | ||||||
| 	"strings" | 	"strings" | ||||||
| 	"sync" | 	"sync" | ||||||
|  | 	"time" | ||||||
|  |  | ||||||
| 	"github.com/pkg/errors" | 	"github.com/pkg/errors" | ||||||
| ) | ) | ||||||
| @@ -119,7 +120,7 @@ func walk(f Fs, path string, includeAll bool, maxLevel int, fn WalkFunc, listDir | |||||||
| 					entries, err := listDir(f, includeAll, job.remote) | 					entries, err := listDir(f, includeAll, job.remote) | ||||||
| 					var jobs []listJob | 					var jobs []listJob | ||||||
| 					if err == nil && job.depth != 0 { | 					if err == nil && job.depth != 0 { | ||||||
| 						entries.ForDir(func(dir *Dir) { | 						entries.ForDir(func(dir Directory) { | ||||||
| 							// Recurse for the directory | 							// Recurse for the directory | ||||||
| 							jobs = append(jobs, listJob{ | 							jobs = append(jobs, listJob{ | ||||||
| 								remote: dir.Remote(), | 								remote: dir.Remote(), | ||||||
| @@ -214,9 +215,7 @@ func (dt DirTree) checkParent(root, dirPath string) { | |||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	dt[parentPath] = append(entries, &Dir{ | 	dt[parentPath] = append(entries, NewDir(dirPath, time.Now())) | ||||||
| 		Name: dirPath, |  | ||||||
| 	}) |  | ||||||
| 	dt.checkParent(root, parentPath) | 	dt.checkParent(root, parentPath) | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -250,7 +249,7 @@ func (dt DirTree) String() string { | |||||||
| 		fmt.Fprintf(out, "%s/\n", dir) | 		fmt.Fprintf(out, "%s/\n", dir) | ||||||
| 		for _, entry := range dt[dir] { | 		for _, entry := range dt[dir] { | ||||||
| 			flag := "" | 			flag := "" | ||||||
| 			if _, ok := entry.(*Dir); ok { | 			if _, ok := entry.(Directory); ok { | ||||||
| 				flag = "/" | 				flag = "/" | ||||||
| 			} | 			} | ||||||
| 			fmt.Fprintf(out, "  %s%s\n", path.Base(entry.Remote()), flag) | 			fmt.Fprintf(out, "  %s%s\n", path.Base(entry.Remote()), flag) | ||||||
| @@ -284,7 +283,7 @@ func walkRDirTree(f Fs, path string, includeAll bool, maxLevel int, listR ListRF | |||||||
| 				} else { | 				} else { | ||||||
| 					Debugf(x, "Excluded from sync (and deletion)") | 					Debugf(x, "Excluded from sync (and deletion)") | ||||||
| 				} | 				} | ||||||
| 			case *Dir: | 			case Directory: | ||||||
| 				if includeAll || Config.Filter.IncludeDirectory(x.Remote()) { | 				if includeAll || Config.Filter.IncludeDirectory(x.Remote()) { | ||||||
| 					if maxLevel < 0 || slashes <= maxLevel-1 { | 					if maxLevel < 0 || slashes <= maxLevel-1 { | ||||||
| 						if slashes == maxLevel-1 { | 						if slashes == maxLevel-1 { | ||||||
| @@ -359,7 +358,7 @@ func walkR(f Fs, path string, includeAll bool, maxLevel int, fn WalkFunc, listR | |||||||
| } | } | ||||||
|  |  | ||||||
| // WalkGetAll runs Walk getting all the results | // WalkGetAll runs Walk getting all the results | ||||||
| func WalkGetAll(f Fs, path string, includeAll bool, maxLevel int) (objs []Object, dirs []*Dir, err error) { | func WalkGetAll(f Fs, path string, includeAll bool, maxLevel int) (objs []Object, dirs []Directory, err error) { | ||||||
| 	err = Walk(f, path, includeAll, maxLevel, func(dirPath string, entries DirEntries, err error) error { | 	err = Walk(f, path, includeAll, maxLevel, func(dirPath string, entries DirEntries, err error) error { | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return err | 			return err | ||||||
| @@ -368,7 +367,7 @@ func WalkGetAll(f Fs, path string, includeAll bool, maxLevel int) (objs []Object | |||||||
| 			switch x := entry.(type) { | 			switch x := entry.(type) { | ||||||
| 			case Object: | 			case Object: | ||||||
| 				objs = append(objs, x) | 				objs = append(objs, x) | ||||||
| 			case *Dir: | 			case Directory: | ||||||
| 				dirs = append(dirs, x) | 				dirs = append(dirs, x) | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -177,8 +177,8 @@ func (ls *listDirs) WalkR() { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| func newDir(name string) *Dir { | func newDir(name string) Directory { | ||||||
| 	return &Dir{Name: name} | 	return NewDir(name, time.Time{}) | ||||||
| } | } | ||||||
|  |  | ||||||
| func testWalkEmpty(t *testing.T) *listDirs { | func testWalkEmpty(t *testing.T) *listDirs { | ||||||
|   | |||||||
| @@ -184,7 +184,7 @@ func CheckListingWithPrecision(t *testing.T, f fs.Fs, items []Item, expectedDirs | |||||||
| 	is := NewItems(items) | 	is := NewItems(items) | ||||||
| 	oldErrors := fs.Stats.GetErrors() | 	oldErrors := fs.Stats.GetErrors() | ||||||
| 	var objs []fs.Object | 	var objs []fs.Object | ||||||
| 	var dirs []*fs.Dir | 	var dirs []fs.Directory | ||||||
| 	var err error | 	var err error | ||||||
| 	var retries = *ListRetries | 	var retries = *ListRetries | ||||||
| 	sleep := time.Second / 2 | 	sleep := time.Second / 2 | ||||||
| @@ -231,7 +231,7 @@ func CheckListingWithPrecision(t *testing.T, f fs.Fs, items []Item, expectedDirs | |||||||
| 	if expectedDirs != nil && len(dirs) != 0 { | 	if expectedDirs != nil && len(dirs) != 0 { | ||||||
| 		actualDirs := []string{} | 		actualDirs := []string{} | ||||||
| 		for _, dir := range dirs { | 		for _, dir := range dirs { | ||||||
| 			actualDirs = append(actualDirs, dir.Name) | 			actualDirs = append(actualDirs, dir.Remote()) | ||||||
| 		} | 		} | ||||||
| 		sort.Strings(actualDirs) | 		sort.Strings(actualDirs) | ||||||
| 		sort.Strings(expectedDirs) | 		sort.Strings(expectedDirs) | ||||||
|   | |||||||
| @@ -183,10 +183,10 @@ func winPath(s string) string { | |||||||
| } | } | ||||||
|  |  | ||||||
| // dirsToNames returns a sorted list of names | // dirsToNames returns a sorted list of names | ||||||
| func dirsToNames(dirs []*fs.Dir) []string { | func dirsToNames(dirs []fs.Directory) []string { | ||||||
| 	names := []string{} | 	names := []string{} | ||||||
| 	for _, dir := range dirs { | 	for _, dir := range dirs { | ||||||
| 		names = append(names, winPath(dir.Name)) | 		names = append(names, winPath(dir.Remote())) | ||||||
| 	} | 	} | ||||||
| 	sort.Strings(names) | 	sort.Strings(names) | ||||||
| 	return names | 	return names | ||||||
| @@ -399,7 +399,7 @@ func TestFsListSubdir(t *testing.T) { | |||||||
| 	fileName := file2.Path | 	fileName := file2.Path | ||||||
| 	var err error | 	var err error | ||||||
| 	var objs []fs.Object | 	var objs []fs.Object | ||||||
| 	var dirs []*fs.Dir | 	var dirs []fs.Directory | ||||||
| 	for i := 0; i < 2; i++ { | 	for i := 0; i < 2; i++ { | ||||||
| 		dir, _ := path.Split(fileName) | 		dir, _ := path.Split(fileName) | ||||||
| 		dir = dir[:len(dir)-1] | 		dir = dir[:len(dir)-1] | ||||||
|   | |||||||
| @@ -324,12 +324,7 @@ func (f *Fs) List(dir string) (entries fs.DirEntries, err error) { | |||||||
| 			if object.Name == "." || object.Name == ".." { | 			if object.Name == "." || object.Name == ".." { | ||||||
| 				continue | 				continue | ||||||
| 			} | 			} | ||||||
| 			d := &fs.Dir{ | 			d := fs.NewDir(newremote, object.Time) | ||||||
| 				Name:  newremote, |  | ||||||
| 				When:  object.Time, |  | ||||||
| 				Bytes: 0, |  | ||||||
| 				Count: -1, |  | ||||||
| 			} |  | ||||||
| 			entries = append(entries, d) | 			entries = append(entries, d) | ||||||
| 		default: | 		default: | ||||||
| 			o := &Object{ | 			o := &Object{ | ||||||
|   | |||||||
| @@ -363,11 +363,7 @@ func (f *Fs) list(dir string, recurse bool, fn listFn) error { | |||||||
| // Convert a list item into a DirEntry | // Convert a list item into a DirEntry | ||||||
| func (f *Fs) itemToDirEntry(remote string, object *storage.Object, isDirectory bool) (fs.DirEntry, error) { | func (f *Fs) itemToDirEntry(remote string, object *storage.Object, isDirectory bool) (fs.DirEntry, error) { | ||||||
| 	if isDirectory { | 	if isDirectory { | ||||||
| 		d := &fs.Dir{ | 		d := fs.NewDir(remote, time.Time{}).SetSize(int64(object.Size)) | ||||||
| 			Name:  remote, |  | ||||||
| 			Bytes: int64(object.Size), |  | ||||||
| 			Count: 0, |  | ||||||
| 		} |  | ||||||
| 		return d, nil | 		return d, nil | ||||||
| 	} | 	} | ||||||
| 	o, err := f.newObjectWithInfo(remote, object) | 	o, err := f.newObjectWithInfo(remote, object) | ||||||
| @@ -411,11 +407,7 @@ func (f *Fs) listBuckets(dir string) (entries fs.DirEntries, err error) { | |||||||
| 			return nil, err | 			return nil, err | ||||||
| 		} | 		} | ||||||
| 		for _, bucket := range buckets.Items { | 		for _, bucket := range buckets.Items { | ||||||
| 			d := &fs.Dir{ | 			d := fs.NewDir(bucket.Name, time.Time{}) | ||||||
| 				Name:  bucket.Name, |  | ||||||
| 				Bytes: 0, |  | ||||||
| 				Count: 0, |  | ||||||
| 			} |  | ||||||
| 			entries = append(entries, d) | 			entries = append(entries, d) | ||||||
| 		} | 		} | ||||||
| 		if buckets.NextPageToken == "" { | 		if buckets.NextPageToken == "" { | ||||||
|   | |||||||
| @@ -307,12 +307,7 @@ func (f *Fs) List(dir string) (entries fs.DirEntries, err error) { | |||||||
| 		name = strings.TrimRight(name, "/") | 		name = strings.TrimRight(name, "/") | ||||||
| 		remote := path.Join(dir, name) | 		remote := path.Join(dir, name) | ||||||
| 		if isDir { | 		if isDir { | ||||||
| 			dir := &fs.Dir{ | 			dir := fs.NewDir(remote, timeUnset) | ||||||
| 				Name:  remote, |  | ||||||
| 				When:  timeUnset, |  | ||||||
| 				Bytes: 0, |  | ||||||
| 				Count: 0, |  | ||||||
| 			} |  | ||||||
| 			entries = append(entries, dir) | 			entries = append(entries, dir) | ||||||
| 		} else { | 		} else { | ||||||
| 			file := &Object{ | 			file := &Object{ | ||||||
|   | |||||||
| @@ -67,8 +67,8 @@ func testListRoot(t *testing.T, f fs.Fs) { | |||||||
|  |  | ||||||
| 	e := entries[0] | 	e := entries[0] | ||||||
| 	assert.Equal(t, "four", e.Remote()) | 	assert.Equal(t, "four", e.Remote()) | ||||||
| 	assert.Equal(t, int64(0), e.Size()) | 	assert.Equal(t, int64(-1), e.Size()) | ||||||
| 	_, ok := e.(*fs.Dir) | 	_, ok := e.(fs.Directory) | ||||||
| 	assert.True(t, ok) | 	assert.True(t, ok) | ||||||
|  |  | ||||||
| 	e = entries[1] | 	e = entries[1] | ||||||
| @@ -79,8 +79,8 @@ func testListRoot(t *testing.T, f fs.Fs) { | |||||||
|  |  | ||||||
| 	e = entries[2] | 	e = entries[2] | ||||||
| 	assert.Equal(t, "three", e.Remote()) | 	assert.Equal(t, "three", e.Remote()) | ||||||
| 	assert.Equal(t, int64(0), e.Size()) | 	assert.Equal(t, int64(-1), e.Size()) | ||||||
| 	_, ok = e.(*fs.Dir) | 	_, ok = e.(fs.Directory) | ||||||
| 	assert.True(t, ok) | 	assert.True(t, ok) | ||||||
|  |  | ||||||
| 	e = entries[3] | 	e = entries[3] | ||||||
|   | |||||||
| @@ -236,12 +236,7 @@ func (f *Fs) List(dir string) (entries fs.DirEntries, err error) { | |||||||
| 				// Ignore directories which are symlinks.  These are junction points under windows which | 				// Ignore directories which are symlinks.  These are junction points under windows which | ||||||
| 				// are kind of a souped up symlink. Unix doesn't have directories which are symlinks. | 				// are kind of a souped up symlink. Unix doesn't have directories which are symlinks. | ||||||
| 				if (mode&os.ModeSymlink) == 0 && f.dev == readDevice(fi) { | 				if (mode&os.ModeSymlink) == 0 && f.dev == readDevice(fi) { | ||||||
| 					d := &fs.Dir{ | 					d := fs.NewDir(f.dirNames.Save(newRemote, f.cleanRemote(newRemote)), fi.ModTime()) | ||||||
| 						Name:  f.dirNames.Save(newRemote, f.cleanRemote(newRemote)), |  | ||||||
| 						When:  fi.ModTime(), |  | ||||||
| 						Bytes: 0, |  | ||||||
| 						Count: 0, |  | ||||||
| 					} |  | ||||||
| 					entries = append(entries, d) | 					entries = append(entries, d) | ||||||
| 				} | 				} | ||||||
| 			} else { | 			} else { | ||||||
|   | |||||||
| @@ -423,14 +423,9 @@ func (f *Fs) List(dir string) (entries fs.DirEntries, err error) { | |||||||
| 		if info.Folder != nil { | 		if info.Folder != nil { | ||||||
| 			// cache the directory ID for later lookups | 			// cache the directory ID for later lookups | ||||||
| 			f.dirCache.Put(remote, info.ID) | 			f.dirCache.Put(remote, info.ID) | ||||||
| 			d := &fs.Dir{ | 			d := fs.NewDir(remote, time.Time(info.LastModifiedDateTime)) | ||||||
| 				Name:  remote, |  | ||||||
| 				Bytes: -1, |  | ||||||
| 				Count: -1, |  | ||||||
| 				When:  time.Time(info.LastModifiedDateTime), |  | ||||||
| 			} |  | ||||||
| 			if info.Folder != nil { | 			if info.Folder != nil { | ||||||
| 				d.Count = info.Folder.ChildCount | 				d.SetItems(info.Folder.ChildCount) | ||||||
| 			} | 			} | ||||||
| 			entries = append(entries, d) | 			entries = append(entries, d) | ||||||
| 		} else { | 		} else { | ||||||
|   | |||||||
							
								
								
									
										13
									
								
								s3/s3.go
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								s3/s3.go
									
									
									
									
									
								
							| @@ -555,11 +555,7 @@ func (f *Fs) itemToDirEntry(remote string, object *s3.Object, isDirectory bool) | |||||||
| 		if object.Size != nil { | 		if object.Size != nil { | ||||||
| 			size = *object.Size | 			size = *object.Size | ||||||
| 		} | 		} | ||||||
| 		d := &fs.Dir{ | 		d := fs.NewDir(remote, time.Time{}).SetSize(size) | ||||||
| 			Name:  remote, |  | ||||||
| 			Bytes: size, |  | ||||||
| 			Count: 0, |  | ||||||
| 		} |  | ||||||
| 		return d, nil | 		return d, nil | ||||||
| 	} | 	} | ||||||
| 	o, err := f.newObjectWithInfo(remote, object) | 	o, err := f.newObjectWithInfo(remote, object) | ||||||
| @@ -599,12 +595,7 @@ func (f *Fs) listBuckets(dir string) (entries fs.DirEntries, err error) { | |||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| 	for _, bucket := range resp.Buckets { | 	for _, bucket := range resp.Buckets { | ||||||
| 		d := &fs.Dir{ | 		d := fs.NewDir(aws.StringValue(bucket.Name), aws.TimeValue(bucket.CreationDate)) | ||||||
| 			Name:  aws.StringValue(bucket.Name), |  | ||||||
| 			When:  aws.TimeValue(bucket.CreationDate), |  | ||||||
| 			Bytes: -1, |  | ||||||
| 			Count: -1, |  | ||||||
| 		} |  | ||||||
| 		entries = append(entries, d) | 		entries = append(entries, d) | ||||||
| 	} | 	} | ||||||
| 	return entries, nil | 	return entries, nil | ||||||
|   | |||||||
| @@ -264,12 +264,7 @@ func (f *Fs) List(dir string) (entries fs.DirEntries, err error) { | |||||||
| 	for _, info := range infos { | 	for _, info := range infos { | ||||||
| 		remote := path.Join(dir, info.Name()) | 		remote := path.Join(dir, info.Name()) | ||||||
| 		if info.IsDir() { | 		if info.IsDir() { | ||||||
| 			d := &fs.Dir{ | 			d := fs.NewDir(remote, info.ModTime()) | ||||||
| 				Name:  remote, |  | ||||||
| 				When:  info.ModTime(), |  | ||||||
| 				Bytes: -1, |  | ||||||
| 				Count: -1, |  | ||||||
| 			} |  | ||||||
| 			entries = append(entries, d) | 			entries = append(entries, d) | ||||||
| 		} else { | 		} else { | ||||||
| 			o := &Object{ | 			o := &Object{ | ||||||
|   | |||||||
| @@ -321,11 +321,7 @@ type addEntryFn func(fs.DirEntry) error | |||||||
| func (f *Fs) list(dir string, recurse bool, fn addEntryFn) error { | func (f *Fs) list(dir string, recurse bool, fn addEntryFn) error { | ||||||
| 	return f.listContainerRoot(f.container, f.root, dir, recurse, func(remote string, object *swift.Object, isDirectory bool) (err error) { | 	return f.listContainerRoot(f.container, f.root, dir, recurse, func(remote string, object *swift.Object, isDirectory bool) (err error) { | ||||||
| 		if isDirectory { | 		if isDirectory { | ||||||
| 			d := &fs.Dir{ | 			d := fs.NewDir(remote, time.Time{}).SetSize(object.Bytes) | ||||||
| 				Name:  remote, |  | ||||||
| 				Bytes: object.Bytes, |  | ||||||
| 				Count: 0, |  | ||||||
| 			} |  | ||||||
| 			err = fn(d) | 			err = fn(d) | ||||||
| 		} else { | 		} else { | ||||||
| 			o, err := f.newObjectWithInfo(remote, object) | 			o, err := f.newObjectWithInfo(remote, object) | ||||||
| @@ -370,11 +366,7 @@ func (f *Fs) listContainers(dir string) (entries fs.DirEntries, err error) { | |||||||
| 		return nil, errors.Wrap(err, "container listing failed") | 		return nil, errors.Wrap(err, "container listing failed") | ||||||
| 	} | 	} | ||||||
| 	for _, container := range containers { | 	for _, container := range containers { | ||||||
| 		d := &fs.Dir{ | 		d := fs.NewDir(container.Name, time.Time{}).SetSize(container.Bytes).SetItems(container.Count) | ||||||
| 			Name:  container.Name, |  | ||||||
| 			Bytes: container.Bytes, |  | ||||||
| 			Count: container.Count, |  | ||||||
| 		} |  | ||||||
| 		entries = append(entries, d) | 		entries = append(entries, d) | ||||||
| 	} | 	} | ||||||
| 	return entries, nil | 	return entries, nil | ||||||
|   | |||||||
| @@ -174,12 +174,7 @@ func (f *Fs) itemToDirEntry(remote string, object *yandex.ResourceInfoResponse) | |||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return nil, errors.Wrap(err, "error parsing time in directory item") | 			return nil, errors.Wrap(err, "error parsing time in directory item") | ||||||
| 		} | 		} | ||||||
| 		d := &fs.Dir{ | 		d := fs.NewDir(remote, t).SetSize(int64(object.Size)) | ||||||
| 			Name:  remote, |  | ||||||
| 			When:  t, |  | ||||||
| 			Bytes: int64(object.Size), |  | ||||||
| 			Count: -1, |  | ||||||
| 		} |  | ||||||
| 		return d, nil | 		return d, nil | ||||||
| 	case "file": | 	case "file": | ||||||
| 		o, err := f.newObjectWithInfo(remote, object) | 		o, err := f.newObjectWithInfo(remote, object) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user