def set_user_history_meal(): if not verify_credentials(request): return "Unauthorized: Invalid or missing credentials", 401 user_id = get_id_from_request(request) if not user_id: return "No user found", 400 params = request.json if not params or not all(k in params for k in ("date", "meal", "foods")): return "Please provide date, meal_name, and foods parameters.", 400 curr_date = str(params["date"]) curr_meal = str(params["meal"]) curr_foods = dict(params["foods"]) curr_doc = db.find_one({"user_id": user_id}) if curr_doc: curr_history = curr_doc["history"] if curr_date in curr_history: curr_history[curr_date][curr_meal] = curr_foods else: curr_history[curr_date] = {curr_meal: curr_foods} else: curr_history = {curr_date: {curr_meal: curr_foods}} db.replace_one({"user_id": user_id}, { "user_id": user_id, "history": curr_history }, upsert=True) return '', 204
def set_user_history_daily(): if not verify_credentials(request): return "Unauthorized: Invalid or missing credentials", 401 user_id = get_id_from_request(request) if not user_id: return "No user found", 400 params = request.json if not params or "day_history" not in params or "date" not in params: return "Please include the daily food history and date", 400 day_history = dict(params["day_history"]) curr_date = str(params["date"]) curr_doc = db.find_one({"user_id": user_id}) if curr_doc: curr_history = curr_doc["history"] curr_history[curr_date] = day_history else: curr_history = {curr_date: curr_history} db.replace_one({"user_id": user_id}, { "user_id": user_id, "history": curr_history }, upsert=True) return '', 204
def delete_user_history_food(): if not verify_credentials(request): return "Unauthorized: Invalid or missing credentials", 401 user_id = get_id_from_request(request) if not user_id: return "No user found", 400 params = request.json if not params or not all(k in params for k in ("prev_food_id", "date", "meal")): return "Please provide prev_food_id, date, meal for removal.", 400 prev_food_id = str(params["prev_food_id"]) curr_date = str(params["date"]) curr_meal = str(params["meal"]) curr_doc = db.find_one({"user_id": user_id}) # This code is complex -- handles missing date, meal name, etc. if curr_doc: curr_history = curr_doc["history"] if curr_date in curr_history: if curr_meal in curr_history[curr_date]: if prev_food_id in curr_history[curr_date][curr_meal]: del curr_history[curr_date][curr_meal][prev_food_id] db.replace_one({"user_id": user_id}, { "user_id": user_id, "history": curr_history }, upsert=True) return '', 204
def get_daily_meals(): if not verify_credentials(request): return "Unauthorized: Invalid or missing credentials", 401 params = request.json user_id = get_id_from_request(request) if not user_id: return "No user found", 400 if not params or "date" not in params: return "Please include the date", 400 given_date = str(params["date"]) # save to date in user_history db user_history = db_user_history.find_one({"user_id": user_id}) if not user_history: # doesn't exist yet so create new_history = {"user_id": user_id, "history": {}} db_user_history.insert_one(new_history) user_history = db_user_history.find_one({"user_id": user_id}) # DAILY PLAN GENERATOR dailyPlan = generateDailyMeals(user_id, given_date, user_history) # go through daily plan for bfast, lunch, dinner, snacks, and one by one add dateObject = {} # Breakfast breakfastObject = {} breakfast = dailyPlan["Breakfast"] for food in breakfast: breakfastObject[str(food["food_id"])] = round(food["Servings"], 1) dateObject["Breakfast"] = breakfastObject # Lunch lunchObject = {} lunch = dailyPlan["Lunch"] for food in lunch: lunchObject[str(food["food_id"])] = round(food["Servings"], 1) dateObject["Lunch"] = lunchObject # Dinner dinnerObject = {} dinner = dailyPlan["Dinner"] for food in dinner: dinnerObject[str(food["food_id"])] = round(food["Servings"], 1) dateObject["Dinner"] = dinnerObject # Snacks dateObject["Snacks"] = {} # add to user_history currHistoryObject = user_history.get("history", {}) currHistoryObject[ given_date] = dateObject # hardcoded date for now b/c frontend isn't passing in date db_user_history.update_one({"user_id": user_id}, {"$set": { "history": currHistoryObject }}) print(dailyPlan) return jsonify(dailyPlan)
def get_foods_keyword_user(): # Handles Auth at the front if not verify_credentials(request): return "Unauthorized: Invalid or missing credentials", 401 user_id = get_id_from_request(request) if not user_id: return "No user found", 400 # Parses arguments params = request.json if not params or "query" not in params: return "Please include a search query", 400 user_query = str(params["query"]) # Fetches user restrictions from DB user_info = user_db.find_one({"user_id": user_id}) if not user_info: return "No user found in DB", 400 # Uses set unions to find all of user's restrictions, which will be # empty if user has no restrictions curr_restrictions = set() curr_restricted_words = set() user_restrictions = user_info["restrictions"] if user_restrictions: for restriction in user_restrictions: curr_groups = RESTRICTIONS_MAP[restriction] curr_restrictions = curr_restrictions.union(curr_groups) curr_words = RESTRICTIONS_WORDS[restriction] curr_restricted_words = curr_restricted_words.union(curr_words) food_regx = re.compile(user_query, re.IGNORECASE) return_list = [] for next_food in db.find({"Food Name": food_regx}): if next_food["Food Group"] not in curr_restrictions: food_name = next_food["Food Name"].lower() restricted_match = False for restricted_word in curr_restricted_words: if re.search(restricted_word, food_name): restricted_match = True break if not restricted_match: del next_food["_id"] return_list.append(next_food) return jsonify(return_list)
def fetch_user_info(): if not verify_credentials(request): return "Unauthorized: Invalid or missing credentials", 401 user_id = get_id_from_request(request) if not user_id: return "No user found", 400 # Gets document from DB user_info = db.find_one({"user_id": user_id}) if not user_info: return "User not in DB", 400 del user_info["_id"] # Can't be jsonified -- remove return jsonify(user_info)
def fetch_user_history(): if not verify_credentials(request): return "Unauthorized: Invalid or missing credentials", 401 user_id = get_id_from_request(request) if not user_id: return "No user found", 400 # Gets document from DB user_info = db.find_one({"user_id": user_id}) if user_info: del user_info["_id"] else: return "No user found in DB", 400 return jsonify(user_info["history"])
def set_user_history_food(): if not verify_credentials(request): return "Unauthorized: Invalid or missing credentials", 401 user_id = get_id_from_request(request) if not user_id: return "No user found", 400 params = request.json if not params or not all(k in params for k in ("food_id", "date", "meal", "servings")): return ( "Please provide food_id, date, meal, and servings (prev_food_id optional).", 400, ) food_id = str(params["food_id"]) curr_date = str(params["date"]) curr_meal = str(params["meal"]) servings = float(params["servings"]) curr_doc = db.find_one({"user_id": user_id}) # This code is complex -- handles missing date, meal name, etc. if curr_doc: curr_history = curr_doc["history"] if curr_date in curr_history: if curr_meal in curr_history[curr_date]: if "prev_food_id" in params: del curr_history[curr_date][curr_meal][str( params["prev_food_id"])] curr_history[curr_date][curr_meal][food_id] = servings else: curr_history[curr_date][curr_meal] = {food_id: servings} else: curr_history[curr_date] = {curr_meal: {food_id: servings}} else: curr_history = {curr_date: {curr_meal: {food_id: servings}}} db.replace_one({"user_id": user_id}, { "user_id": user_id, "history": curr_history }, upsert=True) return '', 204
def set_user_info(): if not verify_credentials(request): return "Unauthorized: Invalid or missing credentials", 401 user_id = get_id_from_request(request) if not user_id: return "No user found", 400 params = request.json if not all(k in params for k in ( "age", "height", "weight", "sex", "activity", "goal", "measurement_system", "weight_to_change", "weeks_to_goal", )): return ( "Please provide an age, height, weight, sex, activity level, goal, measurement_system, weight_to_change, and weeks_to_goal.", 400, ) # Creates document for DB db_post = { "user_id": user_id, "measurement_system": params["measurement_system"], "age": int(params["age"]), "height": float(params["height"]), "weight": float(params["weight"]), "sex": params["sex"], "activity": params["activity"], "goal": params["goal"], "weight_to_change": float(params["weight_to_change"]), "weeks_to_goal": float(params["weeks_to_goal"]), } if "restrictions" in params: db_post["restrictions"] = params["restrictions"] else: db_post["restrictions"] = [] db.replace_one({"user_id": user_id}, db_post, upsert=True) return '', 204
def fetch_user_macros(): if not verify_credentials(request): return "Unauthorized: Invalid or missing credentials", 401 user_id = get_id_from_request(request) if not user_id: return "No user found", 400 user_info = None user_info = db.find_one({"user_id": user_id}) if user_info is None: return "Error: User info not in DB", 400 return_dict = calculate_tdee_macros(user_info) return jsonify(return_dict)
def fetch_user_history_daily(): if not verify_credentials(request): return "Unauthorized: Invalid or missing credentials", 401 user_id = get_id_from_request(request) if not user_id: return "No user found", 400 params = request.json if not params or "date" not in params: return "Please include a date", 400 curr_date = str(params["date"]) # Gets document from DB user_info = db.find_one({"user_id": user_id}) if not user_info: return "No user found in DB", 400 if curr_date not in user_info["history"]: return "Date not in user's history", 400 # Formats history for front end return_dict = {} for next_meal in user_info["history"][curr_date]: meal_list = [] for next_food_id in user_info["history"][curr_date][next_meal]: int_food_id = int(next_food_id) curr_food_dict = {"food_id": int_food_id} full_food = food_db.find_one({"food_id": int_food_id}) if not full_food: continue curr_food_dict["Food Name"] = full_food["Food Name"] curr_food_dict["Calories"] = full_food["Calories"] curr_food_dict["Protein"] = full_food["Protein (g)"] curr_food_dict["Carb"] = full_food["Carbohydrates (g)"] curr_food_dict["Fat"] = full_food["Fat (g)"] curr_food_dict["Servings"] = user_info["history"][curr_date][ next_meal][next_food_id] meal_list.append(curr_food_dict) return_dict[next_meal] = meal_list return jsonify(return_dict)
def fetch_user_history_macros_daily(): if not verify_credentials(request): return "Unauthorized: Invalid or missing credentials", 401 user_id = get_id_from_request(request) if not user_id: return "No user found", 400 params = request.json if not params or "date" not in params: return "Please include a date", 400 curr_date = str(params["date"]) # Gets document from DB user_info = db.find_one({"user_id": user_id}) if not user_info: return "No user found in DB", 400 if curr_date not in user_info["history"]: return "Date not in user's history", 400 return_dict = {"calories": 0.0, "protein": 0.0, "fat": 0.0, "carb": 0.0} # Fetches foods from the given date and finds total macronutrients of all curr_date_info = user_info["history"][curr_date] for curr_meal in curr_date_info: for curr_food in curr_date_info[curr_meal]: curr_servings = curr_date_info[curr_meal][curr_food] food_info = food_db.find_one({"food_id": int(curr_food)}) if not food_info: return "Invalid food in user's history, abort", 400 food_cal = food_info["Calories"] food_pro = food_info["Protein (g)"] food_fat = food_info["Fat (g)"] food_carb = food_info["Carbohydrates (g)"] return_dict["calories"] += food_cal * curr_servings return_dict["protein"] += food_pro * curr_servings return_dict["fat"] += food_fat * curr_servings return_dict["carb"] += food_carb * curr_servings return jsonify(return_dict)
def set_user_history_total(): if not verify_credentials(request): return "Unauthorized: Invalid or missing credentials", 401 user_id = get_id_from_request(request) if not user_id: return "No user found", 400 params = request.json if not params or "history" not in params: return "Please include the food history", 400 history = dict(params["history"]) db.replace_one({"user_id": user_id}, { "user_id": user_id, "history": history }, upsert=True) return '', 204
def get_similar_foods_user(): # Handles Auth at the front if not verify_credentials(request): return "Unauthorized: Invalid or missing credentials", 401 user_id = get_id_from_request(request) if not user_id: return "No user found", 400 # Parses arguments params = request.json if not params or "food_id" not in params: return "Please include a food id", 400 food_id = int(params["food_id"]) if not params or "servings" not in params: return "Please include the number of servings", 400 servings = float(params["servings"]) if not params or "num_foods" not in params: return "Please include the number of foods", 400 num_foods = int(params["num_foods"]) if num_foods >= 15 or num_foods < 1: return "Please request 3-14 foods", 400 user_info = user_db.find_one({"user_id": user_id}) if not user_info: return "No user found in DB", 400 # Uses set unions to find all of user's restrictions, which will be # empty if user has no restrictions curr_restrictions = set() curr_restricted_words = set() user_restrictions = user_info["restrictions"] if user_restrictions: for restriction in user_restrictions: curr_groups = RESTRICTIONS_MAP[restriction] curr_restrictions = curr_restrictions.union(curr_groups) curr_words = RESTRICTIONS_WORDS[restriction] curr_restricted_words = curr_restricted_words.union(curr_words) # Finds the nearest foods using nutrition info curr_food = db.find_one({"food_id": food_id}) if curr_food is None: return "Improper food id provided", 400 num_cals_orig = float(curr_food["Calories"]) orig_group = curr_food["Food Group"] nutritional_atts = get_important_macros(curr_food) best_matches = findAllSimilarFoods(nutritional_atts) if best_matches is None: return "Improper food id provided", 400 # Loops over food groups -- excludes those in restrictions set # Will take at most this many items in same group # Default number of foods of same food group as original to return num_same_group = 3 food_counter = 0 fgs = {orig_group: 0} return_list = [] for next_food in best_matches: next_group = next_food[2] # If the food group has been seen too many times already, ignore it if (( next_group in fgs and (next_group != orig_group or (next_group == orig_group and fgs[next_group] >= num_same_group))) or next_food[0] == food_id or next_group in curr_restrictions): continue else: # Determines new servings for consistent calories num_cals = next_food[3] new_servings = 1 if num_cals > 0: cal_ratio = num_cals_orig / num_cals new_servings = cal_ratio * servings full_food = db.find_one({"food_id": next_food[0]}) if not full_food: continue del full_food["_id"] full_food["Servings"] = new_servings # Final parse on food -- make sure obvious false positives # do not get through. Because of this, the function may return less # than the full amount of foods desired. Uses RegEx food_name = full_food["Food Name"].lower() restricted_match = False for restricted_word in curr_restricted_words: if re.search(restricted_word, food_name): restricted_match = True break if restricted_match: continue # Now handles return situation so that we're returning # the correct number of foods return_list.append(full_food) if next_group in fgs: fgs[next_group] += 1 else: fgs[next_group] = 1 food_counter += 1 if food_counter >= num_foods: break # Returns a list of food objects with servings as an added field to each return jsonify(return_list)