Added ability to fetch products from the database

This commit is contained in:
Luke Else 2024-01-05 18:20:56 +00:00
parent 9fbdb9f3fb
commit 868876b98e
11 changed files with 261 additions and 156 deletions

2
app.py
View File

@ -1,6 +1,6 @@
from flask import Flask from flask import Flask
from os import environ from os import environ
from controllers.web import blueprint from controllers.web.endpoints import blueprint
''' '''
Main entrypoint for Flask application. Main entrypoint for Flask application.

View File

@ -0,0 +1,79 @@
from .database import DatabaseController
from models.products.product import Product
class ProductController(DatabaseController):
FIELDS = ['id', 'name', 'image', 'description', 'cost', 'category', 'sellerID', 'postedDate', 'quantity']
def __init__(self):
super().__init__()
def create(self, product: Product):
params = [
product.name,
product.image,
product.description,
product.cost,
product.category,
product.sellerID,
product.postedDate,
product.quantityAvailable
]
self._conn.execute(
"INSERT INTO Products (name, cost, image, description, category, sellerID, postedDate, quantityAvailable) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
params
)
self._conn.commit()
def read(self, name: str = "") -> list[Product] | None:
params = [
"%" + name + "%"
]
cursor = self._conn.execute(
"SELECT * FROM Products WHERE name like ?",
params
)
rows = cursor.fetchmany()
if rows == None:
return None
products = list()
# Create an object for each row
for product in rows:
params = dict(zip(self.FIELDS, product))
obj = self.new_instance(Product, params)
print(obj.__dict__)
products.push(obj)
return products
def read_all(self) -> list[Product] | None:
cursor = self._conn.execute(
"SELECT * FROM Products",
)
rows = cursor.fetchall()
if len(rows) == 0:
return None
products = list()
# Create an object for each row
for product in rows:
params = dict(zip(self.FIELDS, product))
obj = self.new_instance(Product, params)
print(obj.__dict__)
products.append(obj)
return products
def update(self):
print("Doing work")
def delete(self):
print("Doing work")

View File

@ -1,5 +0,0 @@
from flask import Blueprint
blueprint = Blueprint('endpoints', __name__)
from . import endpoints

View File

@ -1,81 +1,15 @@
from . import blueprint from flask import redirect
from flask import render_template, redirect, request, session, flash from flask import Blueprint
from controllers.database.user import UserController
from models.users.customer import Customer
from hashlib import sha512
from . import user
from . import product
blueprint = Blueprint('main', __name__)
blueprint.register_blueprint(user.blueprint)
blueprint.register_blueprint(product.blueprint)
# Function responsible for displaying the main landing page of the site # Function responsible for displaying the main landing page of the site
@blueprint.route('/') @blueprint.route('/')
def welcome_page(): def index():
return render_template('index.html', content="content.html", user = session.get('user')) return redirect("/products")
### LOGIN FUNCTIONALITY
# Function responsible for delivering the Login page for the site
@blueprint.route('/login')
def display_login():
return render_template('index.html', content="login.html", user = session.get('user'))
# Function responsible for handling logins to the site
@blueprint.post('/login')
def login():
database = UserController()
user = database.read(request.form['username'])
error = None
# No user found
if user == None:
error = "No user found with the username " + request.form['username']
flash(error)
return redirect("/login")
# Incorrect Password
if sha512(request.form['password'].encode()).hexdigest() != user.password:
error = "Incorrect Password"
flash(error)
return redirect("/login")
session['user'] = user.username
return redirect("/")
### SIGNUP FUNCTIONALITY
# Function responsible for delivering the Signup page for the site
@blueprint.route('/signup')
def display_signup():
return render_template('index.html', content="signup.html", user = session.get('user'))
# Function responsible for handling signups to the site
@blueprint.post('/signup')
def signup():
database = UserController()
# User already exists
if database.read(request.form['username']) != None:
error = "User, " + request.form['username'] + " already exists"
flash(error)
return redirect("/signup")
database.create(Customer(
0,
request.form['username'],
sha512(request.form['password'].encode()).hexdigest(), # Hashed as soon as it is recieved on the backend
request.form['firstname'],
request.form['lastname'],
request.form['email'],
"123",
"Customer"
))
# Code 307 Preserves the original request (POST)
return redirect("/login", code=307)
### SIGN OUT FUNCTIONALITY
# Function responsible for handling logouts from the site
@blueprint.route('/logout')
def logout():
session.pop('user')
return redirect("/")

View File

@ -0,0 +1,17 @@
from flask import Blueprint
from flask import render_template, redirect, request, session, flash
from controllers.database.product import ProductController
blueprint = Blueprint("products", __name__, url_prefix="/products")
@blueprint.route('/')
def index():
database = ProductController()
products = database.read_all()
# No Products visible
if products == None:
flash("No Products available")
return render_template('index.html', content="content.html", user = session.get('user'), products = products)

77
controllers/web/user.py Normal file
View File

@ -0,0 +1,77 @@
from flask import Blueprint
from flask import render_template, redirect, request, session, flash
from controllers.database.user import UserController
from models.users.customer import Customer
from hashlib import sha512
# Blueprint to append user endpoints to
blueprint = Blueprint("users", __name__)
### LOGIN FUNCTIONALITY
# Function responsible for delivering the Login page for the site
@blueprint.route('/login')
def display_login():
return render_template('index.html', content="login.html", user = session.get('user'))
# Function responsible for handling logins to the site
@blueprint.post('/login')
def login():
database = UserController()
user = database.read(request.form['username'])
error = None
# No user found
if user == None:
error = "No user found with the username " + request.form['username']
flash(error)
return redirect("/login")
# Incorrect Password
if sha512(request.form['password'].encode()).hexdigest() != user.password:
error = "Incorrect Password"
flash(error)
return redirect("/login")
session['user'] = user.username
return redirect("/")
### SIGNUP FUNCTIONALITY
# Function responsible for delivering the Signup page for the site
@blueprint.route('/signup')
def display_signup():
return render_template('index.html', content="signup.html", user = session.get('user'))
# Function responsible for handling signups to the site
@blueprint.post('/signup')
def signup():
database = UserController()
# User already exists
if database.read(request.form['username']) != None:
error = "User, " + request.form['username'] + " already exists"
flash(error)
return redirect("/signup")
database.create(Customer(
0,
request.form['username'],
sha512(request.form['password'].encode()).hexdigest(), # Hashed as soon as it is recieved on the backend
request.form['firstname'],
request.form['lastname'],
request.form['email'],
"123",
"Customer"
))
# Code 307 Preserves the original request (POST)
return redirect("/login", code=307)
### SIGN OUT FUNCTIONALITY
# Function responsible for handling logouts from the site
@blueprint.route('/logout')
def logout():
session.pop('user')
return redirect("/")

View File

@ -1,22 +1,17 @@
from abc import ABC
from datetime import datetime from datetime import datetime
class Product(ABC): class Product:
''' '''
Base class for a product Base class for a product
''' '''
def __init__(self): def __init__(self):
self.productID = 0 self.id = 0
self.name = "" self.name = ""
self.image = "/static/assets/wmgzon.png"
self.description = ""
self.cost = 0.0 self.cost = 0.0
self.category = "" self.category = ""
self.sellerID = 0 self.sellerID = 0
self.postedDate = datetime.now() self.postedDate = datetime.now()
self.quantityAvailable = 0 self.quantityAvailable = 0
def addToBasket():
pass
def buyProduct():
pass

View File

@ -9,11 +9,13 @@ CREATE TABLE IF NOT EXISTS Users (
role TEXT NOT NULL role TEXT NOT NULL
); );
-- INSERT INTO Users (first_name, last_name, email, phone, password) VALUES ("Luke", "Else", "test@test.com", "07498 289321", "test213"); INSERT INTO Users (first_name, last_name, username, email, phone, password, role) VALUES ("Luke", "Else", "lukejelse04", "test@test.com", "07498 289321", "test213", "Customer");
CREATE TABLE IF NOT EXISTS Products ( CREATE TABLE IF NOT EXISTS Products (
id INTEGER PRIMARY KEY, id INTEGER PRIMARY KEY,
name TEXT NOT NULL, name TEXT NOT NULL,
image TEXT NOT NULL,
description TEXT NOT NULL,
cost DECIMAL NOT NULL, cost DECIMAL NOT NULL,
sellerID INTEGER NOT NULL sellerID INTEGER NOT NULL
REFERENCES Users (id) REFERENCES Users (id)
@ -22,6 +24,17 @@ CREATE TABLE IF NOT EXISTS Products (
category TEXT NOT NULL category TEXT NOT NULL
); );
INSERT INTO Products (name, image, description, cost, sellerID, category) VALUES ("test", "assets/img/wmgzon.png", "this is a product", 20.99, 1, "CarParts");
INSERT INTO Products (name, image, description, cost, sellerID, category) VALUES ("test", "assets/img/wmgzon.png", "this is a product", 20.99, 1, "CarParts");
INSERT INTO Products (name, image, description, cost, sellerID, category) VALUES ("test", "assets/img/wmgzon.png", "this is a product", 20.99, 1, "CarParts");
INSERT INTO Products (name, image, description, cost, sellerID, category) VALUES ("test", "assets/img/wmgzon.png", "this is a product", 20.99, 1, "CarParts");
INSERT INTO Products (name, image, description, cost, sellerID, category) VALUES ("test", "assets/img/wmgzon.png", "this is a product", 20.99, 1, "CarParts");
INSERT INTO Products (name, image, description, cost, sellerID, category) VALUES ("test", "assets/img/wmgzon.png", "this is a product", 20.99, 1, "CarParts");
INSERT INTO Products (name, image, description, cost, sellerID, category) VALUES ("test", "assets/img/wmgzon.png", "this is a product", 20.99, 1, "CarParts");
INSERT INTO Products (name, image, description, cost, sellerID, category) VALUES ("test", "assets/img/wmgzon.png", "this is a product", 20.99, 1, "CarParts");
INSERT INTO Products (name, image, description, cost, sellerID, category) VALUES ("test", "assets/img/wmgzon.png", "this is a product", 20.99, 1, "CarParts");
INSERT INTO Products (name, image, description, cost, sellerID, category) VALUES ("test", "assets/img/wmgzon.png", "this is a product", 20.99, 1, "CarParts");
INSERT INTO Products (name, image, description, cost, sellerID, category) VALUES ("test", "assets/img/wmgzon.png", "this is a product", 20.99, 1, "CarParts");
CREATE TABLE IF NOT EXISTS Orders ( CREATE TABLE IF NOT EXISTS Orders (
id INTEGER PRIMARY KEY, id INTEGER PRIMARY KEY,

39
templates/car_parts.html Normal file
View File

@ -0,0 +1,39 @@
<div class="filter-pane">
<form action="" class="filter-items">
<div class="number-plate">
<span class="country-identifier">
<img src="https://mycarneedsa.com/assets/flint/img/flag_europe_gb.png" alt="">
</span>
<span class="vrn">
<input type="text" class="vrn-text" placeholder="YOUR REG" name="vrn">
</span>
</div>
<select class="product-filter not-required" name="filter">
<option value="relevance">Most Relevant</option>
<option value="price-lh">Price: Low -> High</option>
<option value="price-hl">Price: High -> Low</option>
</select>
</form>
</div>
<div class="product-container">
{% if products != None %}
{% for product in products %}
<div class="product">
<div class="product-title">{{product.name}}</div>
<div class="product-information">
<div class="product-image">
<img src="{{url_for('static', filename=product.image)}}" alt="Brake Disks"/>
</div>
<div class="product-details">
<div class="product-price">£{{product.cost}}</div>
<div class="product-description">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation</div>
</div>
</div>
<div class="product-add-to-cart"></div>
</div>
{% endfor %}
{% endif %}
</div>

View File

@ -1,63 +1,19 @@
<div class="filter-pane">
<form action="" class="filter-items">
<div class="number-plate">
<span class="country-identifier">
<img src="https://mycarneedsa.com/assets/flint/img/flag_europe_gb.png" alt="">
</span>
<span class="vrn">
<input type="text" class="vrn-text" placeholder="YOUR REG" name="vrn">
</span>
</div>
<select class="product-filter not-required" name="filter">
<option value="relevance">Most Relevant</option>
<option value="price-lh">Price: Low -> High</option>
<option value="price-hl">Price: High -> Low</option>
</select>
</form>
</div>
<div class="product-container"> <div class="product-container">
{% if products != None %}
{% for product in products %}
<div class="product"> <div class="product">
<div class="product-title">12" Brake Disks</div> <div class="product-title">{{product.name}}</div>
<div class="product-information"> <div class="product-information">
<div class="product-image"> <div class="product-image">
<img src="{{url_for('static', filename='assets/img/products/brake-disks.png')}}" alt="Brake Disks"/> <img src="{{url_for('static', filename=product.image)}}" alt="Brake Disks"/>
</div> </div>
<div class="product-details"> <div class="product-details">
<div class="product-price">£64.50</div> <div class="product-price">£{{product.cost}}</div>
<div class="product-description">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation</div>
</div>
</div>
<div class="product-add-to-cart"></div>
</div>
<div class="product">
<div class="product-title">12" Brake Disks</div>
<div class="product-information">
<div class="product-image">
<img src="{{url_for('static', filename='assets/img/products/brake-disks.png')}}" alt="Brake Disks"/>
</div>
<div class="product-details">
<div class="product-price">£64.50</div>
<div class="product-description">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation</div>
</div>
</div>
<div class="product-add-to-cart"></div>
</div>
<div class="product">
<div class="product-title">12" Brake Disks</div>
<div class="product-information">
<div class="product-image">
<img src="{{url_for('static', filename='assets/img/products/brake-disks.png')}}" alt="Brake Disks"/>
</div>
<div class="product-details">
<div class="product-price">£64.50</div>
<div class="product-description">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation</div> <div class="product-description">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation</div>
</div> </div>
</div> </div>
<div class="product-add-to-cart"></div> <div class="product-add-to-cart"></div>
</div> </div>
{% endfor %}
{% endif %}
</div> </div>

View File

@ -5,9 +5,9 @@
<input type="submit" class="search-button"> <input type="submit" class="search-button">
</form> </form>
{% if user != None: %} {% if user != None: %}
<a href="logout">Welcome, {{ user }}</a> <a href="/logout">Welcome, {{ user }}</a>
{% else %} {% else %}
<a href="login">Login/Signup</a> <a href="/login">Login/Signup</a>
{% endif %} {% endif %}
</nav> </nav>