// CreateVenueHandler makes a new venue and saves it to the datastore func CreateVenueHandler(w util.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) var venueData Venue if err := json.NewDecoder(r.Body).Decode(&venueData); err != nil { log.Println("Unable to decode create venue data:", err.Error()) http.Error(w, "Unable to decode JSON request body", http.StatusBadRequest) return } if venueData.Name == "" { http.Error(w, `must provide "name" field when creating a venue`, http.StatusBadRequest) return } key := datastore.NewIncompleteKey(c, "Venues", nil) newKey, err := datastore.Put(c, key, &venueData) if err != nil { w.WriteJSON(nil, err) return } venueData.ID = newKey.IntID() w.WriteJSON(&venueData, nil) }
// GetVenueHandler returns information about a single Venue func GetVenueHandler(w util.ResponseWriter, r *http.Request) { // TODO: Test this function c := appengine.NewContext(r) venueID, err := util.GetIntParam(r, "venue_id", 0) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } if !VenueExists(c, venueID) { http.Error(w, "provided venue_id does not exist", http.StatusBadRequest) return } key := datastore.NewKey(c, "Venues", "", venueID, nil) var venue Venue err = datastore.Get(c, key, &venue) if err == datastore.ErrNoSuchEntity { http.NotFound(w.ResponseWriter, r) } else if err != nil { log.Println("Unable to retrieve a venue from datastore:", err.Error()) w.WriteJSON(nil, err) return } venue.ID = venueID w.WriteJSON(&venue, nil) }
// CreateVenueDishHandler creates a new dish based on the request body func CreateVenueDishHandler(w util.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) var dishData Dish if err := json.NewDecoder(r.Body).Decode(&dishData); err != nil { log.Println("Unable to decode create dish data:", err.Error()) http.Error(w, "Unable to decode JSON request body", http.StatusBadRequest) return } venueID, err := util.GetIntParam(r, "venue_id", 0) if !VenueExists(c, venueID) { http.Error(w, "provided venue_id does not exist", http.StatusBadRequest) return } dishData.VenueID = venueID if dishData.Name == "" { http.Error(w, `must provide "name" field when creating a dish`, http.StatusBadRequest) return } key := datastore.NewIncompleteKey(c, "Dishes", nil) newKey, err := datastore.Put(c, key, &dishData) if err != nil { w.WriteJSON(nil, err) return } dishData.ID = newKey.IntID() w.WriteJSON(&dishData, nil) }
// CreateDishRatingHandler inserts a new rating into the datastore. // dish_id parameter must be set to a dish which exists in the datastore and // rating must be between 1 and 10. User must be logged in. func CreateDishRatingHandler(w util.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) dishID, err := util.GetIntParam(r, "dish_id", 0) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } if !DishExists(c, dishID) { http.Error(w, "provided dish_id does not exist", http.StatusBadRequest) return } // Check that no rating already exists for this dish if GetDishRating(c, dishID) != -1 { http.Error(w, "dish already has a rating from this user", http.StatusBadRequest) return } var ratingData Rating if err := json.NewDecoder(r.Body).Decode(&ratingData); err != nil { log.Println("unable to decode create rating data:", err.Error()) http.Error(w, "Unable to decode JSON request body", http.StatusBadRequest) return } if ratingData.Rating > 10 || ratingData.Rating < 1 { http.Error(w, "rating must be between 1 and 10", http.StatusBadRequest) return } ratingData.DishID = dishID ratingData.UserID = GetCurrentUserID(c) ratingData.Timestamp = time.Now() key := datastore.NewIncompleteKey(c, "Ratings", nil) newKey, err := datastore.Put(c, key, &ratingData) if err != nil { w.WriteJSON(nil, err) return } w.WriteCreated("/api/rating/" + strconv.FormatInt(newKey.IntID(), 10)) }
// GetVenuesHandler retrieves all venues func GetVenuesHandler(w util.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) limit, err := util.GetIntParam(r, "limit", 25) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } offset, err := util.GetIntParam(r, "offset", 0) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } q := datastore.NewQuery("Venues").Limit(int(limit)).Offset(int(offset)) var results []Venue keys, err := q.GetAll(c, &results) if err != nil { w.WriteJSON(nil, err) } if len(keys) == 0 { w.WriteJSON([]Venue{}, nil) return } for i, key := range keys { results[i].ID = key.IntID() } w.WriteJSON(results, err) }
// GetUserInfoHandler returns either the location where the user can log into // the app, or metadata about the currently authenticated user. func GetUserInfoHandler(w util.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) u := user.Current(c) dest := mux.Vars(r)["dest"] if dest == "" { dest = "/" } if u == nil { url, err := user.LoginURL(c, dest) w.WriteJSON(map[string]interface{}{"loginURL": url}, err) return } // Check if the user exists in the database q := datastore.NewQuery("Users").Limit(1) q.Filter("GoogleID = ", u.ID) var results []User keys, err := q.GetAll(c, &results) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } if len(results) == 0 { newUser := User{ GoogleID: u.ID, CreatedTime: time.Now(), Email: u.Email, } key := datastore.NewIncompleteKey(c, "Users", nil) newKey, err := datastore.Put(c, key, &newUser) if newKey != nil { newUser.ID = newKey.IntID() } url, _ := user.LogoutURL(c, dest) newUser.LogoutURL = url w.WriteJSON(newUser, err) return } url, _ := user.LogoutURL(c, dest) fullUser := results[0] fullUser.ID = keys[0].IntID() fullUser.LogoutURL = url w.WriteJSON(fullUser, nil) }
// GetDishRatingsHandler returns the ratings for all users on a particular dish func GetDishRatingsHandler(w util.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) dishID, err := util.GetIntParam(r, "dish_id", 0) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } if !DishExists(c, dishID) { http.Error(w, "provided dish_id does not exist", http.StatusBadRequest) return } limit, err := util.GetIntParam(r, "limit", 25) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } offset, err := util.GetIntParam(r, "offset", 0) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } q := datastore.NewQuery("Ratings").Limit(int(limit)).Offset(int(offset)) q = q.Filter("DishID =", dishID) var results []Dish keys, err := q.GetAll(c, &results) if err != nil { w.WriteJSON(nil, err) } if len(keys) == 0 { w.WriteJSON([]Dish{}, nil) return } for i, key := range keys { results[i].ID = key.IntID() } w.WriteJSON(results, err) }
// getDishesHelper performs a datastore query, writing the results to the http // response. If venueID is not 0, the results are filtered to only that venue. func getDishesHelper(venueID int64, w util.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) limit, err := util.GetIntParam(r, "limit", 25) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } offset, err := util.GetIntParam(r, "offset", 0) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } q := datastore.NewQuery("Dishes").Limit(int(limit)).Offset(int(offset)) if venueID != 0 { log.Printf("adding 'VenueID = %d' to query", venueID) q = q.Filter("VenueID =", venueID) } var results []Dish keys, err := q.GetAll(c, &results) if err != nil { w.WriteJSON(nil, err) } if len(keys) == 0 { w.WriteJSON([]Dish{}, nil) return } for i, key := range keys { results[i].ID = key.IntID() } w.WriteJSON(results, err) }
// GetRecentRatingsHandler returns increments of <limit> ratings, starting at // <offset>, ordered from most recent to least. func GetRecentRatingsHandler(w util.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) limit, err := util.GetIntParam(r, "limit", 10) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } offset, err := util.GetIntParam(r, "offset", 0) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } q := datastore.NewQuery("Ratings").Limit(int(limit)).Offset(int(offset)) q = q.Filter("UserID =", GetCurrentUserID(c)) q = q.Order("Timestamp") var results []Dish keys, err := q.GetAll(c, &results) if err != nil { w.WriteJSON(nil, err) } if len(keys) == 0 { w.WriteJSON([]Dish{}, nil) return } for i, key := range keys { results[i].ID = key.IntID() } w.WriteJSON(results, err) }