""" 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 from utils.user_utils import is_role import os import uuid import pathlib 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("No Product available here") return redirect("/") print(product.name) return render_template('index.html', content='content.html', products = [product]) return "ID: " + str(id) @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') # Ensure that the correct file type is uploaded if file is None or not allowed_file(file.filename): flash("Invalid File Uploaded") return redirect("/add") # Create the product object and push to database filename = str(uuid.uuid4()) + pathlib.Path(file.filename).suffix file.save(os.path.join('static/assets/img/products/', filename)) product = Product( request.form.get('name'), filename, 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.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 )