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
Beispiel #4
0
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)
Beispiel #5
0
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)
Beispiel #6
0
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
Beispiel #9
0
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
Beispiel #10
0
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
Beispiel #14
0
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)