1package service
2
3import (
4 "context"
5 "io/fs"
6 "net/url"
7 "path"
8 "strings"
9 "syscall"
10
11 "git.sr.ht/~gabrielgio/img/pkg/database/repository"
12 "git.sr.ht/~gabrielgio/img/pkg/list"
13)
14
15type (
16 FileSystemController struct {
17 fsRepository repository.FileSystemRepository
18 userRepository repository.UserRepository
19 }
20
21 DirectoryParam struct {
22 Name string
23 UrlEncodedPath string
24 }
25
26 FileParam struct {
27 UrlEncodedPath string
28 Info fs.FileInfo
29 }
30
31 Page struct {
32 History []*DirectoryParam
33 Files []*FileParam
34 }
35)
36
37func (f *FileParam) GetUid() int {
38 if stat, ok := f.Info.Sys().(*syscall.Stat_t); ok {
39 return int(stat.Uid)
40 }
41 return 0
42}
43
44func (f *FileParam) GetGid() int {
45 if stat, ok := f.Info.Sys().(*syscall.Stat_t); ok {
46 return int(stat.Gid)
47 }
48 return 0
49}
50
51func NewFileSystemController(
52 fsRepository repository.FileSystemRepository,
53 userRepository repository.UserRepository,
54) *FileSystemController {
55 return &FileSystemController{
56 fsRepository: fsRepository,
57 userRepository: userRepository,
58 }
59}
60
61func getHistory(filepath string) []*DirectoryParam {
62 var (
63 paths = strings.Split(filepath, "/")
64 result = make([]*DirectoryParam, 0, len(paths))
65 acc = ""
66 )
67
68 // add root folder
69 result = append(result, &DirectoryParam{
70 Name: "...",
71 UrlEncodedPath: "",
72 })
73
74 if len(paths) == 1 && paths[0] == "" {
75 return result
76 }
77
78 for _, p := range paths {
79 acc = path.Join(acc, p)
80 result = append(result, &DirectoryParam{
81 Name: p,
82 UrlEncodedPath: url.QueryEscape(acc),
83 })
84 }
85 return result
86}
87
88func (f *FileSystemController) GetFullpath(ctx context.Context, userID uint, filepath string) (string, error) {
89 userPath, err := f.userRepository.GetPathFromUserID(ctx, userID)
90 if err != nil {
91 return "", err
92 }
93
94 return path.Join(userPath, filepath), nil
95}
96
97func (f *FileSystemController) IsFile(ctx context.Context, fullPath string) (bool, error) {
98 inf, err := f.fsRepository.Stat(fullPath)
99 if err != nil {
100 return false, err
101 }
102
103 return !inf.IsDir(), nil
104}
105
106func (f *FileSystemController) GetPage(ctx context.Context, filename string, fullPath string) (*Page, error) {
107 files, err := f.fsRepository.List(fullPath)
108 if err != nil {
109 return nil, err
110 }
111 params := list.Map(files, func(info fs.FileInfo) *FileParam {
112 fullPath := path.Join(filename, info.Name())
113 scapedFullPath := url.QueryEscape(fullPath)
114 return &FileParam{
115 Info: info,
116 UrlEncodedPath: scapedFullPath,
117 }
118 })
119
120 return &Page{
121 Files: params,
122 History: getHistory(filename),
123 }, nil
124}