mirror of
https://github.com/rclone/rclone
synced 2024-11-20 21:27:33 +01:00
fs: add Directory Metadata flags for backends and interfaces
Add backend flags - ReadDirMetadata - WriteDirMetadata - WriteDirSetModTime - UserDirMetadata - DirModTimeUpdatesOnWrite Add Metadata/SetMetadata for directories. Add MkdirMetadata optional feature
This commit is contained in:
parent
6da52d76a7
commit
a4cadd1128
@ -13,27 +13,32 @@ import (
|
||||
// Features describe the optional features of the Fs
|
||||
type Features struct {
|
||||
// Feature flags, whether Fs
|
||||
CaseInsensitive bool // has case insensitive files
|
||||
DuplicateFiles bool // allows duplicate files
|
||||
ReadMimeType bool // can read the mime type of objects
|
||||
WriteMimeType bool // can set the mime type of objects
|
||||
CanHaveEmptyDirectories bool // can have empty directories
|
||||
BucketBased bool // is bucket based (like s3, swift, etc.)
|
||||
BucketBasedRootOK bool // is bucket based and can use from root
|
||||
SetTier bool // allows set tier functionality on objects
|
||||
GetTier bool // allows to retrieve storage tier of objects
|
||||
ServerSideAcrossConfigs bool // can server-side copy between different remotes of the same type
|
||||
IsLocal bool // is the local backend
|
||||
SlowModTime bool // if calling ModTime() generally takes an extra transaction
|
||||
SlowHash bool // if calling Hash() generally takes an extra transaction
|
||||
ReadMetadata bool // can read metadata from objects
|
||||
WriteMetadata bool // can write metadata to objects
|
||||
UserMetadata bool // can read/write general purpose metadata
|
||||
FilterAware bool // can make use of filters if provided for listing
|
||||
PartialUploads bool // uploaded file can appear incomplete on the fs while it's being uploaded
|
||||
NoMultiThreading bool // set if can't have multiplethreads on one download open
|
||||
Overlay bool // this wraps one or more backends to add functionality
|
||||
ChunkWriterDoesntSeek bool // set if the chunk writer doesn't need to read the data more than once
|
||||
CaseInsensitive bool // has case insensitive files
|
||||
DuplicateFiles bool // allows duplicate files
|
||||
ReadMimeType bool // can read the mime type of objects
|
||||
WriteMimeType bool // can set the mime type of objects
|
||||
CanHaveEmptyDirectories bool // can have empty directories
|
||||
BucketBased bool // is bucket based (like s3, swift, etc.)
|
||||
BucketBasedRootOK bool // is bucket based and can use from root
|
||||
SetTier bool // allows set tier functionality on objects
|
||||
GetTier bool // allows to retrieve storage tier of objects
|
||||
ServerSideAcrossConfigs bool // can server-side copy between different remotes of the same type
|
||||
IsLocal bool // is the local backend
|
||||
SlowModTime bool // if calling ModTime() generally takes an extra transaction
|
||||
SlowHash bool // if calling Hash() generally takes an extra transaction
|
||||
ReadMetadata bool // can read metadata from objects
|
||||
WriteMetadata bool // can write metadata to objects
|
||||
UserMetadata bool // can read/write general purpose metadata
|
||||
ReadDirMetadata bool // can read metadata from directories (implements Directory.Metadata)
|
||||
WriteDirMetadata bool // can write metadata to directories (implements Directory.SetMetadata)
|
||||
WriteDirSetModTime bool // can write metadata to directories (implements Directory.SetModTime)
|
||||
UserDirMetadata bool // can read/write general purpose metadata to/from directories
|
||||
DirModTimeUpdatesOnWrite bool // indicate writing files to a directory updates its modtime
|
||||
FilterAware bool // can make use of filters if provided for listing
|
||||
PartialUploads bool // uploaded file can appear incomplete on the fs while it's being uploaded
|
||||
NoMultiThreading bool // set if can't have multiplethreads on one download open
|
||||
Overlay bool // this wraps one or more backends to add functionality
|
||||
ChunkWriterDoesntSeek bool // set if the chunk writer doesn't need to read the data more than once
|
||||
|
||||
// Purge all files in the directory specified
|
||||
//
|
||||
@ -75,6 +80,15 @@ type Features struct {
|
||||
// If destination exists then return fs.ErrorDirExists
|
||||
DirMove func(ctx context.Context, src Fs, srcRemote, dstRemote string) error
|
||||
|
||||
// MkdirMetadata makes the directory passed in as dir.
|
||||
//
|
||||
// It shouldn't return an error if it already exists.
|
||||
//
|
||||
// If the metadata is not nil it is set.
|
||||
//
|
||||
// It returns the directory that was created.
|
||||
MkdirMetadata func(ctx context.Context, dir string, metadata Metadata) (Directory, error)
|
||||
|
||||
// ChangeNotify calls the passed function with a path
|
||||
// that has had changes. If the implementation
|
||||
// uses polling, it should adhere to the given interval.
|
||||
@ -274,6 +288,9 @@ func (ft *Features) Fill(ctx context.Context, f Fs) *Features {
|
||||
if do, ok := f.(DirMover); ok {
|
||||
ft.DirMove = do.DirMove
|
||||
}
|
||||
if do, ok := f.(MkdirMetadataer); ok {
|
||||
ft.MkdirMetadata = do.MkdirMetadata
|
||||
}
|
||||
if do, ok := f.(ChangeNotifier); ok {
|
||||
ft.ChangeNotify = do.ChangeNotify
|
||||
}
|
||||
@ -348,6 +365,11 @@ func (ft *Features) Mask(ctx context.Context, f Fs) *Features {
|
||||
ft.ReadMetadata = ft.ReadMetadata && mask.ReadMetadata
|
||||
ft.WriteMetadata = ft.WriteMetadata && mask.WriteMetadata
|
||||
ft.UserMetadata = ft.UserMetadata && mask.UserMetadata
|
||||
ft.ReadDirMetadata = ft.ReadDirMetadata && mask.ReadDirMetadata
|
||||
ft.WriteDirMetadata = ft.WriteDirMetadata && mask.WriteDirMetadata
|
||||
ft.WriteDirSetModTime = ft.WriteDirSetModTime && mask.WriteDirSetModTime
|
||||
ft.UserDirMetadata = ft.UserDirMetadata && mask.UserDirMetadata
|
||||
ft.DirModTimeUpdatesOnWrite = ft.DirModTimeUpdatesOnWrite && mask.DirModTimeUpdatesOnWrite
|
||||
ft.CanHaveEmptyDirectories = ft.CanHaveEmptyDirectories && mask.CanHaveEmptyDirectories
|
||||
ft.BucketBased = ft.BucketBased && mask.BucketBased
|
||||
ft.BucketBasedRootOK = ft.BucketBasedRootOK && mask.BucketBasedRootOK
|
||||
@ -374,6 +396,9 @@ func (ft *Features) Mask(ctx context.Context, f Fs) *Features {
|
||||
if mask.DirMove == nil {
|
||||
ft.DirMove = nil
|
||||
}
|
||||
if mask.MkdirMetadata == nil {
|
||||
ft.MkdirMetadata = nil
|
||||
}
|
||||
if mask.ChangeNotify == nil {
|
||||
ft.ChangeNotify = nil
|
||||
}
|
||||
@ -505,6 +530,18 @@ type DirMover interface {
|
||||
DirMove(ctx context.Context, src Fs, srcRemote, dstRemote string) error
|
||||
}
|
||||
|
||||
// MkdirMetadataer is an optional interface for Fs
|
||||
type MkdirMetadataer interface {
|
||||
// MkdirMetadata makes the directory passed in as dir.
|
||||
//
|
||||
// It shouldn't return an error if it already exists.
|
||||
//
|
||||
// If the metadata is not nil it is set.
|
||||
//
|
||||
// It returns the directory that was created.
|
||||
MkdirMetadata(ctx context.Context, dir string, metadata Metadata) (Directory, error)
|
||||
}
|
||||
|
||||
// ChangeNotifier is an optional interface for Fs
|
||||
type ChangeNotifier interface {
|
||||
// ChangeNotify calls the passed function with a path
|
||||
|
55
fs/types.go
55
fs/types.go
@ -144,6 +144,16 @@ type Directory interface {
|
||||
ID() string
|
||||
}
|
||||
|
||||
// FullDirectory contains all the optional interfaces for Directory
|
||||
//
|
||||
// Use for checking making wrapping Directories implement everything
|
||||
type FullDirectory interface {
|
||||
Directory
|
||||
Metadataer
|
||||
SetMetadataer
|
||||
SetModTimer
|
||||
}
|
||||
|
||||
// MimeTyper is an optional interface for Object
|
||||
type MimeTyper interface {
|
||||
// MimeType returns the content type of the Object if
|
||||
@ -183,14 +193,32 @@ type GetTierer interface {
|
||||
GetTier() string
|
||||
}
|
||||
|
||||
// Metadataer is an optional interface for Object
|
||||
// Metadataer is an optional interface for DirEntry
|
||||
type Metadataer interface {
|
||||
// Metadata returns metadata for an object
|
||||
// Metadata returns metadata for an DirEntry
|
||||
//
|
||||
// It should return nil if there is no Metadata
|
||||
Metadata(ctx context.Context) (Metadata, error)
|
||||
}
|
||||
|
||||
// SetMetadataer is an optional interface for DirEntry
|
||||
type SetMetadataer interface {
|
||||
// SetMetadata sets metadata for an DirEntry
|
||||
//
|
||||
// It should return fs.ErrorNotImplemented if it can't set metadata
|
||||
SetMetadata(ctx context.Context, metadata Metadata) error
|
||||
}
|
||||
|
||||
// SetModTimer is an optional interface for Directory.
|
||||
//
|
||||
// Object implements this as part of its requires set of interfaces.
|
||||
type SetModTimer interface {
|
||||
// SetModTime sets the metadata on the DirEntry to set the modification date
|
||||
//
|
||||
// If there is any other metadata it does not overwrite it.
|
||||
SetModTime(ctx context.Context, t time.Time) error
|
||||
}
|
||||
|
||||
// FullObjectInfo contains all the read-only optional interfaces
|
||||
//
|
||||
// Use for checking making wrapping ObjectInfos implement everything
|
||||
@ -248,6 +276,29 @@ func ObjectOptionalInterfaces(o Object) (supported, unsupported []string) {
|
||||
return supported, unsupported
|
||||
}
|
||||
|
||||
// DirectoryOptionalInterfaces returns the names of supported and
|
||||
// unsupported optional interfaces for a Directory
|
||||
func DirectoryOptionalInterfaces(d Directory) (supported, unsupported []string) {
|
||||
store := func(ok bool, name string) {
|
||||
if ok {
|
||||
supported = append(supported, name)
|
||||
} else {
|
||||
unsupported = append(unsupported, name)
|
||||
}
|
||||
}
|
||||
|
||||
_, ok := d.(Metadataer)
|
||||
store(ok, "Metadata")
|
||||
|
||||
_, ok = d.(SetMetadataer)
|
||||
store(ok, "SetMetadata")
|
||||
|
||||
_, ok = d.(SetModTimer)
|
||||
store(ok, "SetModTime")
|
||||
|
||||
return supported, unsupported
|
||||
}
|
||||
|
||||
// ListRCallback defines a callback function for ListR to use
|
||||
//
|
||||
// It is called for each tranche of entries read from the listing and
|
||||
|
Loading…
Reference in New Issue
Block a user