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