mirror of https://github.com/Xhofe/alist
🚧 native webdav write
parent
9c5627a382
commit
7dfe48339c
|
@ -4,7 +4,6 @@ import (
|
|||
"github.com/Xhofe/alist/model"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/go-resty/resty/v2"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
|
@ -49,7 +48,7 @@ type TokenResp struct {
|
|||
var driversMap = map[string]Driver{}
|
||||
|
||||
func RegisterDriver(driver Driver) {
|
||||
log.Infof("register driver: [%s]", driver.Config().Name)
|
||||
//log.Infof("register driver: [%s]", driver.Config().Name)
|
||||
driversMap[driver.Config().Name] = driver
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,73 @@
|
|||
package drivers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
)
|
||||
|
||||
// File copies a single file from src to dst
|
||||
func (driver *Native) CopyFile(src, dst string) error {
|
||||
var err error
|
||||
var srcfd *os.File
|
||||
var dstfd *os.File
|
||||
var srcinfo os.FileInfo
|
||||
|
||||
if srcfd, err = os.Open(src); err != nil {
|
||||
return err
|
||||
}
|
||||
defer srcfd.Close()
|
||||
|
||||
if dstfd, err = os.Create(dst); err != nil {
|
||||
return err
|
||||
}
|
||||
defer dstfd.Close()
|
||||
|
||||
if _, err = io.Copy(dstfd, srcfd); err != nil {
|
||||
return err
|
||||
}
|
||||
if srcinfo, err = os.Stat(src); err != nil {
|
||||
return err
|
||||
}
|
||||
return os.Chmod(dst, srcinfo.Mode())
|
||||
}
|
||||
|
||||
// Dir copies a whole directory recursively
|
||||
func (driver *Native) CopyDir(src string, dst string) error {
|
||||
var err error
|
||||
var fds []os.FileInfo
|
||||
var srcinfo os.FileInfo
|
||||
|
||||
if srcinfo, err = os.Stat(src); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = os.MkdirAll(dst, srcinfo.Mode()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if fds, err = ioutil.ReadDir(src); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, fd := range fds {
|
||||
srcfp := path.Join(src, fd.Name())
|
||||
dstfp := path.Join(dst, fd.Name())
|
||||
|
||||
if fd.IsDir() {
|
||||
if err = driver.CopyDir(srcfp, dstfp); err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
} else {
|
||||
if err = driver.CopyFile(srcfp, dstfp); err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
RegisterDriver(&Native{})
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"github.com/Xhofe/alist/utils"
|
||||
"github.com/gin-gonic/gin"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
@ -15,10 +16,9 @@ import (
|
|||
|
||||
type Native struct{}
|
||||
|
||||
|
||||
func (driver Native) Config() DriverConfig {
|
||||
return DriverConfig{
|
||||
Name: "Native",
|
||||
Name: "Native",
|
||||
OnlyProxy: true,
|
||||
}
|
||||
}
|
||||
|
@ -160,22 +160,70 @@ func (driver Native) Preview(path string, account *model.Account) (interface{},
|
|||
}
|
||||
|
||||
func (driver Native) MakeDir(path string, account *model.Account) error {
|
||||
return ErrNotImplement
|
||||
fullPath := filepath.Join(account.RootFolder, path)
|
||||
err := os.MkdirAll(fullPath, 0700)
|
||||
return err
|
||||
}
|
||||
|
||||
func (driver Native) Move(src string, dst string, account *model.Account) error {
|
||||
return ErrNotImplement
|
||||
fullSrc := filepath.Join(account.RootFolder, src)
|
||||
fullDst := filepath.Join(account.RootFolder, dst)
|
||||
return os.Rename(fullSrc, fullDst)
|
||||
}
|
||||
|
||||
func (driver Native) Copy(src string, dst string, account *model.Account) error {
|
||||
return ErrNotImplement
|
||||
fullSrc := filepath.Join(account.RootFolder, src)
|
||||
fullDst := filepath.Join(account.RootFolder, dst)
|
||||
srcFile, err := driver.File(src, account)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dstFile, err := driver.File(dst, account)
|
||||
if err == nil {
|
||||
if !dstFile.IsDir() {
|
||||
return ErrNotSupport
|
||||
}
|
||||
}
|
||||
if srcFile.IsDir() {
|
||||
return driver.CopyDir(fullSrc, fullDst)
|
||||
}
|
||||
return driver.CopyFile(fullSrc, fullDst)
|
||||
}
|
||||
|
||||
func (driver Native) Delete(path string, account *model.Account) error {
|
||||
return ErrNotImplement
|
||||
fullPath := filepath.Join(account.RootFolder, path)
|
||||
file, err := driver.File(path, account)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if file.IsDir() {
|
||||
return os.RemoveAll(fullPath)
|
||||
}
|
||||
return os.Remove(fullPath)
|
||||
}
|
||||
|
||||
func (driver Native) Upload(file *model.FileStream, account *model.Account) error {
|
||||
return ErrNotImplement
|
||||
fullPath := filepath.Join(account.RootFolder, file.Path, file.Name)
|
||||
_, err := driver.File(filepath.Join(file.Path,file.Name), account)
|
||||
if err == nil {
|
||||
// TODO overwrite?
|
||||
}
|
||||
basePath := filepath.Dir(fullPath)
|
||||
if !utils.Exists(basePath) {
|
||||
err := os.MkdirAll(basePath, 0744)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
out, err := os.Create(fullPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
_ = out.Close()
|
||||
}()
|
||||
_, err = io.Copy(out, file)
|
||||
return err
|
||||
}
|
||||
|
||||
var _ Driver = (*Native)(nil)
|
||||
|
|
|
@ -130,8 +130,19 @@ func (fs *FileSystem) Link(r *http.Request, rawPath string) (string, error) {
|
|||
return link, err
|
||||
}
|
||||
|
||||
func (fs *FileSystem) CreateDirectory(ctx context.Context, reqPath string) (interface{}, error) {
|
||||
return nil, nil
|
||||
func (fs *FileSystem) CreateDirectory(ctx context.Context, rawPath string) error {
|
||||
rawPath = utils.ParsePath(rawPath)
|
||||
if rawPath == "/" {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
if model.AccountsCount() > 1 && len(strings.Split(rawPath, "/")) < 2 {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
account, path_, driver, err := ParsePath(rawPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return driver.MakeDir(path_,account)
|
||||
}
|
||||
|
||||
func (fs *FileSystem) Upload(ctx context.Context, r *http.Request, rawPath string) error {
|
||||
|
|
|
@ -281,7 +281,8 @@ func (h *Handler) handlePut(w http.ResponseWriter, r *http.Request, fs *FileSyst
|
|||
return http.StatusMethodNotAllowed, err
|
||||
}
|
||||
|
||||
etag, err := findETag(ctx, fs, h.LockSystem, reqPath, nil)
|
||||
_, fi := isPathExist(ctx, fs, reqPath)
|
||||
etag, err := findETag(ctx, fs, h.LockSystem, reqPath, fi)
|
||||
if err != nil {
|
||||
return http.StatusInternalServerError, err
|
||||
}
|
||||
|
@ -311,7 +312,7 @@ func (h *Handler) handleMkcol(w http.ResponseWriter, r *http.Request, fs *FileSy
|
|||
// ctx = context.WithValue(ctx, fsctx.IgnoreDirectoryConflictCtx, true)
|
||||
//}
|
||||
}
|
||||
if _, err := fs.CreateDirectory(ctx, reqPath); err != nil {
|
||||
if err := fs.CreateDirectory(ctx, reqPath); err != nil {
|
||||
return http.StatusConflict, err
|
||||
}
|
||||
return http.StatusCreated, nil
|
||||
|
|
Loading…
Reference in New Issue