我开发了一个应用程序,在本地与谷歌SDK完美配合。现在我尝试部署它,我不能再将文件保存在云存储上了。
这是我的代码
package galileo
import (
"encoding/json"
"golang.org/x/net/context"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
"google.golang.org/appengine"
"google.golang.org/appengine/file"
"google.golang.org/appengine/urlfetch"
"google.golang.org/cloud"
"google.golang.org/cloud/storage"
"io"
"io/ioutil"
"log"
"net/http"
)
var bucket = "prod_agl_expt"
// saveData struct holds information needed to run the various saving functions.
type saveData struct {
c context.Context
r *http.Request //http response
w http.ResponseWriter //http writer
ctx context.Context
cleanUp []string // cleanUp is a list of filenames that need cleaning up at the end of the saving.
failed bool // failed indicates that one or more of the saving steps failed.
}
// saveData struct holds information needed to run the various saving functions.
type loadData struct {
c context.Context
r *http.Request //http response
w http.ResponseWriter //http writer
ctx context.Context
cleanUp []string // cleanUp is a list of filenames that need cleaning up at the end of the saving.
failed bool // failed indicates that one or more of the saving steps failed.
}
type jsonStruct struct {
User struct {
Gender string `json:"gender"`
Age string `json:"age"`
ID string `json:"id"`
} `json:"user"`
Stim map[string]struct {
Index int `json:"index"`
Word string `json:"word"`
WordDisplayTime int `json:"wordDisplayTime"`
AnswerMaxTime int `json:"answerMaxTime"`
FixationTime int `json:"fixationTime"`
Train bool `json:"train"`
Test bool `json:"test"`
Grammatical bool `json:"grammatical"`
Grammar string `json:"grammar"`
Keyboard bool `json:"keyboard"`
TestSeq int `json:"testSeq"`
} `json:"viewedTrials"`
Answers struct {
Training []struct {
Answer string `json:"ans"`
RT float32 `json:"RT"`
GtAnswer string `json:"gtAns"`
Correct int `json:"correct"`
} `json:"training"`
Test []struct {
Answer string `json:"ans"`
RT float32 `json:"RT"`
GtAnswer bool `json:"gtAns"`
Correct int `json:"correct"`
} `json:"test"`
} `json:"answers"`
Trials []struct {
Trial struct {
Index int `json:"index"`
Word string `json:"word"`
WordDisplayTime int `json:"wordDisplayTime"`
AnswerMaxTime int `json:"answerMaxTime"`
FixationTime int `json:"fixationTime"`
Train bool `json:"train"`
Test bool `json:"test"`
Grammatical bool `json:"grammatical"`
Grammar string `json:"grammar"`
Keyboard bool `json:"keyboard"`
TestSeq int `json:"testSeq"`
} `json:"trial"`
Metadata struct {
Instructions string `json:"instructions"`
SubmitUrl string `json:"submitUrl"`
} `json:"metadata"`
} `json:"shuffledTrials"`
Debriefing []struct {
Type string `json:"type"`
RadioWithTextAns string `json:"radioWithTextAns"`
TextAns string `json:"textAns"`
Rating int `json:"rating"`
RadioOnlyAns string `json:"radioOnlyAns"`
} `json:"debriefingAns"`
}
type trialStruct []struct {
Trial struct {
Index int `json:"index"`
Word string `json:"word"`
WordDisplayTime int `json:"wordDisplayTime"`
AnswerMaxTime int `json:"answerMaxTime"`
FixationTime int `json:"fixationTime"`
Train bool `json:"train"`
Test bool `json:"test"`
Grammatical bool `json:"grammatical"`
Grammar string `json:"grammar"`
Keyboard bool `json:"keyboard"`
TestSeq int `json:"testSeq"`
} `json:"trial"`
Metadata struct {
Instructions string `json:"instructions"`
SubmitUrl string `json:"submitUrl"`
} `json:"metadata"`
}
func fromJSON(r io.Reader) (jsonStruct, error) {
var x jsonStruct
dec := json.NewDecoder(r)
err := dec.Decode(&x)
return x, err
}
func toJSON(b io.Writer, trial trialStruct) (io.Writer, error) {
enc := json.NewEncoder(b)
err := enc.Encode(&trial)
return b, err
}
func init() {
http.HandleFunc("/", handleStatic)
http.HandleFunc("/saveUserData", handleSaveUser)
http.HandleFunc("/loadTrials", handleloadTrials)
}
func handleStatic(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Cache-Control", "no-cache")
http.ServeFile(w, r, "static/"+r.URL.Path)
}
// testSave is the main saving entry point that calls the GCS operations.
func handleSaveUser(w http.ResponseWriter, r *http.Request) {
c := appengine.NewContext(r)
if bucket == "" {
var err error
if bucket, err = file.DefaultBucketName(c); err != nil {
// log.Errorf(c, "failed to get default GCS bucket name: %v", err)
return
}
}
hc := &http.Client{
Transport: &oauth2.Transport{
Source: google.AppEngineTokenSource(c, storage.ScopeFullControl),
Base: &urlfetch.Transport{Context: c},
},
}
ctx := cloud.NewContext(appengine.AppID(c), hc)
// structure to holds information needed to run the various saving functions
d := &saveData{
c: c,
r: r,
w: w,
ctx: ctx,
}
// retrieve data
processedJson, trials, trainAns, testAns, stimSeq, userDetails, debriefingAns, rawJson := getJsonUserData(d.r, d.w)
//
d.createUserFolder(processedJson.User.ID)
// d.saveJson(k.User.ID, "raw", z)
d.saveJson(processedJson.User.ID, "trials", trials)
d.saveJson(processedJson.User.ID, "train", trainAns)
d.saveJson(processedJson.User.ID, "test", testAns)
d.saveJson(processedJson.User.ID, "stim", stimSeq)
d.saveJson(processedJson.User.ID, "user", userDetails)
d.saveJson(processedJson.User.ID, "debriefing", debriefingAns)
d.saveJson(processedJson.User.ID, "raw", rawJson)
}
// Deal with error
func (d *saveData) errorf(format string, args ...interface{}) {
d.failed = true
}
func getJsonUserData(r *http.Request, w http.ResponseWriter) (jsonStruct, []byte, []byte, []byte, []byte, []byte, []byte, []byte) {
defer r.Body.Close()
procJson, err := fromJSON(r.Body)
if err != nil {
log.Fatal(err)
}
log.Printf("initial structure: ", procJson)
log.Printf("%+v\n", procJson)
trials, err := json.Marshal(procJson.Trials)
if err != nil {
log.Fatal(err)
}
trainAns, err := json.Marshal(procJson.Answers.Training)
if err != nil {
log.Fatal(err)
}
testAns, err := json.Marshal(procJson.Answers.Test)
if err != nil {
log.Fatal(err)
}
stimSeq, err := json.Marshal(procJson.Stim)
if err != nil {
log.Fatal(err)
}
userDetail, err := json.Marshal(procJson.User)
if err != nil {
log.Fatal(err)
}
debriefingAns, err := json.Marshal(procJson.Debriefing)
if err != nil {
log.Fatal(err)
}
rawJson, err := json.Marshal(procJson)
if err != nil {
log.Fatal(err)
}
return procJson, trials, trainAns, testAns, stimSeq, userDetail, debriefingAns, rawJson
}
func (d *saveData) createUserFolder(folderName string) {
fName := folderName + "/"
wc := storage.NewWriter(d.ctx, bucket, fName)
wc.ContentType = "text/plain"
d.cleanUp = append(d.cleanUp, fName)
if err := wc.Close(); err != nil {
d.errorf("createFile: unable to close bucket %q, file %q: %v", bucket, fName, err)
return
}
}
func (d *saveData) saveJson(folderName string, fileName string, fileContent []byte) {
fullName := folderName + "/" + fileName
wc := storage.NewWriter(d.ctx, bucket, fullName)
wc.ContentType = "text/plain"
d.cleanUp = append(d.cleanUp, fullName)
d.createFile(fullName, fileContent)
}
func (d *saveData) createFile(fileName string, content []byte) {
wc := storage.NewWriter(d.ctx, bucket, fileName)
wc.ContentType = "text/plain"
d.cleanUp = append(d.cleanUp, fileName)
if _, err := wc.Write([]byte(content)); err != nil {
d.errorf("createFile: unable to write data to bucket %q, file %q: %v", bucket, fileName, err)
return
}
if err := wc.Close(); err != nil {
d.errorf("createFile: unable to close bucket %q, file %q: %v", bucket, fileName, err)
return
}
}
func handleloadTrials(w http.ResponseWriter, r *http.Request) {
c := appengine.NewContext(r)
if bucket == "" {
var err error
if bucket, err = file.DefaultBucketName(c); err != nil {
// log.Errorf(c, "failed to get default GCS bucket name: %v", err)
return
}
}
hc := &http.Client{
Transport: &oauth2.Transport{
Source: google.AppEngineTokenSource(c, storage.ScopeFullControl),
Base: &urlfetch.Transport{Context: c},
},
}
ctx := cloud.NewContext(appengine.AppID(c), hc)
// structure to holds information needed to run the various saving functions
d := &saveData{
c: c,
r: r,
w: w,
ctx: ctx,
}
userID := r.URL.Query().Get("id")
log.Println(userID)
trialJson := d.readFile(userID)
w.Write(trialJson)
}
// readFile reads the named file in Google Cloud Storage.
func (d *saveData) readFile(fileName string) []byte {
trialName := fileName + "/trials"
rc, err := storage.NewReader(d.ctx, bucket, trialName)
if err != nil {
d.errorf("readFile: unable to open file from bucket %q, file %q: %v", bucket, trialName, err)
}
defer rc.Close()
slurp, err := ioutil.ReadAll(rc)
if err != nil {
d.errorf("readFile: unable to read data from bucket %q, file %q: %v", bucket, fileName, err)
}
return slurp
}
javascript代码:
saveUserData : function saveUserData(data) {
var _this = this,
save = this.shadowRoot.querySelector('#save-data');
save.url="http://galileoexp.appspot.com/saveUserData";
save.body = JSON.stringify(data);
save.go();
}
控制台在调用/ saveUserData时没有给出任何错误,所以我真的不知道问题出在哪里,似乎许可是错的,但我检查过它们看起来很好。
有什么想法吗? 感谢