add upload prepare hook

This commit is contained in:
xiaoyaofenfen 2022-04-20 14:14:18 +08:00
parent 70443455de
commit c1115dfcc7
9 changed files with 104 additions and 57 deletions

View File

@ -123,3 +123,8 @@ func WalkDir(dirPth, suffix string) (files []string, err error) {
func ConvertToUnixPathSeparator(p string) string {
return strings.Replace(p, "\\", "/", -1)
}
// ConvertToWindowsPathSeparator 将路径中的所有分隔符转换成windows格式
func ConvertToWindowsPathSeparator(p string) string {
return strings.Replace(p, "/", "\\", -1)
}

View File

@ -17,6 +17,7 @@ import (
"fmt"
"github.com/tickstep/aliyunpan-api/aliyunpan/apierror"
"github.com/tickstep/aliyunpan/cmder"
"github.com/tickstep/aliyunpan/internal/plugins"
"github.com/tickstep/aliyunpan/internal/utils"
"github.com/tickstep/library-go/requester/rio/speeds"
"io/ioutil"
@ -296,6 +297,8 @@ func RunUpload(localPaths []string, savePath string, opt *UploadOptions) {
statistic = &panupload.UploadStatistic{}
folderCreateMutex = &sync.Mutex{}
pluginManger = plugins.NewPluginManager(config.GetConfigDir())
)
executor.SetParallel(opt.AllParallel)
statistic.StartTimer() // 开始计时
@ -303,6 +306,9 @@ func RunUpload(localPaths []string, savePath string, opt *UploadOptions) {
// 全局速度统计
globalSpeedsStat := &speeds.Speeds{}
// 获取当前插件
plugin, _ := pluginManger.GetPlugin()
// 遍历指定的文件并创建上传任务
for _, curPath := range localPaths {
var walkFunc filepath.WalkFunc
@ -345,6 +351,9 @@ func RunUpload(localPaths []string, savePath string, opt *UploadOptions) {
if err != nil {
return err
}
if os.PathSeparator == '\\' {
file = cmdutil.ConvertToWindowsPathSeparator(file)
}
// 是否排除上传
if isExcludeFile(file, opt) {
@ -401,6 +410,31 @@ func RunUpload(localPaths []string, savePath string, opt *UploadOptions) {
return filepath.SkipDir
}
// 插件回调
if !fi.IsDir() { // 针对文件上传前进行回调
pluginParam := &plugins.UploadFilePrepareParams{
LocalFilePath: file,
LocalFileName: fi.Name(),
LocalFileSize: fi.Size(),
LocalFileType: "file",
LocalFileUpdatedAt: fi.ModTime().Format("2006-01-02 15:04:05"),
DriveId: activeUser.ActiveDriveId,
DriveFilePath: strings.TrimPrefix(strings.TrimPrefix(subSavePath, savePath), "/"),
}
if uploadFilePrepareResult, er := plugin.UploadFilePrepareCallback(plugins.GetContext(activeUser), pluginParam); er == nil && uploadFilePrepareResult != nil {
if strings.Compare("yes", uploadFilePrepareResult.UploadApproved) != 0 {
// skip upload this file
fmt.Printf("插件禁止该文件上传: %s\n", file)
return filepath.SkipDir
}
if uploadFilePrepareResult.DriveFilePath != "" {
targetSavePanRelativePath := strings.TrimPrefix(uploadFilePrepareResult.DriveFilePath, "/")
subSavePath = path.Clean(savePath + aliyunpan.PathSeparator + targetSavePanRelativePath)
fmt.Printf("插件修改文件网盘保存路径为: %s\n", subSavePath)
}
}
}
taskinfo := executor.Append(&panupload.UploadTaskUnit{
LocalFileChecksum: localfile.NewLocalFileEntity(file),
SavePath: subSavePath,

View File

@ -1,4 +1,4 @@
package plugin
package plugins
type (
IdlePlugin struct {

View File

@ -1,4 +1,4 @@
package plugin
package plugins
import (
"fmt"
@ -11,15 +11,13 @@ type (
JsPlugin struct {
Name string
vm *goja.Runtime
logger *logger.CmdVerbose
}
)
func NewJsPlugin(log *logger.CmdVerbose) *JsPlugin {
func NewJsPlugin() *JsPlugin {
return &JsPlugin{
Name: "JsPlugin",
vm: nil,
logger: log,
}
}
@ -55,22 +53,24 @@ func (js *JsPlugin) Start() error {
func (js *JsPlugin) LoadScript(script string) error {
_, err := js.vm.RunString(script)
if err != nil {
fmt.Println("JS代码有问题")
logger.Verboseln("JS代码有问题")
return err
}
return nil
}
// UploadFilePrepareCallback 上传文件前的回调函数
func (js *JsPlugin) UploadFilePrepareCallback(context *Context, params *UploadFilePrepareParams) (*UploadFilePrepareResult, error) {
var fn func(*Context, *UploadFilePrepareParams) (*UploadFilePrepareResult, error)
err := js.vm.ExportTo(js.vm.Get("uploadFilePrepareCallback"), &fn)
if err != nil {
fmt.Println("Js函数映射到 Go 函数失败!")
logger.Verboseln("Js函数映射到 Go 函数失败!")
return nil, nil
}
r, er := fn(context, params)
if er != nil {
fmt.Println(er)
logger.Verboseln(er)
return nil, er
}
return r, nil
}

View File

@ -11,7 +11,7 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package plugin
package plugins
type (
// Context 插件回调函数上下文信息
@ -28,7 +28,7 @@ type (
UploadFilePrepareParams struct {
LocalFilePath string `json:"localFilePath"`
LocalFileName string `json:"localFileName"`
LocalFileSize int `json:"localFileSize"`
LocalFileSize int64 `json:"localFileSize"`
LocalFileType string `json:"localFileType"`
LocalFileUpdatedAt string `json:"localFileUpdatedAt"`
DriveId string `json:"driveId"`

View File

@ -1,4 +1,4 @@
package plugin
package plugins
import (
"fmt"
@ -14,14 +14,23 @@ import (
type (
PluginManager struct {
PluginPath string
log *logger.CmdVerbose
}
)
func NewPluginManager() *PluginManager {
func GetContext(user *config.PanUser) *Context {
return &Context{
AppName: "aliyunpan",
Version: config.AppVersion,
UserId: user.UserId,
Nickname: user.Nickname,
FileDriveId: user.DriveList.GetFileDriveId(),
AlbumDriveId: user.DriveList.GetFileDriveId(),
}
}
func NewPluginManager(pluginDir string) *PluginManager {
return &PluginManager{
PluginPath: "",
log: logger.New("PLUGIN", config.EnvVerbose),
PluginPath: pluginDir,
}
}
@ -35,11 +44,11 @@ func (p *PluginManager) SetPluginPath(pluginPath string) error {
}
func (p *PluginManager) GetPlugin() (Plugin, error) {
// js plugin folder
// only support js plugin right now
// js plugins folder
// only support js plugins right now
jsPluginPath := path.Clean(p.PluginPath + string(os.PathSeparator) + "js")
if fi, err := os.Stat(jsPluginPath); err == nil && fi.IsDir() {
jsPlugin := NewJsPlugin(p.log)
jsPlugin := NewJsPlugin()
if jsPlugin.Start() != nil {
logger.Verbosef("初始化JS脚本错误\n")
return interface{}(NewIdlePlugin()).(Plugin), nil
@ -70,6 +79,6 @@ func (p *PluginManager) GetPlugin() (Plugin, error) {
}
}
// default idle plugin
// default idle plugins
return interface{}(NewIdlePlugin()).(Plugin), nil
}

View File

@ -1,4 +1,4 @@
package plugin
package plugins
import (
"fmt"
@ -6,8 +6,7 @@ import (
)
func TestPlugin(t *testing.T) {
pluginManager := NewPluginManager()
pluginManager.SetPluginPath("D:\\smb\\feny\\goprojects\\dev")
pluginManager := NewPluginManager("D:\\smb\\feny\\goprojects\\dev")
plugin, err := pluginManager.GetPlugin()
if err != nil {
fmt.Println(err)

View File

@ -1,4 +1,4 @@
package plugin
package plugins
import (
"github.com/tickstep/library-go/logger"

View File

@ -28,7 +28,7 @@ type Config struct {
LogFormat string
}
// ServeHTTP determines if the request is for this plugin, and if all prerequisites are met.
// ServeHTTP determines if the request is for this plugins, and if all prerequisites are met.
func (c *Config) ServeHTTP(w http.ResponseWriter, r *http.Request) {
u := c.User
requestOrigin := r.Header.Get("Origin")
@ -97,7 +97,7 @@ func (c *Config) ServeHTTP(w http.ResponseWriter, r *http.Request) {
} else {
// Even if Auth is disabled, we might want to get
// the user from the Basic Auth header. Useful for Caddy
// plugin implementation.
// plugins implementation.
username, _, ok := r.BasicAuth()
if ok {
if user, ok := c.Users[username]; ok {