2015年9月9日水曜日

Google App Engine / Go で Google Cloud Storage に画像をアップロードする

How to upload image to Google Cloud Storage with Google App Engine / Go.

この情報は2015年9月9日時点のものです。appengine.Context, context.Context 問題は過渡期のようなので今後インタフェースが変わる可能性があります。

File API が終了になったので調べたけどあんまり情報がなく苦労したのでメモとして残しておく

storage#NewWriter に渡す Context は appengine#Context ではなく context#Context なので次のようにするとエラーになります。

  1. import (  
  2.  "appengine"  
  3.  "google.golang.org/cloud/storage"  
  4.  ...  
  5. )  
  6.   
  7. func uploadImage(w http.ResponseWriter, r *http.Request) {  
  8.  ...  
  9.   
  10.  c := appengine.NewContext(r)  
  11.   
  12.  wc := storage.NewWriter(c, bucketName, fileName)  
  13.  wc.ContentType = "image/jpg"  
  14.   
  15.  if _, err := wc.Write(data); err != nil {  
  16.   ...  
  17.  }  
  18.   
  19.  ...  
  20. }  
google.golang.org/appengine の NewContext は context#Context を返すため、こちらを利用します。このワークアラウンドは https://github.com/golang/oauth2/#app-engine を参考にしています。
  1. import (  
  2.  "appengine"  
  3.  "fmt"  
  4.  "io/ioutil"  
  5.  "net/http"  
  6.  "strings"  
  7.   
  8.  "golang.org/x/net/context"  
  9.  "golang.org/x/oauth2"  
  10.  "golang.org/x/oauth2/google"  
  11.  newappengine "google.golang.org/appengine"  
  12.  newurlfetch "google.golang.org/appengine/urlfetch"  
  13.  "google.golang.org/cloud"  
  14.  "google.golang.org/cloud/storage"  
  15. )  
  16.   
  17. func uploadImage(w http.ResponseWriter, r *http.Request) {  
  18.  file, fileHeader, err := r.FormFile("image_file")  
  19.  if err != nil {  
  20.   fmt.Fprint(w, "no image")  
  21.   // no image  
  22.   return  
  23.  }  
  24.   
  25.  defer file.Close()  
  26.   
  27.  data, err := ioutil.ReadAll(file)  
  28.  if err != nil {  
  29.   fmt.Fprint(w, "cloud not upload image")  
  30.   return  
  31.  }  
  32.   
  33.  var mimeType string  
  34.  if strings.HasSuffix(filename, ".png") {  
  35.   mimeType = "image/png"  
  36.  } else if strings.HasSuffix(filename, ".jpeg") {  
  37.   mimeType = "image/jpg"  
  38.  } else {  
  39.   mimeType = "image/jpg"  
  40.  }  
  41.   
  42.  bucketName := "mybucketname"  
  43.  fileName := fileHeader.Filename  
  44.   
  45.  c := appengine.NewContext(r)  
  46.  ctx := newappengine.NewContext(r)  
  47.   
  48.  hc := &http.Client{  
  49.   Transport: &oauth2.Transport{  
  50.    Source: google.AppEngineTokenSource(ctx, storage.ScopeFullControl),  
  51.    Base:   &newurlfetch.Transport{Context: ctx},  
  52.   },  
  53.  }  
  54.  ctx2 := cloud.NewContext(appengine.AppID(c), hc)  
  55.   
  56.  wc := storage.NewWriter(ctx2, bucketName, fileName)  
  57.  wc.ContentType = mimeType  
  58.   
  59.  if _, err := wc.Write(data); err != nil {  
  60.   fmt.Fprint(w, "cloud not upload image")  
  61.   return  
  62.  }  
  63.   
  64.  if err := wc.Close(); err != nil {  
  65.   return  
  66.  }  

google.golang.org/cloud/storage などは GOPAH を設定して
  1. $ go get -u google.golang.org/cloud/storage  
でインストールしておきます


参考


0 件のコメント:

コメントを投稿