budget-go/backend/controller/file/controller.go
2025-02-08 20:19:26 +01:00

202 lines
3.9 KiB
Go

package file
import (
"bytes"
"fmt"
"io"
"os"
"strings"
"github.com/labstack/echo/v4"
"gitnet.fr/deblan/budget/config"
"gitnet.fr/deblan/budget/database/model"
f "gitnet.fr/deblan/budget/file"
"gitnet.fr/deblan/budget/backend/controller/crud"
)
type Controller struct {
}
func New(e *echo.Echo) *Controller {
c := Controller{}
e.GET("/api/filemanager/files", c.List)
e.POST("/api/filemanager/file", c.CreateFile)
e.POST("/api/filemanager/directory", c.CreateDirectory)
e.GET("/api/filemanager/file/:id/:name", c.Download)
e.DELETE("/api/filemanager/file/:id", c.Delete)
return &c
}
func (ctrl *Controller) List(c echo.Context) error {
if nil == model.LoadSessionUser(c) {
return c.Redirect(302, "/login")
}
tree := f.GetTree("", config.Get().File.Path)
return c.JSON(200, tree)
}
func (ctrl *Controller) CreateFile(c echo.Context) error {
if nil == model.LoadSessionUser(c) {
return c.Redirect(302, "/login")
}
file, err := c.FormFile("file")
if err != nil {
return c.JSON(400, crud.Error{
Code: 400,
Message: err.Error(),
})
}
src, err := file.Open()
if err != nil {
return c.JSON(400, crud.Error{
Code: 400,
Message: err.Error(),
})
}
defer src.Close()
var buf bytes.Buffer
io.Copy(&buf, src)
output := searchDirectory(c.FormValue("path"), f.GetTree("", config.Get().File.Path))
if output != nil {
os.WriteFile(output.Path+"/"+file.Filename, buf.Bytes(), 0644)
return c.JSON(200, true)
}
return c.JSON(400, false)
}
func (ctrl *Controller) CreateDirectory(c echo.Context) error {
if nil == model.LoadSessionUser(c) {
return c.Redirect(302, "/login")
}
type body struct {
Directory string `json:"directory" validate:"required"`
Path string `json:"path" validate:"required"`
}
value := new(body)
if err := c.Bind(value); err != nil {
return c.JSON(400, crud.Error{
Code: 400,
Message: "Bad request",
})
}
fmt.Printf("%+v\n", value)
value.Directory = strings.ReplaceAll(value.Directory, "..", "")
value.Directory = strings.ReplaceAll(value.Directory, "/", "")
value.Directory = strings.ReplaceAll(value.Directory, "\\", "")
value.Directory = strings.TrimSpace(value.Directory)
fmt.Printf("%+v\n", value)
if err := c.Validate(value); err != nil {
return c.JSON(400, crud.Error{
Code: 400,
Message: err.Error(),
})
}
output := searchDirectory(value.Path, f.GetTree("", config.Get().File.Path))
if output != nil {
dir := strings.ReplaceAll(output.Path+"/"+value.Directory, "//", "/")
os.MkdirAll(dir, 0750)
return c.JSON(200, true)
}
return c.JSON(400, crud.Error{
Code: 400,
Message: "Bad request",
})
}
func (ctrl *Controller) Download(c echo.Context) error {
if nil == model.LoadSessionUser(c) {
return c.Redirect(302, "/login")
}
var file string
var contentType string
files := []f.File{}
f.GetFiles(&files, config.Get().File.Path)
for _, f := range files {
if f.Id == c.Param("id") {
file = f.Path
contentType = f.Type
}
}
if file == "" {
return c.JSON(404, "File not found")
}
content, _ := os.ReadFile(file)
return c.Blob(200, contentType, content)
}
func (ctrl *Controller) Delete(c echo.Context) error {
if nil == model.LoadSessionUser(c) {
return c.Redirect(302, "/login")
}
var file string
files := []f.File{}
directories := []f.Directory{}
f.GetFiles(&files, config.Get().File.Path)
f.GetDirectories(&directories, config.Get().File.Path)
for _, f := range files {
if f.Id == c.Param("id") {
file = f.Path
}
}
for _, f := range directories {
if f.Id == c.Param("id") {
file = f.Path
}
}
if file == "" {
return c.JSON(404, "File not found")
}
os.RemoveAll(file)
return c.JSON(200, nil)
}
func searchDirectory(id string, tree f.Tree) *f.Tree {
if tree.Id == id {
return &tree
}
for _, tree = range tree.Directories {
tr := searchDirectory(id, tree)
if tr != nil {
return tr
}
}
return nil
}