135 lines
3.6 KiB
Go
135 lines
3.6 KiB
Go
package route
|
|
|
|
import (
|
|
"errors"
|
|
"leech/config"
|
|
"leech/html"
|
|
"leech/thumbnail"
|
|
"net/url"
|
|
"os"
|
|
"path"
|
|
"sort"
|
|
"strings"
|
|
|
|
"github.com/gofiber/fiber/v2"
|
|
)
|
|
|
|
func RecursivelyGetSize(completePath string) (int64, error) {
|
|
files, err := os.ReadDir(completePath)
|
|
if err != nil {
|
|
return -1, err
|
|
}
|
|
var sum int64
|
|
for _, f := range files {
|
|
dirEntryInfo, err := f.Info()
|
|
if err != nil {
|
|
return -1, err
|
|
}
|
|
dirEntrySize := dirEntryInfo.Size()
|
|
if f.IsDir() {
|
|
dirEntrySize, err = RecursivelyGetSize(path.Join(completePath, f.Name()))
|
|
if err != nil {
|
|
return -1, err
|
|
}
|
|
}
|
|
sum += dirEntrySize
|
|
}
|
|
return sum, nil
|
|
}
|
|
|
|
func HandleList(c *fiber.Ctx) error {
|
|
encodedReq := c.Path()[1:]
|
|
req, err := url.QueryUnescape(encodedReq)
|
|
if err != nil {
|
|
return c.Status(fiber.StatusInternalServerError).SendString(err.Error())
|
|
}
|
|
c.Set(fiber.HeaderContentType, fiber.MIMETextHTML)
|
|
if req == "" {
|
|
keys := make([]string, 0, len(config.Config.ServeDirs))
|
|
for k := range config.Config.ServeDirs {
|
|
keys = append(keys, k)
|
|
}
|
|
sort.Strings(keys)
|
|
|
|
entries := make([]html.Entry, 0, len(config.Config.ServeDirs))
|
|
for _, key := range keys {
|
|
dirEntrySize, err := RecursivelyGetSize(config.Config.ServeDirs[key])
|
|
if err != nil {
|
|
return c.Status(fiber.StatusInternalServerError).SendString(err.Error())
|
|
}
|
|
entries = append(entries, html.Entry{
|
|
Name: key,
|
|
Size: dirEntrySize,
|
|
IsDir: true,
|
|
})
|
|
}
|
|
|
|
return c.SendString(html.FileListPage(req, entries))
|
|
} else {
|
|
pathSlice := strings.Split(req, "/")
|
|
pathBase, ok := config.Config.ServeDirs[pathSlice[0]]
|
|
if ok {
|
|
pathSlice[0] = pathBase
|
|
completePath := path.Join(pathSlice...)
|
|
files, err := os.ReadDir(completePath)
|
|
if err != nil {
|
|
return c.Status(fiber.StatusInternalServerError).SendString(err.Error())
|
|
}
|
|
entries := []html.Entry{}
|
|
for _, f := range files {
|
|
dirEntryInfo, err := f.Info()
|
|
if err != nil {
|
|
return c.Status(fiber.StatusInternalServerError).SendString("Internal server error!")
|
|
}
|
|
dirEntrySize := dirEntryInfo.Size()
|
|
if f.IsDir() {
|
|
dirEntrySize, err = RecursivelyGetSize(path.Join(completePath, f.Name()))
|
|
if err != nil {
|
|
return c.Status(fiber.StatusInternalServerError).SendString(err.Error())
|
|
}
|
|
}
|
|
entries = append(entries, html.Entry{
|
|
Name: f.Name(),
|
|
Size: dirEntrySize,
|
|
IsDir: f.IsDir(),
|
|
})
|
|
}
|
|
return c.SendString(html.FileListPage(req, entries))
|
|
} else {
|
|
return c.Status(fiber.StatusNotFound).SendString("Sorry can't find that!")
|
|
}
|
|
}
|
|
}
|
|
|
|
func HandleThumb(c *fiber.Ctx) error {
|
|
encodedReq := c.Path()[1:]
|
|
req, err := url.QueryUnescape(encodedReq)
|
|
if err != nil {
|
|
return c.Status(fiber.StatusInternalServerError).SendString(err.Error())
|
|
}
|
|
c.Set(fiber.HeaderContentType, fiber.MIMETextHTML)
|
|
pathSlice := strings.Split(req, "/")
|
|
pathSlice = pathSlice[1:len(pathSlice)]
|
|
pathBase, ok := config.Config.ServeDirs[pathSlice[0]]
|
|
if ok {
|
|
pathSlice[0] = pathBase
|
|
completePath := path.Join(pathSlice...)
|
|
if file_info, err := os.Stat(completePath); err == nil {
|
|
if file_info.IsDir() {
|
|
return c.Status(fiber.StatusUnauthorized).SendString("Sorry that's a directory!")
|
|
}
|
|
thumbnail.GetThumbnail(c, completePath)
|
|
} else if errors.Is(err, os.ErrNotExist) {
|
|
return c.Status(fiber.StatusNotFound).SendString("Sorry can't find that!")
|
|
} else {
|
|
// Schrodinger: file may or may not exist. See err for details.
|
|
|
|
// Therefore, do *NOT* use !os.IsNotExist(err) to test for file existence
|
|
|
|
}
|
|
} else {
|
|
return c.Status(fiber.StatusNotFound).SendString("Sorry can't find that!")
|
|
}
|
|
return nil
|
|
}
|