lens @ 9ba05d26ee2382f3191e25ae7af5d462ba2a35e4

 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}