feat(url-tree): implement the Put interface to support adding links directly to the UrlTree on the web side (#8312)
* feat(url-tree)支持PUT * feat(url-tree) UrlTree更新时,需要将路径和内容分割 #8303 * fix: stdpath.Join call Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Andy Hsu <i@nn.ci> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
parent
f0b1aeaf8d
commit
88abb323cb
@ -243,7 +243,25 @@ func (d *Urls) PutURL(ctx context.Context, dstDir model.Obj, name, url string) (
|
||||
}
|
||||
|
||||
func (d *Urls) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
|
||||
return errs.UploadNotSupported
|
||||
if !d.Writable {
|
||||
return errs.PermissionDenied
|
||||
}
|
||||
d.mutex.Lock()
|
||||
defer d.mutex.Unlock()
|
||||
node := GetNodeFromRootByPath(d.root, dstDir.GetPath()) // parent
|
||||
if node == nil {
|
||||
return errs.ObjectNotFound
|
||||
}
|
||||
if node.isFile() {
|
||||
return errs.NotFolder
|
||||
}
|
||||
file, err := parseFileLine(stream.GetName(), d.HeadSize)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
node.Children = append(node.Children, file)
|
||||
d.updateStorage()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Urls) updateStorage() {
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
"github.com/alist-org/alist/v3/internal/driver"
|
||||
"github.com/alist-org/alist/v3/internal/errs"
|
||||
"github.com/alist-org/alist/v3/internal/model"
|
||||
"github.com/alist-org/alist/v3/internal/stream"
|
||||
"github.com/alist-org/alist/v3/pkg/generic_sync"
|
||||
"github.com/alist-org/alist/v3/pkg/singleflight"
|
||||
"github.com/alist-org/alist/v3/pkg/utils"
|
||||
@ -517,6 +518,12 @@ func Put(ctx context.Context, storage driver.Driver, dstDirPath string, file mod
|
||||
log.Errorf("failed to close file streamer, %v", err)
|
||||
}
|
||||
}()
|
||||
// UrlTree PUT
|
||||
if storage.GetStorage().Driver == "UrlTree" {
|
||||
var link string
|
||||
dstDirPath, link = urlTreeSplitLineFormPath(stdpath.Join(dstDirPath, file.GetName()))
|
||||
file = &stream.FileStream{Obj: &model.Object{Name: link}}
|
||||
}
|
||||
// if file exist and size = 0, delete it
|
||||
dstDirPath = utils.FixAndCleanPath(dstDirPath)
|
||||
dstPath := stdpath.Join(dstDirPath, file.GetName())
|
||||
|
@ -2,6 +2,7 @@ package op
|
||||
|
||||
import (
|
||||
"github.com/alist-org/alist/v3/internal/errs"
|
||||
stdpath "path"
|
||||
"strings"
|
||||
|
||||
"github.com/alist-org/alist/v3/internal/driver"
|
||||
@ -27,3 +28,30 @@ func GetStorageAndActualPath(rawPath string) (storage driver.Driver, actualPath
|
||||
actualPath = utils.FixAndCleanPath(strings.TrimPrefix(rawPath, mountPath))
|
||||
return
|
||||
}
|
||||
|
||||
// urlTreeSplitLineFormPath 分割path中分割真实路径和UrlTree定义字符串
|
||||
func urlTreeSplitLineFormPath(path string) (pp string, file string) {
|
||||
// url.PathUnescape 会移除 // ,手动加回去
|
||||
path = strings.Replace(path, "https:/", "https://", 1)
|
||||
path = strings.Replace(path, "http:/", "http://", 1)
|
||||
if strings.Contains(path, ":https:/") || strings.Contains(path, ":http:/") {
|
||||
// URL-Tree模式 /url_tree_drivr/file_name[:size[:time]]:https://example.com/file
|
||||
fPath := strings.SplitN(path, ":", 2)[0]
|
||||
pp, _ = stdpath.Split(fPath)
|
||||
file = path[len(pp):]
|
||||
} else if strings.Contains(path, "/https:/") || strings.Contains(path, "/http:/") {
|
||||
// URL-Tree模式 /url_tree_drivr/https://example.com/file
|
||||
index := strings.Index(path, "/http://")
|
||||
if index == -1 {
|
||||
index = strings.Index(path, "/https://")
|
||||
}
|
||||
pp = path[:index]
|
||||
file = path[index+1:]
|
||||
} else {
|
||||
pp, file = stdpath.Split(path)
|
||||
}
|
||||
if pp == "" {
|
||||
pp = "/"
|
||||
}
|
||||
return
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user