189 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			189 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| """
 | |
|     Product related endpoints. Included contexts for principles such as
 | |
|     categories and image processing.
 | |
| """
 | |
| 
 | |
| from flask import render_template, session, flash, request, redirect, Blueprint
 | |
| 
 | |
| from models.products.product import Product
 | |
| from controllers.database.product import ProductController
 | |
| from controllers.database.category import CategoryController
 | |
| from controllers.database.user import UserController
 | |
| 
 | |
| from datetime import datetime
 | |
| from utils.file_utils import allowed_file, save_image, remove_file
 | |
| from utils.user_utils import is_role
 | |
| 
 | |
| import pathlib
 | |
| import os
 | |
| 
 | |
| blueprint = Blueprint("products", __name__, url_prefix="/products")
 | |
| 
 | |
| 
 | |
| @blueprint.context_processor
 | |
| def category_list():
 | |
|     """ Places a list of all categories in the products context """
 | |
|     database = CategoryController()
 | |
|     categories = database.read_all()
 | |
|     return dict(categories=categories)
 | |
| 
 | |
| 
 | |
| @blueprint.route('/')
 | |
| def index():
 | |
|     """ The front product page """
 | |
|     # Returning an empty category acts the same
 | |
|     # as a generic home page
 | |
|     return category("")
 | |
| 
 | |
| 
 | |
| @blueprint.route('/<string:category>')
 | |
| def category(category: str):
 | |
|     """ Loads a given categories page """
 | |
|     database = ProductController()
 | |
| 
 | |
|     # Check to see if there is a custome search term
 | |
|     search_term = request.args.get("search", type=str)
 | |
|     if search_term is not None:
 | |
|         products = database.read_all(category, search_term)
 | |
|     else:
 | |
|         products = database.read_all(category)
 | |
| 
 | |
|     # No Products visible
 | |
|     if products is None:
 | |
|         flash(
 | |
|             f"No Products available. Try expanding your search criteria.",
 | |
|             "warning"
 | |
|         )
 | |
| 
 | |
|     return render_template(
 | |
|         'index.html',
 | |
|         content="content.html",
 | |
|         products=products,
 | |
|         category=category
 | |
|     )
 | |
| 
 | |
| 
 | |
| @blueprint.route('/<int:id>')
 | |
| def id(id: int):
 | |
|     """ Loads a given product based on ID """
 | |
|     db = ProductController()
 | |
|     product = db.read_id(id)
 | |
| 
 | |
|     # Check that a valid product was returned
 | |
|     if product is None:
 | |
|         flash(f"No Product available with id {id}", "warning")
 | |
|         return redirect("/")
 | |
| 
 | |
|     print(product.name)
 | |
|     return render_template(
 | |
|         'index.html',
 | |
|         content='product.html',
 | |
|         product=product
 | |
|     )
 | |
| 
 | |
| 
 | |
| @blueprint.route('/add')
 | |
| def display_add_product():
 | |
|     """ Launches the page to add a new product to the site """
 | |
|     user_id = session.get('user_id')
 | |
| 
 | |
|     # User needs to be logged in as a seller to view this page
 | |
|     if not is_role("Seller"):
 | |
|         flash("You must be logged in as a seller to view this page!", "error")
 | |
|         return redirect("/")
 | |
| 
 | |
|     return render_template('index.html', content='new_product.html')
 | |
| 
 | |
| 
 | |
| @blueprint.post('/add')
 | |
| def add_product():
 | |
|     """ Server site processing to handle a request to add a
 | |
|         new product to the site
 | |
|     """
 | |
|     user_id = session.get('user_id')
 | |
| 
 | |
|     # User needs to be logged in as a seller to view this page
 | |
|     if not is_role("Seller"):
 | |
|         flash("You must be logged in as a seller to view this page!", "error")
 | |
|         return redirect("/")
 | |
| 
 | |
|     file = request.files.get('image')
 | |
|     image_filename = save_image(file)
 | |
| 
 | |
|     product = Product(
 | |
|         request.form.get('name'),
 | |
|         image_filename if image_filename is not None else "",
 | |
|         request.form.get('description'),
 | |
|         request.form.get('cost'),
 | |
|         request.form.get('category'),
 | |
|         user_id,
 | |
|         datetime.now(),
 | |
|         request.form.get('quantity')
 | |
|     )
 | |
| 
 | |
|     db = ProductController()
 | |
|     db.create(product)
 | |
| 
 | |
|     return redirect('/products/ownproducts')
 | |
| 
 | |
| 
 | |
| @blueprint.post('/update/<int:id>')
 | |
| def update_product(id: int):
 | |
|     """ Processes a request to update a product in place on the site """
 | |
|     # Ensure that the product belongs to the current user
 | |
|     user_id = session.get('user_id')
 | |
| 
 | |
|     # User needs to be logged in as a seller to view this page
 | |
|     if not is_role("Seller"):
 | |
|         flash("You must be logged in as a seller to view this page!", "error")
 | |
|         return redirect("/")
 | |
| 
 | |
|     db = ProductController()
 | |
|     product = db.read_id(id)
 | |
| 
 | |
|     if product.sellerID != user_id:
 | |
|         flash("This product does not belong to you!", "error")
 | |
|         return redirect("/ownproducts")
 | |
| 
 | |
|     # Save new image file
 | |
|     file = request.files.get('image')
 | |
|     new_image = save_image(file)
 | |
| 
 | |
|     if new_image is not None:
 | |
|         remove_file(os.path.join(os.environ.get('FILESTORE'), product.image))
 | |
|         product.image = new_image
 | |
| 
 | |
|     # Update product details
 | |
|     product.name = request.form.get('name')
 | |
|     product.description = request.form.get('description')
 | |
|     product.category = request.form.get('category')
 | |
|     product.cost = request.form.get('cost')
 | |
|     product.quantityAvailable = request.form.get('quantity')
 | |
| 
 | |
|     db.update(product)
 | |
|     flash("Product successfully updated", 'notice')
 | |
|     return redirect(f"/products/{product.id}")
 | |
| 
 | |
| 
 | |
| @blueprint.route('/ownproducts')
 | |
| def display_own_products():
 | |
|     """ Display products owned by the currently logged in seller """
 | |
|     user_id = session.get('user_id')
 | |
| 
 | |
|     # User must be logged in as seller to view page
 | |
|     if not is_role("Seller"):
 | |
|         flash("You must be logged in as a seller to view this page!", "error")
 | |
|         return redirect("/")
 | |
| 
 | |
|     db = ProductController()
 | |
|     products = db.read_user(user_id)
 | |
| 
 | |
|     if products is None:
 | |
|         flash("You don't currently have any products for sale.", "info")
 | |
| 
 | |
|     return render_template(
 | |
|         'index.html',
 | |
|         content='content.html',
 | |
|         products=products
 | |
|     )
 |