func Delete(c *gin.Context, blobKey appengine.BlobKey) { r := c.Request appengine.NewContext(r) err := blobstore.Delete(c, blobKey) var err_msg string if err != nil { err_msg = "failed" } c.JSON(http.StatusOK, gin.H{"err": err_msg, "blobKey": string(blobKey)}) }
func handleFilesItem(w http.ResponseWriter, r *http.Request) { id := r.URL.Path if id == "" { w.WriteHeader(404) return } c := appengine.NewContext(r) key := datastore.NewKey(c, "File", id, 0, nil) switch r.Method { case "GET": var file File err := datastore.Get(c, key, &file) if err == datastore.ErrNoSuchEntity { http.NotFound(w, r) return } if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) log.Errorf(c, "query file: %s", err.Error()) return } w.Header().Set("Content-Type", "application/json") err = json.NewEncoder(w).Encode(&file) if err != nil { log.Errorf(c, "json encode: %s", err.Error()) } case "DELETE": err := datastore.Delete(c, key) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) log.Errorf(c, "delete file: %s", err.Error()) return } err = blobstore.Delete(c, appengine.BlobKey(id)) if err != nil { log.Warningf(c, "delete file '%s': %s", id, err.Error()) } w.WriteHeader(204) default: http.Error(w, "Valid methods are GET and DELETE", http.StatusMethodNotAllowed) return } }
func handleImagesItem(w http.ResponseWriter, r *http.Request) { id := r.URL.Path if id == "" { w.WriteHeader(404) return } c := appengine.NewContext(r) key := datastore.NewKey(c, "Image", id, 0, nil) switch r.Method { case "GET": var img Image err := datastore.Get(c, key, &img) if err == datastore.ErrNoSuchEntity { w.WriteHeader(404) return } if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) log.Errorf(c, "query image: %s", err.Error()) return } w.Header().Set("Content-Type", "application/json") err = json.NewEncoder(w).Encode(&img) if err != nil { log.Errorf(c, "json encode: %s", err.Error()) } case "DELETE": err := datastore.Delete(c, key) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) log.Errorf(c, "delete image: %s", err.Error()) return } err = blobstore.Delete(c, appengine.BlobKey(id)) if err != nil { log.Warningf(c, "delete image '%s': %s", id, err.Error()) } w.WriteHeader(204) case "PUT": var img Image err := json.NewDecoder(r.Body).Decode(&img) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } if img.ID != id { http.Error(w, "Image ID must match URL ID", http.StatusBadRequest) return } _, err = datastore.Put(c, key, &img) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) log.Errorf(c, "put image: %s", err.Error()) return } w.WriteHeader(204) default: http.Error(w, "Valid methods are GET, DELETE and PUT", http.StatusMethodNotAllowed) return } }
func handleImages(w http.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) switch r.Method { case "POST": blobs, vals, err := blobstore.ParseUpload(r) if err != nil { http.Error(w, "bad request", http.StatusBadRequest) log.Errorf(c, "bad request: %s", err.Error()) return } bucketID := vals.Get("BucketID") if bucketID == "" { http.Error(w, "BucketID query parameter is required", http.StatusBadRequest) return } url, err := blobstore.UploadURL(c, "/admin/images", nil) if err == nil { w.Header().Set("UploadURL", url.String()) } imgs := make([]Image, 0, 20) for _, infos := range blobs { for _, info := range infos { var img Image img.Name = info.Filename imgUrl, err := aimage.ServingURL(c, info.BlobKey, nil) if err != nil { log.Errorf(c, "failed to get serving url for blob '%s': %s", info.BlobKey, err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError) return } img.URL = imgUrl.String() img.ID = string(info.BlobKey) ir := blobstore.NewReader(c, info.BlobKey) cfg, _, err := image.DecodeConfig(ir) if err != nil { log.Warningf(c, "decode image '%s': %s", info.BlobKey, err.Error()) err = blobstore.Delete(c, info.BlobKey) if err != nil { log.Errorf(c, "delete blob '%s': %s", info.BlobKey, err.Error()) } continue } img.Height = cfg.Height img.Width = cfg.Width imgs = append(imgs, img) } } // add images to bucket and dtore err = datastore.RunInTransaction(c, func(c context.Context) error { bucketKey := datastore.NewKey(c, "Bucket", bucketID, 0, nil) var b Bucket err := datastore.Get(c, bucketKey, &b) if err != nil { return err } if b.Images == nil { b.Images = make([]string, 0, len(imgs)) } for _, img := range imgs { _, err = datastore.Put(c, datastore.NewKey(c, "Image", img.ID, 0, nil), &img) if err != nil { return err } b.Images = append(b.Images, img.ID) } _, err = datastore.Put(c, bucketKey, &b) return err }, &datastore.TransactionOptions{XG: true}) if err == datastore.ErrNoSuchEntity { for _, img := range imgs { err = blobstore.Delete(c, appengine.BlobKey(img.ID)) if err != nil { log.Warningf(c, "delete blob '%s': %s", img.ID, err.Error()) } } http.NotFound(w, r) return } if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) log.Errorf(c, "update datastore: %s", err.Error()) return } w.Header().Set("Content-Type", "application/json") err = json.NewEncoder(w).Encode(&imgs) if err != nil { log.Errorf(c, "json encode: %s", err.Error()) } case "GET": var imgs []Image _, err := datastore.NewQuery("Image").GetAll(c, &imgs) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) log.Errorf(c, "query images: %s", err.Error()) return } w.Header().Set("Content-Type", "application/json") if imgs == nil { imgs = []Image{} } err = json.NewEncoder(w).Encode(&imgs) if err != nil { log.Errorf(c, "json encode: %s", err.Error()) } default: http.Error(w, "Valid methods are GET and POST", http.StatusMethodNotAllowed) return } }
func handleBucketsItem(w http.ResponseWriter, r *http.Request) { id := r.URL.Path if id == "" { w.WriteHeader(404) return } c := appengine.NewContext(r) key := datastore.NewKey(c, "Bucket", id, 0, nil) switch r.Method { case "GET": var b Bucket err := datastore.Get(c, key, &b) if err == datastore.ErrNoSuchEntity { w.WriteHeader(404) return } if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) log.Errorf(c, "query bucket: %s", err.Error()) return } w.Header().Set("Content-Type", "application/json") err = json.NewEncoder(w).Encode(&b) if err != nil { log.Errorf(c, "json encode: %s", err.Error()) } case "PUT": var b Bucket err := json.NewDecoder(r.Body).Decode(&b) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } if b.ID != id { http.Error(w, "Bucket ID must match URL ID", http.StatusBadRequest) return } _, err = datastore.Put(c, key, &b) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) log.Errorf(c, "put bucket: %s", err.Error()) return } w.WriteHeader(204) case "DELETE": err := datastore.RunInTransaction(c, func(c context.Context) error { metaKey := datastore.NewKey(c, "Meta", "main", 0, nil) var m Meta err := datastore.Get(c, metaKey, &m) if err != nil { return err } b := m.Buckets[:0] for _, bucket := range m.Buckets { if bucket == id { continue } b = append(b, bucket) } m.Buckets = b _, err = datastore.Put(c, metaKey, &m) if err != nil { return err } return err }, &datastore.TransactionOptions{XG: true}) if err != nil { log.Warningf(c, "update meta: %s", err.Error()) } var bk Bucket err = datastore.Get(c, key, &bk) if err == nil && bk.Images != nil { // delete images for _, id := range bk.Images { err = blobstore.Delete(c, appengine.BlobKey(id)) if err != nil { log.Warningf(c, "delete image blob '%s': %s", id, err.Error()) } err = datastore.Delete(c, datastore.NewKey(c, "Image", id, 0, nil)) if err != nil { log.Warningf(c, "delete image entry '%s': %s", id, err.Error()) } } } err = datastore.Delete(c, key) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) log.Errorf(c, "delete bucket: %s", err.Error()) return } w.WriteHeader(204) default: http.Error(w, "Valid methods are GET, DELETE and PUT", http.StatusMethodNotAllowed) return } }
func renameOrDelete(w http.ResponseWriter, r *http.Request, m map[string]interface{}) { lg, b := loghttp.BuffLoggerUniversal(w, r) _ = b c := appengine.NewContext(r) b1 := new(bytes.Buffer) s1 := "" defer func() { w.Header().Set("Content-type", "text/html; charset=utf-8") w.Write(b1.Bytes()) }() // c := appengine.NewContext(r) bk := r.FormValue("blobkey") if bk == "" { b1.WriteString("No blob key given<br>") return } else { s1 = fmt.Sprintf("Blob key given %q<br>", bk) b1.WriteString(s1) } dsKey := datastore.NewKey(c, "__BlobInfo__", bk, 0, nil) q := datastore.NewQuery("__BlobInfo__").Filter("__key__=", dsKey) var bi BlobInfo var found bool for t := q.Run(c); ; { _, err := t.Next(&bi) if err == datastore.Done { aelog.Infof(c, " No Results (any more), blob-rename-delete %v", err) break } // other err if err != nil { lg(err) return } found = true break } if found { ac := r.FormValue("action") if ac == "delete" { b1.WriteString("deletion ") // first the binary data keyBlob, err := blobstore.BlobKeyForFile(c, bi.Filename) lg(err) if err != nil { b1.WriteString(fmt.Sprintf(" ... failed (1) %v", err)) } else { err = blobstore.Delete(c, keyBlob) lg(err) if err != nil { b1.WriteString(fmt.Sprintf(" ... failed (2) %v<br>", err)) } else { // now the datastore record err = datastore.Delete(c, dsKey) lg(err) if err != nil { b1.WriteString(fmt.Sprintf(" ... failed (3) %v<br>%#v<br>", err, dsKey)) } else { b1.WriteString(" ... succeeded<br>") } } } } if ac == "rename" { b1.WriteString("renaming ") nfn := r.FormValue("filename") if nfn == "" || len(nfn) < 4 { b1.WriteString(" ... failed - at LEAST 4 chars required<br>") return } nfn = strings.ToLower(nfn) bi.Filename = nfn _, err := datastore.Put(c, dsKey, &bi) lg(err) if err != nil { b1.WriteString(fmt.Sprintf(" ... failed. %v", err)) } else { b1.WriteString(" ... succeeded<br>") } } } else { b1.WriteString("no blob found for given blobkey<br>") } b1.WriteString("<a href='/blob2'>Back to list</a><br>") }