summaryrefslogtreecommitdiff
path: root/app/routes.py
diff options
context:
space:
mode:
Diffstat (limited to 'app/routes.py')
-rw-r--r--app/routes.py215
1 files changed, 215 insertions, 0 deletions
diff --git a/app/routes.py b/app/routes.py
new file mode 100644
index 0000000..d2bd3f0
--- /dev/null
+++ b/app/routes.py
@@ -0,0 +1,215 @@
+"""
+routes.py module
+----------------
+
+This Python module contains the logic supporting:
+1. Navigating between website pages
+2. Interpreting user requests to the server
+3. Dispatching requested content back to the user
+
+Python dependencies:
+- flask: provides web application features
+- forms: provides secure user form submission
+- sqlalchemy: provides communication with database on server.
+
+Personal imports:
+These are used to avoid cluttering this file with
+placeholder data for posts' content.
+"""
+
+
+from flask import Flask, render_template, request, redirect, flash, url_for, jsonify
+from flask_sqlalchemy import SQLAlchemy
+from flask_bootstrap import Bootstrap
+
+from flask_wtf import FlaskForm
+from wtforms import (
+ SubmitField,
+ SelectField,
+ RadioField,
+ HiddenField,
+ StringField,
+ IntegerField,
+ FloatField,
+)
+from wtforms.validators import InputRequired, Length, Regexp, NumberRange
+from datetime import datetime
+
+import placeholders as p
+
+app = Flask(__name__)
+
+# Flask-Bootstrap requires this line
+Bootstrap(app)
+
+
+# Flask-WTF encryption key
+app.config["SECRET_KEY"] = "Scooby_Lu,_where_are_you?"
+
+# Our database name
+db_name = "fapg.db"
+app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///" + db_name
+app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = True
+db = SQLAlchemy(app)
+
+
+class Users(db.Model):
+ id = db.Column(db.Integer, primary_key=True)
+ name_first = db.Column(db.String(20), nullable=False)
+ name_last = db.Column(db.String(20), nullable=False)
+ email = db.Column(db.String(20), nullable=False)
+ phone_mobile = db.Column(db.Integer, nullable=False)
+ phone_alternative = db.Column(db.Integer)
+ updated = db.Column(db.String)
+
+ def __init__(
+ self, name_first, name_last, email, phone_mobile, phone_alternative, updated
+ ):
+ self.name_first = name_first
+ self.name_last = name_last
+ self.email = email
+ self.phone_mobile = phone_mobile
+ self.phone_alternative = phone_alternative
+ self.updated = updated
+
+ def __repr__(self):
+ return f"<User {self.name_first} {self.name_last}>"
+
+
+class Products(db.Model):
+ id = db.Column(db.Integer, primary_key=True)
+ name = db.Column(db.String(20), nullable=False)
+ supplier = db.Column(db.String(20), nullable=False)
+ price = db.Column(db.Float(10), nullable=False)
+ updated = db.Column(db.String)
+
+ def __init__(self, name, supplier, price, updated):
+ self.name = name
+ self.supplier = supplier
+ self.price = price
+ self.updated = updated
+
+ def __repr__(self):
+ return f"<Product {self.name} by {self.supplier}>"
+
+
+class Projects(db.Model):
+ id = db.Column(db.Integer, primary_key=True)
+ name = db.Column(db.String(20), nullable=False)
+ name_full = db.Column(db.String(20), nullable=False)
+ nickname = db.Column(db.String(20), nullable=False)
+ city = db.Column(db.String(20), nullable=False)
+
+ def __repr__(self):
+ return f"<Project {self.name}>"
+
+
+class Modules(db.Model):
+ id = db.Column(db.Integer, primary_key=True)
+ name = db.Column(db.String(20), unique=True, nullable=False)
+ description = db.Column(db.String(50), nullable=False)
+
+ def __init__(self, name, description, updated):
+ self.name = name
+ self.description = description
+ self.updated = updated
+
+ def __repr__(self):
+ return f"<Module {self.name}>"
+
+
+class AddProduct(FlaskForm):
+ # id used only by update/edit
+ id = HiddenField()
+ name = StringField("Product name", validators=[InputRequired()])
+ supplier = SelectField(
+ "Choose a supplier",
+ choices=[
+ ("", ""),
+ ("Mister Brown", "Mister Brown"),
+ ("Madame Cerise", "Madame Cerise"),
+ ("Biton la Malice", "G. Biton la Malice"),
+ ("Leroy Merlin", "Leroy Merlin"),
+ ("other", "Other"),
+ ],
+ )
+ price = FloatField("Retail price per unit")
+ # updated - date - handled in the route function
+ updated = HiddenField()
+ submit = SubmitField("Add/Update Product")
+
+
+# add a new product to the database
+@app.route("/add_product", methods=["GET", "POST"])
+def add_product():
+ form = AddProduct()
+ if form.validate_on_submit():
+ name = request.form["name"]
+ supplier = request.form["supplier"]
+ price = request.form["price"]
+ # get today's date from function, above all the routes
+ updated = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
+ # the data to be inserted into FAPG model - the table, products
+ record = Products(name, supplier, price, updated)
+ # Flask-SQLAlchemy magic adds record to database
+ db.session.add(record)
+ db.session.commit()
+ # create a message to send to the template
+ message = f"The data for product {name} has been submitted."
+ return render_template("add_product.html", message=message)
+ else:
+ # show validaton errors
+ # see https://pythonprogramming.net/flash-flask-tutorial/
+ for field, errors in form.errors.items():
+ for error in errors:
+ flash(
+ "Error in {}: {}".format(getattr(form, field).label.text, error),
+ "error",
+ )
+ return render_template("add_product.html", form=form)
+
+
+@app.route("/")
+@app.route("/fapg/home")
+def project():
+ """This is our project welcome page."""
+ michel = Users(
+ name_first="Michel",
+ name_last="Peter",
+ email="le-boss@fapg.com",
+ phone_mobile="00000000",
+ phone_alternative="0000000000",
+ updated="2022-04-21",
+ )
+ modules = Modules.query.all()
+ print(module.name for module in modules)
+ return render_template("home.html", user=michel, project=fapg, modules=modules)
+
+
+@app.route("/module/<module>")
+def render_module(module):
+ modules = Modules.query.all()
+ catalog = Products.query.all()
+ user_modules = [module.name for module in modules]
+ print(user_modules)
+ # If a module was purchased by a user and added to their database,
+ # they have access to the corresponding module route.
+ if module in user_modules:
+ return render_template(
+ f"modules/{module}.html",
+ modules=modules,
+ catalog=catalog,
+ )
+ else:
+ return render_template("errors/module-not-found.html", module=module)
+
+
+# If this file is executed as a script (i.e. double-clicked),
+# the Python interpreter will run the Flask process and begin serving
+# the web pages on the standard localhost address (127.0.0.1).
+# But if this file is called as a module by another Python script, it will not
+# serve content to the web pages, but the function definitions contained in
+# this file will be available to the calling script.
+# E.g. calling script will know what the yes() function is.
+if __name__ == "__main__":
+ app.run(debug=True)
Copyright 2019--2024 Marius PETER