diff --git a/Workshop3/Procfile b/Workshop3/Procfile new file mode 100644 index 0000000..93f040b --- /dev/null +++ b/Workshop3/Procfile @@ -0,0 +1 @@ +web: gunicorn app:app --log-file - \ No newline at end of file diff --git a/Workshop3/Templates/404.html b/Workshop3/Templates/404.html new file mode 100644 index 0000000..48a6214 --- /dev/null +++ b/Workshop3/Templates/404.html @@ -0,0 +1,10 @@ + + + + + 404 page + + +

Wrong action value: {{action_value}}

+ + \ No newline at end of file diff --git a/Workshop3/Templates/all.html b/Workshop3/Templates/all.html new file mode 100644 index 0000000..2e52778 --- /dev/null +++ b/Workshop3/Templates/all.html @@ -0,0 +1,12 @@ + + + + + all + + +

Customer {{customer}}

+

Nutrition {{nutrition}}

+ + + \ No newline at end of file diff --git a/Workshop3/Templates/customer.html b/Workshop3/Templates/customer.html new file mode 100644 index 0000000..457a151 --- /dev/null +++ b/Workshop3/Templates/customer.html @@ -0,0 +1,24 @@ + + + + + client + + + + +
+

Name

+

Surname

+

Login

+

Password

+

E-mail

+

Adress

+ +
+ + + + + + \ No newline at end of file diff --git a/Workshop3/Templates/nutrition.html b/Workshop3/Templates/nutrition.html new file mode 100644 index 0000000..0fd7bd3 --- /dev/null +++ b/Workshop3/Templates/nutrition.html @@ -0,0 +1,25 @@ + + + + + event + + + + +
+

Title

+

Brand

+

Ingredient

+

Weight

+

Price

+

Description

+ + +
+ + + + + + \ No newline at end of file diff --git a/Workshop3/WorkShop3 Flask.pdf b/Workshop3/WorkShop3 Flask.pdf new file mode 100644 index 0000000..162def7 Binary files /dev/null and b/Workshop3/WorkShop3 Flask.pdf differ diff --git a/Workshop3/app.py b/Workshop3/app.py new file mode 100644 index 0000000..7f87ac1 --- /dev/null +++ b/Workshop3/app.py @@ -0,0 +1,73 @@ +from flask import Flask, request, render_template + +app = Flask(__name__) + + +nutrition_dictionary = { + "nutr_title": "Big chicken nutrition pack", + "nutr_brand": "Purina Pro plan", + "nutr_ingredient": "Chicken", + "nutr_weight": 10, + "nutr_price": 400, + "nutr_description": "This is a food for dogs" +} + +customer_dictionary = { + "cust_name": "Fedor", + "cust_surname": "Kuprianov", + "cust_login": "fedyakup", + "cust_pass": "poc123poc", + "cust_email": "fedya_kup@gmail.com", + "cust_adress": "Volgogradska str." +} + + +@app.route('/') +def main(): + return 'Priv che delaesh' + + + +@app.route('/api/', methods=['GET']) +def apiget(action): + if action == "nutrition": + return render_template('nutrition.html', nutrition=nutrition_dictionary) + elif action == "customer": + return render_template('customer.html', customer=customer_dictionary) + elif action == "all": + return render_template('all.html', nutrition=nutrition_dictionary, customer=customer_dictionary) + else: + return render_template('404.html', action_value=action) + + +@app.route('/api/nutrition/submit', methods=['POST']) +def nitrition_submit(): + if request.method == "POST": + nutrition_dictionary["Title"] = request.form['title'] + nutrition_dictionary["Brand"] = request.form['brand'] + nutrition_dictionary["Ingredient"] = request.form['ingredient'] + nutrition_dictionary["Weight"] = request.form['weight'] + nutrition_dictionary["Price"] = request.form['price'] + nutrition_dictionary["Short description"] = request.form['descr'] + return render_template("all.html", nutrition=nutrition_dictionary, customer=customer_dictionary) + else: + return render_template("nutrition.html", nutrition=nutrition_dictionary) + + +@app.route('/api/customer/submit', methods=['POST']) +def customer_submit(): + if request.method == "POST": + customer_dictionary["Name"] = request.form['name'] + customer_dictionary["Surname"] = request.form['surname'] + customer_dictionary["Login"] = request.form['login'] + customer_dictionary["Password"] = request.form['pass'] + customer_dictionary["E-mail"] = request.form['email'] + customer_dictionary["Adress"] = request.form['adress'] + return render_template("all.html", nutrition=nutrition_dictionary, customer=customer_dictionary) + else: + return render_template("customer.html", customer=customer_dictionary) + + + +if __name__ == "__main__": + app.run(debug=True) \ No newline at end of file diff --git a/Workshop3/requirements.txt b/Workshop3/requirements.txt new file mode 100644 index 0000000..1c4caa9 --- /dev/null +++ b/Workshop3/requirements.txt @@ -0,0 +1,7 @@ +click==7.1.2 +Flask==1.1.2 +itsdangerous==1.1.0 +Jinja2==2.11.2 +MarkupSafe==1.1.1 +Werkzeug==1.0.1 +gunicorn == 20.0.4 \ No newline at end of file diff --git a/Workshop3/runtime.txt b/Workshop3/runtime.txt new file mode 100644 index 0000000..f8624ef --- /dev/null +++ b/Workshop3/runtime.txt @@ -0,0 +1 @@ +python-3.8.2 \ No newline at end of file diff --git a/Workshop4/source/connection.py b/Workshop4/source/connection.py new file mode 100644 index 0000000..ca6bc03 --- /dev/null +++ b/Workshop4/source/connection.py @@ -0,0 +1,11 @@ +from sqlalchemy.engine import create_engine + +username = 'user' +password = '1234' +sid = 'XE' +host = 'localhost' +port = '1521' + + +oracle_connection_path = 'oracle+cx_oracle://{username}:{password}@{host}:{port}/{sid}' +engine = create_engine(oracle_connection_path) \ No newline at end of file diff --git a/Workshop4/source/workshop4.py b/Workshop4/source/workshop4.py new file mode 100644 index 0000000..8dcacf4 --- /dev/null +++ b/Workshop4/source/workshop4.py @@ -0,0 +1,120 @@ +from sqlalchemy import Integer, String, Column, MetaData, Float, DateTime, ForeignKey, CheckConstraint +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy_utils import EmailType +from database_connection import engine +from sqlalchemy.orm import sessionmaker +from sqlalchemy.orm import relationship +import re +Base = declarative_base() +meta = MetaData() + + +class nutrition(Base): + __tablename__ = 'nutrition' + nutr_title = Column(String(100), primary_key=True, nullable=False) + nutr_brand = Column(String(40), primary_key=True, nullable=False) + nutr_price = Column(Float, primary_key=True, nullable=False) + nutr_weight = Column(Float, primary_key=True, nullable=False) + nutr_ingredient = Column(String(30), primary_key=True, nullable=False) + nutr_description = Column(String(500), nullable=False) + CheckConstraint('price > 0', name='check_price') + CheckConstraint('weight > 0', name='check_weight') + + + + @classmethod + def add(cls, nutr_title, nutr_brand, nutr_price, nutr_weight, nutr_ingredient, nutr_description): + if not nutr_title.isalpha() or not nutr_brand.isalpha() or not nutr_ingredient.isalpha() or not nutr_description.isalpha() \ + or not isinstance(nutr_price, float) or not isinstance(nutr_weight, float): + print("Data is not correct!") + return -1 + Session = sessionmaker(bind=engine) + session = Session() + Nutrition = nutrition(nutr_title=nutr_title, nutr_brand=nutr_brand, nutr_price=nutr_price, nutr_weight=nutr_weight, nutr_ingredient=nutr_ingredient, + nutr_description=nutr_description) + session.add(Nutrition) + session.commit() + +class customer(Base): + __tablename__ = 'customer' + + cust_name = Column(String(80), nullable=False) + cust_surname = Column(String(90)) + cust_login = Column(String(40), primary_key=True, nullable=False) + cust_password = Column(String(50), nullable=False) + cust_email = Column(EmailType, nullable=False) + cust_adress = Column(String(300), nullable=False) + + @classmethod + def add(cls, cust_name, cust_surname, cust_login, cust_password, cust_email, cust_adress): + if not cust_name.isalpha() or not cust_surname.isalpha() or not cust_login.isalpha() or not cust_password.isalpha() \ + or not cust_adress.isalpha() or not re.match(r"[^@]+@[^@]+\.[^@]+", cust_email): + print("Data is not correct!") + return -1 + Session = sessionmaker(bind=engine) + session = Session() + Customer1 = customer(cust_name=cust_name, cust_surname=cust_surname, cust_login=cust_login, cust_password=cust_password, + cust_email=cust_email, cust_adress=cust_adress) + session.add(Customer1) + session.commit() + + +class review(Base): + __tablename__ = 'review' + nutr_title = Column(String(100), ForeignKey('nutrition.nutr_title'), primary_key=True, nullable=False) + nutr_brand = Column(String(40), ForeignKey('nutrition.nutr_brand'), primary_key=True, nullable=False) + nutr_price_fk = Column(Float, ForeignKey('nutrition.nutr_price')) + nutr_ingredient_fk = Column(String(30), ForeignKey('nutrition.nutr_ingredient')) + reviews = Column(String(600), nullable=False) + rating = Column(Integer, nullable=False) + CheckConstraint('nutr_price_fk >= 0', name='check_nutr_price_fk') + CheckConstraint('rating >= 0', name='check_rating') + nutritions = relationship("nutrition", foreign_keys=[nutr_title]) + nutritions_brand = relationship("nutrition", foreign_keys=[nutr_brand]) + nutritions_price = relationship("nutrition", foreign_keys=[nutr_price_fk]) + nutritions_ingredient = relationship("nutrition", foreign_keys=[nutr_ingredient_fk]) + + @classmethod + def add(cls, nutr_title, nutr_brand, nutr_price_fk, nutr_ingredient_fk, reviews, rating): + if not nutr_title.isalpha() or not nutr_brand.isalpha() \ + or not isinstance(nutr_price_fk, float) or not nutr_ingredient_fk.isalpha() or not reviews.isalpha() \ + or not isinstance(rating, int): + print("Data is not correct!") + return -1 + Session = sessionmaker(bind=engine) + session = Session() + review1 = review(nutr_title=nutr_title, nutr_brand=nutr_brand, nutr_price_fk=nutr_price_fk, + nutr_ingredient_fk=nutr_ingredient_fk, reviews=reviews, rating=rating) + session.add(review1) + session.commit() + + +class cust_order(Base): + __tablename__ = 'cust_order' + + nutr_title = Column(String(100), ForeignKey('nutrition.nutr_title'), primary_key=True, nullable=False) + nutr_brand = Column(String(40), ForeignKey('nutrition.nutr_brand'), primary_key=True, nullable=False) + nutr_price = Column(Float, ForeignKey('nutrition.nutr_price')) + nutr_ingredient_fk = Column(String(30), ForeignKey('nutrition.genre'), nullable=False) + status = Column(String(25), nullable=False) + CheckConstraint('price >= 0', name='check_price') + nutritions = relationship("nutrition", foreign_keys=[nutr_title]) + nutritions_brand = relationship("nutrition", foreign_keys=[nutr_brand]) + nutritions_price = relationship("nutrition", foreign_keys=[nutr_price]) + nutritions_ingredient = relationship("nutrition", foreign_keys=[nutr_ingredient_fk]) + + @classmethod + def add(cls, nutr_title, nutr_brand, nutr_price, nutr_ingredient_fk, status): + if not nutr_title.isalpha() or not nutr_brand.isalpha() \ + or not isinstance(nutr_price, float) or not nutr_brand.isalpha() or not status.isalpha(): + print("Data is not correct!") + return -1 + Session = sessionmaker(bind=engine) + session = Session() + cust_order1 = cust_order(nutr_title=nutr_title, nutr_brand=nutr_brand, nutr_price=nutr_price, nutr_ingredient_fk=nutr_ingredient_fk, + status=status) + session.add(cust_order1) + session.commit() + + +Base.metadata.create_all(engine) \ No newline at end of file diff --git a/Workshop4/sql/add_tables.sql b/Workshop4/sql/add_tables.sql new file mode 100644 index 0000000..7b35c3a --- /dev/null +++ b/Workshop4/sql/add_tables.sql @@ -0,0 +1,46 @@ +create table nutrition( + nutr_title VARCHAR2(100), + nutr_brand VARCHAR2(40), + nutr_price NUMBER(8, 2), + nutr_weight NUMBER(6, 2), + nutr_ingredient VARCHAR2(30), + nutr_description VARCHAR2(500) NOT NULL, + CONSTRAINT nutr_constraint PRIMARY KEY (nutr_title, nutr_brand, nutr_price, nutr_ingredient), + CONSTRAINT check_nutr_price CHECK (nutr_price >= 0), + CONSTRAINT check_nutr_weight CHECK (nutr_weight >= 0), +); + +create table customer( + cust_name VARCHAR2(80) NOT NULL, + cust_surname VARCHAR2(90), + cust_login VARCHAR2(40) NOT NULL PRIMARY KEY, + cust_password VARCHAR2(50) NOT NULL, + cust_email VARCHAR2(50) NOT NULL UNIQUE, + cust_adress VARCHAR2(300) NOT NULL + CONSTRAINT cust_email_check CHECK (REGEXP_LIKE (cust_email, '^(\S+)\@(\S+)\.(\S+)$')) +); + +create table review( + nutr_title VARCHAR2(100) NOT NULL, + nutr_brand VARCHAR2(40) NOT NULL, + nutr_price_fk NUMBER(8, 2), + nutr_ingredient_fk VARCHAR2(30), + reviews VARCHAR2(600) NOT NULL, + rating INTEGER NOT NULL, + CONSTRAINT review_constraint PRIMARY KEY (nutr_title, nutr_brand), + CONSTRAINT check_review_nutr_price CHECK (nutr_price_fk >= 0), + CONSTRAINT rating CHECK (rating > 0 and rating <= 10) +); + + +create table cust_order( + nutr_title VARCHAR2(100) NOT NULL, + nutr_brand VARCHAR2(40) NOT NULL, + nutr_price NUMBER(8, 2) NOT NULL, + nutr_ingredient_fk VARCHAR2(30), + status VARCHAR2(25) NOT NULL, + CONSTRAINT order_constraint PRIMARY KEY (nutr_title, nutr_brand), + CONSTRAINT check_order_nutr_price CHECK (nutr_price >= 0) +); + + diff --git a/Workshop4/sql/constraints.sql b/Workshop4/sql/constraints.sql new file mode 100644 index 0000000..923e007 --- /dev/null +++ b/Workshop4/sql/constraints.sql @@ -0,0 +1,88 @@ +ALTER TABLE review +ADD CONSTRAINT review_fk_constraint + FOREIGN KEY (nutrition_title, nutr_brand, nutr_price_fk, nutr_ingredient_fk) + REFERENCES nutrition (nutr_title, nutr_brand, nutr_price, nutr_ingredient); + +ALTER TABLE nutrition_order +ADD CONSTRAINT order_fk_constraint + FOREIGN KEY (nutrition_title, nutr_brand, nutr_price, nutr_ingredient_fk) + REFERENCES nutrition (nutr_title, nutr_brand, nutr_price, nutr_ingredient); + +CREATE OR REPLACE TRIGGER check_nutr_ingredient +BEFORE UPDATE OF nutr_ingredient ON nutrition +FOR EACH ROW +DECLARE +str VARCHAR2(20); +BEGIN + +select regexp_replace(:new.nutr_ingredient, '[[:alpha:]]|_') into str from dual; +IF str is not null then + raise_application_error(-20000, 'Wrong ingredient format for update!'); +END IF; +END; +/ + +CREATE OR REPLACE TRIGGER check_nutr_ingredient_insert +BEFORE INSERT ON nutrition +FOR EACH ROW +DECLARE +str VARCHAR2(20); +BEGIN +select regexp_replace(:new.nutr_ingredient, '[[:alpha:]]|_') into str from dual; +IF str is not null then + raise_application_error(-20000, 'Wrong ingredient format for insert!'); +END IF; +END; +/ + +CREATE OR REPLACE TRIGGER check_cust_name_update +BEFORE UPDATE of cust_name ON customer +FOR EACH ROW +DECLARE +str VARCHAR2(20); +BEGIN +select regexp_replace(:new.cust_name, '[[:alpha:]]|_') into str from dual; +IF str is not null then + raise_application_error(-20000, 'Wrong name format for update!'); +END IF; +END; +/ + +CREATE OR REPLACE TRIGGER check_cust_name_insert +BEFORE Insert ON customer +FOR EACH ROW +DECLARE +str VARCHAR2(20); +BEGIN +select regexp_replace(:new.cust_name, '[[:alpha:]]|_') into str from dual; +IF str is not null then + raise_application_error(-20000, 'Wrong name format for insert!'); +END IF; +END; +/ + +CREATE OR REPLACE TRIGGER check_cust_surname_update +BEFORE UPDATE of cust_surname ON customer +FOR EACH ROW +DECLARE +str VARCHAR2(20); +BEGIN +select regexp_replace(:new.cust_surname, '[[:alpha:]]|_') into str from dual; +IF str is not null then + raise_application_error(-20000, 'Wrong surname format for update!'); +END IF; +END; +/ + +CREATE OR REPLACE TRIGGER check_cust_surname_insert +BEFORE Insert ON customer +FOR EACH ROW +DECLARE +str VARCHAR2(20); +BEGIN +select regexp_replace(:new.cust_surname, '[[:alpha:]]|_') into str from dual; +IF str is not null then + raise_application_error(-20000, 'Wrong surname format for insert!'); +END IF; +END; +/ \ No newline at end of file diff --git a/heroku app.txt b/heroku app.txt new file mode 100644 index 0000000..af8baad --- /dev/null +++ b/heroku app.txt @@ -0,0 +1 @@ +https://workshop3krupovych.herokuapp.com \ No newline at end of file