def post_new_resource(resource_type, new_resource_json): print("new resource", new_resource_json) try: new_resource = load_resource_from_schema(resource_type, new_resource_json) except ValidationError as e: print("here") raise InvalidUsage("There was a problem with your formatting.", payload=(str(e))) try: db.session.add(new_resource) db.session.commit() return new_resource except IntegrityError as e: raise InvalidUsage( "You're trying to load something that is already in the database.", payload="IntegrityError") except ValueError as e: raise InvalidUsage( "You are trying to load a resource that does not conform to database standards.", payload={ "details": { "resource": resource_type.__tablename__, "comments": str(e) } })
def verify_email(): print("verifying email") token = request.args.get("token") print(token) print("args", request.args) if not token: raise InvalidUsage("No token received! Did you put it in the url?") user = User.verify_auth_token(token) if not user: raise InvalidUsage("Unable to get user from token.") user.email_validated = True db.session.commit() return jsonify(user_schema.dump(user))
def change_user_info(id_): updated_user = get_resource_or_404(User, id_) if updated_user.id == g.user.id: try: updated_user_information = create_user_schema.load(request.json) updated_user.email = updated_user_information.email updated_user.hashed_password = updated_user_information.hashed_password db.session.commit() return jsonify(user_schema.dump(updated_user)) except ValidationError as error: raise InvalidUsage("Your user data was not formatted correctly", payload=error.messages) except IntegrityError: raise InvalidUsage("That email is already in use.") raise InvalidUsage("You don't have permission to edit accounts that aren't yours.", 401)
def change_ingredients_in_line(id_): line_to_change = get_resource_or_404(RecipeLine, id_) logged_in = hasattr(g, 'user') def change_line(): new_ingredients_json = request.json.get("new_ingredients") print(new_ingredients_json) new_ingredients = get_new_ingredients_on_line(new_ingredients_json, line_to_change) print(new_ingredients) line_to_change.ingredients = recipeline_association_schema.loads( new_ingredients) print(line_to_change) db.session.commit() return jsonify(recipeline_schema.dump(line_to_change)) if not line_to_change.recipe.creator_id: # anonymously created return change_line() print(logged_in, g.user) if logged_in and g.user.id == line_to_change.recipe.creator_id: return change_line() else: raise InvalidUsage("You don't have permission to modify that line.", 401)
def delete_user(id_): cur_user = get_resource_or_404(User, id_) if g.user != cur_user: raise InvalidUsage("You don't have permission to delete this user.", 401) db.session.delete(cur_user) db.session.commit() return ("", 204)
def post_line(): recipe_to_add_line = get_resource_or_404(Recipe, request.json.get("recipe_id")) if recipe_to_add_line.creator_id == g.user.id: new_line = post_new_resource(RecipeLine, request.json) return jsonify(recipeline_schema.dump(new_line)) else: raise InvalidUsage("You don't have permission to modify that recipe.")
def load_list_and_check_permissions(association_to_modify, association_schema): list_to_modify, resource_to_change = association_schema.load( association_to_modify) if g.user not in list_to_modify.editors and g.user.id != list_to_modify.creator_id: raise InvalidUsage("You don't have permission to modify this list.", 401) return list_to_modify, resource_to_change
def get_auth_token(): refresh_token = request.cookies.get('refresh_token') print(refresh_token) if not refresh_token: raise InvalidUsage("No refresh token", 404) user = User.verify_auth_token(refresh_token) access_token = user.generate_auth_token(expiration=300) return jsonify({'token': access_token, 'user': user_schema.dumps(user)})
def put_recipe(id_): recipe_to_change = get_resource_or_404(Recipe, id_) if recipe_to_change.creator_id == g.user.id: recipe_to_change.name = request.json.get("name", recipe_to_change.name) recipe_to_change.url = request.json.get("url", recipe_to_change.url) db.session.commit() return jsonify(recipe_schema.dump(recipe_to_change)) else: raise InvalidUsage("You don't have permission to modify this recipe.")
def add_editors(id_): current_list = get_resource_or_404(GroceryList, id_) if current_list.creator is not g.user: raise InvalidUsage("You are not the creator of this Grocery List", 401) new_editors = users_schema.load(request.json.get("users")) current_list.editors = new_editors db.session.commit() return jsonify(users_schema.dump(new_editors)), 201
def modify_list(id_): list_to_modify = get_resource_or_404(GroceryList, id_) if list_to_modify.creator_id == g.user.id or g.user.id in list_to_modify.editors: list_to_modify.name = request.json.get("name", list_to_modify.name) db.session.commit() return jsonify(grocerylist_schema.dump(list_to_modify)) else: raise InvalidUsage("You don't have permission to modify this list.", 401)
def delete_recipe(id_): recipe_to_delete = get_resource_or_404(Recipe, id_) if recipe_to_delete.creator is not g.user: raise InvalidUsage("You are not the creator of this recipe.", 401) db.session.delete(recipe_to_delete) db.session.commit() return ('', 204)
def put_line(id_): line_to_change = get_resource_or_404(RecipeLine, id_) if g.user.id == line_to_change.recipe.creator_id: line_to_change.text = request.json.get("text", "") line_to_change.ingredients = ingredients_schema.load( request.json.get("ingredients", "")) db.session.commit() return jsonify(recipeline_schema.dump(line_to_change)) else: raise InvalidUsage("You don't have permission to modify that line.", 401)
def send_verify_email(): # not using decorator because email is not yet validated username = request.authorization["username"] password = request.authorization["password"] print(username, password) verify_password(username, password, needs_valid_email=False) url_to_send = request.args.get("url") if not url_to_send: raise InvalidUsage("You must provide a client-side url for the verification route") token = send_validate_email(g.user, url_to_send) return jsonify({"token": token})
def get_list_by_params(args): if args.get("user"): user_id = args.get("user") if not User.query.get(user_id): raise InvalidUsage("This user does not exist.") user_lists = GroceryList.query\ .join(User)\ .filter(User.id==user_id)\ .all() return user_lists return GroceryList.query.all()
def load_resource_from_schema(resource_type, new_resource_json): if not new_resource_json: raise InvalidUsage( f"Data formatted incorrectly, no label of {resource_type.__tablename__} provided." ) try: new_resource = base_schemas_to_models[ resource_type.__tablename__].load(new_resource_json) return new_resource except ValidationError as e: raise InvalidUsage("Your data was not formatted correctly.", payload=e.messages) except IntegrityError as e: raise InvalidUsage( "Your data was not formatted correctly; you are trying to insert something into the database " "which already exists.", payload=e) except FlushError: raise InvalidUsage( "Your data was not formatted correctly; are you using an id which already exists?" )
def get_recipe_from_url(url): res = requests.get(url) if res.status_code != 200: # didn't get the recipe properly return {"error": res.status_code} soup = BeautifulSoup(res.text) o = urlparse(url) print('url is from ', o.netloc) parsing_information = ingredient_parsers.get(o.netloc, "") if parsing_information: component, attribute, name = parsing_information["title"] try: recipe_title = soup.find(component, {attribute: name}).get_text() except AttributeError: recipe_title = soup.title.get_text( ) # we get some kind of name if we can't parse the actual recipe # get information for the lines component, attribute, name = parsing_information["lines"] ingredients = soup.find_all(component, {attribute: name}) ingredient_lines = [line.get_text().strip() for line in ingredients] elif o.netloc in ingredient_functions: ingredient_information = ingredient_functions[o.netloc](soup) recipe_title = ingredient_information["title"] ingredient_lines = ingredient_information["recipe_lines"] else: # the user's recipe isn't recognized recipe_title = soup.title.get_text() ingredient_lines = [] print("not recognized") raise InvalidUsage("Website isn't in list", status_code=501, payload=o.netloc) print(recipe_title, ingredient_lines, url) return {"name": recipe_title, "url": url, "recipe_lines": ingredient_lines}
def get_associaton_by_params(param): if param.get("recipe") and param.get("list"): print(param.get("recipe"), param.get("list")) association = db.session.query(recipe_list_associations)\ .filter(recipe_list_associations.c.recipe == param.get("recipe"))\ .filter(recipe_list_associations.c.grocery_list == param.get("list")).first() print(association) if not association: raise InvalidUsage( "No association exists between the specified list and recipe", 404) return list_recipes_association_schema.dump(association) if param.get("recipe"): associations = db.session.query(recipe_list_associations).filter( recipe_list_associations.c.recipe == param.get("recipe")).all() elif param.get("list"): associations = db.session.query(recipe_list_associations).filter( recipe_list_associations.c.grocery_list == param.get( "list")).all() else: associations = db.session.query(recipe_list_associations).all() return list_recipes_associations_schema.dump(associations)
def get_association_or_404(id_, table): association = db.session.query(table).filter_by(id=id_).first() if not association: raise InvalidUsage( "The association you're looking for can't be found.", 404) return association