diff options
author | Steve Manuel <nilslice@gmail.com> | 2016-10-29 17:56:46 -0700 |
---|---|---|
committer | Steve Manuel <nilslice@gmail.com> | 2016-10-29 17:56:46 -0700 |
commit | c930db63601095ce386413b3eb764b71ee71fe2c (patch) | |
tree | 0142977cd022caa62ca487010f0e51a3dd2272de /system/admin/upload/upload.go | |
parent | ed4c47babef56f18df0a5b393b0c0fe79e659105 (diff) |
renaming and moving File upload logic into own package
Diffstat (limited to 'system/admin/upload/upload.go')
-rw-r--r-- | system/admin/upload/upload.go | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/system/admin/upload/upload.go b/system/admin/upload/upload.go new file mode 100644 index 0000000..169bffe --- /dev/null +++ b/system/admin/upload/upload.go @@ -0,0 +1,90 @@ +package upload + +import ( + "fmt" + "io" + "net/http" + "os" + "path/filepath" + "strconv" + "time" +) + +// StoreFiles stores file uploads at paths like /YYYY/MM/filename.ext +func StoreFiles(req *http.Request) (map[string]string, error) { + err := req.ParseMultipartForm(1024 * 1024 * 4) // maxMemory 4MB + if err != nil { + return nil, fmt.Errorf("%s", err) + } + + ts := req.FormValue("timestamp") // timestamp in milliseconds since unix epoch + + if ts == "" { + ts = fmt.Sprintf("%d", time.Now().Unix()*1000) // Unix() returns seconds since unix epoch + } + + req.Form.Set("timestamp", ts) + + // To use for FormValue name:urlPath + urlPaths := make(map[string]string) + + // get or create upload directory to save files from request + pwd, err := os.Getwd() + if err != nil { + err := fmt.Errorf("Failed to locate current directory: %s", err) + return nil, err + } + + i, err := strconv.ParseInt(ts, 10, 64) + if err != nil { + return nil, err + } + + tm := time.Unix(int64(i/1000), int64(i%1000)) + + urlPathPrefix := "api" + uploadDirName := "uploads" + + uploadDir := filepath.Join(pwd, uploadDirName, fmt.Sprintf("%d", tm.Year()), fmt.Sprintf("%d", tm.Month())) + err = os.MkdirAll(uploadDir, os.ModeDir|os.ModePerm) + + // loop over all files and save them to disk + for name, fds := range req.MultipartForm.File { + filename := fds[0].Filename + src, err := fds[0].Open() + if err != nil { + err := fmt.Errorf("Couldn't open uploaded file: %s", err) + return nil, err + + } + defer src.Close() + + // check if file at path exists, if so, add timestamp to file + absPath := filepath.Join(uploadDir, filename) + + if _, err := os.Stat(absPath); !os.IsNotExist(err) { + filename = fmt.Sprintf("%d-%s", time.Now().Unix(), filename) + absPath = filepath.Join(uploadDir, filename) + } + + // save to disk (TODO: or check if S3 credentials exist, & save to cloud) + dst, err := os.Create(absPath) + if err != nil { + err := fmt.Errorf("Failed to create destination file for upload: %s", err) + return nil, err + } + + // copy file from src to dst on disk + if _, err = io.Copy(dst, src); err != nil { + err := fmt.Errorf("Failed to copy uploaded file to destination: %s", err) + return nil, err + } + + // add name:urlPath to req.PostForm to be inserted into db + urlPath := fmt.Sprintf("/%s/%s/%d/%d/%s", urlPathPrefix, uploadDirName, tm.Year(), tm.Month(), filename) + + urlPaths[name] = urlPath + } + + return urlPaths, nil +} |