Skip to content

Commit

Permalink
Merge pull request #1 from vivitruong/add-route
Browse files Browse the repository at this point in the history
Add route
  • Loading branch information
vivitruong authored Mar 5, 2024
2 parents 509a644 + f51261f commit 9b6e8ae
Show file tree
Hide file tree
Showing 3 changed files with 258 additions and 0 deletions.
53 changes: 53 additions & 0 deletions app/api/image_routes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
from flask import Blueprint, request, jsonify
from flask_login import current_user, login_required
from .auth_routes import validation_errors_to_error_messages
from app.models import db, Image
from app.forms import ImageForm
from app.awsS3 import (
upload_file_to_s3, allowed_file, get_unique_filename)


image_routes = Blueprint("images", __name__)


@image_routes.route("", methods=["POST"])
@login_required
def upload_image():
if "image" not in request.files:
return {"errors": "At least one image required"}, 400

# print(request.files) # ImmutableMultiDict([('image', <FileStorage: 'chopper.png' ('image/png')>)])

image = request.files["image"]
# <class 'werkzeug.datastructures.FileStorage'>

if not allowed_file(image.filename):
return {"errors": "Image is not a permitted file type (file type must be .gif, .jpeg, .jpg, .png, .svg, .tiff, .webp"}, 400

image.filename = get_unique_filename(image.filename)

upload = upload_file_to_s3(image)

if "url" not in upload:
# if the dictionary doesn't have a url key, there was an error when we tried to upload
return upload, 400

url = upload["url"]

form=ImageForm()
form['csrf_token'].data = request.cookies['csrf_token']

if form.validate_on_submit():
new_image = Image(
user_id=current_user.id,
product_id=form.data['product_id'],
url=url)

db.session.add(new_image)
db.session.commit()

# return {"url": url}
return jsonify(new_image.to_dict())

else:
return {'errors': validation_errors_to_error_messages(form.errors)}, 400
151 changes: 151 additions & 0 deletions app/api/product_routes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
from flask import Blueprint, jsonify, request
from flask_login import current_user, login_required
from .auth_routes import validation_errors_to_error_messages
from app.models import db, Product, Review, Image, Category, User
from app.forms import ProductForm
from datetime import date

product = Blueprint('products', __name__)


@product.route("")
# list all products on homepage, include first image
def all_products():
products = Product.query.all()

product_details = []

if products is not None:
for product in products:
product_id = product.to_dict_product_id()['id']
product = product.to_dict()

main_image = db.session.query(Image).filter(Image.product_id == product_id).first()

if main_image is not None:
product['images'] = [main_image.to_url()]

product_details.append(product)

return jsonify(product_details), 200


@product.route("/<int:product_id>")
# get product by id, include reviews, images
def product_by_id(product_id):
product = db.session.query(Product).get(product_id)
reviews = db.session.query(Review).filter(Review.product_id == product_id).all()
images = db.session.query(Image).filter(Image.product_id == product_id).all()

seller = db.session.query(User).filter(User.id == product.seller_id).first()

avg = None
if reviews is not None:
num_reviews = len(reviews)

if num_reviews > 0:
sum_stars = 0

for review in reviews:
sum_stars += review.to_dict_stars()['stars']

avg = sum_stars / num_reviews

if product is not None:
product_details = []
product = product.to_dict()
product['reviews'] = [review.to_dict() for review in reviews]
product['images'] = [image.to_url() for image in images]
product['avg_stars'] = avg
product['shop_name'] = seller.shop_name
product_details.append(product)

return jsonify(product_details)
else:
return {'errors': ['Product not found']}, 404


@product.route("", methods=['POST'])
@login_required
# add new product
def add_product():
form = ProductForm()
form['csrf_token'].data = request.cookies['csrf_token']

categories = Category.query.all()

form.category.choices=[(category.to_name(), category.to_display_name() )for category in categories]

if form.validate_on_submit():

product = Product(
seller_id = current_user.id,
category = form.data['category'],
name = form.data['name'],
price = form.data['price'],
description = form.data['description']
)

db.session.add(product)
db.session.commit()

return jsonify(product.to_dict()), 201

else:
return {'errors': validation_errors_to_error_messages(form.errors)}, 400


@product.route("/<int:product_id>", methods=['PUT'])
@login_required
# edit product by id
def edit_product(product_id):
form = ProductForm()
form['csrf_token'].data = request.cookies['csrf_token']

categories = Category.query.all()
form.category.choices=[(category.to_name(), category.to_display_name() )for category in categories]

image = db.session.query(Image).filter(Image.product_id == product_id).first()
product = Product.query.get(product_id)

product_details = []

if product.seller_id == current_user.id:

if form.validate_on_submit():

product.category = form.data['category']
product.name = form.data['name']
product.price = form.data['price']
product.description = form.data['description']
product.updated_at = date.today()
db.session.commit()

product = product.to_dict()
product['images'] = [image.to_url()]
product_details.append(product)

# return jsonify(product.to_dict()), 201
return jsonify(product_details), 201
else:
return {'errors': validation_errors_to_error_messages(form.errors)}, 400
else:
return {'errors': ['Unauthorized']}, 403

@product.route("/<int:product_id>", methods=['DELETE'])
@login_required
# delete product by id
def delete_product(product_id):
product = Product.query.get(product_id)

if product.seller_id == current_user.id:
db.session.delete(product)
db.session.commit()

return jsonify({
'message': 'Product successfully deleted',
'status_code': 200
}), 200

else:
return {'errors': ['Unauthorized']}, 403
54 changes: 54 additions & 0 deletions app/api/purchase_routes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
from flask import Blueprint, jsonify, request
from flask_login import current_user, login_required
from .auth_routes import validation_errors_to_error_messages
from app.models import db, Purchase
from app.forms import PurchaseForm


purchase = Blueprint('purchases', __name__)

@purchase.route("", methods=['POST'])
@login_required
# create new purchase
def create_purchase():
form = PurchaseForm()
form['csrf_token'].data = request.cookies['csrf_token']

if form.validate_on_submit():

purchase = Purchase(
order_number = form.data['order_number'],
user_id = current_user.id,
product_id = form.data['product_id'],
quantity = form.data['quantity'],
product_total = form.data['product_total'],
purchase_total = form.data['purchase_total']
)

db.session.add(purchase)
db.session.commit()

return jsonify(purchase.to_dict()), 201

else:
return {'errors': validation_errors_to_error_messages(form.errors)}, 400


@purchase.route("/<int:purchase_id>", methods=['DELETE'])
@login_required
# cancel purchase
def cancel_purchase(purchase_id):
purchase = Purchase.query.filter(Purchase.id == purchase_id).first()


if purchase.user_id == current_user.id:
db.session.delete(purchase)
db.session.commit()

return jsonify({
'message': 'Purchase successfully cancelled',
'status_code': 200
}), 200

else:
return {'errors': ['Unauthorized']}, 403

0 comments on commit 9b6e8ae

Please sign in to comment.