// processItems fetches all the Items for the given Account, and the compares // them to the id list posted from the form. All the matches get applied // the given function: delete, favorite, unfavorite, etc. func processItems(w http.ResponseWriter, r *http.Request, dbCoords database.ConnCoordinates, fn func(*database.Item, *sqlite3.Conn), successTarget string) { // attempt to connect to the db db, err := database.InitializeDB(dbCoords) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } defer db.Close() // get the Account for this request acc, accErr := database.GetDesignatedAccount(db) if accErr != nil { http.Error(w, accErr.Error(), http.StatusInternalServerError) return } // get all the Items for this Account // and store them in a map by their Idscanned/ items, itemsErr := database.GetItems(db, acc) if itemsErr != nil { http.Error(w, itemsErr.Error(), http.StatusInternalServerError) return } accountItems := make(map[int64]*database.Item) for _, item := range items { accountItems[item.Id] = item } // get the list of item ids from the POST values // and apply the processing function if "POST" == r.Method { r.ParseForm() if idVals, exists := r.PostForm["item"]; exists { for _, idString := range idVals { id, idErr := strconv.ParseInt(idString, 10, 64) if idErr == nil { if accountItem, ok := accountItems[id]; ok { fn(accountItem, db) } } } } } // finally, return home, to the scanned items list http.Redirect(w, r, successTarget, http.StatusFound) }
// EmailItems handles the client form post, to send a list of the selected // items via email to the given user func EmailItems(w http.ResponseWriter, r *http.Request, dbCoords database.ConnCoordinates, opts ...interface{}) { // attempt to connect to the db db, err := database.InitializeDB(dbCoords) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } defer db.Close() // get the api server + port from the optional parameters apiHost, apiHostOk := opts[0].(string) if !apiHostOk { http.Error(w, BAD_REQUEST, http.StatusInternalServerError) return } // get the Account for this request acc, accErr := database.GetDesignatedAccount(db) if accErr != nil { http.Error(w, accErr.Error(), http.StatusInternalServerError) return } // get the account from the POST values if "POST" == r.Method { r.ParseForm() // make sure the form sent the required params accVal, accExists := r.PostForm["account"] items, itemsExist := r.PostForm["item"] if itemsExist && accExists { if len(accVal) > 0 { // check the submitted account info id, idErr := strconv.ParseInt(accVal[0], 10, 64) if idErr != nil { http.Error(w, idErr.Error(), http.StatusInternalServerError) return } else { if acc.Id != id { http.Error(w, BAD_REQUEST, http.StatusInternalServerError) return } else { // proceed with the send only if registered if acc.Email != database.ANONYMOUS_EMAIL { // lookup all the items for this account accountItems, accountItemsErr := database.GetItems(db, acc) if accountItemsErr == nil { // ping the server with the selected item data ping := func() { v := url.Values{} v.Set("email", acc.Email) // attach the list of descriptions for the selected items for _, accItem := range accountItems { for _, item := range items { if strconv.FormatInt(accItem.Id, 10) == item { v.Add("item", accItem.Desc) break } } } // use the account api code as the digest key hmac := digest.GenerateDigest(acc.APICode, v.Encode()) v.Set("hmac", hmac) res, err := http.PostForm(strings.Join([]string{apiHost, "/email/"}, ""), v) if err == nil { res.Body.Close() } } go ping() // do not wait for the server to reply } } } } } else { http.Error(w, "Missing account id", http.StatusInternalServerError) return } } else { http.Error(w, BAD_POST, http.StatusInternalServerError) return } } else { http.Error(w, BAD_REQUEST, http.StatusInternalServerError) return } // finally, return home, to the scanned items list with an ack message http.Redirect(w, r, HOME_URL+"?ack=email", http.StatusFound) }
// getItems returns a list of scanned or favorited products, and the correct // corresponding options for the HTML page template func getItems(w http.ResponseWriter, r *http.Request, dbCoords database.ConnCoordinates, favorites bool) { // attempt to connect to the db db, err := database.InitializeDB(dbCoords) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } defer db.Close() // get the Account for this request acc, accErr := database.GetDesignatedAccount(db) if accErr != nil { http.Error(w, accErr.Error(), http.StatusInternalServerError) return } // define the appropriate fetch item function fetch := func(db *sqlite3.Conn, acc *database.Account) ([]*database.Item, error) { if favorites { return database.GetFavoriteItems(db, acc) } else { return database.GetItems(db, acc) } } // get all the desired items for this Account items := make([]*database.Item, 0) itemList, itemsErr := fetch(db, acc) if itemsErr != nil { http.Error(w, itemsErr.Error(), http.StatusInternalServerError) return } for _, item := range itemList { items = append(items, item) } // actions actions := make([]*Action, 0) // commerce options for _, vendor := range database.GetAllVendors(db) { actions = append(actions, &Action{Link: fmt.Sprintf("/buy%s/", vendor.VendorId), Icon: "fa fa-shopping-cart", Action: fmt.Sprintf("Buy from %s", vendor.DisplayName)}) } if acc.Email != database.ANONYMOUS_EMAIL { actions = append(actions, &Action{Link: "/email/", Icon: "fa fa-envelope", Action: "Email to me"}) } if favorites { actions = append(actions, &Action{Link: "/unfavorite/", Icon: "fa fa-star-o", Action: "Remove from favorites"}) } else { actions = append(actions, &Action{Link: "/favorite/", Icon: "fa fa-star", Action: "Add to favorites"}) } actions = append(actions, &Action{Link: "/delete/", Icon: "fa fa-trash", Action: "Delete"}) // define the page title var titleBuffer bytes.Buffer if favorites { titleBuffer.WriteString("Favorite") } else { titleBuffer.WriteString("Scanned") } titleBuffer.WriteString(" Item") if len(itemList) != 1 { titleBuffer.WriteString("s") } p := &ItemsPage{Title: titleBuffer.String(), Scanned: !favorites, ActiveTab: &ActiveTab{Scanned: !favorites, Favorites: favorites, Account: false, ShowTabs: true}, Actions: actions, Account: acc, Items: items} // check for any message to display on page load r.ParseForm() if msg, exists := r.Form["ack"]; exists { ackType := strings.Join(msg, "") if ackType == "email" { p.PageMessage = EMAIL_SENT } } renderItemListTemplate(w, p) }