mirror of
https://github.com/rclone/rclone
synced 2024-11-23 00:06:55 +01:00
fs: allow Metadata calls to be called with Directory or Object
This involved adding the Fs() method to DirEntry as it is needed in the metadata mapper. Unspecialised fs.Dir objects will return a new fs.Unknown from their Fs() methods as they are not specific to any given Fs.
This commit is contained in:
parent
e1032f693f
commit
fd1ca2dfe8
@ -7,6 +7,7 @@ import (
|
|||||||
|
|
||||||
// Dir describes an unspecialized directory for directory/container/bucket lists
|
// Dir describes an unspecialized directory for directory/container/bucket lists
|
||||||
type Dir struct {
|
type Dir struct {
|
||||||
|
f Info // Fs this directory is part of
|
||||||
remote string // name of the directory
|
remote string // name of the directory
|
||||||
modTime time.Time // modification or creation time - IsZero for unknown
|
modTime time.Time // modification or creation time - IsZero for unknown
|
||||||
size int64 // size of directory and contents or -1 if unknown
|
size int64 // size of directory and contents or -1 if unknown
|
||||||
@ -20,6 +21,7 @@ type Dir struct {
|
|||||||
// If the modTime is unknown pass in time.Time{}
|
// If the modTime is unknown pass in time.Time{}
|
||||||
func NewDir(remote string, modTime time.Time) *Dir {
|
func NewDir(remote string, modTime time.Time) *Dir {
|
||||||
return &Dir{
|
return &Dir{
|
||||||
|
f: Unknown,
|
||||||
remote: remote,
|
remote: remote,
|
||||||
modTime: modTime,
|
modTime: modTime,
|
||||||
size: -1,
|
size: -1,
|
||||||
@ -30,6 +32,7 @@ func NewDir(remote string, modTime time.Time) *Dir {
|
|||||||
// NewDirCopy creates an unspecialized copy of the Directory object passed in
|
// NewDirCopy creates an unspecialized copy of the Directory object passed in
|
||||||
func NewDirCopy(ctx context.Context, d Directory) *Dir {
|
func NewDirCopy(ctx context.Context, d Directory) *Dir {
|
||||||
return &Dir{
|
return &Dir{
|
||||||
|
f: d.Fs(),
|
||||||
remote: d.Remote(),
|
remote: d.Remote(),
|
||||||
modTime: d.ModTime(ctx),
|
modTime: d.ModTime(ctx),
|
||||||
size: d.Size(),
|
size: d.Size(),
|
||||||
@ -38,6 +41,11 @@ func NewDirCopy(ctx context.Context, d Directory) *Dir {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fs returns the Fs that this directory is part of
|
||||||
|
func (d *Dir) Fs() Info {
|
||||||
|
return d.f
|
||||||
|
}
|
||||||
|
|
||||||
// String returns the name
|
// String returns the name
|
||||||
func (d *Dir) String() string {
|
func (d *Dir) String() string {
|
||||||
return d.remote
|
return d.remote
|
||||||
|
@ -87,6 +87,7 @@ func TestFilterAndSortCheckDirRoot(t *testing.T) {
|
|||||||
|
|
||||||
type unknownDirEntry string
|
type unknownDirEntry string
|
||||||
|
|
||||||
|
func (o unknownDirEntry) Fs() fs.Info { return fs.Unknown }
|
||||||
func (o unknownDirEntry) String() string { return string(o) }
|
func (o unknownDirEntry) String() string { return string(o) }
|
||||||
func (o unknownDirEntry) Remote() string { return string(o) }
|
func (o unknownDirEntry) Remote() string { return string(o) }
|
||||||
func (o unknownDirEntry) ModTime(ctx context.Context) (t time.Time) { return t }
|
func (o unknownDirEntry) ModTime(ctx context.Context) (t time.Time) { return t }
|
||||||
|
@ -63,10 +63,10 @@ func (m *Metadata) MergeOptions(options []OpenOption) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMetadata from an ObjectInfo
|
// GetMetadata from an DirEntry
|
||||||
//
|
//
|
||||||
// If the object has no metadata then metadata will be nil
|
// If the object has no metadata then metadata will be nil
|
||||||
func GetMetadata(ctx context.Context, o ObjectInfo) (metadata Metadata, err error) {
|
func GetMetadata(ctx context.Context, o DirEntry) (metadata Metadata, err error) {
|
||||||
do, ok := o.(Metadataer)
|
do, ok := o.(Metadataer)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
@ -91,7 +91,7 @@ type mapItem struct {
|
|||||||
|
|
||||||
// This runs an external program on the metadata which can be used to
|
// This runs an external program on the metadata which can be used to
|
||||||
// map it from one form to another.
|
// map it from one form to another.
|
||||||
func metadataMapper(ctx context.Context, cmdLine SpaceSepList, dstFs Fs, o ObjectInfo, metadata Metadata) (newMetadata Metadata, err error) {
|
func metadataMapper(ctx context.Context, cmdLine SpaceSepList, dstFs Fs, o DirEntry, metadata Metadata) (newMetadata Metadata, err error) {
|
||||||
ci := GetConfig(ctx)
|
ci := GetConfig(ctx)
|
||||||
cmd := exec.Command(cmdLine[0], cmdLine[1:]...)
|
cmd := exec.Command(cmdLine[0], cmdLine[1:]...)
|
||||||
in := mapItem{
|
in := mapItem{
|
||||||
@ -145,14 +145,14 @@ func metadataMapper(ctx context.Context, cmdLine SpaceSepList, dstFs Fs, o Objec
|
|||||||
return out.Metadata, nil
|
return out.Metadata, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMetadataOptions from an ObjectInfo and merge it with any in options
|
// GetMetadataOptions from an DirEntry and merge it with any in options
|
||||||
//
|
//
|
||||||
// If --metadata isn't in use it will return nil.
|
// If --metadata isn't in use it will return nil.
|
||||||
//
|
//
|
||||||
// If the object has no metadata then metadata will be nil.
|
// If the object has no metadata then metadata will be nil.
|
||||||
//
|
//
|
||||||
// This should be passed the destination Fs for the metadata mapper
|
// This should be passed the destination Fs for the metadata mapper
|
||||||
func GetMetadataOptions(ctx context.Context, dstFs Fs, o ObjectInfo, options []OpenOption) (metadata Metadata, err error) {
|
func GetMetadataOptions(ctx context.Context, dstFs Fs, o DirEntry, options []OpenOption) (metadata Metadata, err error) {
|
||||||
ci := GetConfig(ctx)
|
ci := GetConfig(ctx)
|
||||||
if !ci.Metadata {
|
if !ci.Metadata {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
@ -54,7 +54,7 @@ func MimeTypeFromName(remote string) (mimeType string) {
|
|||||||
|
|
||||||
// MimeType returns the MimeType from the object, either by calling
|
// MimeType returns the MimeType from the object, either by calling
|
||||||
// the MimeTyper interface or using MimeTypeFromName
|
// the MimeTyper interface or using MimeTypeFromName
|
||||||
func MimeType(ctx context.Context, o ObjectInfo) (mimeType string) {
|
func MimeType(ctx context.Context, o DirEntry) (mimeType string) {
|
||||||
// Read the MimeType from the optional interface if available
|
// Read the MimeType from the optional interface if available
|
||||||
if do, ok := o.(MimeTyper); ok {
|
if do, ok := o.(MimeTyper); ok {
|
||||||
mimeType = do.MimeType(ctx)
|
mimeType = do.MimeType(ctx)
|
||||||
|
31
fs/types.go
31
fs/types.go
@ -102,9 +102,6 @@ type Object interface {
|
|||||||
type ObjectInfo interface {
|
type ObjectInfo interface {
|
||||||
DirEntry
|
DirEntry
|
||||||
|
|
||||||
// Fs returns read only access to the Fs that this object is part of
|
|
||||||
Fs() Info
|
|
||||||
|
|
||||||
// Hash returns the selected checksum of the file
|
// Hash returns the selected checksum of the file
|
||||||
// If no checksum is available it returns ""
|
// If no checksum is available it returns ""
|
||||||
Hash(ctx context.Context, ty hash.Type) (string, error)
|
Hash(ctx context.Context, ty hash.Type) (string, error)
|
||||||
@ -117,6 +114,9 @@ type ObjectInfo interface {
|
|||||||
// a Dir or Object. These are returned from directory listings - type
|
// a Dir or Object. These are returned from directory listings - type
|
||||||
// assert them into the correct type.
|
// assert them into the correct type.
|
||||||
type DirEntry interface {
|
type DirEntry interface {
|
||||||
|
// Fs returns read only access to the Fs that this object is part of
|
||||||
|
Fs() Info
|
||||||
|
|
||||||
// String returns a description of the Object
|
// String returns a description of the Object
|
||||||
String() string
|
String() string
|
||||||
|
|
||||||
@ -332,3 +332,28 @@ type WriterAtCloser interface {
|
|||||||
io.WriterAt
|
io.WriterAt
|
||||||
io.Closer
|
io.Closer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type unknownFs struct{}
|
||||||
|
|
||||||
|
// Name of the remote (as passed into NewFs)
|
||||||
|
func (unknownFs) Name() string { return "unknown" }
|
||||||
|
|
||||||
|
// Root of the remote (as passed into NewFs)
|
||||||
|
func (unknownFs) Root() string { return "" }
|
||||||
|
|
||||||
|
// String returns a description of the FS
|
||||||
|
func (unknownFs) String() string { return "unknown" }
|
||||||
|
|
||||||
|
// Precision of the ModTimes in this Fs
|
||||||
|
func (unknownFs) Precision() time.Duration { return ModTimeNotSupported }
|
||||||
|
|
||||||
|
// Returns the supported hash types of the filesystem
|
||||||
|
func (unknownFs) Hashes() hash.Set { return hash.Set(hash.None) }
|
||||||
|
|
||||||
|
// Features returns the optional features of this Fs
|
||||||
|
func (unknownFs) Features() *Features { return &Features{} }
|
||||||
|
|
||||||
|
// Unknown holds an Info for an unknown Fs
|
||||||
|
//
|
||||||
|
// This is used when we need an Fs but don't have one.
|
||||||
|
var Unknown Info = unknownFs{}
|
||||||
|
Loading…
Reference in New Issue
Block a user