2019-11-30 22:41:39 +08:00
|
|
|
package policy
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
|
|
|
|
"github.com/rclone/rclone/backend/union/upstream"
|
|
|
|
"github.com/rclone/rclone/fs"
|
|
|
|
)
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
registerPolicy("epmfs", &EpMfs{})
|
|
|
|
}
|
|
|
|
|
|
|
|
// EpMfs stands for existing path, most free space
|
|
|
|
// Of all the candidates on which the path exists choose the one with the most free space.
|
|
|
|
type EpMfs struct {
|
|
|
|
EpAll
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *EpMfs) mfs(upstreams []*upstream.Fs) (*upstream.Fs, error) {
|
|
|
|
var maxFreeSpace int64
|
|
|
|
var mfsupstream *upstream.Fs
|
|
|
|
for _, u := range upstreams {
|
|
|
|
space, err := u.GetFreeSpace()
|
|
|
|
if err != nil {
|
|
|
|
fs.LogPrintf(fs.LogLevelNotice, nil,
|
|
|
|
"Free Space is not supported for upstream %s, treating as infinite", u.Name())
|
|
|
|
}
|
|
|
|
if maxFreeSpace < space {
|
|
|
|
maxFreeSpace = space
|
|
|
|
mfsupstream = u
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if mfsupstream == nil {
|
|
|
|
return nil, fs.ErrorObjectNotFound
|
|
|
|
}
|
|
|
|
return mfsupstream, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *EpMfs) mfsEntries(entries []upstream.Entry) (upstream.Entry, error) {
|
|
|
|
var maxFreeSpace int64
|
|
|
|
var mfsEntry upstream.Entry
|
|
|
|
for _, e := range entries {
|
|
|
|
space, err := e.UpstreamFs().GetFreeSpace()
|
|
|
|
if err != nil {
|
|
|
|
fs.LogPrintf(fs.LogLevelNotice, nil,
|
|
|
|
"Free Space is not supported for upstream %s, treating as infinite", e.UpstreamFs().Name())
|
|
|
|
}
|
|
|
|
if maxFreeSpace < space {
|
|
|
|
maxFreeSpace = space
|
|
|
|
mfsEntry = e
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return mfsEntry, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Action category policy, governing the modification of files and directories
|
|
|
|
func (p *EpMfs) Action(ctx context.Context, upstreams []*upstream.Fs, path string) ([]*upstream.Fs, error) {
|
|
|
|
upstreams, err := p.EpAll.Action(ctx, upstreams, path)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
u, err := p.mfs(upstreams)
|
|
|
|
return []*upstream.Fs{u}, err
|
|
|
|
}
|
|
|
|
|
2020-05-20 18:39:20 +08:00
|
|
|
// ActionEntries is ACTION category policy but receiving a set of candidate entries
|
2019-11-30 22:41:39 +08:00
|
|
|
func (p *EpMfs) ActionEntries(entries ...upstream.Entry) ([]upstream.Entry, error) {
|
|
|
|
entries, err := p.EpAll.ActionEntries(entries...)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
e, err := p.mfsEntries(entries)
|
|
|
|
return []upstream.Entry{e}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create category policy, governing the creation of files and directories
|
|
|
|
func (p *EpMfs) Create(ctx context.Context, upstreams []*upstream.Fs, path string) ([]*upstream.Fs, error) {
|
|
|
|
upstreams, err := p.EpAll.Create(ctx, upstreams, path)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
u, err := p.mfs(upstreams)
|
|
|
|
return []*upstream.Fs{u}, err
|
|
|
|
}
|
|
|
|
|
2020-05-20 18:39:20 +08:00
|
|
|
// CreateEntries is CREATE category policy but receiving a set of candidate entries
|
2019-11-30 22:41:39 +08:00
|
|
|
func (p *EpMfs) CreateEntries(entries ...upstream.Entry) ([]upstream.Entry, error) {
|
|
|
|
entries, err := p.EpAll.CreateEntries(entries...)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
e, err := p.mfsEntries(entries)
|
|
|
|
return []upstream.Entry{e}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Search category policy, governing the access to files and directories
|
|
|
|
func (p *EpMfs) Search(ctx context.Context, upstreams []*upstream.Fs, path string) (*upstream.Fs, error) {
|
|
|
|
if len(upstreams) == 0 {
|
|
|
|
return nil, fs.ErrorObjectNotFound
|
|
|
|
}
|
|
|
|
upstreams, err := p.epall(ctx, upstreams, path)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return p.mfs(upstreams)
|
|
|
|
}
|
|
|
|
|
Spelling fixes
Fix spelling of: above, already, anonymous, associated,
authentication, bandwidth, because, between, blocks, calculate,
candidates, cautious, changelog, cleaner, clipboard, command,
completely, concurrently, considered, constructs, corrupt, current,
daemon, dependencies, deprecated, directory, dispatcher, download,
eligible, ellipsis, encrypter, endpoint, entrieslist, essentially,
existing writers, existing, expires, filesystem, flushing, frequently,
hierarchy, however, implementation, implements, inaccurate,
individually, insensitive, longer, maximum, metadata, modified,
multipart, namedirfirst, nextcloud, obscured, opened, optional,
owncloud, pacific, passphrase, password, permanently, persimmon,
positive, potato, protocol, quota, receiving, recommends, referring,
requires, revisited, satisfied, satisfies, satisfy, semver,
serialized, session, storage, strategies, stringlist, successful,
supported, surprise, temporarily, temporary, transactions, unneeded,
update, uploads, wrapped
Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>
2020-10-09 08:17:24 +08:00
|
|
|
// SearchEntries is SEARCH category policy but receiving a set of candidate entries
|
2019-11-30 22:41:39 +08:00
|
|
|
func (p *EpMfs) SearchEntries(entries ...upstream.Entry) (upstream.Entry, error) {
|
|
|
|
if len(entries) == 0 {
|
|
|
|
return nil, fs.ErrorObjectNotFound
|
|
|
|
}
|
|
|
|
return p.mfsEntries(entries)
|
|
|
|
}
|