def get_user_info(id): ''' Given a user's id, return the details associated with that user. A user is only allowed to request their own user information. @Return - Returns the username, id, email, profile picture and associated recipes of the user. @Return Codes - 401 - user is unauthorised (A user isn't logged in or trying to view someone elses information) - 400 - the requested user does not exist in the DB. ''' # If the requesting user is not the user who's info is requested. if g.user.id != id: raise ErrorException('Your authentication is invalid', 401) user = User.query.get(id) # Can't find user in db. if not user: raise ErrorException('This user does not exist in the database', 500) page_num = request.args.get('page_num', default=1, type=int) page_size = request.args.get('page_size', default=12, type=int) response = Recipe.get_recipes_by_user_id(g.user.id, page_num, page_size) response.update({ 'user_id': user.id, 'email': user.email, 'username': user.username, 'profile_pic': user.profile_pic, 'statusCode': 200, 'status': 'success' }) return response
def add_recipe(name, instruction, mealType, ingredients, user_id, image=None): if image: recipe = Recipe(name=name, image=image) else: recipe = Recipe(name=name) db.session.add(recipe) for step in instruction: recipe_instruction = RecipeInstructions(instruction=step) recipe.instructions.append(recipe_instruction) mealtype = Mealtype.query.filter(func.lower(Mealtype.name) == func.lower(mealType)).first() if not mealtype: db.session.rollback() raise ErrorException('Mealtype does not exist: ' + mealType, 400) recipe.mealtypes.append(mealtype) user = User.query.filter_by(id=user_id).first() for ingredient in ingredients: db_ingredient = Ingredient.query.filter(func.lower(Ingredient.name) == func.lower(ingredient['name'])).first() if not db_ingredient: db.session.rollback() raise ErrorException('Ingredient does not exist: ' + ingredient['name'], 400) recipe_ingredient = RecipeIngredients(quantity=ingredient['quantity']) recipe_ingredient.ingredients = db_ingredient recipe.ingredients.append(recipe_ingredient) user.recipes.append(recipe) db.session.commit() IngredientSets.remove_sets(recipe) return recipe
def new_user(): ''' Given the signup details of a user, register them in the database so that login attempts can be made. @params username, password, (email coming soon?) @Returns - the username of the created user @Return codes - 400 - the correct signup details were not submitted OR the username already exists in the system. - 201 - code indicating the cresource has been created. - (TODO) - Add meaningful message to differentiate insufficient signup details vs username already taken. ''' username = request.json.get('username') password = request.json.get('password') if not username or not password: raise ErrorException('Username or Password is not entered', 500) if User.query.filter_by(username=username).first() is not None: raise ErrorException('This user already exists', 500) user = User(username=username) user.hash_password(password) db.session.add(user) db.session.commit() return jsonify({ 'username': user.username, 'statusCode': 201, 'status': 'success' }), 201
def recipe_delete(recipe_id): """ Delete a recipe by its id""" recipe = Recipe.get_recipe_by_id(recipe_id) if not recipe: raise ErrorException('This recipe does not exist', 500) if g.user.id != recipe["user_id"]: raise ErrorException('Your authentication is invalid', 401) # Cant delete a recipe that isn't yours if Recipe.recipe_delete(recipe_id): return jsonify({ 'message': 'Recipe deleted.', 'statusCode': 200, 'status': 'success' })
def add_ingredient(name, category): db_category = Category.query.filter(func.lower(Category.name) == func.lower(category)).first() if not db_category: raise ErrorException('Category does not exist: ' + category, 400) ingredient = Ingredient(name=name) ingredient.categories.append(db_category) db.session.add(ingredient) db.session.commit() return ingredient
def get_recipe_by_id(id): recipe = Recipe.query.get(id) if not recipe: raise ErrorException('Recipe id does not exist: ' + str(id), 400) instructions = [x.instruction for x in recipe.instructions] count = recipe.rating.count() schema = RecipeSchema(many=False) recipe = schema.dump(recipe) rating = Recipe.get_rating(recipe['id']) recipe['rating'] = rating recipe['rating_count'] = count recipe['instruction'] = instructions return recipe
def recipe_image_upload(recipe_id): ''' On a POST request with /recipe_image_upload will upload a picture and store in our storage ''' msg, code = extract_photo(request) if code == 200: #TODO HANDLE ERRORS - Turn into objects? picture_path = request.url_root + url_for('static', filename=msg) Recipe.upload_recipe_image(recipe_id, picture_path) else: raise ErrorException(msg, code) return jsonify({'msg': msg, 'statusCode': 201, 'status': 'success'}), code
def profile_pic_upload(): ''' On a POST request with /profile_pic_upload will upload a picture and store in our storage ''' msg, code = extract_photo(request) if code == 200: #TODO HANDLE ERRORS picture_path = request.url_root + url_for('static', filename=msg) user_id = g.user.id User.upload_profile_image(user_id, picture_path) else: raise ErrorException(msg, code) return jsonify({'msg': msg, 'statusCode': 201, 'status': 'success'}), code
def edit_user(id): ''' On POST edit a user's profile ''' # If the requesting user is not the user who's info is requested. if g.user.id != id: raise ErrorException('Your authentication is invalid', 401) user = User.query.get(id) # Can't find user in db. if not user: raise ErrorException('This user does not exist in the database', 500) old_pass = request.json.get('old_password') new_pass = request.json.get('new_password') if user.verify_password(old_pass): user.hash_password(new_pass) else: raise ErrorException('Your old password is invalid', 500) db.session.commit() return jsonify({ 'message': 'Success', 'statusCode': 200, 'status': 'success' })
def delete_rating(): ''' On a POST request with /delete_rating will delete a rating for post, please supply 'ratingId' ''' ratingId = request.json.get('ratingId') userId = request.json.get('userId') if not Rating.delete_rating(ratingId, userId): raise ErrorException('User does not own the rating', 500) return { 'rating_id': ratingId, 'message': 'Rating has been deleted', 'statusCode': 201, 'status': 'success' }
def rating(id): ''' On a GET request with /rating/recipe_id it will return all the ratings for a recipe On a POST request with /rating/recipe_id will add a new rating for post, please supply 'rating' between 1 and 5, 'comment', 'user_id' as a JSON ''' if request.method == 'POST': rating = request.json.get('rating') if int(rating) > 5 or int(rating) < 1: raise ErrorException('Ratings must be between 1 and 5', 500) comment = request.json.get('comment') user = User.query.filter_by(id=request.json.get('user_id')).first() recipe = Recipe.query.filter_by(id=id).first() new_rating = Rating(rating=int(rating), comment=comment) # Check if rating already exists by a user for user_rating in user.rating: for rating_recipe in user_rating.recipe: if rating_recipe == recipe: user_rating.rating = rating user_rating.comment = comment db.session.commit() return jsonify({ 'id': user_rating.id, 'rating': user_rating.rating, 'comment': user_rating.comment }) # return jsonify(Rating.json_dump(user.rating)) recipe.rating.append(new_rating) user.rating.append(new_rating) db.session.add(new_rating) db.session.commit() return jsonify({ 'id': new_rating.id, 'rating': new_rating.rating, 'comment': new_rating.comment }) recipe = Recipe.query.filter_by(id=id).first() ratings = recipe.rating return jsonify(Rating.json_dump(ratings))
def edit_recipe(): ''' On a POST request with /edit_recipe will add a new recipe for post, please supply 'name', 'instruction', 'mealType' and 'ingredients' ''' recipe_id = request.json.get('id') name = request.json.get('name') instruction = request.json.get('instruction') mealType = request.json.get('mealType') ingredients = request.json.get('ingredients') recipe = Recipe.edit_recipe(recipe_id, name, instruction, mealType, ingredients) if g.user.id != recipe.user_id: raise ErrorException('This is not your recipe, you cannot edit it.', 401) return { 'recipe_id': recipe.id, 'message': 'Recipe has been edited', 'statusCode': 201, 'status': 'success' }
def edit_recipe(recipe_id, name, instruction, mealType, ingredients): recipe = Recipe.query.get(recipe_id) if not recipe: raise ErrorException('Recipe id does not exist: ' + recipe_id, 400) recipe.name = name recipe.instructions = [RecipeInstructions(instruction=x) for x in instruction] db_mealtype = Mealtype.query.filter(func.lower(Mealtype.name) == func.lower(mealType)).first() if db_mealtype: recipe.mealtypes = [db_mealtype] # Check if any of the ingredients have been updated to avoid an additional delete and write recipe_ingredients = (RecipeIngredients .query .with_entities(Ingredient.name, RecipeIngredients.quantity) .filter(RecipeIngredients.ingredient_id == Ingredient.id) .filter(RecipeIngredients.recipe_id == recipe.id) .all() ) ingredients = [(x['name'], x['quantity']) for x in ingredients] if recipe_ingredients != ingredients: # Ingredients have changed, updating db.. RecipeIngredients.query.filter_by(recipe_id=recipe.id).delete() for name, quantity in ingredients: ingredient = Ingredient.query.filter(func.lower(Ingredient.name) == func.lower(name)).first() # doesn't support ingredient creation if ingredient: recipe_ingredient = RecipeIngredients(quantity=quantity) recipe_ingredient.ingredients = ingredient recipe.ingredients.append(recipe_ingredient) db.session.commit() IngredientSets.remove_sets(recipe) return recipe
def auth_error(status): raise ErrorException('Your authentication is invalid', 401)