commit 950482dbafbe1c72f03a0b7ea86f7437ea934130 Author: Lucas Date: Sat May 11 17:25:51 2024 +0200 Initial commit diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 0000000..722d153 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,7 @@ +FROM python:3.11.8-alpine + +# Dev depedencies +RUN apk add --no-cache git + +# Prod depedencies +RUN pip install flask psycopg2-binary sqlalchemy \ No newline at end of file diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..b2ddb07 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,19 @@ +// For format details, see https://aka.ms/devcontainer.json +{ + "name": "avsa-form devenv", + "dockerComposeFile": "docker-compose.yml", + "service": "devenv", + "workspaceFolder": "/home/developer/workspace", + + "remoteEnv": { + "XDG_RUNTIME_DIR": "/tmp/runtime-developer" + }, + + "customizations": { + "vscode": { + "extensions": [ + "shardulm94.trailing-spaces" + ] + } + } +} \ No newline at end of file diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml new file mode 100644 index 0000000..ff2494b --- /dev/null +++ b/.devcontainer/docker-compose.yml @@ -0,0 +1,29 @@ +services: + devenv: + build: + context: . + dockerfile: Dockerfile + + container_name: avsa_form-dev + restart: always + + volumes: + - ..:/home/developer/workspace + + command: sleep infinity + networks: + - avsa_form + + db: + image: postgres:13.1 + container_name: avsa_form_db + restart: always + volumes: + - ../postgresql:/var/lib/postgresql/data + env_file: + - ../db.env + networks: + - avsa_form + +networks: + avsa_form: \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2d7e6aa --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.venv +postgresql +__pycache__ \ No newline at end of file diff --git a/create_table.sql b/create_table.sql new file mode 100644 index 0000000..f71fe31 --- /dev/null +++ b/create_table.sql @@ -0,0 +1,10 @@ +CREATE TABLE accounts ( + user_id SERIAL PRIMARY KEY, + first_name VARCHAR (50) NOT NULL, + last_name VARCHAR (50) NOT NULL, + phone_number VARCHAR (30) NOT NULL, + request_at TIMESTAMP NOT NULL, + start_availability TIMESTAMP NOT NULL, + end_availability TIMESTAMP NOT NULL, + user_type VARCHAR (10) NOT NULL +); \ No newline at end of file diff --git a/db.env b/db.env new file mode 100644 index 0000000..af3180c --- /dev/null +++ b/db.env @@ -0,0 +1,3 @@ +POSTGRES_USER=avsa_form +POSTGRES_PASSWORD=#4gvAwnUr5@MuZk9cYb! +POSTGRES_DB=avsa_form_db \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..27fee6a --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,21 @@ +#version: '3' + +services: + db: + image: postgres:13.1 + container_name: avsa_form_db + restart: always + volumes: + - ./postgresql:/var/lib/postgresql/data + env_file: + - db.env + networks: + - avsa_form + + flask: + image: python:3.11.8-alpine + +networks: + avsa_form: + external: true + #reverse-proxy: diff --git a/hello.py b/hello.py new file mode 100644 index 0000000..ee751db --- /dev/null +++ b/hello.py @@ -0,0 +1,85 @@ +from datetime import datetime + +from urllib.parse import quote_plus +from sqlalchemy import create_engine, text + +from flask import Flask +from flask import request +from flask import render_template + +DB_USER = 'avsa_form' +DB_PASSWORD = '#4gvAwnUr5@MuZk9cYb!' +DB_HOST = 'avsa_form_db' +DB_PORT = '5432' +DB_NAME = 'avsa_form_db' +DB_TABLE = 'accounts' + +class user_data: + def __init__(self, first_name, last_name, phone_number, request_at, start_availability, end_availability, user_type): + self.first_name = first_name + self.last_name = last_name + self.phone_number = phone_number + self.request_at = request_at + self.start_availability = start_availability + self.end_availability = end_availability + self.user_type = user_type + +# new_data = current_data('lucas','royer','0612345678','2011-05-16 15:36:38','2011-05-16 15:36:38','2011-05-16 15:36:38','benevole') + +def insert_db(current_data): + # Connect to DB + engine = create_engine(f"postgresql+psycopg2://{DB_USER}:%s@{DB_HOST}:{DB_PORT}/{DB_NAME}" % quote_plus(DB_PASSWORD)) + conn = engine.connect() + + + + data = { + 'first_name': current_data.first_name, + 'last_name': current_data.last_name, + 'phone_number': current_data.phone_number, + 'request_at': current_data.request_at, + 'start_availability': current_data.start_availability, + 'end_availability': current_data.end_availability, + 'user_type': current_data.user_type, + } + + # SQL query + query=text(f"INSERT INTO {DB_TABLE} (first_name, last_name, phone_number, request_at, start_availability, end_availability, user_type) VALUES (:first_name, :last_name, :phone_number, :request_at, :start_availability, :end_availability, :user_type);") + + conn.execute(query, data) + conn.commit() + +app = Flask(__name__) + +@app.route("/") +def accueil(): + return render_template('accueil.html') + +@app.route('/formulaire', methods=['GET']) +def formulaire(): + return render_template('formulaire.html', retry=False) + +@app.route('/resultat', methods=['POST']) +def resultat(): + if request.method == 'POST': + first_name = request.form['first_name'] + last_name = request.form['last_name'] + phone_number = request.form['phone_number'] + request_at = datetime.now().strftime("%m-%d-%Y %H:%M:%S") + + availability_date = request.form['availability_date'] + start_availability_h = request.form['start_availability_h'] + start_availability_m = request.form['start_availability_m'] + end_availability_h = request.form['end_availability_h'] + end_availability_m = request.form['end_availability_m'] + + start_availability = f'{availability_date} {start_availability_h}:{start_availability_m}:00' + end_availability = f'{availability_date} {end_availability_h}:{end_availability_m}:00' + user_type = request.form['user_type'] + current_data = user_data(first_name, last_name, phone_number, request_at, start_availability, end_availability, user_type) + + if any(value is None for value in current_data.__dict__.values()): + return render_template('formulaire.html', retry=True) + else: + insert_db(current_data) + return render_template('resultat.html', first_name=first_name, last_name=last_name, phone_number=phone_number, request_at=request_at, start_availability_h=start_availability_h, start_availability_m=start_availability_m, end_availability_h=end_availability_h, end_availability_m=end_availability_m, user_type=current_data.user_type) diff --git a/templates/accueil.html b/templates/accueil.html new file mode 100644 index 0000000..fe3eee1 --- /dev/null +++ b/templates/accueil.html @@ -0,0 +1,13 @@ + + + + + + AVSA - Familles + + + + + + + \ No newline at end of file diff --git a/templates/formulaire.html b/templates/formulaire.html new file mode 100644 index 0000000..d51cdfb --- /dev/null +++ b/templates/formulaire.html @@ -0,0 +1,257 @@ + + + + + + + +

Proposition de créneau de balade - A Vélo Sans Age Nantes

+

Merci de préciser votre demande ci-dessous :

+ +
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+ +
+
+
+ + + +
+ + + \ No newline at end of file diff --git a/templates/resultat.html b/templates/resultat.html new file mode 100644 index 0000000..96bbe3d --- /dev/null +++ b/templates/resultat.html @@ -0,0 +1,20 @@ + + + + + + AVSA - Familles + + +

Votre demande a bien été prise en compte :

+

Vous êtes : {{ user_type }}

+

Prenom : {{ first_name }}

+

Nom : {{ last_name }}

+

Téléphone : {{ user_message }}

+

Date : {{ availability_date }}

+

Horaire : de {{ start_availability_h }}h{{ start_availability_m }} à {{ end_availability_h }}h{{ end_availability_m }}

+ + + + + \ No newline at end of file