chore: 初始化 Cloudreve 源码仓库
This commit is contained in:
@@ -0,0 +1 @@
|
||||
package node
|
||||
@@ -0,0 +1,120 @@
|
||||
package node
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/cloudreve/Cloudreve/v4/application/dependency"
|
||||
"github.com/cloudreve/Cloudreve/v4/inventory"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/credmanager"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/filemanager/fs"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/filemanager/manager"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/serializer"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/util"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type SlaveNotificationService struct {
|
||||
Subject string `uri:"subject" binding:"required"`
|
||||
}
|
||||
|
||||
type (
|
||||
OauthCredentialParamCtx struct{}
|
||||
OauthCredentialService struct {
|
||||
ID string `uri:"id" binding:"required"`
|
||||
}
|
||||
)
|
||||
|
||||
// Get 获取主机Oauth策略的AccessToken
|
||||
func (s *OauthCredentialService) Get(c *gin.Context) (*credmanager.CredentialResponse, error) {
|
||||
dep := dependency.FromContext(c)
|
||||
credManager := dep.CredManager()
|
||||
|
||||
cred, err := credManager.Obtain(c, s.ID)
|
||||
if cred == nil || err != nil {
|
||||
return nil, serializer.NewError(serializer.CodeNotFound, "Credential not found", err)
|
||||
}
|
||||
|
||||
return &credmanager.CredentialResponse{
|
||||
Token: cred.String(),
|
||||
ExpireAt: cred.Expiry(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
type (
|
||||
StatelessPrepareUploadParamCtx struct{}
|
||||
)
|
||||
|
||||
func StatelessPrepareUpload(s *fs.StatelessPrepareUploadService, c *gin.Context) (*fs.StatelessPrepareUploadResponse, error) {
|
||||
dep := dependency.FromContext(c)
|
||||
userClient := dep.UserClient()
|
||||
user, err := userClient.GetLoginUserByID(c, s.UserID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctx := context.WithValue(c.Request.Context(), inventory.UserCtx{}, user)
|
||||
fm := manager.NewFileManager(dep, user)
|
||||
uploadSession, err := fm.PrepareUpload(ctx, s.UploadRequest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &fs.StatelessPrepareUploadResponse{
|
||||
Session: uploadSession,
|
||||
Req: s.UploadRequest,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type (
|
||||
StatelessCompleteUploadParamCtx struct{}
|
||||
)
|
||||
|
||||
func StatelessCompleteUpload(s *fs.StatelessCompleteUploadService, c *gin.Context) (fs.File, error) {
|
||||
dep := dependency.FromContext(c)
|
||||
userClient := dep.UserClient()
|
||||
user, err := userClient.GetLoginUserByID(c, s.UserID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
util.WithValue(c, inventory.UserCtx{}, user)
|
||||
fm := manager.NewFileManager(dep, user)
|
||||
return fm.CompleteUpload(c, s.UploadSession)
|
||||
}
|
||||
|
||||
type (
|
||||
StatelessOnUploadFailedParamCtx struct{}
|
||||
)
|
||||
|
||||
func StatelessOnUploadFailed(s *fs.StatelessOnUploadFailedService, c *gin.Context) error {
|
||||
dep := dependency.FromContext(c)
|
||||
userClient := dep.UserClient()
|
||||
user, err := userClient.GetLoginUserByID(c, s.UserID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
util.WithValue(c, inventory.UserCtx{}, user)
|
||||
fm := manager.NewFileManager(dep, user)
|
||||
fm.OnUploadFailed(c, s.UploadSession)
|
||||
return nil
|
||||
}
|
||||
|
||||
type StatelessCreateFileParamCtx struct{}
|
||||
|
||||
func StatelessCreateFile(s *fs.StatelessCreateFileService, c *gin.Context) error {
|
||||
dep := dependency.FromContext(c)
|
||||
userClient := dep.UserClient()
|
||||
user, err := userClient.GetLoginUserByID(c, s.UserID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
uri, err := fs.NewUriFromString(s.Path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
util.WithValue(c, inventory.UserCtx{}, user)
|
||||
fm := manager.NewFileManager(dep, user)
|
||||
_, err = fm.Create(c, uri, s.Type)
|
||||
return err
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
package node
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"github.com/cloudreve/Cloudreve/v4/application/dependency"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/task"
|
||||
"github.com/cloudreve/Cloudreve/v4/inventory/types"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/cluster"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/cluster/routes"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/filemanager/workflows"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/logging"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/queue"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/serializer"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type (
|
||||
CreateSlaveTaskParamCtx struct{}
|
||||
)
|
||||
|
||||
func CreateTaskInSlave(s *cluster.CreateSlaveTask, c *gin.Context) (int, error) {
|
||||
dep := dependency.FromContext(c)
|
||||
registry := dep.TaskRegistry()
|
||||
|
||||
props, err := slaveTaskPropsFromContext(c)
|
||||
if err != nil {
|
||||
return 0, serializer.NewError(serializer.CodeParamErr, "failed to get master props from header", err)
|
||||
}
|
||||
|
||||
var t queue.Task
|
||||
switch s.Type {
|
||||
case queue.SlaveUploadTaskType:
|
||||
t = workflows.NewSlaveUploadTask(c, props, registry.NextID(), s.State)
|
||||
case queue.SlaveCreateArchiveTaskType:
|
||||
t = workflows.NewSlaveCreateArchiveTask(c, props, registry.NextID(), s.State)
|
||||
case queue.SlaveExtractArchiveType:
|
||||
t = workflows.NewSlaveExtractArchiveTask(c, props, registry.NextID(), s.State)
|
||||
default:
|
||||
return 0, serializer.NewError(serializer.CodeParamErr, "type not supported", nil)
|
||||
}
|
||||
|
||||
if err := dep.SlaveQueue(c).QueueTask(c, t); err != nil {
|
||||
return 0, serializer.NewError(serializer.CodeInternalSetting, "failed to queue task", err)
|
||||
}
|
||||
|
||||
registry.Set(t.ID(), t)
|
||||
return t.ID(), nil
|
||||
}
|
||||
|
||||
type (
|
||||
GetSlaveTaskParamCtx struct{}
|
||||
GetSlaveTaskService struct {
|
||||
ID int `uri:"id" binding:"required"`
|
||||
}
|
||||
)
|
||||
|
||||
func (s *GetSlaveTaskService) Get(c *gin.Context) (*cluster.SlaveTaskSummary, error) {
|
||||
dep := dependency.FromContext(c)
|
||||
registry := dep.TaskRegistry()
|
||||
|
||||
t, ok := registry.Get(s.ID)
|
||||
if !ok {
|
||||
return nil, serializer.NewError(serializer.CodeNotFound, "task not found", nil)
|
||||
}
|
||||
status := t.Status()
|
||||
_, clearOnComplete := c.GetQuery(routes.SlaveClearTaskRegistryQuery)
|
||||
if clearOnComplete && status == task.StatusCompleted ||
|
||||
status == task.StatusError ||
|
||||
status == task.StatusCanceled {
|
||||
registry.Delete(s.ID)
|
||||
}
|
||||
|
||||
res := &cluster.SlaveTaskSummary{
|
||||
Status: status,
|
||||
PrivateState: t.State(),
|
||||
Progress: t.Progress(c),
|
||||
}
|
||||
err := t.Error()
|
||||
if err != nil {
|
||||
res.Error = err.Error()
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func slaveTaskPropsFromContext(ctx context.Context) (*types.SlaveTaskProps, error) {
|
||||
nodeIdStr, ok := ctx.Value(cluster.SlaveNodeIDCtx{}).(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("failed to get node ID from context")
|
||||
}
|
||||
|
||||
nodeId, err := strconv.Atoi(nodeIdStr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to convert node ID to int: %w", err)
|
||||
}
|
||||
|
||||
masterSiteUrl := cluster.MasterSiteUrlFromContext(ctx)
|
||||
if masterSiteUrl == "" {
|
||||
return nil, fmt.Errorf("failed to get master site URL from context")
|
||||
}
|
||||
|
||||
masterSiteVersion, ok := ctx.Value(cluster.MasterSiteVersionCtx{}).(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("failed to get master site version from context")
|
||||
}
|
||||
|
||||
masterSiteId, ok := ctx.Value(cluster.MasterSiteIDCtx{}).(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("failed to convert master site ID to int: %w", err)
|
||||
}
|
||||
|
||||
props := &types.SlaveTaskProps{
|
||||
NodeID: nodeId,
|
||||
MasterSiteID: masterSiteId,
|
||||
MasterSiteURl: masterSiteUrl,
|
||||
MasterSiteVersion: masterSiteVersion,
|
||||
}
|
||||
|
||||
return props, nil
|
||||
}
|
||||
|
||||
type (
|
||||
FolderCleanupParamCtx struct{}
|
||||
)
|
||||
|
||||
func Cleanup(args *cluster.FolderCleanup, c *gin.Context) error {
|
||||
l := logging.FromContext(c)
|
||||
ae := serializer.NewAggregateError()
|
||||
for _, p := range args.Path {
|
||||
l.Info("Cleaning up folder %q", p)
|
||||
if err := os.RemoveAll(p); err != nil {
|
||||
l.Warning("Failed to clean up folder %q: %s", p, err)
|
||||
ae.Add(p, err)
|
||||
}
|
||||
}
|
||||
|
||||
return ae.Aggregate()
|
||||
}
|
||||
|
||||
type (
|
||||
CreateSlaveDownloadTaskParamCtx struct{}
|
||||
GetSlaveDownloadTaskParamCtx struct{}
|
||||
CancelSlaveDownloadTaskParamCtx struct{}
|
||||
SelectSlaveDownloadFilesParamCtx struct{}
|
||||
TestSlaveDownloadParamCtx struct{}
|
||||
)
|
||||
Reference in New Issue
Block a user