github.com/goravel/framework@v1.13.9/filesystem/local.go (about) 1 package filesystem 2 3 import ( 4 "context" 5 "errors" 6 "fmt" 7 "os" 8 "path/filepath" 9 "strings" 10 "time" 11 12 "github.com/goravel/framework/contracts/config" 13 "github.com/goravel/framework/contracts/filesystem" 14 supportfile "github.com/goravel/framework/support/file" 15 "github.com/goravel/framework/support/str" 16 ) 17 18 type Local struct { 19 config config.Config 20 root string 21 url string 22 } 23 24 func NewLocal(config config.Config, disk string) (*Local, error) { 25 return &Local{ 26 config: config, 27 root: config.GetString(fmt.Sprintf("filesystems.disks.%s.root", disk)), 28 url: config.GetString(fmt.Sprintf("filesystems.disks.%s.url", disk)), 29 }, nil 30 } 31 32 func (r *Local) AllDirectories(path string) ([]string, error) { 33 var directories []string 34 err := filepath.Walk(r.fullPath(path), func(fullPath string, info os.FileInfo, err error) error { 35 if err != nil { 36 return err 37 } 38 if info.IsDir() { 39 realPath := strings.ReplaceAll(fullPath, r.fullPath(path), "") 40 realPath = strings.TrimPrefix(realPath, string(filepath.Separator)) 41 if realPath != "" { 42 directories = append(directories, realPath+string(filepath.Separator)) 43 } 44 } 45 46 return nil 47 }) 48 49 return directories, err 50 } 51 52 func (r *Local) AllFiles(path string) ([]string, error) { 53 var files []string 54 err := filepath.Walk(r.fullPath(path), func(fullPath string, info os.FileInfo, err error) error { 55 if err != nil { 56 return err 57 } 58 if !info.IsDir() { 59 files = append(files, strings.ReplaceAll(fullPath, r.fullPath(path)+string(filepath.Separator), "")) 60 } 61 62 return nil 63 }) 64 65 return files, err 66 } 67 68 func (r *Local) Copy(originFile, targetFile string) error { 69 content, err := r.Get(originFile) 70 if err != nil { 71 return err 72 } 73 74 return r.Put(targetFile, content) 75 } 76 77 func (r *Local) Delete(files ...string) error { 78 for _, file := range files { 79 fileInfo, err := os.Stat(r.fullPath(file)) 80 if err != nil { 81 return err 82 } 83 84 if fileInfo.IsDir() { 85 return errors.New("can't delete directory, please use DeleteDirectory") 86 } 87 } 88 89 for _, file := range files { 90 if err := os.Remove(r.fullPath(file)); err != nil { 91 return err 92 } 93 } 94 95 return nil 96 } 97 98 func (r *Local) DeleteDirectory(directory string) error { 99 return os.RemoveAll(r.fullPath(directory)) 100 } 101 102 func (r *Local) Directories(path string) ([]string, error) { 103 var directories []string 104 fileInfo, _ := os.ReadDir(r.fullPath(path)) 105 for _, f := range fileInfo { 106 if f.IsDir() { 107 directories = append(directories, f.Name()+string(filepath.Separator)) 108 } 109 } 110 111 return directories, nil 112 } 113 114 func (r *Local) Exists(file string) bool { 115 _, err := os.Stat(r.fullPath(file)) 116 if err != nil { 117 return os.IsExist(err) 118 } 119 return true 120 } 121 122 func (r *Local) Files(path string) ([]string, error) { 123 var files []string 124 fileInfo, err := os.ReadDir(r.fullPath(path)) 125 if err != nil { 126 return nil, err 127 } 128 for _, f := range fileInfo { 129 if !f.IsDir() { 130 files = append(files, f.Name()) 131 } 132 } 133 134 return files, nil 135 } 136 137 func (r *Local) Get(file string) (string, error) { 138 data, err := r.GetBytes(file) 139 140 return string(data), err 141 } 142 143 func (r *Local) GetBytes(file string) ([]byte, error) { 144 data, err := os.ReadFile(r.fullPath(file)) 145 if err != nil { 146 return nil, err 147 } 148 149 return data, nil 150 } 151 152 func (r *Local) LastModified(file string) (time.Time, error) { 153 return supportfile.LastModified(r.fullPath(file), r.config.GetString("app.timezone")) 154 } 155 156 func (r *Local) MakeDirectory(directory string) error { 157 return os.MkdirAll(filepath.Dir(r.fullPath(directory)+string(filepath.Separator)), os.ModePerm) 158 } 159 160 func (r *Local) MimeType(file string) (string, error) { 161 return supportfile.MimeType(r.fullPath(file)) 162 } 163 164 func (r *Local) Missing(file string) bool { 165 return !r.Exists(file) 166 } 167 168 func (r *Local) Move(oldFile, newFile string) error { 169 newFile = r.fullPath(newFile) 170 if err := os.MkdirAll(filepath.Dir(newFile), os.ModePerm); err != nil { 171 return err 172 } 173 174 if err := os.Rename(r.fullPath(oldFile), newFile); err != nil { 175 return err 176 } 177 178 return nil 179 } 180 181 func (r *Local) Path(file string) string { 182 return r.fullPath(file) 183 } 184 185 func (r *Local) Put(file, content string) error { 186 file = r.fullPath(file) 187 if err := os.MkdirAll(filepath.Dir(file), os.ModePerm); err != nil { 188 return err 189 } 190 191 f, err := os.Create(file) 192 if err != nil { 193 return err 194 } 195 defer f.Close() 196 197 if _, err = f.WriteString(content); err != nil { 198 return err 199 } 200 201 return nil 202 } 203 204 func (r *Local) PutFile(filePath string, source filesystem.File) (string, error) { 205 return r.PutFileAs(filePath, source, str.Random(40)) 206 } 207 208 func (r *Local) PutFileAs(filePath string, source filesystem.File, name string) (string, error) { 209 data, err := os.ReadFile(source.File()) 210 if err != nil { 211 return "", err 212 } 213 214 fullPath, err := fullPathOfFile(filePath, source, name) 215 if err != nil { 216 return "", err 217 } 218 219 if err := r.Put(fullPath, string(data)); err != nil { 220 return "", err 221 } 222 223 return fullPath, nil 224 } 225 226 func (r *Local) Size(file string) (int64, error) { 227 return supportfile.Size(r.fullPath(file)) 228 } 229 230 func (r *Local) TemporaryUrl(file string, time time.Time) (string, error) { 231 return r.Url(file), nil 232 } 233 234 func (r *Local) WithContext(ctx context.Context) filesystem.Driver { 235 return r 236 } 237 238 func (r *Local) Url(file string) string { 239 return strings.TrimSuffix(r.url, "/") + "/" + strings.TrimPrefix(filepath.ToSlash(file), "/") 240 } 241 242 func (r *Local) fullPath(path string) string { 243 realPath := filepath.Clean(path) 244 245 if realPath == "." { 246 return r.rootPath() 247 } 248 249 return filepath.Join(r.rootPath(), realPath) 250 } 251 252 func (r *Local) rootPath() string { 253 return strings.TrimSuffix(r.root, string(filepath.Separator)) + string(filepath.Separator) 254 }