mirror of
https://github.com/rclone/rclone.git
synced 2025-07-18 04:54:42 +02:00
All user visible Durations should be fs.Duration rather than time.Duration. Suffix is then optional and defaults to s. Additional suffices d, w, M and y are supported, in addition to ms, s, m and h - which are the only ones supported by time.Duration. Absolute times can also be specified, and will be interpreted as duration relative to now.
94 lines
3.8 KiB
Go
94 lines
3.8 KiB
Go
// Package fs is a generic file system interface for rclone object storage systems
|
|
package fs
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"io"
|
|
"math"
|
|
"time"
|
|
)
|
|
|
|
// Constants
|
|
const (
|
|
// ModTimeNotSupported is a very large precision value to show
|
|
// mod time isn't supported on this Fs
|
|
ModTimeNotSupported = 100 * 365 * 24 * time.Hour
|
|
// MaxLevel is a sentinel representing an infinite depth for listings
|
|
MaxLevel = math.MaxInt32
|
|
// The suffix added to a translated symbolic link
|
|
LinkSuffix = ".rclonelink"
|
|
)
|
|
|
|
// Globals
|
|
var (
|
|
// ErrorNotFoundInConfigFile is returned by NewFs if not found in config file
|
|
ErrorNotFoundInConfigFile = errors.New("didn't find section in config file")
|
|
ErrorCantPurge = errors.New("can't purge directory")
|
|
ErrorCantCopy = errors.New("can't copy object - incompatible remotes")
|
|
ErrorCantMove = errors.New("can't move object - incompatible remotes")
|
|
ErrorCantDirMove = errors.New("can't move directory - incompatible remotes")
|
|
ErrorCantUploadEmptyFiles = errors.New("can't upload empty files to this remote")
|
|
ErrorDirExists = errors.New("can't copy directory - destination already exists")
|
|
ErrorCantSetModTime = errors.New("can't set modified time")
|
|
ErrorCantSetModTimeWithoutDelete = errors.New("can't set modified time without deleting existing object")
|
|
ErrorDirNotFound = errors.New("directory not found")
|
|
ErrorObjectNotFound = errors.New("object not found")
|
|
ErrorLevelNotSupported = errors.New("level value not supported")
|
|
ErrorListAborted = errors.New("list aborted")
|
|
ErrorListBucketRequired = errors.New("bucket or container name is needed in remote")
|
|
ErrorIsFile = errors.New("is a file not a directory")
|
|
ErrorIsDir = errors.New("is a directory not a file")
|
|
ErrorNotAFile = errors.New("is not a regular file")
|
|
ErrorNotDeleting = errors.New("not deleting files as there were IO errors")
|
|
ErrorNotDeletingDirs = errors.New("not deleting directories as there were IO errors")
|
|
ErrorOverlapping = errors.New("can't sync or move files on overlapping remotes (try excluding the destination with a filter rule)")
|
|
ErrorDirectoryNotEmpty = errors.New("directory not empty")
|
|
ErrorImmutableModified = errors.New("immutable file modified")
|
|
ErrorPermissionDenied = errors.New("permission denied")
|
|
ErrorCantShareDirectories = errors.New("this backend can't share directories with link")
|
|
ErrorNotImplemented = errors.New("optional feature not implemented")
|
|
ErrorCommandNotFound = errors.New("command not found")
|
|
ErrorFileNameTooLong = errors.New("file name too long")
|
|
)
|
|
|
|
// CheckClose is a utility function used to check the return from
|
|
// Close in a defer statement.
|
|
func CheckClose(c io.Closer, err *error) {
|
|
cerr := c.Close()
|
|
if *err == nil {
|
|
*err = cerr
|
|
}
|
|
}
|
|
|
|
// FileExists returns true if a file remote exists.
|
|
// If remote is a directory, FileExists returns false.
|
|
func FileExists(ctx context.Context, fs Fs, remote string) (bool, error) {
|
|
_, err := fs.NewObject(ctx, remote)
|
|
if err != nil {
|
|
if err == ErrorObjectNotFound || err == ErrorNotAFile || err == ErrorPermissionDenied {
|
|
return false, nil
|
|
}
|
|
return false, err
|
|
}
|
|
return true, nil
|
|
}
|
|
|
|
// GetModifyWindow calculates the maximum modify window between the given Fses
|
|
// and the Config.ModifyWindow parameter.
|
|
func GetModifyWindow(ctx context.Context, fss ...Info) time.Duration {
|
|
window := time.Duration(GetConfig(ctx).ModifyWindow)
|
|
for _, f := range fss {
|
|
if f != nil {
|
|
precision := f.Precision()
|
|
if precision == ModTimeNotSupported {
|
|
return ModTimeNotSupported
|
|
}
|
|
if precision > window {
|
|
window = precision
|
|
}
|
|
}
|
|
}
|
|
return window
|
|
}
|