136 lines
2.4 KiB
Go
136 lines
2.4 KiB
Go
package rest
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"errors"
|
|
"io/fs"
|
|
"net/http"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/gofiber/fiber/v2"
|
|
"github.com/marcopeocchi/yt-dlp-web-ui/server/config"
|
|
)
|
|
|
|
type DirectoryEntry struct {
|
|
Name string `json:"name"`
|
|
Path string `json:"path"`
|
|
SHASum string `json:"shaSum"`
|
|
IsDirectory bool `json:"isDirectory"`
|
|
}
|
|
|
|
func isValidEntry(d fs.DirEntry) bool {
|
|
return !strings.HasPrefix(d.Name(), ".") &&
|
|
!strings.HasSuffix(d.Name(), ".part") &&
|
|
!strings.HasSuffix(d.Name(), ".ytdl")
|
|
}
|
|
|
|
func shaSumString(path string) string {
|
|
h := sha256.New()
|
|
h.Write([]byte(path))
|
|
return hex.EncodeToString(h.Sum(nil))
|
|
}
|
|
|
|
func walkDir(root string) (*[]DirectoryEntry, error) {
|
|
files := []DirectoryEntry{}
|
|
|
|
dirs, err := os.ReadDir(root)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
for _, d := range dirs {
|
|
if !isValidEntry(d) {
|
|
continue
|
|
}
|
|
|
|
path := filepath.Join(root, d.Name())
|
|
|
|
files = append(files, DirectoryEntry{
|
|
Path: path,
|
|
Name: d.Name(),
|
|
SHASum: shaSumString(path),
|
|
IsDirectory: d.IsDir(),
|
|
})
|
|
}
|
|
|
|
return &files, err
|
|
}
|
|
|
|
type ListRequest struct {
|
|
SubDir string `json:"subdir"`
|
|
}
|
|
|
|
func ListDownloaded(ctx *fiber.Ctx) error {
|
|
root := config.Instance().GetConfig().DownloadPath
|
|
req := new(ListRequest)
|
|
|
|
err := ctx.BodyParser(req)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
files, err := walkDir(filepath.Join(root, req.SubDir))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
ctx.Status(http.StatusOK)
|
|
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
|
|
}
|
|
|
|
sum := shaSumString(req.Path)
|
|
if sum != req.SHASum {
|
|
return errors.New("shasum mismatch")
|
|
}
|
|
|
|
err = os.Remove(req.Path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
ctx.Status(fiber.StatusOK)
|
|
return ctx.JSON("ok")
|
|
}
|
|
|
|
type PlayRequest struct {
|
|
Path string
|
|
}
|
|
|
|
func PlayFile(ctx *fiber.Ctx) error {
|
|
path := ctx.Query("path")
|
|
|
|
if path == "" {
|
|
return errors.New("inexistent path")
|
|
}
|
|
|
|
decoded, err := hex.DecodeString(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
root := config.Instance().GetConfig().DownloadPath
|
|
|
|
//TODO: further path / file validations
|
|
|
|
if strings.Contains(filepath.Dir(string(decoded)), root) {
|
|
ctx.SendStatus(fiber.StatusPartialContent)
|
|
return ctx.SendFile(string(decoded))
|
|
}
|
|
|
|
ctx.Status(fiber.StatusOK)
|
|
return ctx.SendStatus(fiber.StatusUnauthorized)
|
|
}
|