func (this *GCSImageStore) Exists(obj *StoreObject) (bool, error) { _, err := storage.StatObject(this.ctx, this.bucketName, this.toPath(obj)) if err != nil { return false, err } return true, nil }
func (c *GoogleStorage) Exists(name string) (bool, error) { _, err := storage.StatObject(c.ctx, c.bucket, name) if err != nil { return false, err } return true, nil }
// alreadyUploaded reports whether *file has already been uploaded and the correct contents // are on cloud storage already. func alreadyUploaded(ctx context.Context, bucket, object string) bool { if *file == "-" { return false // don't know. } o, err := storage.StatObject(ctx, bucket, object) if err == storage.ErrObjectNotExist { return false } if err != nil { log.Printf("Warning: stat failure: %v", err) return false } m5 := md5.New() fi, err := os.Stat(*file) if err != nil { log.Fatal(err) } if fi.Size() != o.Size { return false } f, err := os.Open(*file) if err != nil { log.Fatal(err) } defer f.Close() n, err := io.Copy(m5, f) if err != nil { log.Fatal(err) } if n != fi.Size() { log.Printf("Warning: file size of %v changed", *file) } return bytes.Equal(m5.Sum(nil), o.MD5) }
// Stat implements part of the VFS interface. func (s FS) Stat(ctx context.Context, path string) (os.FileInfo, error) { obj, err := storage.StatObject(ctx, s.Bucket, path) if err != nil { return nil, err } return objInfo{obj}, os.ErrNotExist }
func getFileLink(ctx context.Context, name string) (string, error) { cctx := getCloudContext(ctx) obj, err := storage.StatObject(cctx, bucketName, name) if err != nil { return "", err } return obj.MediaLink, nil }
func storageStatObject(context context.Context, bucket string, name string) (*storage.Object, error) { var obj *storage.Object err := retry(5, func() error { var err error obj, err = storage.StatObject(context, bucket, name) return err }) return obj, err }
// statFile reads the stats of the named file in Google Cloud Storage. func (d *demo) statFile(fileName string) { io.WriteString(d.w, "\nFile stat:\n") obj, err := storage.StatObject(d.ctx, bucket, fileName) if err != nil { d.errorf("statFile: unable to stat file from bucket %q, file %q: %v", bucket, fileName, err) return } d.dumpStats(obj) }
func (bs *GCSBlobStore) BlobSize(blobpath string) (int64, error) { ctx := bs.newAuthedContext(context.TODO()) obj, err := storage.StatObject(ctx, bs.bucketName, blobpath) if err != nil { if err == storage.ErrObjectNotExist { return -1, blobstore.ENOENT } return -1, err } return obj.Size, nil }
func (c *GoogleStorage) Mirror(obj *Object) (*Object, error) { gcsObj, err := storage.StatObject(c.ctx, c.bucket, obj.Path) if err != nil { return c.Post(obj) } newPath := c.bucket + "/" + gcsObj.Name newUrl := "https://storage.googleapis.com/" + newPath newObj := &Object{ Filename: obj.Filename, Bucket: c.bucket, Path: newPath, MimeType: gcsObj.ContentType, Url: newUrl, } return newObj, nil }
// ReadStream retrieves an io.ReadCloser for the content stored at "path" // with a given byte offset. // May be used to resume reading a stream by providing a nonzero offset. func (d *driver) ReadStream(context ctx.Context, path string, offset int64) (io.ReadCloser, error) { name := d.pathToKey(path) // copied from google.golang.org/cloud/storage#NewReader : // to set the additional "Range" header u := &url.URL{ Scheme: "https", Host: "storage.googleapis.com", Path: fmt.Sprintf("/%s/%s", d.bucket, name), } req, err := http.NewRequest("GET", u.String(), nil) if err != nil { return nil, err } if offset > 0 { req.Header.Set("Range", fmt.Sprintf("bytes=%v-", offset)) } res, err := d.client.Do(req) if err != nil { return nil, err } if res.StatusCode == http.StatusNotFound { res.Body.Close() return nil, storagedriver.PathNotFoundError{Path: path} } if res.StatusCode == http.StatusRequestedRangeNotSatisfiable { res.Body.Close() obj, err := storage.StatObject(d.context(context), d.bucket, name) if err != nil { return nil, err } if offset == int64(obj.Size) { return ioutil.NopCloser(bytes.NewReader([]byte{})), nil } return nil, storagedriver.InvalidOffsetError{Path: path, Offset: offset} } if res.StatusCode < 200 || res.StatusCode > 299 { res.Body.Close() return nil, fmt.Errorf("storage: can't read object %v/%v, status code: %v", d.bucket, name, res.Status) } return res.Body, nil }
// Delete removes an object by name from the bucket being used. If the object does not // exist and there is nothing to delete, Delete returns with no error. // TODO Delete thumbnail and web view copies too! func Delete(filename string, r *http.Request) error { c := appengine.NewContext(r) bucket, err := file.DefaultBucketName(c) if err != nil { log.Errorf(c, "Failed to get default bucket: %v", err) return err } ctx, err := auth(r) if err != nil { log.Errorf(c, "Failed to get context: %v", err) return err } log.Infof(c, "Attempting to delete file %v from bucket %v.", filename, bucket) // StatObject is used here to check existence before calling DeleteObject. // If the object does not exist, DeleteObject returns an error that is NOT // ErrObjectNotExist, so it seemed more reliable to check with StatObject first... _, err = storage.StatObject(ctx, bucket, filename) if err == storage.ErrObjectNotExist { log.Warningf(c, "Object does not exist, nothing to delete.") return nil } err = storage.DeleteObject(ctx, bucket, filename) if err != nil { log.Errorf(c, "Failed to delete file.") log.Infof(c, "Attempting to remove public access to file...") aclErr := storage.DeleteACLRule(ctx, bucket, filename, storage.AllUsers) if aclErr != nil { log.Errorf(c, "Failed to remove public file access!") } else { log.Infof(c, "File access removed.") } return err } return nil }
// Stat retrieves the FileInfo for the given path, including the current // size in bytes and the creation time. func (d *driver) Stat(context ctx.Context, path string) (storagedriver.FileInfo, error) { var fi storagedriver.FileInfoFields //try to get as file gcsContext := d.context(context) obj, err := storage.StatObject(gcsContext, d.bucket, d.pathToKey(path)) if err == nil { fi = storagedriver.FileInfoFields{ Path: path, Size: obj.Size, ModTime: obj.Updated, IsDir: false, } return storagedriver.FileInfoInternal{FileInfoFields: fi}, nil } //try to get as folder dirpath := d.pathToDirKey(path) var query *storage.Query query = &storage.Query{} query.Prefix = dirpath query.MaxResults = 1 objects, err := storage.ListObjects(gcsContext, d.bucket, query) if err != nil { return nil, err } if len(objects.Results) < 1 { return nil, storagedriver.PathNotFoundError{Path: path} } fi = storagedriver.FileInfoFields{ Path: path, IsDir: true, } obj = objects.Results[0] if obj.Name == dirpath { fi.Size = obj.Size fi.ModTime = obj.Updated } return storagedriver.FileInfoInternal{FileInfoFields: fi}, nil }
func FileStats(filename string, r *http.Request) (*storage.Object, error) { c := appengine.NewContext(r) bucket, err := file.DefaultBucketName(c) if err != nil { log.Errorf(c, "Failed to get default bucket: %v", err) return nil, err } ctx, err := auth(r) if err != nil { log.Errorf(c, "Failed to get context: %v", err) return nil, err } log.Infof(c, "Getting stats for file %v from bucket %v.", filename, bucket) obj, err := storage.StatObject(ctx, bucket, filename) if err != nil { log.Errorf(c, "Failed to stat file: %v", err) return nil, err } return obj, nil }
func handleUploadImage(c appengine.Context, w http.ResponseWriter, r *http.Request) { file, fileHeader, err := r.FormFile(uploadImageKey) if err != nil { c.Infof("Failed to get uploaded image: %v", err) http.Error(w, "Failed to get uploaded image", http.StatusBadRequest) return } defer file.Close() data, err := ioutil.ReadAll(file) if err != nil { c.Errorf("Failed to read uploaded image: %v", err) http.Error(w, "Failed to get uploaded image", http.StatusBadRequest) return } ext := path.Ext(fileHeader.Filename) mimeType := mime.TypeByExtension(ext) // create context for Google Cloud Storage and upload file gc := gappengine.NewContext(r) hc := &http.Client{ Transport: &oauth2.Transport{ Source: google.AppEngineTokenSource(gc, storage.ScopeFullControl), Base: &urlfetch.Transport{Context: gc}, }, } ctx := cloud.NewContext(gappengine.AppID(gc), hc) c.Infof("Demo GCS Application running from Version: %v\n", appengine.VersionID(c)) filePath := path.Join(tempImagePath, createTempImagePath, fileHeader.Filename) c.Infof("file: %v, size: %d, MIME: %v, path: %v", fileHeader.Filename, len(data), mimeType, filePath) wc := storage.NewWriter(ctx, bucketName, filePath) wc.ContentType = mimeType _, err = wc.Write(data) if err != nil { c.Errorf("Failed to upload image: %v", err) http.Error(w, "Failed to upload image", http.StatusInternalServerError) return } err = wc.Close() if err != nil { c.Errorf("Failed to close uploaded image: %v", err) http.Error(w, "Failed to upload image", http.StatusInternalServerError) return } obj, err := storage.StatObject(ctx, bucketName, filePath) if err != nil { c.Errorf("Failed to stat object: %v", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } // c.Infof("obj: %v", obj) // get blob key for GCS file // obj := wc.Object() objName := path.Join("/gs", bucketName, obj.Name) c.Infof("Getting blob key from path: %v", objName) imgKey, err := blobstore.BlobKeyForFile(c, objName) if err != nil { c.Errorf("Failed to get image blob key: %v", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } url, err := getImageUrl(c, imgKey) if err != nil { c.Errorf("Failed to get room image url: %v", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } info := ImageInfo{ Key: imgKey, Url: url.String(), } outBuf, err := json.Marshal(&info) if err != nil { c.Errorf("%s", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") _, err = w.Write(outBuf) if err != nil { c.Errorf("%s", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } }