package resource import ( "context" "io/ioutil" "log" "os" "path/filepath" "resource-manager/domain/cache" "resource-manager/security" "strings" "time" ) func newLocalFolder(cacheManager cache.Manager, expiration time.Duration) Manager { path := os.Getenv("LOCAL_PATH_PREFIX") // if path isn't set use local if path == "" { path, _ = os.Getwd() } log.Println("Manager | using path (" + path + ") and expiration of " + expiration.String()) manager := fileManager{cacheManager, path, expiration} return &manager } type fileManager struct { cache cache.Manager path string expiration time.Duration } func (f *fileManager) Upload(request UploadRequest) { fullPath := filepath.Join(f.path, request.Path) createFolder(fullPath) if checkFileExists(fullPath) && !request.Overwrite { log.Println("Manager | cannot upload file as file on same path already exists") return } log.Println("Manager | uploading to (" + request.Path + ")") if err := os.WriteFile(fullPath, request.Buffer.Bytes(), 0o644); err != nil { log.Println("Manager | failed uploading (" + request.Path + ") cause: " + err.Error()) } } func checkFileExists(path string) bool { _, err := os.Stat(path) return err == nil } func (f *fileManager) Download(ctx context.Context, path string) (file []byte, err error) { fullPath := filepath.Join(f.path, path) file, err = ioutil.ReadFile(fullPath) if err != nil { log.Println("Manager | failed downloading (" + path + ") cause: " + err.Error()) } return } func (f *fileManager) Presign(_ context.Context, path string) (string, error) { token, err := security.CreateToken(security.PresignToken{Path: path}, f.expiration) if err != nil { return "", err } return "/api/v1/resources?token=" + token, nil } func (f *fileManager) Copy(from string, to string, overwrite bool) error { fromPath := filepath.Join(f.path, from) toPath := filepath.Join(f.path, to) log.Println("Manager | copying from (" + fromPath + ") to (" + toPath + ")") createFolder(filepath.Join(toPath, "file")) return copyFolder(fromPath, toPath, overwrite) } func (f *fileManager) Delete(path string) error { log.Println("Manager | deleting " + path) fullPath := filepath.Join(f.path, path) if err := os.Remove(fullPath); err != nil { log.Println("Manager | failed deleting (" + path + ") cause: " + err.Error()) return err } f.cache.Remove(path) return nil } func createFolder(path string) { paths := strings.Split(path, "/") folderPath := "/" + filepath.Join(paths[:len(paths)-1]...) if err := os.MkdirAll(folderPath, 0o755); err != nil { log.Println("[error] ", err) } } func copyFolder(source, destination string, overwrite bool) error { var err = filepath.WalkDir(source, func(path string, d os.DirEntry, err error) error { relPath := strings.Replace(path, source, "", 1) if relPath == "" { return nil } if d.IsDir() { return os.Mkdir(filepath.Join(destination, relPath), 0755) } else { doesExist := false if _, err := os.Stat(filepath.Join(destination, relPath)); !os.IsNotExist(err) { doesExist = true } if !doesExist || overwrite { var data, err1 = ioutil.ReadFile(filepath.Join(source, relPath)) if err1 != nil { return err1 } return ioutil.WriteFile(filepath.Join(destination, relPath), data, 0777) } else { return nil } } }) return err }