summaryrefslogtreecommitdiff
path: root/system/admin/upload/upload.go
diff options
context:
space:
mode:
authorSteve Manuel <nilslice@gmail.com>2016-10-29 17:56:46 -0700
committerSteve Manuel <nilslice@gmail.com>2016-10-29 17:56:46 -0700
commitc930db63601095ce386413b3eb764b71ee71fe2c (patch)
tree0142977cd022caa62ca487010f0e51a3dd2272de /system/admin/upload/upload.go
parented4c47babef56f18df0a5b393b0c0fe79e659105 (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.go90
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
+}