mirror of
				https://github.com/cloudreve/cloudreve.git
				synced 2025-11-01 00:57:15 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			172 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			172 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package manager
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"io"
 | |
| 	"time"
 | |
| 
 | |
| 	"github.com/cloudreve/Cloudreve/v4/application/dependency"
 | |
| 	"github.com/cloudreve/Cloudreve/v4/ent"
 | |
| 	"github.com/cloudreve/Cloudreve/v4/inventory"
 | |
| 	"github.com/cloudreve/Cloudreve/v4/inventory/types"
 | |
| 	"github.com/cloudreve/Cloudreve/v4/pkg/auth"
 | |
| 	"github.com/cloudreve/Cloudreve/v4/pkg/cache"
 | |
| 	"github.com/cloudreve/Cloudreve/v4/pkg/conf"
 | |
| 	"github.com/cloudreve/Cloudreve/v4/pkg/filemanager/driver"
 | |
| 	"github.com/cloudreve/Cloudreve/v4/pkg/filemanager/fs"
 | |
| 	"github.com/cloudreve/Cloudreve/v4/pkg/filemanager/fs/dbfs"
 | |
| 	"github.com/cloudreve/Cloudreve/v4/pkg/hashid"
 | |
| 	"github.com/cloudreve/Cloudreve/v4/pkg/logging"
 | |
| 	"github.com/cloudreve/Cloudreve/v4/pkg/serializer"
 | |
| 	"github.com/cloudreve/Cloudreve/v4/pkg/setting"
 | |
| )
 | |
| 
 | |
| var (
 | |
| 	ErrUnknownPolicyType = serializer.NewError(serializer.CodeInternalSetting, "Unknown policy type", nil)
 | |
| )
 | |
| 
 | |
| const (
 | |
| 	UploadSessionCachePrefix = "callback_"
 | |
| 	// Ctx key for upload session
 | |
| 	UploadSessionCtx = "uploadSession"
 | |
| )
 | |
| 
 | |
| type (
 | |
| 	FileOperation interface {
 | |
| 		// Get gets file object by given path
 | |
| 		Get(ctx context.Context, path *fs.URI, opts ...fs.Option) (fs.File, error)
 | |
| 		// List lists files under given path
 | |
| 		List(ctx context.Context, path *fs.URI, args *ListArgs) (fs.File, *fs.ListFileResult, error)
 | |
| 		// Create creates a file or directory
 | |
| 		Create(ctx context.Context, path *fs.URI, fileType types.FileType, opt ...fs.Option) (fs.File, error)
 | |
| 		// Rename renames a file or directory
 | |
| 		Rename(ctx context.Context, path *fs.URI, newName string) (fs.File, error)
 | |
| 		// Delete deletes a group of file or directory. UnlinkOnly indicates whether to delete file record in DB only.
 | |
| 		Delete(ctx context.Context, path []*fs.URI, opts ...fs.Option) error
 | |
| 		// Restore restores a group of files
 | |
| 		Restore(ctx context.Context, path ...*fs.URI) error
 | |
| 		// MoveOrCopy moves or copies a group of files
 | |
| 		MoveOrCopy(ctx context.Context, src []*fs.URI, dst *fs.URI, isCopy bool) error
 | |
| 		// Update puts file content. If given file does not exist, it will create a new one.
 | |
| 		Update(ctx context.Context, req *fs.UploadRequest, opts ...fs.Option) (fs.File, error)
 | |
| 		// Walk walks through given path
 | |
| 		Walk(ctx context.Context, path *fs.URI, depth int, f fs.WalkFunc, opts ...fs.Option) error
 | |
| 		// UpsertMedata update or insert metadata of given file
 | |
| 		PatchMedata(ctx context.Context, path []*fs.URI, data ...fs.MetadataPatch) error
 | |
| 		// CreateViewerSession creates a viewer session for given file
 | |
| 		CreateViewerSession(ctx context.Context, uri *fs.URI, version string, viewer *setting.Viewer) (*ViewerSession, error)
 | |
| 	}
 | |
| 
 | |
| 	FsManagement interface {
 | |
| 		// SharedAddressTranslation translates shared symbolic address to real address. If path does not exist,
 | |
| 		// most recent existing parent directory will be returned.
 | |
| 		SharedAddressTranslation(ctx context.Context, path *fs.URI, opts ...fs.Option) (fs.File, *fs.URI, error)
 | |
| 		// Capacity gets capacity of current file system
 | |
| 		Capacity(ctx context.Context) (*fs.Capacity, error)
 | |
| 		// CheckIfCapacityExceeded checks if given user's capacity exceeded, and send notification email
 | |
| 		CheckIfCapacityExceeded(ctx context.Context) error
 | |
| 		// LocalDriver gets local driver for operating local files.
 | |
| 		LocalDriver(policy *ent.StoragePolicy) driver.Handler
 | |
| 		// CastStoragePolicyOnSlave check if given storage policy need to be casted to another.
 | |
| 		// It is used on slave node, when local policy need to cast to remote policy;
 | |
| 		// Remote policy with same node ID can be casted to local policy.
 | |
| 		CastStoragePolicyOnSlave(ctx context.Context, policy *ent.StoragePolicy) *ent.StoragePolicy
 | |
| 		// GetStorageDriver gets storage driver for given policy
 | |
| 		GetStorageDriver(ctx context.Context, policy *ent.StoragePolicy) (driver.Handler, error)
 | |
| 	}
 | |
| 
 | |
| 	ShareManagement interface {
 | |
| 		// CreateShare creates a share link for given path
 | |
| 		CreateOrUpdateShare(ctx context.Context, path *fs.URI, args *CreateShareArgs) (*ent.Share, error)
 | |
| 	}
 | |
| 
 | |
| 	Archiver interface {
 | |
| 		CreateArchive(ctx context.Context, uris []*fs.URI, writer io.Writer, opts ...fs.Option) (int, error)
 | |
| 	}
 | |
| 
 | |
| 	FileManager interface {
 | |
| 		fs.LockSystem
 | |
| 		FileOperation
 | |
| 		EntityManagement
 | |
| 		UploadManagement
 | |
| 		FsManagement
 | |
| 		ShareManagement
 | |
| 		Archiver
 | |
| 
 | |
| 		// Recycle reset current FileManager object and put back to resource pool
 | |
| 		Recycle()
 | |
| 	}
 | |
| 
 | |
| 	// GetEntityUrlArgs single args to get entity url
 | |
| 	GetEntityUrlArgs struct {
 | |
| 		URI               *fs.URI
 | |
| 		PreferredEntityID string
 | |
| 	}
 | |
| 
 | |
| 	// CreateShareArgs args to create share link
 | |
| 	CreateShareArgs struct {
 | |
| 		ExistedShareID  int
 | |
| 		IsPrivate       bool
 | |
| 		RemainDownloads int
 | |
| 		Expire          *time.Time
 | |
| 	}
 | |
| )
 | |
| 
 | |
| type manager struct {
 | |
| 	user         *ent.User
 | |
| 	l            logging.Logger
 | |
| 	fs           fs.FileSystem
 | |
| 	settings     setting.Provider
 | |
| 	kv           cache.Driver
 | |
| 	config       conf.ConfigProvider
 | |
| 	stateless    bool
 | |
| 	auth         auth.Auth
 | |
| 	hasher       hashid.Encoder
 | |
| 	policyClient inventory.StoragePolicyClient
 | |
| 
 | |
| 	dep dependency.Dep
 | |
| }
 | |
| 
 | |
| func NewFileManager(dep dependency.Dep, u *ent.User) FileManager {
 | |
| 	config := dep.ConfigProvider()
 | |
| 	if config.System().Mode == conf.SlaveMode || u == nil {
 | |
| 		return newStatelessFileManager(dep)
 | |
| 	}
 | |
| 	return &manager{
 | |
| 		l:        dep.Logger(),
 | |
| 		user:     u,
 | |
| 		settings: dep.SettingProvider(),
 | |
| 		fs: dbfs.NewDatabaseFS(u, dep.FileClient(), dep.ShareClient(), dep.Logger(), dep.LockSystem(),
 | |
| 			dep.SettingProvider(), dep.StoragePolicyClient(), dep.HashIDEncoder(), dep.UserClient(), dep.KV(), dep.NavigatorStateKV()),
 | |
| 		kv:           dep.KV(),
 | |
| 		config:       config,
 | |
| 		auth:         dep.GeneralAuth(),
 | |
| 		hasher:       dep.HashIDEncoder(),
 | |
| 		policyClient: dep.StoragePolicyClient(),
 | |
| 		dep:          dep,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func newStatelessFileManager(dep dependency.Dep) FileManager {
 | |
| 	return &manager{
 | |
| 		l:         dep.Logger(),
 | |
| 		settings:  dep.SettingProvider(),
 | |
| 		kv:        dep.KV(),
 | |
| 		config:    dep.ConfigProvider(),
 | |
| 		stateless: true,
 | |
| 		auth:      dep.GeneralAuth(),
 | |
| 		dep:       dep,
 | |
| 		hasher:    dep.HashIDEncoder(),
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func (m *manager) Recycle() {
 | |
| 	if m.fs != nil {
 | |
| 		m.fs.Recycle()
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func newOption() *fs.FsOption {
 | |
| 	return &fs.FsOption{}
 | |
| }
 | 
