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}