WMGZON/controllers/web/product.py

152 lines
4.4 KiB
Python

"""
Product related endpoints. Included contexts for principles such as
categories and image processing.
"""
from flask import Blueprint
from flask import render_template, session, flash, request, redirect
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 werkzeug.utils import secure_filename
import os
import uuid
import pathlib
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}
def allowed_file(filename):
""" Ensures only filenames ending with the correct extension are allowed.
Note: This does not verify that the content inside of the file
matches the type specified
"""
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
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 """
database = ProductController()
products = database.read_all()
# No Products visible
if products is None:
flash("No Products available")
return render_template('index.html',
content="content.html",
products=products
)
@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:
print(f"Search Term {search_term}")
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 in {category}")
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 """
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 must be logged in to view this page
if user_id is None:
flash("Please Login to view this page")
return redirect('/login')
db = UserController()
user = db.read_id(user_id)
if user is None or user.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 must be logged in to view this page
if user_id is None:
flash("Please Login to view this page")
return redirect('/login', code=302)
db = UserController()
user = db.read_id(user_id)
if user is None or user.role != "Seller":
flash("You must be logged in as a Seller to perform this action")
return redirect('/', code=302)
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 render_template('index.html', content='new_product.html')