Пример #1
0
func Delete(k int64, r *http.Request) (err error) {
	c := appengine.NewContext(r)
	key := datastore.NewKey(c, "Photo", "", k, nil)

	// Get the database record
	var p Photo
	err = datastore.Get(c, key, &p)
	if err != nil {
		return
	}

	// Now we need to clean up the blobstore
	// First we'll drop out the full resolution image
	// then the thumbnail
	err = blobstore.Delete(c, appengine.BlobKey(p.Blob))
	if len(p.Thumb) != 0 {
		err = blobstore.Delete(c, appengine.BlobKey(p.Thumb))
	}

	log.Println(err)
	if err != nil {
		return
	}

	// Delete from the database
	err = datastore.Delete(c, key)
	if err != nil {
		return
	}

	return
}
Пример #2
0
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)
}
Пример #3
0
func (sto *appengineStorage) Fetch(br blob.Ref) (file io.ReadCloser, size uint32, err error) {
	loan := ctxPool.Get()
	ctx := loan
	defer func() {
		if loan != nil {
			loan.Return()
		}
	}()

	row, err := fetchEnt(ctx, br)
	if err == datastore.ErrNoSuchEntity {
		err = os.ErrNotExist
		return
	}
	if err != nil {
		return
	}
	if !row.inNamespace(sto.namespace) {
		err = os.ErrNotExist
		return
	}

	closeLoan := loan
	var c io.Closer = &onceCloser{fn: func() { closeLoan.Return() }}
	loan = nil // take it, so it's not defer-closed

	reader := blobstore.NewReader(ctx, appengine.BlobKey(string(row.BlobKey)))
	type readCloser struct {
		io.Reader
		io.Closer
	}
	return readCloser{reader, c}, uint32(row.Size), nil
}
Пример #4
0
func (p paintings) convert(w http.ResponseWriter, c appengine.Context, cs categories, ms media) {
	for _, o := range p {
		old := o.Fields
		p := &painting.Painting{
			Object: object.New(
				painting.Kind,
				strconv.Itoa(old.Number),
			),
			Title: old.Title,
			Image: painting.Image{
				BlobKey: appengine.BlobKey(" "),
			},
			Description: old.Description,
			Year:        old.Year,
			Categories:  cs.convert(old.Categories),
			Media:       ms.convert(old.Medium),
			Price:       old.Price,
			Width:       old.Width,
			Height:      old.Height,
			ForSale:     old.Status == "F",
		}
		if old.Image != "" {
			p.Image.URL = baseURL + old.Image
		}
		saveLater.Call(c, p)
	}
}
Пример #5
0
Файл: anif.go Проект: hamax/avy
// Get a file that is part of a visualization
func getVisualizationFile(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)
	vars := mux.Vars(r)

	// Get visualization object
	key, err := datastore.DecodeKey(vars["key"])
	if err != nil {
		common.Serve404(w)
		return
	}

	var e model.Visualization
	err = datastore.Get(c, key, &e)
	if err != nil {
		if err == datastore.ErrNoSuchEntity {
			common.Serve404(w)
			return
		}
		common.ServeError(c, w, err)
		return
	}

	// Find blob key
	filename := vars["filename"]
	for i := range e.Files {
		if e.Files[i].Filename == filename {
			blobstore.Send(w, appengine.BlobKey(e.Files[i].BlobKey))
			return
		}
	}

	common.Serve404(w)
}
Пример #6
0
func cleanImage(w http.ResponseWriter, r *http.Request) {
	// Con esta manejador borramos las imagenes que no están asociadas a
	// ningún punto y han quedado huerfanas

	c := appengine.NewContext(r)

	var blobs []blobstore.BlobInfo

	q := datastore.NewQuery("__BlobInfo__")
	keys, _ := q.GetAll(c, &blobs)
	for _, key := range keys {

		var imgk = appengine.BlobKey(key.StringID())

		// Busco algun punto con esa key como imagen
		var points []points.Point
		qp := datastore.NewQuery("points").Filter("ImageKey = ", imgk)
		qp.GetAll(c, &points)
		if len(points) == 0 {
			// borro la imagen
			c.Infof("borro imagen %s", imgk)
			err := blobstore.Delete(c, imgk)
			if err != nil {
				app.ServeError(c, w, err)
				return
			}
		}
	}
}
Пример #7
0
// propValue returns a Go value that combines the raw PropertyValue with a
// meaning. For example, an Int64Value with GD_WHEN becomes a time.Time.
func propValue(v *pb.PropertyValue, m pb.Property_Meaning) (interface{}, error) {
	switch {
	case v.Int64Value != nil:
		if m == pb.Property_GD_WHEN {
			return fromUnixMicro(*v.Int64Value), nil
		} else {
			return *v.Int64Value, nil
		}
	case v.BooleanValue != nil:
		return *v.BooleanValue, nil
	case v.StringValue != nil:
		if m == pb.Property_BLOB {
			return []byte(*v.StringValue), nil
		} else if m == pb.Property_BLOBKEY {
			return appengine.BlobKey(*v.StringValue), nil
		} else if m == pb.Property_BYTESTRING {
			return ByteString(*v.StringValue), nil
		} else {
			return *v.StringValue, nil
		}
	case v.DoubleValue != nil:
		return *v.DoubleValue, nil
	case v.Referencevalue != nil:
		key, err := referenceValueToKey(v.Referencevalue)
		if err != nil {
			return nil, err
		}
		return key, nil
	case v.Pointvalue != nil:
		// NOTE: Strangely, latitude maps to X, longitude to Y.
		return appengine.GeoPoint{Lat: v.Pointvalue.GetX(), Lng: v.Pointvalue.GetY()}, nil
	}
	return nil, nil
}
Пример #8
0
func downloadTranslationHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method != "GET" {
		panic(&core.Error{http.StatusMethodNotAllowed, ""})
	}

	// parses query parameters
	params, err := url.ParseQuery(r.URL.RawQuery)
	if err != nil {
		panic(&core.Error{http.StatusBadRequest, ""})
	}

	// TODO supports other query params

	blobKey := params.Get("blobKey")

	translations, err := loadTranslations(appengine.NewContext(r), false)
	if err != nil {
		panic(&core.Error{http.StatusInternalServerError, err.Error()})
	}
	for _, t := range translations {
		if (string)(t.BlobKey) == blobKey {
			blobstore.Send(w, appengine.BlobKey(blobKey))
			return
		}
	}

	panic(&core.Error{http.StatusNotFound, ""})
}
Пример #9
0
// Key returns the created blob key. It must be called after Close.
// An error is returned if Close wasn't called or returned an error.
func (w *Writer) Key() (appengine.BlobKey, error) {
	if !w.closed {
		return "", errorf("cannot call Key before Close")
	}

	if w.blobKey != "" {
		return w.blobKey, w.closeErr
	}

	handle := w.filename[len(blobstoreFileDirectory):]
	if !strings.HasPrefix(handle, creationHandlePrefix) {
		w.blobKey = appengine.BlobKey(handle)
		return w.blobKey, w.closeErr
	}

	k, err := w.keyNewWay(handle)
	if err == nil {
		w.blobKey = k
		return k, nil
	}

	k, err = w.keyOldWay(handle)
	if err == nil {
		w.blobKey = k
	}

	return k, err
}
Пример #10
0
// propValue returns a Go value that combines the raw PropertyValue with a
// meaning. For example, an Int64Value with GD_WHEN becomes a time.Time.
func propValue(v *pb.PropertyValue, m pb.Property_Meaning) (interface{}, error) {
	switch {
	case v.Int64Value != nil:
		if m == pb.Property_GD_WHEN {
			return fromUnixMicro(*v.Int64Value), nil
		} else {
			return *v.Int64Value, nil
		}
	case v.BooleanValue != nil:
		return *v.BooleanValue, nil
	case v.StringValue != nil:
		if m == pb.Property_BLOB {
			return []byte(*v.StringValue), nil
		} else if m == pb.Property_BLOBKEY {
			return appengine.BlobKey(*v.StringValue), nil
		} else {
			return *v.StringValue, nil
		}
	case v.DoubleValue != nil:
		return *v.DoubleValue, nil
	case v.Referencevalue != nil:
		key, err := referenceValueToKey(v.Referencevalue)
		if err != nil {
			return nil, err
		}
		return key, nil
	}
	return nil, nil
}
Пример #11
0
func delete(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)
	var dTile Tile
	//	var now Period
	//	datastore.Get(c, currentSemesterKey(c), &now)
	num, e := strconv.Atoi(r.FormValue("num"))
	sem, e1 := strconv.Atoi(r.FormValue("semester"))
	yr, e2 := strconv.Atoi(r.FormValue("year"))
	if e != nil || e1 != nil || e2 != nil {
		panic("shouldn't happen; semester and year guaranteed to be ints")
	}
	k := datastore.NewKey(c, "Tile", strint(r.FormValue("name"), num), 0, tileRootKey(c, sem, yr))
	datastore.Get(c, k, &dTile)
	if u := user.Current(c); !u.Admin {
		http.Redirect(w, r, "/", http.StatusFound)
		return
	} else {
		log.Println("deleting things now...")
		e1 := blobstore.Delete(c, appengine.BlobKey(dTile.Imgref))
		e2 := datastore.Delete(c, k)
		if e1 != nil {
			log.Println("error with blobstore delete")
		}
		if e2 != nil {
			log.Println("error with datastore delete")
		}
	}
	log.Println("redirecting")
	http.Redirect(w, r, "/", http.StatusFound)
}
Пример #12
0
func Delete(rw http.ResponseWriter, req *http.Request, r render.Render, params martini.Params) {
	ctx := appengine.NewContext(req)

	b := banner.Banner{}

	intID, err := strconv.Atoi(params["id"])
	if err == nil {
		b.ID = int64(intID)
	}

	if err := b.Get(ctx); err != nil {
		http.Error(rw, "failed to delete banner", http.StatusInternalServerError)
		return
	}

	segs := strings.Split(b.Image, "/")
	blobstore.Delete(ctx, appengine.BlobKey(segs[len(segs)-1]))

	if err := b.Delete(ctx); err != nil {
		http.Error(rw, "failed to delete banner", http.StatusInternalServerError)
		return
	}

	r.Status(200)
	return
}
Пример #13
0
func (fileStore *blobstoreFileStore) RemoveFiles(fileKeys []string) {
	keys := make([]appengine.BlobKey, len(fileKeys))
	for i := 0; i < len(fileKeys); i++ {
		keys[i] = appengine.BlobKey(fileKeys[i])
	}

	blobstore.DeleteMulti(fileStore.context, keys)
}
Пример #14
0
// loadMapEntry converts a Property into an entry of an existing Map,
// or into an element of a slice-valued Map entry.
func loadMapEntry(m Map, k *Key, p *pb.Property) os.Error {
	var (
		result    interface{}
		sliceType reflect.Type
	)
	switch {
	case p.Value.Int64Value != nil:
		if p.Meaning != nil && *p.Meaning == pb.Property_GD_WHEN {
			result = Time(*p.Value.Int64Value)
			sliceType = reflect.TypeOf([]Time(nil))
		} else {
			result = *p.Value.Int64Value
			sliceType = reflect.TypeOf([]int64(nil))
		}
	case p.Value.BooleanValue != nil:
		result = *p.Value.BooleanValue
		sliceType = reflect.TypeOf([]bool(nil))
	case p.Value.StringValue != nil:
		if p.Meaning != nil && *p.Meaning == pb.Property_BLOB {
			result = []byte(*p.Value.StringValue)
			sliceType = reflect.TypeOf([][]byte(nil))
		} else if p.Meaning != nil && *p.Meaning == pb.Property_BLOBKEY {
			result = appengine.BlobKey(*p.Value.StringValue)
			sliceType = reflect.TypeOf([]appengine.BlobKey(nil))
		} else {
			result = *p.Value.StringValue
			sliceType = reflect.TypeOf([]string(nil))
		}
	case p.Value.DoubleValue != nil:
		result = *p.Value.DoubleValue
		sliceType = reflect.TypeOf([]float64(nil))
	case p.Value.Referencevalue != nil:
		key, err := referenceValueToKey(p.Value.Referencevalue)
		if err != nil {
			return err
		}
		result = key
		sliceType = reflect.TypeOf([]*Key(nil))
	default:
		return nil
	}
	name := proto.GetString(p.Name)
	if proto.GetBool(p.Multiple) {
		var s reflect.Value
		if x := m[name]; x != nil {
			s = reflect.ValueOf(x)
		} else {
			s = reflect.MakeSlice(sliceType, 0, 0)
		}
		s = reflect.Append(s, reflect.ValueOf(result))
		m[name] = s.Interface()
	} else {
		m[name] = result
	}
	return nil
}
Пример #15
0
// BlobKeyForFile returns a BlobKey for a Google Storage file.
// The filename should be of the form "/gs/bucket_name/object_name".
func BlobKeyForFile(c appengine.Context, filename string) (appengine.BlobKey, error) {
	req := &blobpb.CreateEncodedGoogleStorageKeyRequest{
		Filename: &filename,
	}
	res := &blobpb.CreateEncodedGoogleStorageKeyResponse{}
	if err := c.Call("blobstore", "CreateEncodedGoogleStorageKey", req, res, nil); err != nil {
		return "", err
	}
	return appengine.BlobKey(*res.BlobKey), nil
}
Пример #16
0
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)
	}
}
Пример #17
0
func protoToProperties(dst chan<- Property, errc chan<- error, src *pb.EntityProto) {
	defer close(dst)
	props, rawProps := src.Property, src.RawProperty
	for {
		var (
			x       *pb.Property
			noIndex bool
		)
		if len(props) > 0 {
			x, props = props[0], props[1:]
		} else if len(rawProps) > 0 {
			x, rawProps = rawProps[0], rawProps[1:]
			noIndex = true
		} else {
			break
		}

		var value interface{}
		switch {
		case x.Value.Int64Value != nil:
			if x.Meaning != nil && *x.Meaning == pb.Property_GD_WHEN {
				value = fromUnixMicro(*x.Value.Int64Value)
			} else {
				value = *x.Value.Int64Value
			}
		case x.Value.BooleanValue != nil:
			value = *x.Value.BooleanValue
		case x.Value.StringValue != nil:
			if x.Meaning != nil && *x.Meaning == pb.Property_BLOB {
				value = []byte(*x.Value.StringValue)
			} else if x.Meaning != nil && *x.Meaning == pb.Property_BLOBKEY {
				value = appengine.BlobKey(*x.Value.StringValue)
			} else {
				value = *x.Value.StringValue
			}
		case x.Value.DoubleValue != nil:
			value = *x.Value.DoubleValue
		case x.Value.Referencevalue != nil:
			key, err := referenceValueToKey(x.Value.Referencevalue)
			if err != nil {
				errc <- err
				return
			}
			value = key
		}
		dst <- Property{
			Name:     x.GetName(),
			Value:    value,
			NoIndex:  noIndex,
			Multiple: x.GetMultiple(),
		}
	}
	errc <- nil
}
Пример #18
0
func (photo Photo) Store(r *http.Request) (err error) {
	c := appengine.NewContext(r)

	photo.Added = time.Now()
	_, err = datastore.Put(c, datastore.NewIncompleteKey(c, "Photo", nil), &photo)

	if err != nil {
		_ = blobstore.Delete(c, appengine.BlobKey(photo.Blob))
	}
	return
}
Пример #19
0
func blob(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)
	w.Header().Set("Content-Type", "image/png")
	f := blobstore.NewReader(c, appengine.BlobKey("AMIfv97HhOdzO1aYQEe0QBrzbWSjSgWr2-JUxFJh_KnwxAhEdAqqK76TeE7vm5eDJW0ZoMwFVwur0Ub3t1kD_KzP3yJi4LIG6A-dCdJrJYafoJgH7SITCBum4MF9CY-C7na5fBulmKwQXd2mEYMyfk_RDgeQN1SZug"))
	buf := make([]byte, 1024*1024)
	n, err := f.Read(buf)
	if err != nil {
		panic(err)
	}
	w.Write(buf[:n])
}
Пример #20
0
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
}
Пример #21
0
func RestoreTask(w http.ResponseWriter, r *http.Request) {
	blobKey := appengine.BlobKey(r.FormValue("blobKey"))
	c := appengine.NewContext(r)
	blobInfo, err := blobstore.Stat(c, blobKey)
	if err != nil {
		c.Errorf("%v", err)
		return
	}
	c.Infof("Restoring from %s", blobInfo.Filename)
	reader := blobstore.NewReader(c, blobKey)
	LoadDB(c, reader)
}
Пример #22
0
func handleFile(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	c := appengine.NewContext(r)
	reader := blobstore.NewReader(c, appengine.BlobKey(r.FormValue("blobKey")))
	buf := new(bytes.Buffer)
	buf.ReadFrom(reader)
	err := pageTemplate.Execute(w, buf)
	if err != nil {
		serveError(c, w, err)
	}
	//blobstore.Send(w, appengine.BlobKey(r.FormValue("blobKey")))
}
// Close flushes outstanding buffered writes and finalizes the blob. After
// calling Close the key can be retrieved by calling Key.
func (w *Writer) Close() (closeErr os.Error) {
	defer func() {
		// Save the error for Key
		w.closeErr = closeErr
	}()
	if w.closed {
		return errorf("Writer is already closed")
	}
	w.closed = true
	w.flush()
	if w.writeErr != nil {
		return w.writeErr
	}
	req := &files.CloseRequest{
		Filename: proto.String(w.filename),
		Finalize: proto.Bool(true),
	}
	res := &files.CloseResponse{}
	if err := w.c.Call("file", "Close", req, res); err != nil {
		return err
	}
	handle := w.filename[len(blobstoreFileDirectory):]
	if !strings.HasPrefix(handle, creationHandlePrefix) {
		w.blobKey = appengine.BlobKey(handle)
		return nil
	}
	query := datastore.NewQuery("__BlobInfo__").
		Filter("creation_handle =", handle).
		KeysOnly().
		Limit(1)
	key, err := query.Run(w.c).Next(nil)
	if err != nil {
		if err != datastore.Done {
			return errorf("error looking up __BlobInfo__ entity for creation_handle %q: %v", handle, key)
		}
		return errorf("didn't find __BlobInfo__ entity for creation_handle %q", handle)
	}
	w.blobKey = appengine.BlobKey(key.StringID())
	return nil
}
Пример #24
0
func deleteImage(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)
	if err := users.CheckPerm(w, r, users.OP_UPDATE); err != nil {
		return
	}

	key := appengine.BlobKey(r.FormValue("blobKey"))
	err := blobstore.Delete(c, key)
	if err != nil {
		app.ServeError(c, w, err)
		return
	}
}
Пример #25
0
func handleServe(w http.ResponseWriter, r *http.Request) {
	// Instantiate blobstore reader
	reader := blobstore.NewReader(appengine.NewContext(r),
		appengine.BlobKey(r.FormValue("blobKey")))

	lat, lng, _ := getLatLng(reader)

	blobstore.Delete(appengine.NewContext(r),
		appengine.BlobKey(r.FormValue("blobKey")))

	if lat == "" {
		io.WriteString(w, "Sorry but your photo has no GeoTag information...")
		return
	}

	s := "http://maps.googleapis.com/maps/api/staticmap?zoom=5&size=600x300&maptype=roadmap&amp;center="
	s = s + lat + "," + lng + "&markers=color:blue%7Clabel:I%7C" + lat + "," + lng

	img := "<img src='" + s + "' alt='map' />"
	fmt.Fprint(w, img)

}
Пример #26
0
// Serves several package related urls that package.el expects.
//
// First are readmes, which are served from
// /packages/<package-name>-readme.txt.
//
// Second are package contents, which exist for all uploaded versions
// of a packages. They are servered from
// /packages/<package-name>-<package-version>.el
func packages(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)
	w.Header().Set("Content-Type", "text/plain")
	file := r.URL.Path[strings.LastIndex(r.URL.Path, "/")+1:]
	if readmeRE.MatchString(file) {
		name := file[:strings.LastIndex(file, "-")]
		var p Package
		err := datastore.Get(c, packageKey(c, name), &p)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		details, err := decodeDetails(&p.Details)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		if len(details.Readme) == 0 {
			fmt.Fprintf(w, "%v", p.Description)
		} else {
			// These \r's will show up as "^M" in the emacs buffer.
			// We don't want that, although hopefully package.el will
			// eventually fix this.
			fmt.Fprintf(w, "%v", strings.Replace(details.Readme, "\r", "", -1))
		}
	} else {
		parts := nameVersionRE.FindStringSubmatch(file)
		if len(parts) < 3 {
			http.Error(w, "Invalid package name",
				http.StatusInternalServerError)
			return
		}
		name := parts[1][:len(parts[1])-1]
		version := parts[2]
		q := datastore.NewQuery("Contents").Filter("Version=", version).
			Ancestor(packageKey(c, name))
		for cursor := q.Run(c); ; {
			var contents Contents
			_, err := cursor.Next(&contents)
			if err == datastore.Done {
				break
			}
			if err != nil {
				http.Error(w, err.Error(),
					http.StatusInternalServerError)
				return
			}
			blobstore.Send(w, appengine.BlobKey(contents.BlobKey))
		}
	}
}
Пример #27
0
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)
}
Пример #28
0
// Delete a file in the blobstore
func deleteFile(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)
	// Check the CSRF
	if csrf.ValidateToken(r, r.FormValue("CSRFToken")) {
		// Get the file ID
		trimPath := strings.Trim(r.URL.Path, "/admin/files/delete/")
		key := appengine.BlobKey(trimPath)

		// Delete blobstore entry
		blobstore.Delete(c, key)
		// Redirect
		http.Redirect(w, r, r.Referer(), http.StatusFound)
	}
}
Пример #29
0
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)
		blobKey := appengine.BlobKey(key)
		err := blobstore.Delete(c, blobKey)
		check(err)
		err = image.DeleteServingURL(c, blobKey)
		check(err)
	}
}
Пример #30
0
// keyOldWay looks up a blobkey from its creation_handle the old way:
// by doing an query against __BlobInfo__ entities.  This is now
// deprecated (corollary: the other way doesn't work yet), so we try
// this only after the new way fails, like Python does.
func (w *Writer) keyOldWay(handle string) (appengine.BlobKey, error) {
	query := datastore.NewQuery(blobInfoKind).
		Filter("creation_handle =", handle).
		KeysOnly().
		Limit(1)
	key, err := query.Run(w.c).Next(nil)
	if err != nil {
		if err != datastore.Done {
			return "", errorf("error looking up __BlobInfo__ entity for creation_handle %q: %v", handle, key)
		}
		return "", errorf("didn't find __BlobInfo__ entity for creation_handle %q", handle)
	}
	return appengine.BlobKey(key.StringID()), w.closeErr
}