""" 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('/') 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.") return render_template( 'index.html', content="content.html", products=products, category=category ) @blueprint.route('/') 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}") 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!") 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!") 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/') 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!") return redirect("/") db = ProductController() product = db.read_id(id) if product.sellerID != user_id: flash("This product does not belong to you!") 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") 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!") return redirect("/") db = ProductController() products = db.read_user(user_id) if products is None: flash("You don't currently have any products for sale.") return render_template( 'index.html', content='content.html', products=products )