Files
crawlab/core/controllers/base_file.go
2024-11-18 16:48:09 +08:00

304 lines
6.1 KiB
Go

package controllers
import (
"errors"
"fmt"
log2 "github.com/apex/log"
"github.com/crawlab-team/crawlab/core/fs"
"github.com/crawlab-team/crawlab/core/interfaces"
"github.com/crawlab-team/crawlab/core/utils"
"github.com/gin-gonic/gin"
"io"
"os"
"path/filepath"
"sync"
)
func GetBaseFileListDir(rootPath string, c *gin.Context) {
path := c.Query("path")
fsSvc, err := getBaseFileFsSvc(rootPath)
if err != nil {
HandleErrorBadRequest(c, err)
return
}
files, err := fsSvc.List(path)
if err != nil {
if !errors.Is(err, os.ErrNotExist) {
HandleErrorInternalServerError(c, err)
return
}
}
HandleSuccessWithData(c, files)
}
func GetBaseFileFile(rootPath string, c *gin.Context) {
path := c.Query("path")
fsSvc, err := getBaseFileFsSvc(rootPath)
if err != nil {
HandleErrorBadRequest(c, err)
return
}
data, err := fsSvc.GetFile(path)
if err != nil {
HandleErrorInternalServerError(c, err)
return
}
HandleSuccessWithData(c, string(data))
}
func GetBaseFileFileInfo(rootPath string, c *gin.Context) {
path := c.Query("path")
fsSvc, err := getBaseFileFsSvc(rootPath)
if err != nil {
HandleErrorBadRequest(c, err)
return
}
info, err := fsSvc.GetFileInfo(path)
if err != nil {
HandleErrorInternalServerError(c, err)
return
}
HandleSuccessWithData(c, info)
}
func PostBaseFileSaveFile(rootPath string, c *gin.Context) {
fsSvc, err := getBaseFileFsSvc(rootPath)
if err != nil {
HandleErrorInternalServerError(c, err)
return
}
if c.GetHeader("Content-Type") == "application/json" {
var payload struct {
Path string `json:"path"`
Data string `json:"data"`
}
if err := c.ShouldBindJSON(&payload); err != nil {
HandleErrorBadRequest(c, err)
return
}
if err := fsSvc.Save(payload.Path, []byte(payload.Data)); err != nil {
HandleErrorInternalServerError(c, err)
return
}
} else {
path, ok := c.GetPostForm("path")
if !ok {
HandleErrorBadRequest(c, errors.New("missing required field 'path'"))
return
}
file, err := c.FormFile("file")
if err != nil {
HandleErrorBadRequest(c, err)
return
}
f, err := file.Open()
if err != nil {
HandleErrorBadRequest(c, err)
return
}
fileData, err := io.ReadAll(f)
if err != nil {
HandleErrorBadRequest(c, err)
return
}
if err := fsSvc.Save(path, fileData); err != nil {
HandleErrorInternalServerError(c, err)
return
}
}
HandleSuccess(c)
}
func PostBaseFileSaveFiles(rootPath string, c *gin.Context) {
fsSvc, err := getBaseFileFsSvc(rootPath)
if err != nil {
HandleErrorInternalServerError(c, err)
return
}
form, err := c.MultipartForm()
if err != nil {
HandleErrorBadRequest(c, err)
return
}
wg := sync.WaitGroup{}
wg.Add(len(form.File))
for path := range form.File {
go func(path string) {
file, err := c.FormFile(path)
if err != nil {
log2.Warnf("invalid file header: %s", path)
log2.Error(err.Error())
wg.Done()
return
}
f, err := file.Open()
if err != nil {
log2.Warnf("unable to open file: %s", path)
log2.Error(err.Error())
wg.Done()
return
}
fileData, err := io.ReadAll(f)
if err != nil {
log2.Warnf("unable to read file: %s", path)
log2.Error(err.Error())
wg.Done()
return
}
if err := fsSvc.Save(path, fileData); err != nil {
log2.Warnf("unable to save file: %s", path)
log2.Error(err.Error())
wg.Done()
return
}
wg.Done()
}(path)
}
wg.Wait()
HandleSuccess(c)
}
func PostBaseFileSaveDir(rootPath string, c *gin.Context) {
var payload struct {
Path string `json:"path"`
NewPath string `json:"new_path"`
Data string `json:"data"`
}
if err := c.ShouldBindJSON(&payload); err != nil {
HandleErrorBadRequest(c, err)
return
}
fsSvc, err := getBaseFileFsSvc(rootPath)
if err != nil {
HandleErrorBadRequest(c, err)
return
}
if err := fsSvc.CreateDir(payload.Path); err != nil {
HandleErrorInternalServerError(c, err)
return
}
HandleSuccess(c)
}
func PostBaseFileRenameFile(rootPath string, c *gin.Context) {
var payload struct {
Path string `json:"path"`
NewPath string `json:"new_path"`
}
if err := c.ShouldBindJSON(&payload); err != nil {
HandleErrorBadRequest(c, err)
return
}
fsSvc, err := getBaseFileFsSvc(rootPath)
if err != nil {
HandleErrorBadRequest(c, err)
return
}
if err := fsSvc.Rename(payload.Path, payload.NewPath); err != nil {
HandleErrorInternalServerError(c, err)
return
}
}
func DeleteBaseFileFile(rootPath string, c *gin.Context) {
var payload struct {
Path string `json:"path"`
}
if err := c.ShouldBindJSON(&payload); err != nil {
HandleErrorBadRequest(c, err)
return
}
if payload.Path == "~" {
payload.Path = "."
}
fsSvc, err := getBaseFileFsSvc(rootPath)
if err != nil {
HandleErrorBadRequest(c, err)
return
}
if err := fsSvc.Delete(payload.Path); err != nil {
HandleErrorInternalServerError(c, err)
return
}
_, err = fsSvc.GetFileInfo(".")
if err != nil {
_ = fsSvc.CreateDir("/")
}
HandleSuccess(c)
}
func PostBaseFileCopyFile(rootPath string, c *gin.Context) {
var payload struct {
Path string `json:"path"`
NewPath string `json:"new_path"`
}
if err := c.ShouldBindJSON(&payload); err != nil {
HandleErrorBadRequest(c, err)
return
}
fsSvc, err := getBaseFileFsSvc(rootPath)
if err != nil {
HandleErrorBadRequest(c, err)
return
}
if err := fsSvc.Copy(payload.Path, payload.NewPath); err != nil {
HandleErrorInternalServerError(c, err)
return
}
HandleSuccess(c)
}
func PostBaseFileExport(rootPath string, c *gin.Context) {
fsSvc, err := getBaseFileFsSvc(rootPath)
if err != nil {
HandleErrorBadRequest(c, err)
return
}
// zip file path
zipFilePath, err := fsSvc.Export()
if err != nil {
HandleErrorInternalServerError(c, err)
return
}
// download
c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s", zipFilePath))
c.File(zipFilePath)
}
func GetBaseFileFsSvc(rootPath string) (svc interfaces.FsService, err error) {
return getBaseFileFsSvc(rootPath)
}
func getBaseFileFsSvc(rootPath string) (svc interfaces.FsService, err error) {
workspacePath := utils.GetWorkspace()
fsSvc := fs.NewFsService(filepath.Join(workspacePath, rootPath))
return fsSvc, nil
}