func getImageUrl(c appengine.Context, key appengine.BlobKey) (*url.URL, error) { // get image url only if it was specified option := image.ServingURLOptions{ Secure: true, // serve on https } return image.ServingURL(c, key, &option) }
func (c Creature) CropImage(width, height, max int, ctx appengine.Context) (image.Image, error) { url, _ := aeimg.ServingURL(ctx, c.BlobKey, &aeimg.ServingURLOptions{Size: max, Crop: true}) client := urlfetch.Client(ctx) resp, _ := client.Get(url.String()) // Just in case if resp.StatusCode != 200 { return nil, errors.New("Blob not found") } // Do we need further cropping? if width == height { return jpeg.Decode(resp.Body) } src, err := jpeg.Decode(resp.Body) dest := image.NewRGBA(image.Rect(0, 0, width, height)) if err != nil { return nil, err } graphics.Thumbnail(dest, src) return dest, nil }
func handleConfirmItemEntry(w http.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) q := datastore.NewQuery("lighting").Order("-CreationTime").Limit(1) confirm := &ResultRead{} //set up an infinite loop - it will break when "Done" for t := q.Run(c); ; { var x ResultData _, err := t.Next(&x) if err == datastore.Done { break } if err != nil { serveError(c, w, err) return } //Do something with the iterator url, err := image.ServingURL(c, x.MainPhoto, nil) if err != nil { serveError(c, w, err) return } confirm.Manufacturer = x.Manufacturer confirm.URL = template.HTML(url.String()) } w.Header().Set("Content-Type", "text/html") err := confirmItemEntryTemplate.Execute(w, confirm) if err != nil { serveError(c, w, err) return } }
func handleLast10(w http.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) q := datastore.NewQuery("lighting").Order("-CreationTime").Limit(10) confirm := &ResultRead{} b := make(map[int]ResultRead) for t, i := q.Run(c), 0; ; i++ { var x ResultData _, err := t.Next(&x) if err == datastore.Done { break } if err != nil { serveError(c, w, err) return } url, err := image.ServingURL(c, x.MainPhoto, nil) if err != nil { serveError(c, w, err) return } confirm.Manufacturer = x.Manufacturer confirm.URL = template.HTML(url.String()) b[i] = *confirm } w.Header().Set("Content-Type", "text/html") err := last10Template.Execute(w, b) if err != nil { serveError(c, w, err) return } }
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 + "?delete=true" fi.DeleteType = "DELETE" if imageTypes.MatchString(fi.Type) { servingUrl, err := image.ServingURL( c, fi.Key, &image.ServingURLOptions{ Secure: strings.HasSuffix(u.Scheme, "s"), Size: 0, Crop: false, }, ) check(err) fi.ThumbnailUrl = servingUrl.String() + THUMBNAIL_PARAM } }
func loadImage(c appengine.Context, f *Feed) string { s := f.Link if s == "" { s = f.Url } u, err := url.Parse(s) if err != nil { return "" } u.Path = "/favicon.ico" u.RawQuery = "" u.Fragment = "" g := goon.FromContext(c) i := &Image{Id: u.String()} if err := g.Get(i); err == nil { return i.Url } client := urlfetch.Client(c) r, err := client.Get(u.String()) if err != nil || r.StatusCode != http.StatusOK || r.ContentLength == 0 { return "" } b, err := ioutil.ReadAll(r.Body) r.Body.Close() if err != nil { return "" } buf := bytes.NewBuffer(b) _, t, err := image.DecodeConfig(buf) if err != nil { t = "application/octet-stream" } else { t = "image/" + t } w, err := blobstore.Create(c, t) if err != nil { return "" } if _, err := w.Write(b); err != nil { return "" } if w.Close() != nil { return "" } i.Blob, _ = w.Key() su, err := aimage.ServingURL(c, i.Blob, &aimage.ServingURLOptions{Size: 16}) if err != nil { if err = blobstore.Delete(c, i.Blob); err != nil { c.Errorf("blob delete err: %v", err) } return "" } i.Url = su.String() g.Put(i) return i.Url }
func UpdateServingLogoUrl(w http.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) const batch = 50 page, _ := strconv.Atoi(r.FormValue("pg")) if page < 1 { page = 1 } offset := batch * (page - 1) q := datastore.NewQuery("EmpLogo").Offset(offset).Order("IdEmp").Limit(batch) n, _ := q.Count(c) for i := q.Run(c); ; { var e model.Image key, err := i.Next(&e) if err == datastore.Done { break } // Se crea la URL para servir la oferta desde el CDN, si no se puede // se deja en blanco var imgprops image.ServingURLOptions imgprops.Secure = true imgprops.Size = 180 imgprops.Crop = false if e.Sp4 == "" && e.IdEmp != "" { var blobkey appengine.BlobKey blob, err := blobstore.Create(c, "image/jpeg") if err != nil { c.Errorf("blobstore Create: %v", e.IdEmp) } _, err = blob.Write(e.Data) if err != nil { c.Errorf("blobstore Write: %v", e.IdEmp) } err = blob.Close() if err != nil { c.Errorf("blobstore Close: %v", e.IdEmp) } blobkey, err = blob.Key() if err != nil { c.Errorf("blobstore Key Gen: %v", e.IdEmp) } if url, err := image.ServingURL(c, blobkey, &imgprops); err != nil { c.Errorf("Cannot construct EmpLogo ServingURL : %v", e.IdEmp) } else { e.Sp3 = string(blobkey) e.Sp4 = url.String() } _, err = datastore.Put(c, key, &e) if err != nil { c.Errorf("PutEmpLogo(); Error al intentar actualizar Emplogo : %v", e.IdEmp) } } } c.Infof("UpdateServingLogoUrl() Pagina: %d, actualizados: %d, del %d al %d", page, n, offset, offset+n) return }
func handleServeImg(w http.ResponseWriter, r *http.Request) { if r.FormValue("id") != "none" { c := appengine.NewContext(r) var imgprops image.ServingURLOptions imgprops.Secure = true imgprops.Size = 400 imgprops.Crop = false url, _ := image.ServingURL(c, appengine.BlobKey(r.FormValue("id")), &imgprops) http.Redirect(w, r, url.String(), http.StatusFound) } return }
func serveThumb(c appengine.Context, w http.ResponseWriter, r *http.Request) { // c := appengine.NewContext(r) k := appengine.BlobKey(r.FormValue("blobkey")) var o image.ServingURLOptions = *new(image.ServingURLOptions) o.Size = 200 o.Crop = true url, err := image.ServingURL(c, k, &o) util_err.Err_http(w, r, err, false) http.Redirect(w, r, url.String(), http.StatusFound) }
// GCSに保存された画像の公開URLを取得します。 func GetServingURL(c appengine.Context, filename string) (servingURL *url.URL, err error) { blobKey, err := blobstore.BlobKeyForFile(c, filename) if err != nil { c.Errorf("serve.go:14: %s", err.Error()) return nil, err } opts := &image.ServingURLOptions{Secure: true} servingURL, err = image.ServingURL(c, blobKey, opts) if err != nil { c.Errorf("serve.go:25: %s", err.Error()) return nil, err } return servingURL, nil }
func (m *Message) images2urls(c appengine.Context) { urlc := make(chan string) for _, im := range m.images { go func(img *img_attachment) { w, err := blobstore.Create(c, img.Type) if err != nil { urlc <- err.Error() return } _, err = w.Write(img.Data) if err != nil { urlc <- err.Error() return } err = w.Close() if err != nil { urlc <- err.Error() return } key, err := w.Key() if err != nil { urlc <- err.Error() return } url, err := image.ServingURL(c, key, &image.ServingURLOptions{Secure: false, Size: 0, Crop: false}) if err != nil { urlc <- err.Error() return } urlc <- url.String() }(&im) } imagescnt := len(m.images) m.ImageUrls = make([]string, 0, imagescnt) for i := 0; i < imagescnt; i++ { u := <-urlc if strings.HasPrefix(u, "http") { m.ImageUrls = append(m.ImageUrls, u) } else { c.Errorf("Error converting image to url: %v", u) } } return }
func fetch(w http.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) imageUrl := r.FormValue("image") c.Infof("THIS IS IMAGE URL %v", imageUrl) client := urlfetch.Client(c) resp, err := client.Get(imageUrl) if error3(err, c, w) { return } blob, err := blobstore.Create(c, resp.Header.Get("Content-Type")) if error3(err, c, w) { return } written, err := io.Copy(blob, resp.Body) if error3(err, c, w) { return } if written < 100 { c.Infof("image is too small %v", written) return } err = blob.Close() if error3(err, c, w) { return } blobkey, err := blob.Key() if error3(err, c, w) { return } thumbnailUrl, err := image.ServingURL(c, blobkey, &image.ServingURLOptions{Size: 100}) if error3(err, c, w) { return } t := thumbnailUrl.String() errr := channel.Send(c, "qwerty", t) if error3(errr, c, w) { return } // c.Infof("THIS IS IMAGE URL %v", t) }
// Get the image link for an object. func api_imageLinkObject(w http.ResponseWriter, r *http.Request) { // We use the blob store + images to generate a serving url for the file c := appengine.NewContext(r) vars := mux.Vars(r) bk, err := blobstore.BlobKeyForFile(c, "/gs/"+bucketName+"/"+vars["key"]) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } if imageUrl, err := image.ServingURL(c, bk, nil); err == nil { fmt.Fprint(w, imageUrl) } else { http.Error(w, err.Error(), http.StatusInternalServerError) return } }
func UpdateServingUrl(w http.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) const batch = 300 page, _ := strconv.Atoi(r.FormValue("pg")) if page < 1 { page = 1 } offset := batch * (page - 1) q := datastore.NewQuery("Oferta").Offset(offset).Order("-FechaHora").Limit(batch) n, _ := q.Count(c) for i := q.Run(c); ; { var e model.Oferta key, err := i.Next(&e) if err == datastore.Done { break } // Se crea la URL para servir la oferta desde el CDN, si no se puede // se deja en blanco var imgprops image.ServingURLOptions imgprops.Secure = true imgprops.Size = 400 imgprops.Crop = false if e.BlobKey != "none" && e.Codigo == "" { if url, err := image.ServingURL(c, e.BlobKey, &imgprops); err != nil { c.Errorf("Cannot construct ServingURL : %v", e.IdOft) e.Codigo = "" } else { e.Codigo = url.String() } //c.Errorf("Get Cta Key; Error al intentar leer key.Parent() de Empresa : %v", e.IdEmp) _, err = datastore.Put(c, key, &e) if err != nil { c.Errorf("PutEmpresa(); Error al intentar actualizar empresa : %v", e.IdEmp) } } } c.Infof("UpdateServingUrl() Pagina: %d, actualizados: %d, del %d al %d", page, n, offset, offset+n) return }
func handleUpload(w http.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) blobs, other, err := blobstore.ParseUpload(r) if err != nil { serveError(c, w, err) return } mainPhoto := blobs["mainPhoto"][0].BlobKey creationTime := blobs["mainPhoto"][0].CreationTime result := ResultData{ Manufacturer: other["manufacturer"][0], MainPhoto: mainPhoto, CreationTime: creationTime, } key, err := datastore.Put(c, datastore.NewIncompleteKey(c, "lighting", nil), &result) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } var result2 ResultData if err = datastore.Get(c, key, &result2); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Header().Set("Content-Type", "text/html") url, err := image.ServingURL(c, result2.MainPhoto, nil) if err != nil { serveError(c, w, err) return } toPass := &ResultRead2{result2, template.HTML(url.String())} w.Header().Set("Content-Type", "text/html") err = uploadTemplate.Execute(w, toPass) if err != nil { serveError(c, w, err) return } }
func handleServeImgById(w http.ResponseWriter, r *http.Request) { if r.FormValue("id") != "none" { c := appengine.NewContext(r) oft, _ := model.GetOferta(c, r.FormValue("id")) if oft.BlobKey != "none" { var imgprops image.ServingURLOptions imgprops.Secure = true imgprops.Size = 400 imgprops.Crop = false if url, err := image.ServingURL(c, oft.BlobKey, &imgprops); err != nil { c.Infof("Cannot construct ServingURL : %v", r.FormValue("id")) blobstore.Send(w, oft.BlobKey) } else { http.Redirect(w, r, url.String(), http.StatusFound) } } else { w.WriteHeader(http.StatusNotFound) //w.Header().Set("Content-Type", "text/plain; charset=utf-8") //io.WriteString(w, "404 - Not Found") } } return }
func loadImage(c appengine.Context, f *Feed) { if f.ImageDate.After(time.Now()) { return } f.ImageDate = time.Now().Add(time.Hour * 24 * 7) s := f.Link if s == "" { s = f.Url } u, err := url.Parse(s) if err != nil { return } u.RawQuery = "" u.Fragment = "" p := "/favicon.ico" client := urlfetch.Client(c) if r, err := client.Get(u.String()); err == nil { b, err := ioutil.ReadAll(r.Body) r.Body.Close() if err == nil { i, err := FindIcon(b) if err == nil { p = i } } } u, err = u.Parse(p) if err != nil { return } r, err := client.Get(u.String()) if err != nil || r.StatusCode != http.StatusOK || r.ContentLength == 0 { return } b, err := ioutil.ReadAll(r.Body) r.Body.Close() if err != nil { return } buf := bytes.NewBuffer(b) _, t, err := image.DecodeConfig(buf) if err != nil { t = "application/octet-stream" } else { t = "image/" + t } w, err := blobstore.Create(c, t) if err != nil { return } if _, err := w.Write(b); err != nil { return } if w.Close() != nil { return } g := goon.FromContext(c) i := &Image{Id: u.String()} if err := g.Get(i); err == nil { blobstore.Delete(c, i.Blob) } i.Blob, _ = w.Key() su, err := aimage.ServingURL(c, i.Blob, &aimage.ServingURLOptions{Size: 16}) if err != nil { if err = blobstore.Delete(c, i.Blob); err != nil { c.Errorf("blob delete err: %v", err) } return } i.Url = su.String() g.Put(i) f.Image = i.Url }
func save(c appengine.Context, p *painting.Painting) error { if p.Image.URL != "" { // Fetch the image. res, err := urlfetch.Client(c).Get(p.Image.URL) if err != nil { logger.Error(c, err) return err } defer res.Body.Close() // Save what we read to decode the image config, // so we can save the whole image to the blobstore. buf := &bytes.Buffer{} t := io.TeeReader(res.Body, buf) // Decode the config to get the size and content type. conf, ext, err := image.DecodeConfig(t) if err != nil { logger.Error(c, err) return err } p.Image.Width = conf.Width p.Image.Height = conf.Height // Create a new blob. b, err := blobstore.Create(c, "image/"+ext) if err != nil { logger.Error(c, err) return err } // Copy the image into it. // Prepend what we read to decode the image config. r := io.MultiReader(buf, res.Body) _, err = io.Copy(b, r) if err != nil { logger.Error(c, err) return err } err = b.Close() if err != nil { logger.Error(c, err) return err } // Add the image to the painting. p.Image.BlobKey, err = b.Key() if err != nil { logger.Error(c, err) return err } u, err := aeimage.ServingURL(c, p.Image.BlobKey, nil) if err != nil { logger.Error(c, err) return err } p.Image.URL = u.String() } return p.Save(c) }
func (i *ImageIndex) FetchImage(info imageInfo, pageID string) { i.wg.Add(1) _, err := i.s.Conn.Storage("Image").NewQuery().KeysOnly(). Filter("Location", model.EQ, info.src).GetFirst(nil) if err != model.ErrNotFound { i.s.Log("Error: %s\n", "galleyes: indexed image") i.wg.Done() return } resp, err := i.s.Client.Get(info.src) if err != nil { i.s.Log("Error: %s\n", err.Error()) i.wg.Done() return } mime := resp.Header.Get("Content-Type") if mime != "image/png" && mime != "image/jpeg" && mime != "image/gif" { i.s.Log("Error: %s - %s - %s\n", "galleyes: not supported image format", mime, info.src) i.wg.Done() return } data, err := ioutil.ReadAll(resp.Body) if err != nil { i.s.Log("Error: %s\n", err.Error()) i.wg.Done() return } // caculate PHash var buff bytes.Buffer _, err = buff.Write(data) if err != nil { i.s.Log("Error: %s\n", err.Error()) i.wg.Done() return } m, _, err := tipimage.Decode(&buff) if err != nil { i.s.Log("Error: %s\n", err.Error()) i.wg.Done() return } hash, part := PHash(m) // caculate md5 checksum h := md5.New() _, err = h.Write(data) if err != nil { i.s.Log("Error: %s\n", err.Error()) i.wg.Done() return } checksum := h.Sum(nil) // save the original image w, err := blobstore.Create(i.s.Context, mime) if err != nil { i.s.Log("Error: %s\n", err.Error()) i.wg.Done() return } w.Write(data) _, err = w.Write(data) if err != nil { i.s.Log("Error: %s\n", err.Error()) i.wg.Done() return } err = w.Close() if err != nil { i.s.Log("Error: %s\n", err.Error()) i.wg.Done() return } key, err := w.Key() if err != nil { i.s.Log("Error: %s\n", err.Error()) i.wg.Done() return } link, err := imgs.ServingURL(i.s.Context, key, nil) if err != nil { i.s.Log("Error: %s\n", err.Error()) i.wg.Done() return } // assign value img := Image{} img.PageID = pageID img.SavedID = string(key) img.SavedLocation = link.String() img.Location = info.src img.Description = info.alt img.CheckSum = base64.URLEncoding.EncodeToString(checksum) img.PHash = hash img.Part0 = part[0] img.Part1 = part[1] img.Part2 = part[2] img.Part3 = part[3] img.Part4 = part[4] img.Part5 = part[5] img.Part6 = part[6] img.Part7 = part[7] _, err = i.s.Conn.Storage("Image").Put(&img) if err != nil { i.s.Log("Error: %s\n", err.Error()) i.wg.Done() return } i.wg.Done() }
// upload is the HTTP handler for uploading images; it handles "/". func upload(w http.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) var imgprops appimage.ServingURLOptions imgprops.Secure = true imgprops.Size = 180 imgprops.Crop = false if s, ok := sess.IsSess(w, r, c); ok { u, _ := model.GetCta(c, s.User) emp, err := u.GetEmpresa(c, r.FormValue("IdEmp")) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } imgo := model.GetLogo(c, r.FormValue("IdEmp")) if imgo == nil { imgo = new(model.Image) imgo.IdEmp = emp.IdEmp } fd := imgToForm(*imgo) tc := make(map[string]interface{}) tc["Sess"] = s tc["Empresa"] = emp tc["FormData"] = fd if r.Method != "POST" { // No upload; show the upload form. micrositio(w, r) return } idemp := r.FormValue("IdEmp") sp1 := r.FormValue("Sp1") sp2 := r.FormValue("Sp2") f, _, err := r.FormFile("image") model.Check(err) defer f.Close() // Grab the image data var buf bytes.Buffer io.Copy(&buf, f) i, _, err := image.Decode(&buf) if err != nil { if r.FormValue("tipo") == "async" { //w.Header().Set("Content-Type", "application/json") fmt.Fprintf(w, "<p>'%s'</p>", "No se actualizó el logotipo, formato no aceptado") } else { tc["Error"] = struct{ Badformat string }{"badformat"} micrositioTpl.Execute(w, tc) } return } const max = 600 // We aim for less than max pixels in any dimension. if b := i.Bounds(); b.Dx() > max || b.Dy() > max { // If it's gigantic, it's more efficient to downsample first // and then resize; resizing will smooth out the roughness. if b.Dx() > 2*max || b.Dy() > 2*max { w, h := max*2, max*2 if b.Dx() > b.Dy() { h = b.Dy() * h / b.Dx() } else { w = b.Dx() * w / b.Dy() } i = resize.Resample(i, i.Bounds(), w, h) b = i.Bounds() } w, h := max, max if b.Dx() > b.Dy() { h = b.Dy() * h / b.Dx() } else { w = b.Dx() * w / b.Dy() } i = resize.Resize(i, i.Bounds(), w, h) } // Encode as a new JPEG image. buf.Reset() err = jpeg.Encode(&buf, i, nil) if err != nil { if r.FormValue("tipo") == "async" { fmt.Fprintf(w, "<p>'%s'</p>", "No se actualizó el logotipo, formato no aceptado") } else { tc["Error"] = struct{ Badencode string }{"badencode"} micrositioTpl.Execute(w, tc) } return } var blobkey appengine.BlobKey blob, err := blobstore.Create(c, "image/jpeg") if err != nil { c.Errorf("blobstore Create: %v", idemp) } _, err = blob.Write(buf.Bytes()) if err != nil { c.Errorf("blobstore Write: %v", idemp) } err = blob.Close() if err != nil { c.Errorf("blobstore Close: %v", idemp) } blobkey, err = blob.Key() if err != nil { c.Errorf("blobstore Key Gen: %v", idemp) } if url, err := appimage.ServingURL(c, blobkey, &imgprops); err != nil { c.Errorf("Cannot construct EmpLogo ServingURL : %v", idemp) } else { // Save the image under a unique key, a hash of the image. img := &model.Image{ Data: buf.Bytes(), IdEmp: idemp, IdImg: model.RandId(20), Kind: "EmpLogo", Name: imgo.Name, Desc: imgo.Desc, Sizepx: 0, Sizepy: 0, Url: imgo.Url, Type: "", Sp1: sp1, Sp2: sp2, Sp3: string(blobkey), Sp4: url.String(), Np1: 0, Np2: 0, Np3: 0, Np4: 0, } _, err = model.PutLogo(c, img) if err != nil { if r.FormValue("tipo") == "async" { fmt.Fprintf(w, "<p>'%s'</p>", "No se actualizó el logotipo. Sistema en matenimiento, intente en unos minutos") } else { tc["Error"] = struct{ Cantsave string }{"cantsave"} micrositioTpl.Execute(w, tc) } return } } /* se crea icono */ val := slogores(c, idemp, 70, 0) if val != 0 { tc["Error"] = struct{ Cantsave string }{"cantsave"} micrositioTpl.Execute(w, tc) return } if r.FormValue("tipo") == "async" { fmt.Fprintf(w, "<p></p>") } else { micrositio(w, r) } return } else { http.Redirect(w, r, "/r/registro", http.StatusFound) } }
// rotate rotates the Painting's image counter-clockwise by angle in degrees. // angle modulo 360 must be one of 0, 90, 180, 270. func (p *Painting) rotate(c appengine.Context, angle int) error { switch math.Abs(float64(angle % 360)) { case 0, 90, 180, 270: break default: return errors.New(fmt.Sprintf("painting: Unsupported angle %f.", angle)) } if p.Image == (Image{}) { return nil } // Read the image from the blobstore. r := blobstore.NewReader(c, p.Image.BlobKey) src, _, err := image.Decode(r) if err != nil { return err } // Create the rotated image. srcRect := src.Bounds() var dstRect image.Rectangle if angle == 0 || angle == 180 { dstRect = srcRect } else { dstRect = image.Rect(0, 0, srcRect.Dy(), srcRect.Dx()) } dst := image.NewNRGBA(dstRect) err = graphics.Rotate(dst, src, &graphics.RotateOptions{ Angle: float64(angle%360) * math.Pi / 180, }) if err != nil { return err } // Create a new blob for the rotated image. w, err := blobstore.Create(c, "image/png") if err != nil { return err } err = png.Encode(w, dst) if err != nil { return err } err = w.Close() if err != nil { return err } // Delete the old blob. deleteBlobLater.Call(c, p.Image.BlobKey) // Update the image metadata. p.Image.BlobKey, err = w.Key() if err != nil { return err } p.Image.Width = dstRect.Dx() p.Image.Height = dstRect.Dy() u, err := aeimage.ServingURL(c, p.Image.BlobKey, nil) if err != nil { return err } p.Image.URL = u.String() err = p.Save(c) if err != nil { return err } return nil }
func storeAttachments(c appengine.Context, rawAttachments []AttachmentJSON) ([]*datastore.Key, error) { keys := []*datastore.Key{} for _, rawAttachment := range rawAttachments { bytes, err := base64.StdEncoding.DecodeString(rawAttachment.Content) if err != nil { return nil, fmt.Errorf("failed to decode attachment '%v':", rawAttachment.Name, err) } w, err := blobstore.Create(c, rawAttachment.ContentType) if err != nil { return nil, fmt.Errorf("failed to create blobstore entry: %v", err) } _, err = w.Write(bytes) if err != nil { return nil, fmt.Errorf("failed to write to blobstore: %v", err) } err = w.Close() if err != nil { return nil, fmt.Errorf("failed to close blobstore entry: %v", err) } blobKey, err := w.Key() if err != nil { return nil, fmt.Errorf("failed to get key for blobstore entry: %v", err) } thumbnailURL, err := image.ServingURL(c, blobKey, &image.ServingURLOptions{ Secure: true, Size: 400, Crop: false, }) if err != nil { return nil, fmt.Errorf("failed to create thumbnail: %v", err) } bigImageURL, err := image.ServingURL(c, blobKey, &image.ServingURLOptions{ Secure: true, Size: 1600, Crop: false, }) if err != nil { return nil, fmt.Errorf("failed to create big image: %v", err) } e := Attachment{ Name: rawAttachment.Name, Content: blobKey, ContentType: rawAttachment.ContentType, CreationTime: time.Now(), Thumbnail: thumbnailURL.String(), BigImage: bigImageURL.String(), } key, err := datastore.Put(c, datastore.NewIncompleteKey(c, "Attachment", nil), &e) if err != nil { return nil, fmt.Errorf("Failed to save to datastore: %s", err) } keys = append(keys, key) } return keys, nil }
func handleUpload(w http.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) var out OfImg blobOpts := blobstore.UploadURLOptions{ MaxUploadBytesPerBlob: 1048576, } out.Status = "invalidId" out.IdBlob = "" if _, ok := sess.IsSess(w, r, c); ok { blobs, form, err := blobstore.ParseUpload(r) file := blobs["image"] out.IdBlob = string(file[0].BlobKey) out.IdOft = form.Get("IdOft") if err != nil { out.Status = "invalidUpload" berr := blobstore.Delete(c, file[0].BlobKey) model.Check(berr) } else { oferta, _ := model.GetOferta(c, out.IdOft) if oferta.IdEmp == "none" { out.Status = "invalidUpload" berr := blobstore.Delete(c, file[0].BlobKey) model.Check(berr) } else { out.Status = "ok" if len(file) == 0 { out.Status = "invalidUpload" berr := blobstore.Delete(c, file[0].BlobKey) model.Check(berr) } else { var oldblobkey = oferta.BlobKey oferta.BlobKey = file[0].BlobKey out.IdOft = oferta.IdOft // Se crea la URL para servir la oferta desde el CDN, si no se puede var imgprops image.ServingURLOptions imgprops.Secure = true imgprops.Size = 400 imgprops.Crop = false if url, err := image.ServingURL(c, oferta.BlobKey, &imgprops); err != nil { c.Errorf("Cannot construct ServingURL : %v", oferta.IdOft) oferta.Codigo = "" } else { oferta.Codigo = url.String() } err = model.PutOferta(c, oferta) if err != nil { out.Status = "invalidUpload" berr := blobstore.Delete(c, file[0].BlobKey) model.Check(berr) } /* Se borra el blob anterior, porque siempre crea uno nuevo No se necesita revisar el error Si es el blobkey = none no se borra por obvias razones Se genera una sesion nueva de upload en caso de que quieran cambiar la imágen en la misma pantalla. Esto es debido a que se utiliza un form estático con ajax */ if oldblobkey != "none" { blobstore.Delete(c, oldblobkey) UploadURL, err := blobstore.UploadURL(c, "/r/ofimgup", &blobOpts) out.UploadURL = UploadURL.String() if err != nil { out.Status = "uploadSessionError" } } } } } } w.Header().Set("Content-Type", "application/json") b, _ := json.Marshal(out) w.Write(b) }