def rate_recipe(recipe_id): """ Updates the recipe rating and number of ratings :return Redirect to recipe page """ try: # calculate new rating current_recipe = DB_RECIPES.find_one({'_id': ObjectId(recipe_id)}) calculated_rating_total = int(current_recipe['total_ratings']) + 1 calculated_sum = int(current_recipe['sum_ratings']) + int( request.form.get('rating')) # rounded average for simplicity calculated_avg = round(calculated_sum / calculated_rating_total) # update record DB_RECIPES.update_one({'_id': ObjectId(recipe_id)}, { "$set": { 'total_ratings': calculated_rating_total, 'sum_ratings': calculated_sum, 'current_rating': calculated_avg } }, upsert=True) except: # raises a 404 error if any of these fail return abort(404, description="Resource not found") return redirect(url_for('recipe', recipe_id=recipe_id))
def profile(): """ Directs user profile.html template if they are signed in, else to sign in page :return profile.html if the user is signed in sign-in.html if the user is not signed """ # REFERENCE CREDITS: # Login System -> # https://www.youtube.com/watch?v=vVx1737auSE, https://www.youtube.com/watch?v=PYILMiGxpAU # User is signed in and exists in the database if session.get('USERNAME', None): username = session['USERNAME'] # Fetch user and related recipes existing_user = DB_USERS.find_one({'username': username}) users_recipes = DB_RECIPES.find({'author_id': existing_user['_id']}) favorites = DB_RECIPES.find( {'_id': { '$in': existing_user['favorites'] }}) return render_template('profile.html', user_data=existing_user, users_recipes=users_recipes, favorites=favorites) else: # User not signed in return redirect(url_for('sign_in'))
def del_recipe(recipe_id): """ Deletes the recipe from the database :return Redirects to the user's profile url """ # User not Signed in if not session.get('USERNAME', None): return redirect(url_for('sign_in')) # Get username username = session['USERNAME'] try: current_user = DB_USERS.find_one({'username': username}) current_recipe = DB_RECIPES.find_one({'_id': ObjectId(recipe_id)}) # if the current logged in user is recipe author if current_recipe['author_id'] == current_user['_id']: DB_RECIPES.remove({'_id': ObjectId(recipe_id)}) DB_INGREDIENTS.delete_many({'recipe_id': ObjectId(recipe_id)}) DB_METHODS.delete_many({'recipe_id': ObjectId(recipe_id)}) return redirect(url_for('profile')) except: # raises a 404 error if any of these fail return abort(404, description="Resource not found")
def featured(pg, limit, sort): """ Renders the featured view :return a view of featured recipes """ # variables count = 0 # all featured recipes count featured_count = DB_RECIPES.count_documents({'featured': 'true'}) # all featured recipes featured_recipe_list = list(DB_RECIPES.find({'featured': 'true'})) # Error handeling try: # limits user to a valid limit range limit = int(limit) if limit > featured_count or limit < 2: # raises a 404 error if fail abort(404, description="Resource not found") # calculate the last page for r_page in range(featured_count): if r_page % limit == 0: count += 1 # limits user to a valid page range page = int(pg) if page > count or page < 1: # raises a 404 error if fail abort(404, description="Resource not found") # sorting sort = int(sort) if sort not in [1, 2]: # raises a 404 error if fail abort(404, description="Resource not found") if sort == 2: sort = -1 except: # raises a 404 error if any of these fail abort(404, description="Resource not found") # pagination skip = 0 if int(pg) == 1 else (int(pg) - 1) * limit paginated_recipes = DB_RECIPES.find({ 'featured': 'true' }).sort([('name', sort)]).skip(skip).limit(limit) return render_template('featured.html', all_recipes=DB_RECIPES.find(), paginated_recipes=paginated_recipes, limit=limit, current_pg=pg, sort=sort, lastpg=count, featured_count=featured_count)
def add_favorite(recipe_id): """ Adds the recipe to the users favorites list in the users profile :return Redirect to recipe url with updated favorite """ updated_favorites = [] # User is signed in and exists in the database if session.get('USERNAME', None): username = session['USERNAME'] user = DB_USERS.find_one({'username': username}) recipe = DB_RECIPES.find_one({'_id': ObjectId(recipe_id)}) # Update users favorites current_favorites = user['favorites'] # if the recipe is not already in the list if ObjectId(recipe_id) not in current_favorites: current_favorites.append(ObjectId(recipe_id)) DB_USERS.update_one({'_id': user['_id']}, {"$set": { 'favorites': current_favorites, }}, upsert=True) updated_user = DB_USERS.find_one({'username': username}) updated_favorites = updated_user['favorites'] return redirect( url_for('recipe', recipe_id=recipe_id, favorites=updated_favorites))
def edit_recipe(user_id, recipe_id): """ Renders the edit-recipe template passing in the temporary recipe id :return returns the edit-recipe.html form """ # User not Signed in if not session.get('USERNAME', None): return redirect(url_for('sign_in')) username = session['USERNAME'] # user exists in the database try: current_user = DB_USERS.find_one({'username': username}) current_recipe = DB_RECIPES.find_one({'_id': ObjectId(recipe_id)}) current_ingredients = DB_INGREDIENTS.find( {'recipe_id': current_recipe['_id']}) current_methods = DB_METHODS.find({'recipe_id': current_recipe['_id']}) # if the current logged in user is recipe author if current_recipe['author_id'] == current_user['_id']: return render_template('edit-recipe.html', user_id=user_id, recipe_id=recipe_id, current_recipe=current_recipe, current_ingredients=current_ingredients, current_methods=current_methods) else: # raises a 403 error return abort(403, description="Forbidden") except: # raises a 404 error if any of these fail return abort(404, description="Resource not found")
def add_temp_recipe(user_id): """ Creates a temporary recipe record to assign to the user :return Redirect to edit_recipe url """ # User exists in the database and Signed in if session.get('USERNAME', None): username = session['USERNAME'] # user exists in the database try: current_user = DB_USERS.find_one({'username': username}) requested_user = DB_USERS.find_one({'_id': ObjectId(user_id)}) # if the current logged in user is the user requested if requested_user['_id'] == current_user['_id']: # Default recipe image image_url = 'https://res.cloudinary.com/dajuujhvs/image/upload/v1591896759/gi5h7ejymbig1yybptcy.png' image_url_id = 'gi5h7ejymbig1yybptcy' # create empty temp record temp_record = DB_RECIPES.insert_one({ 'name': 'My Awesome Recipe', 'image_url': image_url, 'image_url_id': image_url_id, 'featured': 'false', 'current_rating': '0', 'total_ratings': 0, 'sum_ratings': 0, 'author_id': ObjectId(user_id), 'preptime_hrs': '0', 'preptime_min': '0', 'cooktime_hrs': '0', 'cooktime_min': '0' }) return redirect( url_for('edit_recipe', user_id=user_id, recipe_id=temp_record.inserted_id)) else: # raises a 403 error return abort(403, description="Forbidden") except: # raises a 404 return abort(404, description="Resource not found") else: # User not signed in return redirect(url_for('sign_in'))
def update_recipe(user_id, recipe_id): """ Updates the recipe database record :return returns the edit-recipe.html form overview tab """ # User not Signed in if not session.get('USERNAME', None): return redirect(url_for('sign_in')) try: # get the current user's record current_user = DB_USERS.find_one({'_id': ObjectId(user_id)}) # update the recipe record DB_RECIPES.update_one({'_id': ObjectId(recipe_id)}, { "$set": { 'name': request.form.get('recipe-name'), 'description': request.form.get('recipe-description'), 'notes': request.form.get('recipe-notes'), 'preptime_hrs': request.form.get('prep-hours'), 'preptime_min': request.form.get('prep-minutes'), 'cooktime_hrs': request.form.get('cook-hours'), 'cooktime_min': request.form.get('cook-minutes'), 'serves': request.form.get('serves'), 'author': current_user['username'], 'author_id': ObjectId(user_id), 'date_updated': TODAY_STR } }, upsert=True) # return to recipe overview page return redirect( url_for('edit_recipe', _anchor='overview', user_id=user_id, recipe_id=recipe_id)) except: # raises a 404 error if any of these fail return abort(404, description="Resource not found")
def search_recipes(): """Renders the search view and filter searched recipes. :return search view """ if request.method == 'POST': result = DB_RECIPES.create_index([('name', pymongo.TEXT)]) showing = request.form.get('search') search = DB_RECIPES.find( {"$text": { "$search": request.form.get('search') }}) search_count = DB_RECIPES.count_documents( {"$text": { "$search": request.form.get('search') }}) return render_template('search-recipes.html', all_recipes=DB_RECIPES.find(), paginated_recipes=search, filtered=True, showing=showing, search_count=search_count) # all recipes count paginated_recipes = DB_RECIPES.find() return render_template('search-recipes.html', all_recipes=DB_RECIPES.find(), paginated_recipes=paginated_recipes)
def delete_user(user_id): """ Deletes the users db record , also Delete the cloadinary image data and all users recipe data :return Redirect to sign in view """ # REFERENCE CREDITS: # Cloudinary api -> # https://github.com/tiagocordeiro/flask-cloudinary # User exists in the database and Signed in if session.get('USERNAME', None): username = session['USERNAME'] # user exists in the database current_user = DB_USERS.find_one({'username': username}) requested_user = DB_USERS.find_one({'_id': ObjectId(user_id)}) # if the current logged in user is the user requested if requested_user['_id'] == current_user['_id']: # Delete related user records DB_RECIPES.delete_many({'author_id': ObjectId(user_id)}) DB_INGREDIENTS.delete_many({'author_id': ObjectId(user_id)}) DB_METHODS.delete_many({'author_id': ObjectId(user_id)}) # Delete the current user image form cloudinary current_user = DB_USERS.find_one({'_id': ObjectId(user_id)}) if current_user['profile_image_id'] != 'wbzphoxefkdid3kheuqd': destroy(current_user['profile_image_id'], invalidate=True) # Delete main user record DB_USERS.remove({'_id': ObjectId(user_id)}) return redirect(url_for('sign_out')) else: # raises a 404 error if any of these fail return abort(403, description="Forbidden") else: # raises a 404 error if any of these fail return abort(403, description="Forbidden")
def update_recipe_image(user_id, recipe_id): """ Updates the recipe image in cloudinary :return returns the edit-recipe.html form image tab with updated image """ # User not Signed in if not session.get('USERNAME', None): return redirect(url_for('sign_in')) # get the file from the form file_to_upload = request.files.get('file') if file_to_upload: # get the current recipe record current_recipe = DB_RECIPES.find_one({'_id': ObjectId(recipe_id)}) # delete the current recipe image on cloudinary if current_recipe['image_url_id'] != 'gi5h7ejymbig1yybptcy': destroy(current_recipe['image_url_id'], invalidate=True) # upload the new image upload_result = upload(file_to_upload) # update record DB_RECIPES.update_one({'_id': ObjectId(recipe_id)}, { "$set": { 'image_url': upload_result['secure_url'], 'image_url_id': upload_result['public_id'], 'date_updated': TODAY_STR } }, upsert=True) return redirect( url_for('edit_recipe', _anchor='image', user_id=user_id, recipe_id=recipe_id))
def recipe(recipe_id): """ Returns the main recipe view :return Renders recipe.html """ current_recipe = None current_recipe_author = None current_recipe_ingredients = None current_recipe_methods = None try: current_recipe = DB_RECIPES.find_one({'_id': ObjectId(recipe_id)}) current_recipe_author = DB_USERS.find_one( {'_id': ObjectId(current_recipe['author_id'])}) current_recipe_ingredients = DB_INGREDIENTS.find( {'recipe_id': ObjectId(recipe_id)}) current_recipe_methods = DB_METHODS.find( {'recipe_id': ObjectId(recipe_id)}) except: # raises a 404 error if any of these fail abort(404, description="Resource not found") # Set loged in variable loged_in = False if session.get('USERNAME', None): username = session['USERNAME'] user = DB_USERS.find_one({'username': username}) favorites = user['favorites'] loged_in = True else: favorites = [] return render_template( 'recipe.html', current_recipe=current_recipe, current_recipe_author=current_recipe_author, current_recipe_ingredients=current_recipe_ingredients, current_recipe_methods=current_recipe_methods, favorites=favorites, loged_in=loged_in)
def index(pg, limit, sort): """ Renders the index view :return index.html from the render templates directory passing in all the recipes from the recipe database random recipes are generated for the feature slider """ # variables count = 0 # all recipes count all_count = DB_RECIPES.count_documents({}) # all featured recipes featured_recipe_list = list(DB_RECIPES.find({'featured': 'true'})) # randomly select 4 from the featured random_recipes = random.sample(featured_recipe_list, k=4) # Error handling try: # limits user to a valid limit range limit = int(limit) if limit > all_count or limit < 2: # raises a 404 error if fail abort(404, description="Resource not found") # calculate the last page for r_page in range(all_count): if r_page % limit == 0: count += 1 # limits user to a valid page range page = int(pg) if page > count or page < 1: # raises a 404 error if fail abort(404, description="Resource not found") # sorting sort = int(sort) if sort not in [1, 2]: # raises a 404 error if fail abort(404, description="Resource not found") if sort == 2: sort = -1 except: # raises a 404 error if any of these fail abort(404, description="Resource not found") # pagination calculation skip = 0 if int(pg) == 1 else (int(pg) - 1) * limit paginated_recipes = DB_RECIPES.find().sort([('name', sort) ]).skip(skip).limit(limit) return render_template('index.html', all_recipes=DB_RECIPES.find(), paginated_recipes=paginated_recipes, random_recipes=random_recipes, limit=limit, current_pg=pg, sort=sort, lastpg=count, all_count=all_count)