在go中使用app引擎在GCS上发布Json

时间:2015-06-01 18:35:57

标签: javascript json google-app-engine go google-cloud-storage

我开发了一个应用程序,在本地与谷歌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时没有给出任何错误,所以我真的不知道问题出在哪里,似乎许可是错的,但我检查过它们看起来很好。

有什么想法吗? 感谢

0 个答案:

没有答案