diff options
Diffstat (limited to 'vendors/jquery-file-upload/server/gae-go')
-rw-r--r-- | vendors/jquery-file-upload/server/gae-go/app.yaml | 12 | ||||
-rw-r--r-- | vendors/jquery-file-upload/server/gae-go/app/main.go | 361 | ||||
-rw-r--r-- | vendors/jquery-file-upload/server/gae-go/resize/resize.go | 247 | ||||
-rw-r--r-- | vendors/jquery-file-upload/server/gae-go/static/favicon.ico | bin | 1150 -> 0 bytes | |||
-rw-r--r-- | vendors/jquery-file-upload/server/gae-go/static/robots.txt | 2 |
5 files changed, 0 insertions, 622 deletions
diff --git a/vendors/jquery-file-upload/server/gae-go/app.yaml b/vendors/jquery-file-upload/server/gae-go/app.yaml deleted file mode 100644 index 2d09daa56..000000000 --- a/vendors/jquery-file-upload/server/gae-go/app.yaml +++ /dev/null @@ -1,12 +0,0 @@ -application: jquery-file-upload -version: 2 -runtime: go -api_version: go1 - -handlers: -- url: /(favicon\.ico|robots\.txt) - static_files: static/\1 - upload: static/(.*) - expiration: '1d' -- url: /.* - script: _go_app diff --git a/vendors/jquery-file-upload/server/gae-go/app/main.go b/vendors/jquery-file-upload/server/gae-go/app/main.go deleted file mode 100644 index 01dc2f204..000000000 --- a/vendors/jquery-file-upload/server/gae-go/app/main.go +++ /dev/null @@ -1,361 +0,0 @@ -/* - * jQuery File Upload Plugin GAE Go Example 2.0 - * https://github.com/blueimp/jQuery-File-Upload - * - * Copyright 2011, Sebastian Tschan - * https://blueimp.net - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/MIT - */ - -package app - -import ( - "appengine" - "appengine/blobstore" - "appengine/memcache" - "appengine/taskqueue" - "bytes" - "encoding/base64" - "encoding/json" - "fmt" - "image" - "image/png" - "io" - "log" - "mime/multipart" - "net/http" - "net/url" - "regexp" - "resize" - "strings" - "time" -) - -import _ "image/gif" -import _ "image/jpeg" - -const ( - WEBSITE = "http://blueimp.github.com/jQuery-File-Upload/" - MIN_FILE_SIZE = 1 // bytes - MAX_FILE_SIZE = 5000000 // bytes - IMAGE_TYPES = "image/(gif|p?jpeg|(x-)?png)" - ACCEPT_FILE_TYPES = IMAGE_TYPES - EXPIRATION_TIME = 300 // seconds - THUMBNAIL_MAX_WIDTH = 80 - THUMBNAIL_MAX_HEIGHT = THUMBNAIL_MAX_WIDTH -) - -var ( - imageTypes = regexp.MustCompile(IMAGE_TYPES) - acceptFileTypes = regexp.MustCompile(ACCEPT_FILE_TYPES) -) - -type FileInfo struct { - Key appengine.BlobKey `json:"-"` - Url string `json:"url,omitempty"` - ThumbnailUrl string `json:"thumbnail_url,omitempty"` - Name string `json:"name"` - Type string `json:"type"` - Size int64 `json:"size"` - Error string `json:"error,omitempty"` - DeleteUrl string `json:"delete_url,omitempty"` - DeleteType string `json:"delete_type,omitempty"` -} - -func (fi *FileInfo) ValidateType() (valid bool) { - if acceptFileTypes.MatchString(fi.Type) { - return true - } - fi.Error = "acceptFileTypes" - return false -} - -func (fi *FileInfo) ValidateSize() (valid bool) { - if fi.Size < MIN_FILE_SIZE { - fi.Error = "minFileSize" - } else if fi.Size > MAX_FILE_SIZE { - fi.Error = "maxFileSize" - } else { - return true - } - return false -} - -func (fi *FileInfo) CreateUrls(r *http.Request, c appengine.Context) { - u := &url.URL{ - Scheme: r.URL.Scheme, - Host: appengine.DefaultVersionHostname(c), - Path: "/", - } - uString := u.String() - fi.Url = uString + escape(string(fi.Key)) + "/" + - escape(string(fi.Name)) - fi.DeleteUrl = fi.Url - fi.DeleteType = "DELETE" - if fi.ThumbnailUrl != "" && -1 == strings.Index( - r.Header.Get("Accept"), - "application/json", - ) { - fi.ThumbnailUrl = uString + "thumbnails/" + - escape(string(fi.Key)) - } -} - -func (fi *FileInfo) CreateThumbnail(r io.Reader, c appengine.Context) (data []byte, err error) { - defer func() { - if rec := recover(); rec != nil { - log.Println(rec) - // 1x1 pixel transparent GIf, bas64 encoded: - s := "R0lGODlhAQABAIAAAP///////yH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" - data, _ = base64.StdEncoding.DecodeString(s) - fi.ThumbnailUrl = "data:image/gif;base64," + s - } - memcache.Add(c, &memcache.Item{ - Key: string(fi.Key), - Value: data, - Expiration: EXPIRATION_TIME, - }) - }() - img, _, err := image.Decode(r) - check(err) - if bounds := img.Bounds(); bounds.Dx() > THUMBNAIL_MAX_WIDTH || - bounds.Dy() > THUMBNAIL_MAX_HEIGHT { - w, h := THUMBNAIL_MAX_WIDTH, THUMBNAIL_MAX_HEIGHT - if bounds.Dx() > bounds.Dy() { - h = bounds.Dy() * h / bounds.Dx() - } else { - w = bounds.Dx() * w / bounds.Dy() - } - img = resize.Resize(img, img.Bounds(), w, h) - } - var b bytes.Buffer - err = png.Encode(&b, img) - check(err) - data = b.Bytes() - fi.ThumbnailUrl = "data:image/png;base64," + - base64.StdEncoding.EncodeToString(data) - return -} - -func check(err error) { - if err != nil { - panic(err) - } -} - -func escape(s string) string { - return strings.Replace(url.QueryEscape(s), "+", "%20", -1) -} - -func delayedDelete(c appengine.Context, fi *FileInfo) { - if key := string(fi.Key); key != "" { - task := &taskqueue.Task{ - Path: "/" + escape(key) + "/-", - Method: "DELETE", - Delay: time.Duration(EXPIRATION_TIME) * time.Second, - } - taskqueue.Add(c, task, "") - } -} - -func handleUpload(r *http.Request, p *multipart.Part) (fi *FileInfo) { - fi = &FileInfo{ - Name: p.FileName(), - Type: p.Header.Get("Content-Type"), - } - if !fi.ValidateType() { - return - } - defer func() { - if rec := recover(); rec != nil { - log.Println(rec) - fi.Error = rec.(error).Error() - } - }() - var b bytes.Buffer - lr := &io.LimitedReader{R: p, N: MAX_FILE_SIZE + 1} - context := appengine.NewContext(r) - w, err := blobstore.Create(context, fi.Type) - defer func() { - w.Close() - fi.Size = MAX_FILE_SIZE + 1 - lr.N - fi.Key, err = w.Key() - check(err) - if !fi.ValidateSize() { - err := blobstore.Delete(context, fi.Key) - check(err) - return - } - delayedDelete(context, fi) - if b.Len() > 0 { - fi.CreateThumbnail(&b, context) - } - fi.CreateUrls(r, context) - }() - check(err) - var wr io.Writer = w - if imageTypes.MatchString(fi.Type) { - wr = io.MultiWriter(&b, w) - } - _, err = io.Copy(wr, lr) - return -} - -func getFormValue(p *multipart.Part) string { - var b bytes.Buffer - io.CopyN(&b, p, int64(1<<20)) // Copy max: 1 MiB - return b.String() -} - -func handleUploads(r *http.Request) (fileInfos []*FileInfo) { - fileInfos = make([]*FileInfo, 0) - mr, err := r.MultipartReader() - check(err) - r.Form, err = url.ParseQuery(r.URL.RawQuery) - check(err) - part, err := mr.NextPart() - for err == nil { - if name := part.FormName(); name != "" { - if part.FileName() != "" { - fileInfos = append(fileInfos, handleUpload(r, part)) - } else { - r.Form[name] = append(r.Form[name], getFormValue(part)) - } - } - part, err = mr.NextPart() - } - return -} - -func get(w http.ResponseWriter, r *http.Request) { - if r.URL.Path == "/" { - http.Redirect(w, r, WEBSITE, http.StatusFound) - return - } - parts := strings.Split(r.URL.Path, "/") - if len(parts) == 3 { - if key := parts[1]; key != "" { - blobKey := appengine.BlobKey(key) - bi, err := blobstore.Stat(appengine.NewContext(r), blobKey) - if err == nil { - w.Header().Add( - "Cache-Control", - fmt.Sprintf("public,max-age=%d", EXPIRATION_TIME), - ) - if imageTypes.MatchString(bi.ContentType) { - w.Header().Add("X-Content-Type-Options", "nosniff") - } else { - w.Header().Add("Content-Type", "application/octet-stream") - w.Header().Add( - "Content-Disposition:", - fmt.Sprintf("attachment; filename=%s;", parts[2]), - ) - } - blobstore.Send(w, appengine.BlobKey(key)) - return - } - } - } - http.Error(w, "404 Not Found", http.StatusNotFound) -} - -func post(w http.ResponseWriter, r *http.Request) { - b, err := json.Marshal(handleUploads(r)) - check(err) - if redirect := r.FormValue("redirect"); redirect != "" { - http.Redirect(w, r, fmt.Sprintf( - redirect, - escape(string(b)), - ), http.StatusFound) - return - } - jsonType := "application/json" - if strings.Index(r.Header.Get("Accept"), jsonType) != -1 { - w.Header().Set("Content-Type", jsonType) - } - fmt.Fprintln(w, string(b)) -} - -func delete(w http.ResponseWriter, r *http.Request) { - parts := strings.Split(r.URL.Path, "/") - if len(parts) != 3 { - return - } - if key := parts[1]; key != "" { - c := appengine.NewContext(r) - blobstore.Delete(c, appengine.BlobKey(key)) - memcache.Delete(c, key) - } -} - -func serveThumbnail(w http.ResponseWriter, r *http.Request) { - parts := strings.Split(r.URL.Path, "/") - if len(parts) == 3 { - if key := parts[2]; key != "" { - var data []byte - c := appengine.NewContext(r) - item, err := memcache.Get(c, key) - if err == nil { - data = item.Value - } else { - blobKey := appengine.BlobKey(key) - if _, err = blobstore.Stat(c, blobKey); err == nil { - fi := FileInfo{Key: blobKey} - data, _ = fi.CreateThumbnail( - blobstore.NewReader(c, blobKey), - c, - ) - } - } - if err == nil && len(data) > 3 { - w.Header().Add( - "Cache-Control", - fmt.Sprintf("public,max-age=%d", EXPIRATION_TIME), - ) - contentType := "image/png" - if string(data[:3]) == "GIF" { - contentType = "image/gif" - } else if string(data[1:4]) != "PNG" { - contentType = "image/jpeg" - } - w.Header().Set("Content-Type", contentType) - fmt.Fprintln(w, string(data)) - return - } - } - } - http.Error(w, "404 Not Found", http.StatusNotFound) -} - -func handle(w http.ResponseWriter, r *http.Request) { - params, err := url.ParseQuery(r.URL.RawQuery) - check(err) - w.Header().Add("Access-Control-Allow-Origin", "*") - w.Header().Add( - "Access-Control-Allow-Methods", - "OPTIONS, HEAD, GET, POST, PUT, DELETE", - ) - switch r.Method { - case "OPTIONS": - case "HEAD": - case "GET": - get(w, r) - case "POST": - if len(params["_method"]) > 0 && params["_method"][0] == "DELETE" { - delete(w, r) - } else { - post(w, r) - } - case "DELETE": - delete(w, r) - default: - http.Error(w, "501 Not Implemented", http.StatusNotImplemented) - } -} - -func init() { - http.HandleFunc("/", handle) - http.HandleFunc("/thumbnails/", serveThumbnail) -} diff --git a/vendors/jquery-file-upload/server/gae-go/resize/resize.go b/vendors/jquery-file-upload/server/gae-go/resize/resize.go deleted file mode 100644 index dcb627870..000000000 --- a/vendors/jquery-file-upload/server/gae-go/resize/resize.go +++ /dev/null @@ -1,247 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package resize - -import ( - "image" - "image/color" -) - -// Resize returns a scaled copy of the image slice r of m. -// The returned image has width w and height h. -func Resize(m image.Image, r image.Rectangle, w, h int) image.Image { - if w < 0 || h < 0 { - return nil - } - if w == 0 || h == 0 || r.Dx() <= 0 || r.Dy() <= 0 { - return image.NewRGBA64(image.Rect(0, 0, w, h)) - } - switch m := m.(type) { - case *image.RGBA: - return resizeRGBA(m, r, w, h) - case *image.YCbCr: - if m, ok := resizeYCbCr(m, r, w, h); ok { - return m - } - } - ww, hh := uint64(w), uint64(h) - dx, dy := uint64(r.Dx()), uint64(r.Dy()) - // The scaling algorithm is to nearest-neighbor magnify the dx * dy source - // to a (ww*dx) * (hh*dy) intermediate image and then minify the intermediate - // image back down to a ww * hh destination with a simple box filter. - // The intermediate image is implied, we do not physically allocate a slice - // of length ww*dx*hh*dy. - // For example, consider a 4*3 source image. Label its pixels from a-l: - // abcd - // efgh - // ijkl - // To resize this to a 3*2 destination image, the intermediate is 12*6. - // Whitespace has been added to delineate the destination pixels: - // aaab bbcc cddd - // aaab bbcc cddd - // eeef ffgg ghhh - // - // eeef ffgg ghhh - // iiij jjkk klll - // iiij jjkk klll - // Thus, the 'b' source pixel contributes one third of its value to the - // (0, 0) destination pixel and two thirds to (1, 0). - // The implementation is a two-step process. First, the source pixels are - // iterated over and each source pixel's contribution to 1 or more - // destination pixels are summed. Second, the sums are divided by a scaling - // factor to yield the destination pixels. - // TODO: By interleaving the two steps, instead of doing all of - // step 1 first and all of step 2 second, we could allocate a smaller sum - // slice of length 4*w*2 instead of 4*w*h, although the resultant code - // would become more complicated. - n, sum := dx*dy, make([]uint64, 4*w*h) - for y := r.Min.Y; y < r.Max.Y; y++ { - for x := r.Min.X; x < r.Max.X; x++ { - // Get the source pixel. - r32, g32, b32, a32 := m.At(x, y).RGBA() - r64 := uint64(r32) - g64 := uint64(g32) - b64 := uint64(b32) - a64 := uint64(a32) - // Spread the source pixel over 1 or more destination rows. - py := uint64(y) * hh - for remy := hh; remy > 0; { - qy := dy - (py % dy) - if qy > remy { - qy = remy - } - // Spread the source pixel over 1 or more destination columns. - px := uint64(x) * ww - index := 4 * ((py/dy)*ww + (px / dx)) - for remx := ww; remx > 0; { - qx := dx - (px % dx) - if qx > remx { - qx = remx - } - sum[index+0] += r64 * qx * qy - sum[index+1] += g64 * qx * qy - sum[index+2] += b64 * qx * qy - sum[index+3] += a64 * qx * qy - index += 4 - px += qx - remx -= qx - } - py += qy - remy -= qy - } - } - } - return average(sum, w, h, n*0x0101) -} - -// average convert the sums to averages and returns the result. -func average(sum []uint64, w, h int, n uint64) image.Image { - ret := image.NewRGBA(image.Rect(0, 0, w, h)) - for y := 0; y < h; y++ { - for x := 0; x < w; x++ { - index := 4 * (y*w + x) - ret.SetRGBA(x, y, color.RGBA{ - uint8(sum[index+0] / n), - uint8(sum[index+1] / n), - uint8(sum[index+2] / n), - uint8(sum[index+3] / n), - }) - } - } - return ret -} - -// resizeYCbCr returns a scaled copy of the YCbCr image slice r of m. -// The returned image has width w and height h. -func resizeYCbCr(m *image.YCbCr, r image.Rectangle, w, h int) (image.Image, bool) { - var verticalRes int - switch m.SubsampleRatio { - case image.YCbCrSubsampleRatio420: - verticalRes = 2 - case image.YCbCrSubsampleRatio422: - verticalRes = 1 - default: - return nil, false - } - ww, hh := uint64(w), uint64(h) - dx, dy := uint64(r.Dx()), uint64(r.Dy()) - // See comment in Resize. - n, sum := dx*dy, make([]uint64, 4*w*h) - for y := r.Min.Y; y < r.Max.Y; y++ { - Y := m.Y[y*m.YStride:] - Cb := m.Cb[y/verticalRes*m.CStride:] - Cr := m.Cr[y/verticalRes*m.CStride:] - for x := r.Min.X; x < r.Max.X; x++ { - // Get the source pixel. - r8, g8, b8 := color.YCbCrToRGB(Y[x], Cb[x/2], Cr[x/2]) - r64 := uint64(r8) - g64 := uint64(g8) - b64 := uint64(b8) - // Spread the source pixel over 1 or more destination rows. - py := uint64(y) * hh - for remy := hh; remy > 0; { - qy := dy - (py % dy) - if qy > remy { - qy = remy - } - // Spread the source pixel over 1 or more destination columns. - px := uint64(x) * ww - index := 4 * ((py/dy)*ww + (px / dx)) - for remx := ww; remx > 0; { - qx := dx - (px % dx) - if qx > remx { - qx = remx - } - qxy := qx * qy - sum[index+0] += r64 * qxy - sum[index+1] += g64 * qxy - sum[index+2] += b64 * qxy - sum[index+3] += 0xFFFF * qxy - index += 4 - px += qx - remx -= qx - } - py += qy - remy -= qy - } - } - } - return average(sum, w, h, n), true -} - -// resizeRGBA returns a scaled copy of the RGBA image slice r of m. -// The returned image has width w and height h. -func resizeRGBA(m *image.RGBA, r image.Rectangle, w, h int) image.Image { - ww, hh := uint64(w), uint64(h) - dx, dy := uint64(r.Dx()), uint64(r.Dy()) - // See comment in Resize. - n, sum := dx*dy, make([]uint64, 4*w*h) - for y := r.Min.Y; y < r.Max.Y; y++ { - pixOffset := m.PixOffset(r.Min.X, y) - for x := r.Min.X; x < r.Max.X; x++ { - // Get the source pixel. - r64 := uint64(m.Pix[pixOffset+0]) - g64 := uint64(m.Pix[pixOffset+1]) - b64 := uint64(m.Pix[pixOffset+2]) - a64 := uint64(m.Pix[pixOffset+3]) - pixOffset += 4 - // Spread the source pixel over 1 or more destination rows. - py := uint64(y) * hh - for remy := hh; remy > 0; { - qy := dy - (py % dy) - if qy > remy { - qy = remy - } - // Spread the source pixel over 1 or more destination columns. - px := uint64(x) * ww - index := 4 * ((py/dy)*ww + (px / dx)) - for remx := ww; remx > 0; { - qx := dx - (px % dx) - if qx > remx { - qx = remx - } - qxy := qx * qy - sum[index+0] += r64 * qxy - sum[index+1] += g64 * qxy - sum[index+2] += b64 * qxy - sum[index+3] += a64 * qxy - index += 4 - px += qx - remx -= qx - } - py += qy - remy -= qy - } - } - } - return average(sum, w, h, n) -} - -// Resample returns a resampled copy of the image slice r of m. -// The returned image has width w and height h. -func Resample(m image.Image, r image.Rectangle, w, h int) image.Image { - if w < 0 || h < 0 { - return nil - } - if w == 0 || h == 0 || r.Dx() <= 0 || r.Dy() <= 0 { - return image.NewRGBA64(image.Rect(0, 0, w, h)) - } - curw, curh := r.Dx(), r.Dy() - img := image.NewRGBA(image.Rect(0, 0, w, h)) - for y := 0; y < h; y++ { - for x := 0; x < w; x++ { - // Get a source pixel. - subx := x * curw / w - suby := y * curh / h - r32, g32, b32, a32 := m.At(subx, suby).RGBA() - r := uint8(r32 >> 8) - g := uint8(g32 >> 8) - b := uint8(b32 >> 8) - a := uint8(a32 >> 8) - img.SetRGBA(x, y, color.RGBA{r, g, b, a}) - } - } - return img -} diff --git a/vendors/jquery-file-upload/server/gae-go/static/favicon.ico b/vendors/jquery-file-upload/server/gae-go/static/favicon.ico Binary files differdeleted file mode 100644 index 1a71ea772..000000000 --- a/vendors/jquery-file-upload/server/gae-go/static/favicon.ico +++ /dev/null diff --git a/vendors/jquery-file-upload/server/gae-go/static/robots.txt b/vendors/jquery-file-upload/server/gae-go/static/robots.txt deleted file mode 100644 index eb0536286..000000000 --- a/vendors/jquery-file-upload/server/gae-go/static/robots.txt +++ /dev/null @@ -1,2 +0,0 @@ -User-agent: * -Disallow: |