func UpdateAllPortfoliosAndAlert(w http.ResponseWriter, r *http.Request) { ctx := appengine.NewContext(r) if len(cachedStocks) == 0 { log.Debugf(ctx, "UpdateAllPortfoliosAndAlert: cachedStocks are empty") return } if !isWeekDay() { log.Debugf(ctx, "UpdateAllPortfoliosAndAlert: is not a weekday.") return } defer func() { isUpdateInProgress = false }() isUpdateInProgress = true var portfolioStocks []PortfolioStock if err := GetAllEntities(ctx, "PortfolioStock", &portfolioStocks); err != nil { log.Debugf(ctx, "UpdateAllPortfoliosAndAlert: Could not fetch all portfolios ", err) return } if len(portfolioStocks) == 0 { log.Debugf(ctx, "UpdateAllPortfoliosAndAlert: fetched portfoilios len is 0") return } // log.Debugf(ctx,"Before filteting eligible stocks ", Jsonify(portfolioStocks)) eligibleStocks := FilterForAlertEligiblePortfolioStocks(ctx, portfolioStocks) // log.Debugf(ctx,"After filteting eligible stocks ", Jsonify(portfolioStocks)) SendAlerts(ctx, eligibleStocks) }
func (sink *LogSink) writeLogStorage(r *wcg.LogRecord) error { c := sink.ctx formatter := sink.formatter if c == nil { c = NewContext(r.Request) } var text string if r.SourceStack != nil && len(r.SourceStack) > 0 { text = fmt.Sprintf( "%s\n-- Stack Trace --\n%s", string(formatter.Format(r)), strings.Join(r.SourceStack, "\n"), ) } else { text = string(formatter.Format(r)) } switch r.Level { case wcg.LogLevelTrace: log.Debugf(c, "%s", text) // app engine does not support trace level case wcg.LogLevelDebug: log.Debugf(c, "%s", text) case wcg.LogLevelInfo: log.Infof(c, "%s", text) case wcg.LogLevelWarn: log.Warningf(c, "%s", text) case wcg.LogLevelError: log.Errorf(c, "%s", text) case wcg.LogLevelFatal: log.Criticalf(c, "%s", text) default: // nothing } return nil }
func ajaxAboutAllIdioms(w http.ResponseWriter, r *http.Request) error { c := appengine.NewContext(r) log.Debugf(c, "retrieveAllIdioms start...") allIdioms, err := retrieveAllIdioms(r) if err != nil { return err } log.Debugf(c, "retrieveAllIdioms end.") data := AboutFacade{ PageMeta: PageMeta{ Toggles: toggles, }, UserProfile: readUserProfile(r), AllIdioms: allIdioms, } log.Debugf(c, "block-about-all-idioms templating start...") if err := templates.ExecuteTemplate(w, "block-about-all-idioms", data); err != nil { return PiError{err.Error(), http.StatusInternalServerError} } log.Debugf(c, "block-about-all-idioms templating end.") return nil }
func (api *API) handlePostMessage(res http.ResponseWriter, req *http.Request) error { ctx := appengine.NewContext(req) // handle incoming messages, send them out to everyone type Post struct { Text string } var post Post // post := struct{ // Text string // }{} err := json.NewDecoder(req.Body).Decode(&post) if err != nil { return err } log.Debugf(ctx, "the post is %s", post.Text) query := datastore.NewQuery("connections") it := query.Run(ctx) for { var connection struct{ Email string } _, err := it.Next(&connection) if err == datastore.Done { break } else if err != nil { return err } log.Debugf(ctx, "here is the email %s", connection.Email) err = channel.SendJSON(ctx, connection.Email, post) if err != nil { return err } } return nil }
// CurrentUser checks for both JWT and Bearer tokens. // // It first tries to decode and verify JWT token (if conditions are met) // and falls back to Bearer token. // // The returned user will have only ID, Email and ClientID fields set. // User.ID is a Google Account ID, which is different from GAE user ID. // For more info on User.ID see 'sub' claim description on // https://developers.google.com/identity/protocols/OpenIDConnect#obtainuserinfo func CurrentUser(c context.Context, scopes []string, audiences []string, clientIDs []string) (*user.User, error) { // The user hasn't provided any information to allow us to parse either // an ID token or a Bearer token. if len(scopes) == 0 && len(audiences) == 0 && len(clientIDs) == 0 { return nil, errors.New("no client ID or scope info provided.") } r := HTTPRequest(c) if r == nil { return nil, errNoRequest } token := parseToken(r) if token == "" { return nil, errors.New("No token in the current context.") } // If the only scope is the email scope, check an ID token. Alternatively, // we dould check if token starts with "ya29." or "1/" to decide that it // is a Bearer token. This is what is done in Java. if len(scopes) == 1 && scopes[0] == EmailScope && len(clientIDs) > 0 { log.Debugf(c, "Checking for ID token.") now := currentUTC().Unix() u, err := currentIDTokenUser(c, token, audiences, clientIDs, now) // Only return in case of success, else pass along and try // parsing Bearer token. if err == nil { return u, err } } log.Debugf(c, "Checking for Bearer token.") return CurrentBearerTokenUser(c, scopes, clientIDs) }
// buildSlackJSON returns a public or private Slack JSON response as a byte slice. // Context is passed in for logging. func buildSlackJSON(ctx context.Context, text string, isPublic bool) ([]byte, error) { // JustinResponse is a response we send back to Slack type JustinResponse struct { ResponseType string `json:"response_type"` // "ephemeral" (private) or "in_channel" (public) Text string `json:"text"` } justinResponse := &JustinResponse{ Text: text, } if isPublic { justinResponse.ResponseType = "in_channel" } else { justinResponse.ResponseType = "ephemeral" } log.Debugf(ctx, "Marshalling JustinResponse: %#v", justinResponse) justinJSON, err := json.Marshal(justinResponse) if err != nil { log.Errorf(ctx, "Error marshalling JSON for JustinResponse: %#v - %s", justinResponse, err) return nil, err } log.Debugf(ctx, "Slack response: %s", string(justinJSON)) return justinJSON, nil }
// fetchTokeninfo retrieves token info from tokeninfoEndpointURL (tokeninfo API) func fetchTokeninfo(c context.Context, token string) (*tokeninfo, error) { url := tokeninfoEndpointURL + "?access_token=" + token log.Debugf(c, "Fetching token info from %q", url) resp, err := newHTTPClient(c).Get(url) if err != nil { return nil, err } defer resp.Body.Close() log.Debugf(c, "Tokeninfo replied with %s", resp.Status) ti := &tokeninfo{} if err = json.NewDecoder(resp.Body).Decode(ti); err != nil { return nil, err } if resp.StatusCode != http.StatusOK { errMsg := fmt.Sprintf("Error fetching tokeninfo (status %d)", resp.StatusCode) if ti.ErrorDescription != "" { errMsg += ": " + ti.ErrorDescription } return nil, errors.New(errMsg) } switch { case ti.ExpiresIn <= 0: return nil, errors.New("Token is expired") case !ti.VerifiedEmail: return nil, fmt.Errorf("Unverified email %q", ti.Email) case ti.Email == "": return nil, fmt.Errorf("Invalid email address") } return ti, err }
// clearLock clears the current lease, it should be called at the end of every task // execution if things fail, to try and prevent unecessary locks and to count the // number of retries func (l *Locker) clearLock(c context.Context, key *datastore.Key, entity Lockable) error { lock := entity.getLock() if lock.Retries == l.MaxRetries { if l.AlertOnFailure { if err := alertAdmins(c, key, entity, "Permanent task failure"); err != nil { log.Errorf(c, "failed to send alert email for permanent task failure: %v", err) } } return ErrTaskFailed } err := storage.RunInTransaction(c, func(tc context.Context) error { if err := storage.Get(tc, key, entity); err != nil { log.Debugf(c, "clearLock get %v", err) return err } lock := entity.getLock() lock.Timestamp = getTime() lock.RequestID = "" lock.Retries++ if _, err := storage.Put(tc, key, entity); err != nil { log.Debugf(c, "clearLock put %v", err) return err } return nil }, nil) return err }
func (a *MemcacheDatastoreAccessor) cacheSameValues(c context.Context, cacheKeys []string, data interface{}, expiration time.Duration) error { N := len(cacheKeys) var buffer bytes.Buffer enc := gob.NewEncoder(&buffer) err := enc.Encode(&data) if err != nil { log.Debugf(c, "Failed encoding for cache keys [%v] : %v", cacheKeys, err) return err } items := make([]*memcache.Item, N) for i, cacheKey := range cacheKeys { cacheItem := &memcache.Item{ Key: cacheKey, Value: buffer.Bytes(), Expiration: expiration, } items[i] = cacheItem } // Set the items, unconditionally, in 1 batch call err = memcache.SetMulti(c, items) if err != nil { log.Debugf(c, "Failed setting cache items: %v", cacheKeys, err) } return err }
func (a *MemcacheDatastoreAccessor) cacheValues(c context.Context, cacheKeys []string, data []interface{}, expiration time.Duration) error { if len(cacheKeys) != len(data) { panic(fmt.Errorf("Wrong params length", len(cacheKeys), len(data))) } N := len(cacheKeys) var buffer bytes.Buffer enc := gob.NewEncoder(&buffer) items := make([]*memcache.Item, N) for i, cacheKey := range cacheKeys { cacheData := data[i] err := enc.Encode(&cacheData) if err != nil { log.Debugf(c, "Failed encoding for cache[%v] : %v", cacheKey, err) return err } cacheItem := &memcache.Item{ Key: cacheKey, Value: buffer.Bytes(), Expiration: expiration, } items[i] = cacheItem } // Set the items, unconditionally, in 1 batch call err := memcache.SetMulti(c, items) if err != nil { log.Debugf(c, "Failed setting cache items: %v", cacheKeys, err) } return err }
func commitBoardState(w http.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) log.Debugf(c, "Commit Board State received!", nil) if r.Method != "POST" { http.Error(w, "Invalid method.", 500) return } dec := json.NewDecoder(r.Body) defer r.Body.Close() state := &BoardState{} err := dec.Decode(&state) if err != nil { http.Error(w, fmt.Sprintf("Failed to parse board state. %s", err.Error()), 500) return } log.Debugf(c, "Input: %v", state) newState, err := SaveGame(c, state) if err != nil { http.Error(w, fmt.Sprintf("Failed to save board state. %s", err.Error()), 500) return } enc := json.NewEncoder(w) err = enc.Encode(newState) if err != nil { http.Error(w, fmt.Sprintf("Failed to parse board state response. %s", err.Error()), 500) return } }
func sendUpdate(ctx context.Context, g *Game) { fb, err := firebase(ctx) if err != nil { log.Errorf(ctx, "getFirebase: %v", err) } chans := fb.Child("channels") gameKey := g.K.Encode() if g.UserO != "" { channelID := g.UserO + gameKey if err := chans.Child(channelID).Set(g); err != nil { log.Errorf(ctx, "Updating UserO (%s): %v", channelID, err) } else { log.Debugf(ctx, "Update O sent.") } } if g.UserX != "" { channelID := g.UserX + gameKey if err := chans.Child(channelID).Set(g); err != nil { log.Errorf(ctx, "Updating UserX (%s): %v", channelID, err) } else { log.Debugf(ctx, "Update X sent.") } } }
func SendAlerts(ctx context.Context, stocksForAlert []PortfolioStock) { if len(stocksForAlert) == 0 { log.Debugf(ctx, "SendAlerts: Alert stocks are empty") return } //group by user emails to send a consolidated email groupedStockAlerts := make(map[string][]PortfolioStock) for _, alert := range stocksForAlert { userPortfolioStocks := groupedStockAlerts[alert.Email] userPortfolioStocks = append(userPortfolioStocks, alert) groupedStockAlerts[alert.Email] = userPortfolioStocks } log.Debugf(ctx, "Will send alerts for ", Jsonify(groupedStockAlerts)) for email, alerts := range groupedStockAlerts { msg := &mail.Message{ Sender: "NewTechFellas Stock Alerts <*****@*****.**>", To: []string{email}, Subject: "Newtechfellas stock alerts for your stocks - " + DateString(), Body: getStocksAlertMailBody(alerts), } if err := mail.Send(ctx, msg); err != nil { log.Debugf(ctx, "Couldn't send email: %v", err) } } for _, portfolioStock := range stocksForAlert { portfolioStock.AlertSentTime = time.Now() //Save stocksForAlert to update last alert sent time CreateOrUpdate(ctx, &portfolioStock, portfolioStock.kind(), portfolioStock.stringId(), 0) } }
// cachedCerts fetches public certificates info from DefaultCertURI and // caches it for the duration specified in Age header of a response. func cachedCerts(c context.Context) (*certsList, error) { namespacedContext, err := appengine.Namespace(c, certNamespace) if err != nil { return nil, err } var certs *certsList _, err = memcache.JSON.Get(namespacedContext, DefaultCertURI, &certs) if err == nil { return certs, nil } // Cache miss or server error. // If any error other than cache miss, it's proably not a good time // to use memcache. var cacheResults = err == memcache.ErrCacheMiss if !cacheResults { log.Debugf(c, "%s", err.Error()) } log.Debugf(c, "Fetching provider certs from: %s", DefaultCertURI) resp, err := newHTTPClient(c).Get(DefaultCertURI) if err != nil { return nil, err } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { return nil, errors.New("Could not reach Cert URI or bad response.") } certBytes, err := ioutil.ReadAll(resp.Body) if err != nil { return nil, err } err = json.Unmarshal(certBytes, &certs) if err != nil { return nil, err } if cacheResults { expiration := certExpirationTime(resp.Header) if expiration > 0 { item := &memcache.Item{ Key: DefaultCertURI, Value: certBytes, Expiration: expiration, } err = memcache.Set(namespacedContext, item) if err != nil { log.Errorf(c, "Error adding Certs to memcache: %v", err) } } } return certs, nil }
func GetValidUser(email string, ctx context.Context, w http.ResponseWriter, r *http.Request) (user User, err error) { //Is user verified if err = GetEntity(ctx, email, 0, "User", &user); err != nil { log.Debugf(ctx, "User not found for email ", email) return } if !user.IsVerified { log.Debugf(ctx, "User ", email, " is not verified") ErrorResponse(w, errors.New("User is not verified. Check your email to confirm the registration"), http.StatusBadRequest) return } return }
// ServeHTTP handles the HTTP request, by forwarding it to the target VM. // If the VM is not up, it will be launched. func (vm *VM) ServeHTTP(w http.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) log.Debugf(c, "Servicing a new request with VM Proxy %s/%s", vm.Instance.Name, vm.ip) if !vm.IsRunning(c) { log.Debugf(c, "VM not running, starting a new one ...") if err := vm.Start(c); err != nil { log.Errorf(c, "Error starting VM: %v", err) http.Error(w, fmt.Sprintf("Failed to start VM: %v", err), http.StatusInternalServerError) return } } log.Debugf(c, "Forwarding request ...") vm.forward(c, w, r) }
func GetStocksUsingYql(ctx context.Context, symbols []string) (stocks []Stock, err error) { client := urlfetch.Client(ctx) quotedSymbols := MapStr(func(s string) string { return `"` + s + `"` }, symbols) query := fmt.Sprintf(`SELECT Symbol,Name,Open,LastTradePriceOnly,ChangeinPercent,DaysLow,DaysHigh,Change FROM %s WHERE symbol IN (%s)`, "yahoo.finance.quotes", strings.Join(quotedSymbols, ",")) log.Debugf(ctx, "Quotes query = ", query) v := url.Values{} v.Set("q", query) v.Set("format", "json") v.Set("env", DatatablesUrl) url := PublicApiUrl + "?" + v.Encode() resp, err := client.Get(url) if err != nil { log.Debugf(ctx, "Failed to fetch data from YQL for ", url, " error is ", err) return } defer resp.Body.Close() httpBody, err := ioutil.ReadAll(resp.Body) if err != nil { log.Debugf(ctx, "Error in Reading from response body while fetching quote from YQL", err) return } log.Debugf(ctx, "Response from YQL is ", string(httpBody[:])) if len(symbols) == 1 { var sresp YqlJsonSingleQuoteResponse if err = json.Unmarshal(httpBody, &sresp); err != nil { log.Debugf(ctx, "Error in unmarshalling for single response ", err) return } stocks = append(stocks, sresp.Query.Results.Quote.toStock()) } else { var resp YqlJsonQuoteResponse if err = json.Unmarshal(httpBody, &resp); err != nil { return } for _, q := range resp.Query.Results.Quote { stocks = append(stocks, q.toStock()) } } for _, s := range stocks { s.LastUpdated = time.Now() cachedStocks[s.Symbol] = s //update the cache } return }
func projections(c context.Context, u User, days int) (int64, int64, error) { var projected, earned int64 g := syncutil.Group{} g.Go(func() error { q := datastore.NewQuery("Task"). Filter("Disabled = ", false). Filter("Assignee = ", u.Email) for t := q.Run(c); ; { var x Task _, err := t.Next(&x) if err == datastore.Done { return nil } else if err != nil { return err } log.Debugf(c, "Item worth %v every %v", x.Value, x.Period) projected += int64(float64(x.Value) * (float64(days) / float64(x.Period))) } }) g.Go(func() error { q := datastore.NewQuery("LoggedTask"). Filter("User = "******"Completed >=", time.Now().Add(-24*time.Hour*time.Duration(days))) for t := q.Run(c); ; { var x LoggedTask _, err := t.Next(&x) if err == datastore.Done { return nil } else if err != nil { return err } log.Debugf(c, "Logged task worth %v", x.Amount) earned += int64(x.Amount) } }) g.Wait() return projected, earned, g.Err() }
func twitterSearch(w http.ResponseWriter, r *http.Request) { ctx := appengine.NewContext(r) query := r.URL.Query().Get("q") hash := r.URL.Query().Get("h") log.Debugf(ctx, "Twitter search", string(query)) anaconda.SetConsumerKey("cW0kdWCjgnE8vpJGOvUxe4epL") anaconda.SetConsumerSecret("GEcenuc4kLzZLAfYddfC3PovRVdAu3CL3n9sc61zikH4wK2eDw") api := anaconda.NewTwitterApi("", "") api.HttpClient.Transport = &urlfetch.Transport{Context: ctx} v := url.Values{ "result_type": {"mixed"}, "count": {"1000"}, "include_entities": {"false"}, } if hash == "true" { query = "#" + query } else { query = "@" + query } searchResult, _ := api.GetSearch(url.QueryEscape(string(query)), v) js, err := json.Marshal(searchResult.Statuses[rand.Intn(len(searchResult.Statuses))]) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") w.Write(js) }
func jobTrackTimezoneHandler(r *http.Request, f *oldfdb.Flight) (string, error) { c := appengine.NewContext(r) defaultTP := f.Track.ClosestTrackpoint(sfo.KFixes["EPICK"]) adsbTP := f.Tracks["ADSB"].ClosestTrackpoint(sfo.KFixes["EPICK"]) trackTimeDelta := defaultTP.TimestampUTC.Sub(adsbTP.TimestampUTC) str := fmt.Sprintf("OK, looked up %s\n Default: %s\n ADSB : %s\n delta: %s\n", f, defaultTP, adsbTP, trackTimeDelta) if trackTimeDelta < -4*time.Hour || trackTimeDelta > 4*time.Hour { str += fmt.Sprintf("* recoding\n* before: %s\n", f.Tracks["ADSB"]) for i, _ := range f.Tracks["ADSB"] { f.Tracks["ADSB"][i].TimestampUTC = f.Tracks["ADSB"][i].TimestampUTC.Add(time.Hour * -8) } str += fmt.Sprintf("* after : %s\n", f.Tracks["ADSB"]) db := oldfgae.FlightDB{C: oldappengine.NewContext(r)} if err := db.UpdateFlight(*f); err != nil { log.Errorf(c, "Persist Flight %s: %v", f, err) return str, err } log.Infof(c, "Updated flight %s", f) str += fmt.Sprintf("--\nFlight was updated\n") } else { log.Debugf(c, "Skipped flight %s, delta=%s", f, trackTimeDelta) str += "--\nFlight was OK, left untouched\n" } return str, nil }
// To run a job directly: /backend/fdb-batch/flight?job=...&key=...& func batchSingleFlightHandler(w http.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) f, err := formValueFlightByKey(r) if err != nil { log.Errorf(c, "batch/fdb/track/getflight: %v", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } // You now have a job name, and a flight object. Get to it ! job := r.FormValue("job") var str string = "" switch job { case "tracktimezone": str, err = jobTrackTimezoneHandler(r, f) case "oceanictag": str, err = jobOceanicTagHandler(r, f) case "v2adsb": str, err = jobV2adsbHandler(r, f) } if err != nil { log.Errorf(c, "%s", str) log.Errorf(c, "backend/fdb-batch/flight: %v", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } log.Debugf(c, "job=%s, on %s: %s", job, f, str) w.Header().Set("Content-Type", "text/plain") w.Write([]byte(fmt.Sprintf("OK\n * %s\n%s\n", f, str))) }
func authCallbackHandler(w http.ResponseWriter, r *http.Request) { ctx := appengine.NewContext(r) c := NewTwitterClient(ctx) token := r.FormValue("oauth_token") verificationCode := r.FormValue("oauth_verifier") log.Debugf(ctx, "oauth_token:%v oauth_verifier:%v", token, verificationCode) requestToken := FindRequest(ctx, token) if requestToken == nil { fmt.Fprint(w, "token not found") w.WriteHeader(500) return } accessToken, err := c.AuthorizeToken(requestToken, verificationCode) if err != nil { fmt.Fprint(w, err) w.WriteHeader(500) return } fmt.Fprintln(w, accessToken.AdditionalData) api := anaconda.NewTwitterApi(accessToken.Token, accessToken.Secret) api.HttpClient = urlfetch.Client(ctx) ok, err := api.VerifyCredentials() if err != nil { fmt.Fprint(w, err) w.WriteHeader(500) return } fmt.Fprintln(w, ok) }
// determine whether old request has ended according to logs func (l *Locker) previousRequestEnded(c context.Context, requestID string) bool { q := &log.Query{ RequestIDs: []string{requestID}, } results := q.Run(c) record, err := results.Next() if err == log.Done { // no record found so it hasn't ended if l.LogVerbose { log.Warningf(c, "no log found for previous request %s", requestID) } return false } if err != nil { // Managed VMs do not have access to the logservice API if l.LogVerbose { log.Warningf(c, "err getting log for previous request %s %v", requestID, err) } return false } if l.LogVerbose { log.Debugf(c, "found previous request log %v", record) } return record.Finished }
func perftesterHandler(w http.ResponseWriter, r *http.Request) { ctx := appengine.NewContext(r) tStart := time.Now() str := "" debugf := func(step string, fmtstr string, varargs ...interface{}) { payload := fmt.Sprintf(fmtstr, varargs...) outStr := fmt.Sprintf("[%s] %9.6f %s", step, time.Since(tStart).Seconds(), payload) log.Debugf(ctx, outStr) str += "* " + outStr + "\n" } debugf("pt_001", "starting") stats := map[string]*complaintdb.DailyCount{} dailys := []complaintdb.DailyCount{} counts := []types.CountItem{} debugf("pt_002", "populating") t := time.Now().AddDate(0, -6, 0) for i := 0; i < 150; i++ { t = t.AddDate(0, 0, 1) dailys = append(dailys, complaintdb.DailyCount{t.Format("2006.01.02"), i, i, false, false}) item := complaintdb.DailyCount{t.Format("2006.01.02"), i, i, false, false} stats[date.Datestring2MidnightPdt(item.Datestring).Format("Jan 02")] = &item } debugf("pt_005", "populating all done") pdt, _ := time.LoadLocation("America/Los_Angeles") dateNoTimeFormat := "2006.01.02" arbitraryDatestring2MidnightPdt := func(s string, fmt string) time.Time { t, _ := time.ParseInLocation(fmt, s, pdt) return t } datestring2MidnightPdt := func(s string) time.Time { return arbitraryDatestring2MidnightPdt(s, dateNoTimeFormat) } _ = datestring2MidnightPdt debugf("pt_010", "daily stats loaded (%d dailys, %d stats)", len(dailys), len(stats)) for _, daily := range dailys { // cdb.C.Infof(" -- we have a daily: %#v", daily) //key := datestring2MidnightPdt(daily.Datestring).Format("Jan 02") item := types.CountItem{ //Key: key, //fmt.Sprintf("Jan %02d", j+1), //daily.Timestamp().Format("Jan 02"), Key: daily.Timestamp().Format("Jan 02"), Count: daily.NumComplaints, } if dc, exists := stats[item.Key]; exists { item.TotalComplainers = dc.NumComplainers item.TotalComplaints = dc.NumComplaints item.IsMaxComplainers = dc.IsMaxComplainers item.IsMaxComplaints = dc.IsMaxComplaints } //counts = append(counts, item) } debugf("pt_090", "daily stats munged (%d counts)", len(counts)) w.Header().Set("Content-Type", "text/plain") w.Write([]byte(str)) }
func sessionHandler(w http.ResponseWriter, r *http.Request) { ctx := appengine.NewContext(r) if r.Method == "POST" { // create new Session var newSession session parseError := json.NewDecoder(r.Body).Decode(&newSession) if parseError != nil { log.Debugf(ctx, "Error parsing session: %s", parseError.Error()) writeError(http.StatusBadRequest, "Unable to parse JSON: "+parseError.Error(), w) } else { if newSession.Talks == nil { newSession.Talks = []talk{} } sessions = append(sessions, newSession) marshalled, _ := json.Marshal(newSession) w.Header().Set("Content-Type", "application/json") w.Write(marshalled) } } else if r.Method == "GET" { sessionIndex := sessionFromRequest(r) if sessionIndex == -1 { writeError(404, "Session not found", w) return } marshalled, _ := json.Marshal(sessions[sessionIndex]) w.Header().Set("Content-Type", "application/json") w.Write(marshalled) } else { writeError(405, "Method not allowed", w) } }
func voteHandler(w http.ResponseWriter, r *http.Request) { ctx := appengine.NewContext(r) sessionIndex, talkIndex := talkIndexByRequest(r) if sessionIndex == -1 || talkIndex == -1 { writeError(404, "Talk not found", w) return } if r.Method == "POST" { var newVote vote parseError := json.NewDecoder(r.Body).Decode(&newVote) if parseError != nil { log.Debugf(ctx, "Error parsing session: %s", parseError.Error()) writeError(http.StatusBadRequest, "Unable to parse JSON: "+parseError.Error(), w) } else { newVote.Timestamp = time.Now() sessions[sessionIndex].Talks[talkIndex].Votes = append(sessions[sessionIndex].Talks[talkIndex].Votes, newVote) } return } if r.Method == "GET" { marshalled, _ := json.Marshal(sessions[sessionIndex].Talks[talkIndex].Votes) w.Header().Set("Content-Type", "application/json") w.Write(marshalled) return } writeError(405, "Method not allowed", w) }
func createOrGetTalkHandler(w http.ResponseWriter, r *http.Request) { ctx := appengine.NewContext(r) sessionIndex := sessionFromRequest(r) if sessionIndex == -1 { writeError(500, "No sessionId path parameter or name query parameter passed", w) return } if r.Method == "GET" { marshalled, _ := json.Marshal(sessions[sessionIndex].Talks) w.Header().Set("Content-Type", "application/json") w.Write(marshalled) return } if r.Method == "POST" { var newTalk talk parseError := json.NewDecoder(r.Body).Decode(&newTalk) if parseError != nil { log.Debugf(ctx, "Error parsing session: %s", parseError.Error()) writeError(http.StatusBadRequest, "Unable to parse JSON: "+parseError.Error(), w) } else { newTalk.Votes = []vote{} sessions[sessionIndex].Talks = append(sessions[sessionIndex].Talks, newTalk) currentTalkIndex = len(sessions[sessionIndex].Talks) - 1 marshalled, _ := json.Marshal(newTalk) w.Header().Set("Content-Type", "application/json") w.Write(marshalled) } return } writeError(405, "Method not allowed", w) }
func textMessageHandler(w http.ResponseWriter, r *http.Request) { ctx := appengine.NewContext(r) to := r.FormValue("to") text := r.FormValue("text") log.Debugf(ctx, "to: %s, text: %s.", to, text) chi, _ := strconv.ParseInt(os.Getenv("CHANNEL_ID"), 10, 64) chs := os.Getenv("CHANNEL_SECRET") mid := os.Getenv("MID") client := urlfetch.Client(ctx) bot, err := linebot.NewClient(chi, chs, mid, linebot.WithHTTPClient(client)) if err != nil { log.Errorf(ctx, "Client initialization failure. to: %s, text: %s, context: %s", to, text, err.Error()) w.WriteHeader(http.StatusInternalServerError) return } res, err := bot.SendText([]string{to}, text) if err != nil { log.Errorf(ctx, "Message Send Failed. to: %s, text: %s, context: %s", to, text, err.Error()) w.WriteHeader(http.StatusInternalServerError) return } log.Infof(ctx, "Message send succeed. MessageID: %s, to: %s, text: %s", res.MessageID, to, text) w.WriteHeader(http.StatusOK) }
func (b *InventorySearchBuilder) PutDocument(c context.Context, src *InventorySearch) (string, error) { index, err := search.Open(b.IndexName()) if err != nil { return "", err } docID := "" if v, ok := interface{}(src).(smgutils.DocIDer); ok { // TODO can I shorten this cond expression? docID, err = v.DocID(c) if err != nil { return "", err } src.ID = docID } log.Debugf(c, "id: %#v, payload: %#v", docID, src) docID, err = index.Put(c, docID, src) if err != nil { return "", err } src.ID = docID return docID, nil }
func incrementCounter(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { c := appengine.NewContext(r) key := datastore.NewKey(c, "Counter", "TheCounter", 0, nil) var result Counter err := datastore.RunInTransaction(c, func(c context.Context) error { var counter Counter err := datastore.Get(c, key, &counter) if err == datastore.ErrNoSuchEntity { log.Debugf(c, "No entity, creating a new one.") } else if err != nil { log.Errorf(c, "Error getting counter. %v", err) return err } else { } counter.Value += 1 result = counter _, err = datastore.Put(c, key, &result) return err }, nil) if err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(err.Error())) return } w.WriteHeader(http.StatusOK) w.Write([]byte(strconv.FormatInt(result.Value, 10))) }