code refactoring

This commit is contained in:
2024-02-12 12:02:23 +01:00
parent cc06487b0a
commit 65b0c8bc0e
7 changed files with 51 additions and 32 deletions

View File

@@ -1,37 +1,33 @@
package internal package internal
type Node[T any] struct {
Value T
}
type Stack[T any] struct { type Stack[T any] struct {
Nodes []*Node[T] Elements []*T
count int count int
} }
func NewStack[T any]() *Stack[T] { func NewStack[T any]() *Stack[T] {
return &Stack[T]{ return &Stack[T]{
Nodes: make([]*Node[T], 10), Elements: make([]*T, 10),
} }
} }
func (s *Stack[T]) Push(val T) { func (s *Stack[T]) Push(val T) {
if s.count >= len(s.Nodes) { if s.count >= len(s.Elements) {
Nodes := make([]*Node[T], len(s.Nodes)*2) Elements := make([]*T, len(s.Elements)*2)
copy(Nodes, s.Nodes) copy(Elements, s.Elements)
s.Nodes = Nodes s.Elements = Elements
} }
s.Nodes[s.count] = &Node[T]{Value: val} s.Elements[s.count] = &val
s.count++ s.count++
} }
func (s *Stack[T]) Pop() *Node[T] { func (s *Stack[T]) Pop() *T {
if s.count == 0 { if s.count == 0 {
return nil return nil
} }
node := s.Nodes[s.count-1] Element := s.Elements[s.count-1]
s.count-- s.count--
return node return Element
} }
func (s *Stack[T]) IsEmpty() bool { func (s *Stack[T]) IsEmpty() bool {

View File

@@ -30,5 +30,6 @@ func ApplyRouter(db *sql.DB, mdb *internal.MemoryDB, mq *internal.MessageQueue)
r.Post("/template", h.AddTemplate()) r.Post("/template", h.AddTemplate())
r.Get("/template/all", h.GetTemplates()) r.Get("/template/all", h.GetTemplates())
r.Delete("/template/{id}", h.DeleteTemplate()) r.Delete("/template/{id}", h.DeleteTemplate())
r.Get("/tree", h.DirectoryTree())
} }
} }

View File

@@ -154,3 +154,22 @@ func (h *Handler) DeleteTemplate() http.HandlerFunc {
} }
} }
} }
func (h *Handler) DirectoryTree() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
w.Header().Set("Content-Type", "application/json")
tree, err := h.service.DirectoryTree(r.Context())
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
err = json.NewEncoder(w).Encode(tree)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
}

View File

@@ -9,6 +9,7 @@ import (
"github.com/google/uuid" "github.com/google/uuid"
"github.com/marcopeocchi/yt-dlp-web-ui/server/internal" "github.com/marcopeocchi/yt-dlp-web-ui/server/internal"
"github.com/marcopeocchi/yt-dlp-web-ui/server/sys"
) )
type Service struct { type Service struct {
@@ -118,3 +119,7 @@ func (s *Service) DeleteTemplate(ctx context.Context, id string) error {
return err return err
} }
func (s *Service) DirectoryTree(ctx context.Context) (*internal.Stack[sys.FSNode], error) {
return sys.DirectoryTree()
}

View File

@@ -140,7 +140,7 @@ func (s *Service) FreeSpace(args NoArgs, free *uint64) error {
} }
// Return a flattned tree of the download directory // Return a flattned tree of the download directory
func (s *Service) DirectoryTree(args NoArgs, tree *[]string) error { func (s *Service) DirectoryTree(args NoArgs, tree *internal.Stack[sys.FSNode]) error {
dfsTree, err := sys.DirectoryTree() dfsTree, err := sys.DirectoryTree()
if dfsTree != nil { if dfsTree != nil {
*tree = *dfsTree *tree = *dfsTree

View File

@@ -18,39 +18,35 @@ func FreeSpace() (uint64, error) {
return (stat.Bavail * uint64(stat.Bsize)), nil return (stat.Bavail * uint64(stat.Bsize)), nil
} }
type FSNode struct {
path string
children []FSNode
}
// Build a directory tree started from the specified path using DFS. // Build a directory tree started from the specified path using DFS.
// Then return the flattened tree represented as a list. // Then return the flattened tree represented as a list.
func DirectoryTree() (*[]string, error) { func DirectoryTree() (*internal.Stack[FSNode], error) {
type Node struct {
path string
children []Node
}
rootPath := config.Instance().DownloadPath rootPath := config.Instance().DownloadPath
stack := internal.NewStack[Node]() stack := internal.NewStack[FSNode]()
flattened := make([]string, 0)
stack.Push(Node{path: rootPath}) stack.Push(FSNode{path: rootPath})
flattened = append(flattened, rootPath)
for stack.IsNotEmpty() { for stack.IsNotEmpty() {
current := stack.Pop().Value current := stack.Pop()
children, err := os.ReadDir(current.path) children, err := os.ReadDir(current.path)
if err != nil { if err != nil {
return nil, err return nil, err
} }
for _, entry := range children { for _, entry := range children {
childPath := filepath.Join(current.path, entry.Name()) childPath := filepath.Join(current.path, entry.Name())
childNode := Node{path: childPath} childNode := FSNode{path: childPath}
if entry.IsDir() { if entry.IsDir() {
current.children = append(current.children, childNode) current.children = append(current.children, childNode)
stack.Push(childNode) stack.Push(childNode)
flattened = append(flattened, childNode.path)
} }
} }
} }
return &flattened, nil return stack, nil
} }

View File

@@ -1,11 +1,13 @@
import { tryCatch } from 'fp-ts/TaskEither' import { tryCatch } from 'fp-ts/TaskEither'
/**
* functional fetch(): composable as TaskEither
*/
export const ffetch = <T>(url: string, opt?: RequestInit) => tryCatch( export const ffetch = <T>(url: string, opt?: RequestInit) => tryCatch(
() => fetcher<T>(url, opt), () => fetcher<T>(url, opt),
(e) => `error while fetching: ${e}` (e) => `error while fetching: ${e}`
) )
const fetcher = async <T>(url: string, opt?: RequestInit) => { const fetcher = async <T>(url: string, opt?: RequestInit) => {
const jwt = localStorage.getItem('token') const jwt = localStorage.getItem('token')