mirror of
https://github.com/get-drexa/drive.git
synced 2025-12-05 15:51:40 +00:00
feat: impl directory endpoints
This commit is contained in:
213
apps/backend/internal/catalog/directory.go
Normal file
213
apps/backend/internal/catalog/directory.go
Normal file
@@ -0,0 +1,213 @@
|
|||||||
|
package catalog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/get-drexa/drexa/internal/account"
|
||||||
|
"github.com/get-drexa/drexa/internal/httperr"
|
||||||
|
"github.com/get-drexa/drexa/internal/virtualfs"
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
DirItemKindDirectory = "directory"
|
||||||
|
DirItemKindFile = "file"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DirectoryInfo struct {
|
||||||
|
Kind string `json:"kind"`
|
||||||
|
ID string `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
CreatedAt time.Time `json:"createdAt"`
|
||||||
|
UpdatedAt time.Time `json:"updatedAt"`
|
||||||
|
DeletedAt *time.Time `json:"deletedAt,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type createDirectoryRequest struct {
|
||||||
|
ParentID string `json:"parentID"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *HTTPHandler) currentDirectoryMiddleware(c *fiber.Ctx) error {
|
||||||
|
account := account.CurrentAccount(c)
|
||||||
|
if account == nil {
|
||||||
|
return c.SendStatus(fiber.StatusUnauthorized)
|
||||||
|
}
|
||||||
|
|
||||||
|
directoryID := c.Params("directoryID")
|
||||||
|
node, err := h.vfs.FindNodeByPublicID(c.Context(), h.db, account.ID, directoryID)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, virtualfs.ErrNodeNotFound) {
|
||||||
|
return c.SendStatus(fiber.StatusNotFound)
|
||||||
|
}
|
||||||
|
return httperr.Internal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Locals("directory", node)
|
||||||
|
|
||||||
|
return c.Next()
|
||||||
|
}
|
||||||
|
|
||||||
|
func mustCurrentDirectoryNode(c *fiber.Ctx) *virtualfs.Node {
|
||||||
|
return c.Locals("directory").(*virtualfs.Node)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *HTTPHandler) createDirectory(c *fiber.Ctx) error {
|
||||||
|
account := account.CurrentAccount(c)
|
||||||
|
if account == nil {
|
||||||
|
return c.SendStatus(fiber.StatusUnauthorized)
|
||||||
|
}
|
||||||
|
|
||||||
|
req := new(createDirectoryRequest)
|
||||||
|
if err := c.BodyParser(req); err != nil {
|
||||||
|
return c.SendStatus(fiber.StatusBadRequest)
|
||||||
|
}
|
||||||
|
|
||||||
|
parent, err := h.vfs.FindNodeByPublicID(c.Context(), h.db, account.ID, req.ParentID)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, virtualfs.ErrNodeNotFound) {
|
||||||
|
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Parent not found"})
|
||||||
|
}
|
||||||
|
return httperr.Internal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if parent.Kind != virtualfs.NodeKindDirectory {
|
||||||
|
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Parent is not a directory"})
|
||||||
|
}
|
||||||
|
|
||||||
|
node, err := h.vfs.CreateDirectory(c.Context(), h.db, account.ID, parent.ID, req.Name)
|
||||||
|
if err != nil {
|
||||||
|
return httperr.Internal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(DirectoryInfo{
|
||||||
|
Kind: DirItemKindDirectory,
|
||||||
|
ID: node.PublicID,
|
||||||
|
Name: node.Name,
|
||||||
|
CreatedAt: node.CreatedAt,
|
||||||
|
UpdatedAt: node.UpdatedAt,
|
||||||
|
DeletedAt: node.DeletedAt,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *HTTPHandler) fetchDirectory(c *fiber.Ctx) error {
|
||||||
|
node := mustCurrentDirectoryNode(c)
|
||||||
|
i := DirectoryInfo{
|
||||||
|
Kind: DirItemKindDirectory,
|
||||||
|
ID: node.PublicID,
|
||||||
|
Name: node.Name,
|
||||||
|
CreatedAt: node.CreatedAt,
|
||||||
|
UpdatedAt: node.UpdatedAt,
|
||||||
|
DeletedAt: node.DeletedAt,
|
||||||
|
}
|
||||||
|
return c.JSON(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *HTTPHandler) listDirectory(c *fiber.Ctx) error {
|
||||||
|
node := mustCurrentDirectoryNode(c)
|
||||||
|
children, err := h.vfs.ListChildren(c.Context(), h.db, node)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, virtualfs.ErrNodeNotFound) {
|
||||||
|
return c.SendStatus(fiber.StatusNotFound)
|
||||||
|
}
|
||||||
|
return httperr.Internal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
items := make([]any, len(children))
|
||||||
|
for i, child := range children {
|
||||||
|
switch child.Kind {
|
||||||
|
case virtualfs.NodeKindDirectory:
|
||||||
|
items[i] = DirectoryInfo{
|
||||||
|
Kind: DirItemKindDirectory,
|
||||||
|
ID: child.PublicID,
|
||||||
|
Name: child.Name,
|
||||||
|
CreatedAt: child.CreatedAt,
|
||||||
|
UpdatedAt: child.UpdatedAt,
|
||||||
|
DeletedAt: child.DeletedAt,
|
||||||
|
}
|
||||||
|
case virtualfs.NodeKindFile:
|
||||||
|
items[i] = FileInfo{
|
||||||
|
Kind: DirItemKindFile,
|
||||||
|
ID: child.PublicID,
|
||||||
|
Name: child.Name,
|
||||||
|
Size: child.Size,
|
||||||
|
MimeType: child.MimeType,
|
||||||
|
CreatedAt: child.CreatedAt,
|
||||||
|
UpdatedAt: child.UpdatedAt,
|
||||||
|
DeletedAt: child.DeletedAt,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(items)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *HTTPHandler) patchDirectory(c *fiber.Ctx) error {
|
||||||
|
node := mustCurrentDirectoryNode(c)
|
||||||
|
|
||||||
|
patch := new(patchDirectoryRequest)
|
||||||
|
if err := c.BodyParser(patch); err != nil {
|
||||||
|
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid request"})
|
||||||
|
}
|
||||||
|
|
||||||
|
tx, err := h.db.BeginTx(c.Context(), nil)
|
||||||
|
if err != nil {
|
||||||
|
return httperr.Internal(err)
|
||||||
|
}
|
||||||
|
defer tx.Rollback()
|
||||||
|
|
||||||
|
if patch.Name != "" {
|
||||||
|
err := h.vfs.RenameNode(c.Context(), tx, node, patch.Name)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, virtualfs.ErrNodeNotFound) {
|
||||||
|
return c.SendStatus(fiber.StatusNotFound)
|
||||||
|
}
|
||||||
|
return httperr.Internal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = tx.Commit()
|
||||||
|
if err != nil {
|
||||||
|
return httperr.Internal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(DirectoryInfo{
|
||||||
|
Kind: DirItemKindDirectory,
|
||||||
|
ID: node.PublicID,
|
||||||
|
Name: node.Name,
|
||||||
|
CreatedAt: node.CreatedAt,
|
||||||
|
UpdatedAt: node.UpdatedAt,
|
||||||
|
DeletedAt: node.DeletedAt,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *HTTPHandler) deleteDirectory(c *fiber.Ctx) error {
|
||||||
|
node := mustCurrentDirectoryNode(c)
|
||||||
|
|
||||||
|
tx, err := h.db.BeginTx(c.Context(), nil)
|
||||||
|
if err != nil {
|
||||||
|
return httperr.Internal(err)
|
||||||
|
}
|
||||||
|
defer tx.Rollback()
|
||||||
|
|
||||||
|
shouldTrash := c.Query("trash") == "true"
|
||||||
|
if shouldTrash {
|
||||||
|
err = h.vfs.SoftDeleteNode(c.Context(), h.db, node)
|
||||||
|
if err != nil {
|
||||||
|
return httperr.Internal(err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err = h.vfs.PermanentlyDeleteNode(c.Context(), h.db, node)
|
||||||
|
if err != nil {
|
||||||
|
return httperr.Internal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = tx.Commit()
|
||||||
|
if err != nil {
|
||||||
|
return httperr.Internal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.SendStatus(fiber.StatusNoContent)
|
||||||
|
}
|
||||||
@@ -1,8 +1,18 @@
|
|||||||
package catalog
|
package catalog
|
||||||
|
|
||||||
import "time"
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/get-drexa/drexa/internal/account"
|
||||||
|
"github.com/get-drexa/drexa/internal/httperr"
|
||||||
|
"github.com/get-drexa/drexa/internal/virtualfs"
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
)
|
||||||
|
|
||||||
type FileInfo struct {
|
type FileInfo struct {
|
||||||
|
Kind string `json:"kind"`
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Size int64 `json:"size"`
|
Size int64 `json:"size"`
|
||||||
@@ -11,3 +21,151 @@ type FileInfo struct {
|
|||||||
UpdatedAt time.Time `json:"updatedAt"`
|
UpdatedAt time.Time `json:"updatedAt"`
|
||||||
DeletedAt *time.Time `json:"deletedAt,omitempty"`
|
DeletedAt *time.Time `json:"deletedAt,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func mustCurrentFileNode(c *fiber.Ctx) *virtualfs.Node {
|
||||||
|
return c.Locals("file").(*virtualfs.Node)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *HTTPHandler) currentFileMiddleware(c *fiber.Ctx) error {
|
||||||
|
account := account.CurrentAccount(c)
|
||||||
|
if account == nil {
|
||||||
|
return c.SendStatus(fiber.StatusUnauthorized)
|
||||||
|
}
|
||||||
|
|
||||||
|
fileID := c.Params("fileID")
|
||||||
|
node, err := h.vfs.FindNodeByPublicID(c.Context(), h.db, account.ID, fileID)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, virtualfs.ErrNodeNotFound) {
|
||||||
|
return c.SendStatus(fiber.StatusNotFound)
|
||||||
|
}
|
||||||
|
return httperr.Internal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Locals("file", node)
|
||||||
|
|
||||||
|
return c.Next()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *HTTPHandler) fetchFile(c *fiber.Ctx) error {
|
||||||
|
node := mustCurrentFileNode(c)
|
||||||
|
i := FileInfo{
|
||||||
|
Kind: DirItemKindFile,
|
||||||
|
ID: node.PublicID,
|
||||||
|
Name: node.Name,
|
||||||
|
Size: node.Size,
|
||||||
|
MimeType: node.MimeType,
|
||||||
|
CreatedAt: node.CreatedAt,
|
||||||
|
UpdatedAt: node.UpdatedAt,
|
||||||
|
DeletedAt: node.DeletedAt,
|
||||||
|
}
|
||||||
|
return c.JSON(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *HTTPHandler) downloadFile(c *fiber.Ctx) error {
|
||||||
|
node := mustCurrentFileNode(c)
|
||||||
|
|
||||||
|
content, err := h.vfs.ReadFile(c.Context(), h.db, node)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, virtualfs.ErrUnsupportedOperation) {
|
||||||
|
return c.SendStatus(fiber.StatusNotFound)
|
||||||
|
}
|
||||||
|
return httperr.Internal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if content.URL != "" {
|
||||||
|
return c.Redirect(content.URL, fiber.StatusTemporaryRedirect)
|
||||||
|
}
|
||||||
|
|
||||||
|
if content.Reader != nil {
|
||||||
|
if node.MimeType != "" {
|
||||||
|
c.Set("Content-Type", node.MimeType)
|
||||||
|
}
|
||||||
|
if content.Size > 0 {
|
||||||
|
return c.SendStream(content.Reader, int(content.Size))
|
||||||
|
}
|
||||||
|
return c.SendStream(content.Reader)
|
||||||
|
}
|
||||||
|
|
||||||
|
return httperr.Internal(errors.New("vfs returned neither a reader nor a URL"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *HTTPHandler) patchFile(c *fiber.Ctx) error {
|
||||||
|
node := mustCurrentFileNode(c)
|
||||||
|
|
||||||
|
patch := new(patchFileRequest)
|
||||||
|
if err := c.BodyParser(patch); err != nil {
|
||||||
|
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid request"})
|
||||||
|
}
|
||||||
|
|
||||||
|
tx, err := h.db.BeginTx(c.Context(), nil)
|
||||||
|
if err != nil {
|
||||||
|
return httperr.Internal(err)
|
||||||
|
}
|
||||||
|
defer tx.Rollback()
|
||||||
|
|
||||||
|
if patch.Name != "" {
|
||||||
|
err := h.vfs.RenameNode(c.Context(), tx, node, patch.Name)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, virtualfs.ErrNodeNotFound) {
|
||||||
|
return c.SendStatus(fiber.StatusNotFound)
|
||||||
|
}
|
||||||
|
return httperr.Internal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = tx.Commit()
|
||||||
|
if err != nil {
|
||||||
|
return httperr.Internal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("node deleted at: %v\n", node.DeletedAt)
|
||||||
|
|
||||||
|
return c.JSON(FileInfo{
|
||||||
|
ID: node.PublicID,
|
||||||
|
Name: node.Name,
|
||||||
|
Size: node.Size,
|
||||||
|
MimeType: node.MimeType,
|
||||||
|
CreatedAt: node.CreatedAt,
|
||||||
|
UpdatedAt: node.UpdatedAt,
|
||||||
|
DeletedAt: node.DeletedAt,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *HTTPHandler) deleteFile(c *fiber.Ctx) error {
|
||||||
|
node := mustCurrentFileNode(c)
|
||||||
|
|
||||||
|
tx, err := h.db.BeginTx(c.Context(), nil)
|
||||||
|
if err != nil {
|
||||||
|
return httperr.Internal(err)
|
||||||
|
}
|
||||||
|
defer tx.Rollback()
|
||||||
|
|
||||||
|
shouldTrash := c.Query("trash") == "true"
|
||||||
|
if shouldTrash {
|
||||||
|
err = h.vfs.SoftDeleteNode(c.Context(), tx, node)
|
||||||
|
if err != nil {
|
||||||
|
return httperr.Internal(err)
|
||||||
|
}
|
||||||
|
return c.JSON(FileInfo{
|
||||||
|
ID: node.PublicID,
|
||||||
|
Name: node.Name,
|
||||||
|
Size: node.Size,
|
||||||
|
MimeType: node.MimeType,
|
||||||
|
CreatedAt: node.CreatedAt,
|
||||||
|
UpdatedAt: node.UpdatedAt,
|
||||||
|
DeletedAt: node.DeletedAt,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
err = h.vfs.PermanentlyDeleteNode(c.Context(), tx, node)
|
||||||
|
if err != nil {
|
||||||
|
return httperr.Internal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = tx.Commit()
|
||||||
|
if err != nil {
|
||||||
|
return httperr.Internal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.SendStatus(fiber.StatusNoContent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
package catalog
|
package catalog
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/get-drexa/drexa/internal/account"
|
|
||||||
"github.com/get-drexa/drexa/internal/httperr"
|
|
||||||
"github.com/get-drexa/drexa/internal/virtualfs"
|
"github.com/get-drexa/drexa/internal/virtualfs"
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
"github.com/uptrace/bun"
|
"github.com/uptrace/bun"
|
||||||
@@ -20,165 +15,28 @@ type patchFileRequest struct {
|
|||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type patchDirectoryRequest struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
func NewHTTPHandler(vfs *virtualfs.VirtualFS, db *bun.DB) *HTTPHandler {
|
func NewHTTPHandler(vfs *virtualfs.VirtualFS, db *bun.DB) *HTTPHandler {
|
||||||
return &HTTPHandler{vfs: vfs, db: db}
|
return &HTTPHandler{vfs: vfs, db: db}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HTTPHandler) RegisterRoutes(api fiber.Router) {
|
func (h *HTTPHandler) RegisterRoutes(api fiber.Router) {
|
||||||
g := api.Group("/files/:fileID")
|
fg := api.Group("/files/:fileID")
|
||||||
g.Use(h.currentFileMiddleware)
|
fg.Use(h.currentFileMiddleware)
|
||||||
g.Get("/", h.fetchFile)
|
fg.Get("/", h.fetchFile)
|
||||||
g.Get("/content", h.downloadFile)
|
fg.Get("/content", h.downloadFile)
|
||||||
g.Patch("/", h.patchFile)
|
fg.Patch("/", h.patchFile)
|
||||||
g.Delete("/", h.deleteFile)
|
fg.Delete("/", h.deleteFile)
|
||||||
}
|
|
||||||
|
api.Post("/directories", h.createDirectory)
|
||||||
func mustCurrentFileNode(c *fiber.Ctx) *virtualfs.Node {
|
|
||||||
return c.Locals("file").(*virtualfs.Node)
|
dg := api.Group("/directories/:directoryID")
|
||||||
}
|
dg.Use(h.currentDirectoryMiddleware)
|
||||||
|
dg.Get("/", h.fetchDirectory)
|
||||||
func (h *HTTPHandler) currentFileMiddleware(c *fiber.Ctx) error {
|
dg.Get("/content", h.listDirectory)
|
||||||
account := account.CurrentAccount(c)
|
dg.Patch("/", h.patchDirectory)
|
||||||
if account == nil {
|
dg.Delete("/", h.deleteDirectory)
|
||||||
return c.SendStatus(fiber.StatusUnauthorized)
|
|
||||||
}
|
|
||||||
|
|
||||||
fileID := c.Params("fileID")
|
|
||||||
node, err := h.vfs.FindNodeByPublicID(c.Context(), h.db, account.ID, fileID)
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, virtualfs.ErrNodeNotFound) {
|
|
||||||
return c.SendStatus(fiber.StatusNotFound)
|
|
||||||
}
|
|
||||||
return httperr.Internal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
c.Locals("file", node)
|
|
||||||
|
|
||||||
return c.Next()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *HTTPHandler) fetchFile(c *fiber.Ctx) error {
|
|
||||||
node := mustCurrentFileNode(c)
|
|
||||||
i := FileInfo{
|
|
||||||
ID: node.PublicID,
|
|
||||||
Name: node.Name,
|
|
||||||
Size: node.Size,
|
|
||||||
MimeType: node.MimeType,
|
|
||||||
CreatedAt: node.CreatedAt,
|
|
||||||
UpdatedAt: node.UpdatedAt,
|
|
||||||
}
|
|
||||||
if node.DeletedAt != nil {
|
|
||||||
i.DeletedAt = node.DeletedAt
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.JSON(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *HTTPHandler) downloadFile(c *fiber.Ctx) error {
|
|
||||||
node := mustCurrentFileNode(c)
|
|
||||||
|
|
||||||
content, err := h.vfs.ReadFile(c.Context(), h.db, node)
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, virtualfs.ErrUnsupportedOperation) {
|
|
||||||
return c.SendStatus(fiber.StatusNotFound)
|
|
||||||
}
|
|
||||||
return httperr.Internal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if content.URL != "" {
|
|
||||||
return c.Redirect(content.URL, fiber.StatusTemporaryRedirect)
|
|
||||||
}
|
|
||||||
|
|
||||||
if content.Reader != nil {
|
|
||||||
if node.MimeType != "" {
|
|
||||||
c.Set("Content-Type", node.MimeType)
|
|
||||||
}
|
|
||||||
if content.Size > 0 {
|
|
||||||
return c.SendStream(content.Reader, int(content.Size))
|
|
||||||
}
|
|
||||||
return c.SendStream(content.Reader)
|
|
||||||
}
|
|
||||||
|
|
||||||
return httperr.Internal(errors.New("vfs returned neither a reader nor a URL"))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *HTTPHandler) patchFile(c *fiber.Ctx) error {
|
|
||||||
node := mustCurrentFileNode(c)
|
|
||||||
|
|
||||||
patch := new(patchFileRequest)
|
|
||||||
if err := c.BodyParser(patch); err != nil {
|
|
||||||
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid request"})
|
|
||||||
}
|
|
||||||
|
|
||||||
tx, err := h.db.BeginTx(c.Context(), nil)
|
|
||||||
if err != nil {
|
|
||||||
return httperr.Internal(err)
|
|
||||||
}
|
|
||||||
defer tx.Rollback()
|
|
||||||
|
|
||||||
if patch.Name != "" {
|
|
||||||
err := h.vfs.RenameNode(c.Context(), tx, node, patch.Name)
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, virtualfs.ErrNodeNotFound) {
|
|
||||||
return c.SendStatus(fiber.StatusNotFound)
|
|
||||||
}
|
|
||||||
return httperr.Internal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
err = tx.Commit()
|
|
||||||
if err != nil {
|
|
||||||
return httperr.Internal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("node deleted at: %v\n", node.DeletedAt)
|
|
||||||
|
|
||||||
return c.JSON(FileInfo{
|
|
||||||
ID: node.PublicID,
|
|
||||||
Name: node.Name,
|
|
||||||
Size: node.Size,
|
|
||||||
MimeType: node.MimeType,
|
|
||||||
CreatedAt: node.CreatedAt,
|
|
||||||
UpdatedAt: node.UpdatedAt,
|
|
||||||
DeletedAt: node.DeletedAt,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *HTTPHandler) deleteFile(c *fiber.Ctx) error {
|
|
||||||
node := mustCurrentFileNode(c)
|
|
||||||
|
|
||||||
tx, err := h.db.BeginTx(c.Context(), nil)
|
|
||||||
if err != nil {
|
|
||||||
return httperr.Internal(err)
|
|
||||||
}
|
|
||||||
defer tx.Rollback()
|
|
||||||
|
|
||||||
shouldTrash := c.Query("trash") == "true"
|
|
||||||
if shouldTrash {
|
|
||||||
err = h.vfs.SoftDeleteNode(c.Context(), tx, node)
|
|
||||||
if err != nil {
|
|
||||||
return httperr.Internal(err)
|
|
||||||
}
|
|
||||||
return c.JSON(FileInfo{
|
|
||||||
ID: node.PublicID,
|
|
||||||
Name: node.Name,
|
|
||||||
Size: node.Size,
|
|
||||||
MimeType: node.MimeType,
|
|
||||||
CreatedAt: node.CreatedAt,
|
|
||||||
UpdatedAt: node.UpdatedAt,
|
|
||||||
DeletedAt: node.DeletedAt,
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
err = h.vfs.PermanentlyDeleteNode(c.Context(), tx, node)
|
|
||||||
if err != nil {
|
|
||||||
return httperr.Internal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = tx.Commit()
|
|
||||||
if err != nil {
|
|
||||||
return httperr.Internal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.SendStatus(fiber.StatusNoContent)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user