diff --git a/go.mod b/go.mod index 35f9947..c08ce79 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/gofiber/websocket/v2 v2.1.5 github.com/google/uuid v1.3.0 github.com/marcopeocchi/fazzoletti v0.0.0-20230308161120-c545580f79fa + golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc golang.org/x/sys v0.7.0 gopkg.in/yaml.v3 v3.0.1 ) diff --git a/go.sum b/go.sum index 74e695e..fef2991 100644 --- a/go.sum +++ b/go.sum @@ -76,6 +76,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc h1:mCRnTeVUjcrhlRmO0VK8a6k6Rrf6TF9htwo2pJVSjIU= +golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= diff --git a/server/rest/handlers.go b/server/rest/handlers.go new file mode 100644 index 0000000..5506382 --- /dev/null +++ b/server/rest/handlers.go @@ -0,0 +1,106 @@ +package rest + +import ( + "crypto/sha256" + "encoding/hex" + "io/fs" + "os" + "path/filepath" + "strings" + + "github.com/gofiber/fiber/v2" + "github.com/marcopeocchi/yt-dlp-web-ui/server/config" + "golang.org/x/exp/slices" +) + +type DirectoryEntry struct { + Name string `json:"name"` + Path string `json:"path"` + SHASum string `json:"shaSum"` +} + +func walkDir(root string) (*[]DirectoryEntry, error) { + files := []DirectoryEntry{} + + err := filepath.WalkDir(root, func(path string, d fs.DirEntry, err error) error { + if err != nil { + return err + } + if !d.IsDir() && !strings.HasPrefix(d.Name(), ".") { + h := sha256.New() + h.Write([]byte(path)) + + files = append(files, DirectoryEntry{ + Path: path, + Name: d.Name(), + SHASum: hex.EncodeToString(h.Sum(nil)), + }) + } + return nil + }) + + return &files, err +} + +func ListDownloaded(ctx *fiber.Ctx) error { + root := config.Instance().GetConfig().DownloadPath + + files, err := walkDir(root) + if err != nil { + return err + } + + return ctx.JSON(files) +} + +type DeleteRequest = DirectoryEntry + +func DeleteFile(ctx *fiber.Ctx) error { + req := new(DeleteRequest) + + err := ctx.BodyParser(req) + if err != nil { + return err + } + + root := config.Instance().GetConfig().DownloadPath + + files, err := walkDir(root) + if err != nil { + return err + } + + index := slices.IndexFunc(*files, func(e DirectoryEntry) bool { + return e.Path == req.Path && e.SHASum == req.SHASum + }) + + if index >= 0 { + err := os.Remove(req.Path) + if err != nil { + return err + } + } + + return ctx.JSON(index) +} + +type PlayRequest struct { + Path string +} + +func PlayFile(ctx *fiber.Ctx) error { + req := new(PlayRequest) + + err := ctx.BodyParser(req) + if err != nil { + return err + } + + root := config.Instance().GetConfig().DownloadPath + + if strings.Contains(filepath.Dir(req.Path), root) { + return ctx.SendFile(req.Path) + } + + return ctx.SendStatus(fiber.StatusUnauthorized) +} diff --git a/server/server.go b/server/server.go index 12b6897..047d509 100644 --- a/server/server.go +++ b/server/server.go @@ -12,6 +12,7 @@ import ( "github.com/gofiber/fiber/v2/middleware/cors" "github.com/gofiber/fiber/v2/middleware/filesystem" "github.com/gofiber/websocket/v2" + "github.com/marcopeocchi/yt-dlp-web-ui/server/rest" ) var db MemoryDB @@ -31,6 +32,10 @@ func RunBlocking(port int, frontend fs.FS) { return c.Redirect("/") }) + app.Get("/downloaded", rest.ListDownloaded) + app.Post("/delete", rest.DeleteFile) + app.Post("/play", rest.PlayFile) + // RPC handlers // websocket app.Get("/ws-rpc", websocket.New(func(c *websocket.Conn) {