package filesystem import ( "io/fs" "net/url" "path" "strings" ) type ( Controller struct { repository Repository } DirectoryParam struct { Name string UrlEncodedPath string } FileParam struct { UrlEncodedPath string Info fs.FileInfo } Page struct { History []*DirectoryParam Files []*FileParam } ) func NewController(repository Repository) *Controller { return &Controller{ repository: repository, } } func getHistory(filepath string) []*DirectoryParam { var ( paths = strings.Split(filepath, "/") result = make([]*DirectoryParam, 0, len(paths)) acc = "" ) // add root folder result = append(result, &DirectoryParam{ Name: "...", UrlEncodedPath: "", }) if len(paths) == 1 && paths[0] == "" { return result } for _, p := range paths { acc = path.Join(acc, p) result = append(result, &DirectoryParam{ Name: p, UrlEncodedPath: url.QueryEscape(acc), }) } return result } func (self *Controller) GetPage(filepath string) (*Page, error) { decodedPath, err := url.QueryUnescape(filepath) if err != nil { return nil, err } files, err := self.repository.List(decodedPath) if err != nil { return nil, err } params := make([]*FileParam, 0, len(files)) for _, info := range files { fullPath := path.Join(decodedPath, info.Name()) scapedFullPath := url.QueryEscape(fullPath) params = append(params, &FileParam{ Info: info, UrlEncodedPath: scapedFullPath, }) } return &Page{ Files: params, History: getHistory(decodedPath), }, nil }