mirror of
https://github.com/kataras/iris.git
synced 2025-12-21 11:57:02 +00:00
Add tutorial for DropzoneJS. Stay tuned for two-parts article series on https://medium.com/@kataras and https://dev.to/@kataras
Former-commit-id: 2aac5c1f5a5b5a7039a7a5fad3312a49e9311ddd
This commit is contained in:
171
_examples/tutorial/dropzonejs/src/main.go
Normal file
171
_examples/tutorial/dropzonejs/src/main.go
Normal file
@@ -0,0 +1,171 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"image/jpeg"
|
||||
"image/png"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/kataras/iris"
|
||||
|
||||
"github.com/nfnt/resize"
|
||||
)
|
||||
|
||||
// $ go get -u github.com/nfnt/resize
|
||||
|
||||
const uploadsDir = "./public/uploads/"
|
||||
|
||||
type uploadedFile struct {
|
||||
// {name: "", size: } are the dropzone's only requirements.
|
||||
Name string `json:"name"`
|
||||
Size int64 `json:"size"`
|
||||
}
|
||||
|
||||
type uploadedFiles struct {
|
||||
dir string
|
||||
items []uploadedFile
|
||||
mu sync.RWMutex // slices are safe but RWMutex is a good practise for you.
|
||||
}
|
||||
|
||||
func scanUploads(dir string) *uploadedFiles {
|
||||
|
||||
f := new(uploadedFiles)
|
||||
|
||||
lindex := dir[len(dir)-1]
|
||||
if lindex != os.PathSeparator && lindex != '/' {
|
||||
dir += string(os.PathSeparator)
|
||||
}
|
||||
|
||||
// create directories if necessary
|
||||
// and if, then return empty uploaded files; skipping the scan.
|
||||
if err := os.MkdirAll(dir, os.FileMode(0666)); err != nil {
|
||||
return f
|
||||
}
|
||||
|
||||
// otherwise scan the given "dir" for files.
|
||||
f.scan(dir)
|
||||
return f
|
||||
}
|
||||
|
||||
func (f *uploadedFiles) scan(dir string) {
|
||||
f.dir = dir
|
||||
filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
|
||||
|
||||
// if it's directory or a thumbnail we saved ealier, skip it.
|
||||
if info.IsDir() || strings.HasPrefix(info.Name(), "thumbnail_") {
|
||||
return nil
|
||||
}
|
||||
|
||||
f.add(info.Name(), info.Size())
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (f *uploadedFiles) add(name string, size int64) uploadedFile {
|
||||
f.mu.Lock()
|
||||
uf := uploadedFile{
|
||||
Name: name,
|
||||
Size: size,
|
||||
}
|
||||
f.items = append(f.items, uf)
|
||||
f.mu.Unlock()
|
||||
|
||||
return uf
|
||||
}
|
||||
|
||||
func (f *uploadedFiles) createThumbnail(uf uploadedFile) {
|
||||
file, err := os.Open(path.Join(f.dir, uf.Name))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
name := strings.ToLower(uf.Name)
|
||||
|
||||
out, err := os.OpenFile(f.dir+"thumbnail_"+uf.Name,
|
||||
os.O_WRONLY|os.O_CREATE, 0666)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer out.Close()
|
||||
|
||||
if strings.HasSuffix(name, ".jpg") {
|
||||
// decode jpeg into image.Image
|
||||
img, err := jpeg.Decode(file)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// write new image to file
|
||||
resized := resize.Thumbnail(180, 180, img, resize.Lanczos3)
|
||||
jpeg.Encode(out, resized,
|
||||
&jpeg.Options{Quality: jpeg.DefaultQuality})
|
||||
|
||||
} else if strings.HasSuffix(name, ".png") {
|
||||
img, err := png.Decode(file)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// write new image to file
|
||||
resized := resize.Thumbnail(180, 180, img, resize.Lanczos3) // slower but better res
|
||||
png.Encode(out, resized)
|
||||
}
|
||||
// and so on... you got the point, this code can be simplify, as a practise.
|
||||
|
||||
}
|
||||
|
||||
func main() {
|
||||
app := iris.New()
|
||||
app.RegisterView(iris.HTML("./views", ".html"))
|
||||
|
||||
app.StaticWeb("/public", "./public")
|
||||
|
||||
app.Get("/", func(ctx iris.Context) {
|
||||
ctx.View("upload.html")
|
||||
})
|
||||
|
||||
files := scanUploads(uploadsDir)
|
||||
|
||||
app.Get("/uploads", func(ctx iris.Context) {
|
||||
ctx.JSON(files.items)
|
||||
})
|
||||
|
||||
app.Post("/upload", iris.LimitRequestBodySize(10<<20), func(ctx iris.Context) {
|
||||
// Get the file from the dropzone request
|
||||
file, info, err := ctx.FormFile("file")
|
||||
if err != nil {
|
||||
ctx.StatusCode(iris.StatusInternalServerError)
|
||||
ctx.Application().Logger().Warnf("Error while uploading: %v", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
defer file.Close()
|
||||
fname := info.Filename
|
||||
|
||||
// Create a file with the same name
|
||||
// assuming that you have a folder named 'uploads'
|
||||
out, err := os.OpenFile(uploadsDir+fname,
|
||||
os.O_WRONLY|os.O_CREATE, 0666)
|
||||
|
||||
if err != nil {
|
||||
ctx.StatusCode(iris.StatusInternalServerError)
|
||||
ctx.Application().Logger().Warnf("Error while preparing the new file: %v", err.Error())
|
||||
return
|
||||
}
|
||||
defer out.Close()
|
||||
|
||||
io.Copy(out, file)
|
||||
|
||||
// optionally, add that file to the list in order to be visible when refresh.
|
||||
uploadedFile := files.add(fname, info.Size)
|
||||
go files.createThumbnail(uploadedFile)
|
||||
})
|
||||
|
||||
// start the server at http://localhost:8080
|
||||
app.Run(iris.Addr(":8080"))
|
||||
}
|
||||
Reference in New Issue
Block a user