func allCSS(c common.Context) { c.SetContentType("text/css; charset=UTF-8", true) renderText(c, cssTemplates, "bootstrap.min.css") renderText(c, cssTemplates, "bootstrap-theme.min.css") renderText(c, cssTemplates, "bootstrap-multiselect.css") renderText(c, cssTemplates, "common.css") }
func allJS(c common.Context) { c.SetContentType("application/javascript; charset=UTF-8", true) renderText(c, jsTemplates, "jquery-2.0.3.min.js") renderText(c, jsTemplates, "underscore-min.js") renderText(c, jsTemplates, "backbone-min.js") renderText(c, jsTemplates, "bootstrap.min.js") renderText(c, jsTemplates, "bootstrap-multiselect.js") renderText(c, jsTemplates, "viz.js") renderText(c, jsTemplates, "tinycolor.js") render_Templates(c) for _, templ := range jsModelTemplates.Templates() { if err := templ.Execute(c.Resp, c); err != nil { panic(err) } } for _, templ := range jsCollectionTemplates.Templates() { if err := templ.Execute(c.Resp, c); err != nil { panic(err) } } for _, templ := range jsViewTemplates.Templates() { if err := templ.Execute(c.Resp, c); err != nil { panic(err) } } renderText(c, jsTemplates, "app.js") }
func deleteAI(c common.Context) { if c.Authenticated() { if ai := models.GetAIById(c, common.MustDecodeKey(c.Vars["ai_id"])); ai != nil && ai.Owner == c.User.Email { ai.Delete(c) } } }
func getAIErrors(c common.Context) { if c.Authenticated() { if ai := models.GetAIById(c, common.MustDecodeKey(c.Vars["ai_id"])); ai != nil && ai.Owner == c.User.Email { c.RenderJSON(ai.GetErrors(c)) } } }
func createGame(c common.Context) { if c.Authenticated() { var game models.Game aiCommon.MustDecodeJSON(c.Req.Body, &game) if len(game.Players) > 0 { c.RenderJSON(game.Save(c)) } } }
func createAI(c common.Context) { if c.Authenticated() { var ai models.AI aiCommon.MustDecodeJSON(c.Req.Body, &ai) if ai.Name != "" && ai.URL != "" { ai.Owner = c.User.Email ai.Id = nil c.RenderJSON(ai.Save(c)) } } }
func handler(f func(c common.Context)) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { c := common.Context{ Context: appengine.NewContext(r), Req: r, Resp: w, Vars: mux.Vars(r), } c.User = user.Current(c) c.Version = appengine.VersionID(c.Context) f(c) } }
func (self *AI) AddError(c common.Context, turnId *datastore.Key, err error) { _, e := datastore.Put(c, datastore.NewKey(c, AIErrorKind, "", 0, self.Id), &AIError{ CreatedAt: time.Now(), Turn: turnId, ErrorBytes: []byte(err.Error()), ErrorDetail1Bytes: []byte(fmt.Sprintf("%+v", err)), ErrorDetail2Bytes: []byte(fmt.Sprintf("%#v", err)), }) if e != nil { c.Errorf("Got %+v when trying to save a new error!", e) } common.MemDel(c, aiErrorsKeyByParent(self.Id)) }
func nextTurn(cont appengine.Context, id *datastore.Key, playerNames []string) { con := common.Context{Context: cont} self := getGameById(con, id) self.PlayerNames = playerNames if self.Length > maxGameDuration { self.State = StateFinished self.Save(con) con.Infof("Ended %v due to timeout", self.Id) return } errorSavers := []func(){} if err := common.Transaction(con, func(c common.Context) (err error) { lastTurn := GetLatestTurnByParent(c, self.Id) responses := make(chan orderResponse, len(self.Players)) for _, playerId := range self.Players { orderResp := orderResponse{ DatastorePlayerId: playerId, StatePlayerId: state.PlayerId(playerId.Encode()), } if foundAi := GetAIById(c, playerId); foundAi != nil { go func() { // Always deliver the order response defer func() { responses <- orderResp }() // create a request orderRequest := ai.OrderRequest{ Me: orderResp.StatePlayerId, State: lastTurn.State, GameId: state.GameId(self.Id.Encode()), } // encode it into a body, and remember its string representation sendBody := &bytes.Buffer{} aiCommon.MustEncodeJSON(sendBody, orderRequest) sendBodyString := sendBody.String() // get a client client := urlfetch.Client(c) // send the request to the ai req, err := http.NewRequest("POST", foundAi.URL, sendBody) var resp *http.Response if err == nil { req.Header.Set("Content-Type", "application/json; charset=UTF-8") resp, err = client.Do(req) } recvBody := &bytes.Buffer{} recvBodyString := "" if err == nil { // check what we received _, err = io.Copy(recvBody, resp.Body) recvBodyString = recvBody.String() } // if we have no other errors, but we got a non-200 if err == nil && resp.StatusCode != 200 { err = orderError{ Request: req, RequestBody: sendBodyString, Response: resp, ResponseBody: recvBodyString, } } // lets try to unserialize if err == nil { err = json.Unmarshal(recvBody.Bytes(), &orderResp.Orders) } // store the error, if any if err != nil { orderResp.Error = err } }() } else { responses <- orderResp } } orderMap := map[state.PlayerId]state.Orders{} for _, _ = range self.Players { // wait for the responses orderResp := <-responses // store it orderMap[orderResp.StatePlayerId] = orderResp.Orders // if we got an error if orderResp.Error != nil { // make sure to save it later errorSavers = append(errorSavers, func() { if ai := GetAIById(con, orderResp.DatastorePlayerId); ai != nil { ai.AddError(con, lastTurn.Id, orderResp.Error) } }) } } // execute the orders newTurn, winner := lastTurn.Next(c, orderMap) // save the new turn newTurn.Save(c, self.Id) // if we got a winner, end the game and store the winner if winner == nil { self.State = StatePlaying } else { self.Winner = common.MustDecodeKey(string(*winner)) self.State = StateFinished } // increase our length with the new turn self.Length += 1 // save us self.Save(c) // if we didn't end, queue the next turn if winner == nil { nextTurnFunc.Call(c, self.Id, playerNames) } return nil }); err != nil { panic(err) } // run any error savers we got for _, saver := range errorSavers { saver() } // store the new stats in the players if we ended if self.State == StateFinished { for _, playerId := range self.Players { common.Transaction(con, func(c common.Context) error { if ai := GetAIById(c, playerId); ai != nil { if playerId.Equal(self.Winner) { ai.Wins += 1 } else { ai.Losses += 1 } ai.Save(c) } return nil }) } } }
func getGame(c common.Context) { c.RenderJSON(models.GetGameById(c, common.MustDecodeKey(c.Vars["game_id"]))) }
func getGames(c common.Context) { limit := aiCommon.TryParseInt(c.Req.URL.Query().Get("limit"), 10) offset := aiCommon.TryParseInt(c.Req.URL.Query().Get("offset"), 0) c.RenderJSON(models.GetGamePage(c, offset, limit)) }
func getAIs(c common.Context) { c.RenderJSON(models.GetAllAIs(c)) }
func getUser(c common.Context) { c.RenderJSON(c.User) }
func index(c common.Context) { c.SetContentType("text/html; charset=UTF-8", false) renderText(c, htmlTemplates, "index.html") }