// updateRecipeFromURL is a helper function that attempts to parse the // recipe URL to get the recipe data. If an error occurs, false is // returned and a proper message will have been sent as a // response. This case should be terminal. If a parser isn't available // for the URL, no error is returned, but nothing is changed in the // recipe. func updateRecipeFromURL(c appengine.Context, w http.ResponseWriter, r *http.Request, recipe *Recipe) bool { p, err := parsers.GetParserForURL(recipe.URL) if err != nil { gorca.LogAndUnexpected(c, w, r, err) return false } if p == nil { gorca.Log(c, r, "warn", "no parser found for: %s", recipe.URL) return true } client := urlfetch.Client(c) resp, err := client.Get(recipe.URL) if err != nil { gorca.LogAndUnexpected(c, w, r, err) return false } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { gorca.LogAndUnexpected(c, w, r, err) return false } recipe.Name = p.GetName(body) recipe.Ingredients = p.GetIngredients(body) recipe.Directions = p.GetDirections(body) return true }
// GetList fetches the list for the given tag. func GetList(w http.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) // Get the Key. vars := mux.Vars(r) key := vars["key"] // Handle Not-modified ut := r.FormValue("date") if ut != "" { notmod(c, w, r, key, ut) return } l, ok := GetListHelper(c, w, r, key) if !ok { return } // Save the results to memcache. item := &memcache.Item{ Key: key, Value: []byte(fmt.Sprintf("%d", l.LastModified.Unix())), } if err := memcache.Set(c, item); err != nil { gorca.Log(c, r, "error", "failed to set memcache: %v", err) } // Write the lists as JSON. gorca.WriteJSON(c, w, r, l) }
// notmod checks to see if the cached date for the key is newer than // the date given from the url. This call is terminal. It will always // respond to the request. If the dates are equal, then this function // sends a 304 Not Modified. If an error occurs, the error is logged // and sent back. func notmod(c appengine.Context, w http.ResponseWriter, r *http.Request, key string, date string) { // Convert the given string. i, err := strconv.ParseInt(date, 10, 64) if err != nil { gorca.LogAndFailed(c, w, r, err) return } t := time.Unix(i, 0) // Try to get the key from memcache item, err := memcache.Get(c, key) if err != nil && err != memcache.ErrCacheMiss { gorca.LogAndFailed(c, w, r, err) return } var mt time.Time // Check to see if it's simply not there. if err == memcache.ErrCacheMiss { gorca.Log(c, r, "info", "failed to get memcache: %s", key) // Try to get the list. l, ok := GetListHelper(c, w, r, key) if !ok { return } // Save the results to memcache. item := &memcache.Item{ Key: key, Value: []byte(fmt.Sprintf("%d", l.LastModified.Unix())), } if err := memcache.Set(c, item); err != nil { gorca.Log(c, r, "error", "failed to set memcache: %v", err) } mt = l.LastModified } else { // Convert the memcache string. mi, err := strconv.ParseInt(string(item.Value), 10, 64) if err != nil { gorca.LogAndFailed(c, w, r, err) return } mt = time.Unix(mi, 0) } if mt.Equal(t) { // Write out the not modified. w.WriteHeader(http.StatusNotModified) return } // Write out that we modified. gorca.WriteMessage(c, w, r, "success", "Modified.", http.StatusOK) return }