From c930db63601095ce386413b3eb764b71ee71fe2c Mon Sep 17 00:00:00 2001 From: Steve Manuel Date: Sat, 29 Oct 2016 17:56:46 -0700 Subject: renaming and moving File upload logic into own package --- system/admin/handlers.go | 5 ++- system/admin/upload.go | 90 ------------------------------------------- system/admin/upload/upload.go | 90 +++++++++++++++++++++++++++++++++++++++++++ system/api/external.go | 4 +- 4 files changed, 95 insertions(+), 94 deletions(-) delete mode 100644 system/admin/upload.go create mode 100644 system/admin/upload/upload.go (limited to 'system') diff --git a/system/admin/handlers.go b/system/admin/handlers.go index ce07c4c..6f23683 100644 --- a/system/admin/handlers.go +++ b/system/admin/handlers.go @@ -14,6 +14,7 @@ import ( "github.com/bosssauce/ponzu/management/editor" "github.com/bosssauce/ponzu/management/manager" "github.com/bosssauce/ponzu/system/admin/config" + "github.com/bosssauce/ponzu/system/admin/upload" "github.com/bosssauce/ponzu/system/admin/user" "github.com/bosssauce/ponzu/system/api" "github.com/bosssauce/ponzu/system/db" @@ -869,7 +870,7 @@ func editHandler(res http.ResponseWriter, req *http.Request) { req.PostForm.Set("updated", ts) } - urlPaths, err := StoreFileUploads(req) + urlPaths, err := upload.StoreFiles(req) if err != nil { log.Println(err) res.WriteHeader(http.StatusInternalServerError) @@ -971,7 +972,7 @@ func editUploadHandler(res http.ResponseWriter, req *http.Request) { return } - urlPaths, err := StoreFileUploads(req) + urlPaths, err := upload.StoreFiles(req) if err != nil { log.Println("Couldn't store file uploads.", err) res.WriteHeader(http.StatusInternalServerError) diff --git a/system/admin/upload.go b/system/admin/upload.go deleted file mode 100644 index 3f61765..0000000 --- a/system/admin/upload.go +++ /dev/null @@ -1,90 +0,0 @@ -package admin - -import ( - "fmt" - "io" - "net/http" - "os" - "path/filepath" - "strconv" - "time" -) - -// StoreFileUploads stores file uploads at paths like /YYYY/MM/filename.ext -func StoreFileUploads(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 -} 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 +} diff --git a/system/api/external.go b/system/api/external.go index 1c69afb..52240d5 100644 --- a/system/api/external.go +++ b/system/api/external.go @@ -8,7 +8,7 @@ import ( "time" "github.com/bosssauce/ponzu/content" - "github.com/bosssauce/ponzu/system/admin" + "github.com/bosssauce/ponzu/system/admin/upload" "github.com/bosssauce/ponzu/system/db" ) @@ -68,7 +68,7 @@ func externalPostsHandler(res http.ResponseWriter, req *http.Request) { req.PostForm.Set("updated", ts) req.PostForm.Set("id", ts) - urlPaths, err := admin.storeFileUploads(req) + urlPaths, err := upload.StoreFiles(req) if err != nil { log.Println(err) res.WriteHeader(http.StatusInternalServerError) -- cgit v1.2.3