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