lens @ 3e435fc0d032a6cac0bdd15cdb138905ecdb7267

  1package service
  2
  3import (
  4	"context"
  5	"io/fs"
  6	"net/url"
  7	"path"
  8	"strings"
  9
 10	"git.sr.ht/~gabrielgio/img/pkg/database/repository"
 11	"git.sr.ht/~gabrielgio/img/pkg/list"
 12)
 13
 14type (
 15	FileSystemController struct {
 16		fsRepository   repository.FileSystemRepository
 17		userRepository repository.UserRepository
 18	}
 19
 20	DirectoryParam struct {
 21		Name           string
 22		UrlEncodedPath string
 23	}
 24
 25	FileParam struct {
 26		UrlEncodedPath string
 27		Info           fs.FileInfo
 28	}
 29
 30	Page struct {
 31		History []*DirectoryParam
 32		Files   []*FileParam
 33	}
 34)
 35
 36func NewFileSystemController(
 37	fsRepository repository.FileSystemRepository,
 38	userRepository repository.UserRepository,
 39) *FileSystemController {
 40	return &FileSystemController{
 41		fsRepository:   fsRepository,
 42		userRepository: userRepository,
 43	}
 44}
 45
 46func getHistory(filepath string) []*DirectoryParam {
 47	var (
 48		paths  = strings.Split(filepath, "/")
 49		result = make([]*DirectoryParam, 0, len(paths))
 50		acc    = ""
 51	)
 52
 53	// add root folder
 54	result = append(result, &DirectoryParam{
 55		Name:           "...",
 56		UrlEncodedPath: "",
 57	})
 58
 59	if len(paths) == 1 && paths[0] == "" {
 60		return result
 61	}
 62
 63	for _, p := range paths {
 64		acc = path.Join(acc, p)
 65		result = append(result, &DirectoryParam{
 66			Name:           p,
 67			UrlEncodedPath: url.QueryEscape(acc),
 68		})
 69	}
 70	return result
 71}
 72
 73func (self *FileSystemController) GetPage(ctx context.Context, userID uint, filepath string) (*Page, error) {
 74	userPath, err := self.userRepository.GetPathFromUserID(ctx, userID)
 75	if err != nil {
 76		return nil, err
 77	}
 78	decodedPath, err := url.QueryUnescape(filepath)
 79	if err != nil {
 80		return nil, err
 81	}
 82
 83	fullPath := path.Join(userPath, decodedPath)
 84	files, err := self.fsRepository.List(fullPath)
 85	if err != nil {
 86		return nil, err
 87	}
 88
 89	params := list.Map(files, func(info fs.FileInfo) *FileParam {
 90		fullPath := path.Join(decodedPath, info.Name())
 91		scapedFullPath := url.QueryEscape(fullPath)
 92		return &FileParam{
 93			Info:           info,
 94			UrlEncodedPath: scapedFullPath,
 95		}
 96	})
 97
 98	return &Page{
 99		Files:   params,
100		History: getHistory(decodedPath),
101	}, nil
102}