From 5d9cf228858cbb243366e272fd8b655dd86562a7 Mon Sep 17 00:00:00 2001 From: Vincent Date: Thu, 1 Aug 2024 13:15:08 +0000 Subject: [PATCH] Sauvegarde --- .env.template | 10 +++ Dockerfile | 2 +- app copy.py | 179 --------------------------------------------- config.py | 8 +++ initialize_db.py | 32 ++++----- wait-for-it.sh | 183 ----------------------------------------------- 6 files changed, 31 insertions(+), 383 deletions(-) create mode 100644 .env.template delete mode 100644 app copy.py delete mode 100755 wait-for-it.sh diff --git a/.env.template b/.env.template new file mode 100644 index 0000000..287285a --- /dev/null +++ b/.env.template @@ -0,0 +1,10 @@ +# Nom de base de données +DB_NAME= +# Utilisateur +DB_USER= +# Mot de passe +DB_PASSWORD= +# Host Mysql +DB_HOST= +# Clé sécrète generée avec +SECRET_KEY= \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index af01408..351dfb6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,7 +10,7 @@ RUN pip install --no-cache-dir -r requirements.txt COPY . . # Set environment variables -ENV FLASK_APP=app.py +#ENV FLASK_APP=app.py # Expose port EXPOSE 5000 diff --git a/app copy.py b/app copy.py deleted file mode 100644 index 2bf5884..0000000 --- a/app copy.py +++ /dev/null @@ -1,179 +0,0 @@ -# app.py - -from flask import Flask, render_template, request, redirect, url_for, flash, session, send_from_directory -from flask_sqlalchemy import SQLAlchemy -from werkzeug.security import generate_password_hash, check_password_hash -from werkzeug.utils import secure_filename -from datetime import datetime -import os -import re -from models import db, User, Article -from config import db_config, SECRET_KEY - -app = Flask(__name__) -app.config['SQLALCHEMY_DATABASE_URI'] = f"mysql+mysqlconnector://{db_config['user']}:{db_config['password']}@{db_config['host']}/{db_config['database']}" -app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False -app.config['SECRET_KEY'] = SECRET_KEY - -# Configurer l'upload d'images -UPLOAD_FOLDER = 'static/uploads' -ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'} -app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER - -db.init_app(app) - -def allowed_file(filename): - return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS - -@app.route('/') -def home(): - category = request.args.get('category') - if category: - articles = Article.query.filter_by(category=category).order_by(Article.created_at.desc()).all() - else: - articles = Article.query.order_by(Article.created_at.desc()).all() - return render_template('home.html', articles=articles) - -@app.route('/article/') -def article(article_id): - article = Article.query.get_or_404(article_id) - return render_template('article.html', article=article) - -@app.route('/article/delete/', methods=['POST']) -def delete_article(article_id): - article = Article.query.get_or_404(article_id) - if article.author_id != session.get('user_id'): - flash('Vous ne pouvez supprimer que vos propres articles.') - return redirect(url_for('home')) - db.session.delete(article) - db.session.commit() - flash('Article supprimé avec succès.') - return redirect(url_for('home')) - -@app.route('/article/edit/', methods=['GET', 'POST']) -def edit_article(article_id): - article = Article.query.get_or_404(article_id) - if article.author_id != session.get('user_id'): - flash('Vous ne pouvez modifier que vos propres articles.') - return redirect(url_for('home')) - - if request.method == 'POST': - title = request.form['title'] - category = request.form['category'] - content = request.form['content'] - file = request.files['image'] - - if not title or not category or not content: - flash('Tous les champs sont obligatoires.') - elif len(content.split()) > 1000: - flash('Le contenu dépasse la limite maximale de 1000 mots.') - elif file and allowed_file(file.filename): - if file.mimetype not in ['image/jpeg', 'image/png', 'image/gif']: - flash('Format d\'image non supporté.') - elif len(file.read()) > 1 * 1024 * 1024: # 1 Mo - flash('La taille de l\'image dépasse 1 Mo.') - else: - filename = secure_filename(file.filename) - filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename) - file.seek(0) - file.save(filepath) - article.image_path = filepath - article.title = title - article.category = category - article.content = content - article.updated_at = datetime.utcnow() - - db.session.commit() - flash('Article modifié avec succès !') - return redirect(url_for('article', article_id=article.id)) - - return render_template('edit_article.html', article=article) - -@app.route('/register', methods=['GET', 'POST']) -def register(): - if request.method == 'POST': - username = request.form['username'] - email = request.form['email'] - password = request.form['password'] - if not re.match(r"[^@]+@[^@]+\.[^@]+", email): - flash('Adresse email invalide.') - return redirect(url_for('register')) - hashed_password = generate_password_hash(password, method='pbkdf2:sha256') - - new_user = User(username=username, email=email, password=hashed_password) - db.session.add(new_user) - db.session.commit() - flash('Inscription réussie ! Veuillez vous connecter.') - return redirect(url_for('login')) - return render_template('register.html') - -@app.route('/login', methods=['GET', 'POST']) -def login(): - if request.method == 'POST': - email = request.form['email'] - password = request.form['password'] - user = User.query.filter_by(email=email).first() - - if user and check_password_hash(user.password, password): - session['user_id'] = user.id - session['username'] = user.username - flash('Connexion réussie !') - return redirect(url_for('home')) - else: - flash('Identifiants invalides. Veuillez réessayer.') - return render_template('login.html') - -@app.route('/logout') -def logout(): - session.pop('user_id', None) - session.pop('username', None) - flash('Vous avez été déconnecté.') - return redirect(url_for('home')) - -@app.route('/write', methods=['GET', 'POST']) -def write(): - if 'user_id' not in session: - flash('Vous devez être connecté pour écrire un article.') - return redirect(url_for('login')) - - if request.method == 'POST': - title = request.form['title'] - category = request.form['category'] - content = request.form['content'] - file = request.files['image'] - - if not title or not category or not content: - flash('Tous les champs sont obligatoires.') - elif len(content.split()) > 1000: - flash('Le contenu dépasse la limite maximale de 1000 mots.') - elif file and allowed_file(file.filename): - if file.mimetype not in ['image/jpeg', 'image/png', 'image/gif']: - flash('Format d\'image non supporté.') - elif len(file.read()) > 1 * 1024 * 1024: # 1 Mo - flash('La taille de l\'image dépasse 1 Mo.') - else: - filename = secure_filename(file.filename) - filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename) - file.seek(0) - file.save(filepath) - - new_article = Article( - title=title, - category=category, - content=content, - author_id=session['user_id'], - image_path=filepath - ) - db.session.add(new_article) - db.session.commit() - flash('Article publié avec succès !') - return redirect(url_for('home')) - - return render_template('write.html') - -@app.route('/uploads/') -def uploaded_file(filename): - return send_from_directory(app.config['UPLOAD_FOLDER'], filename) - -if __name__ == '__main__': - app.run(debug=True, host='0.0.0.0') diff --git a/config.py b/config.py index 3b7ab96..3935d64 100644 --- a/config.py +++ b/config.py @@ -13,3 +13,11 @@ } SECRET_KEY = os.getenv('SECRET_KEY', 'your_secret_key') + + +# Debugging print statements +print(f"DB_HOST={db_config['host']}") +print(f"DB_USER={db_config['user']}") +print(f"DB_PASSWORD={db_config['password']}") +print(f"DB_NAME={db_config['database']}") +print(f"SECRET_KEY={SECRET_KEY}") \ No newline at end of file diff --git a/initialize_db.py b/initialize_db.py index 2f7cda9..89a291e 100644 --- a/initialize_db.py +++ b/initialize_db.py @@ -1,25 +1,17 @@ -# initialize_db.py +from dotenv import load_dotenv +import os -import time -import mysql.connector -from app import db, app +load_dotenv() -def wait_for_db(): - while True: - try: - conn = mysql.connector.connect( - host=app.config['SQLALCHEMY_DATABASE_URI'].split('@')[1].split('/')[0].split(':')[0], - user=app.config['SQLALCHEMY_DATABASE_URI'].split('//')[1].split(':')[0], - password=app.config['SQLALCHEMY_DATABASE_URI'].split(':')[2].split('@')[0] - ) - conn.close() - break - except mysql.connector.Error as err: - print("Waiting for MySQL to be ready...") - time.sleep(5) +print(f"DB_HOST={os.getenv('DB_HOST')}") +print(f"DB_USER={os.getenv('DB_USER')}") +print(f"DB_PASSWORD={os.getenv('DB_PASSWORD')}") +print(f"DB_NAME={os.getenv('DB_NAME')}") +print(f"SECRET_KEY={os.getenv('SECRET_KEY')}") -wait_for_db() +from app import db +from config import db_config -with app.app_context(): - db.create_all() +print(f"DB Config: {db_config}") +db.create_all() diff --git a/wait-for-it.sh b/wait-for-it.sh deleted file mode 100755 index e2ff0a2..0000000 --- a/wait-for-it.sh +++ /dev/null @@ -1,183 +0,0 @@ -#!/usr/bin/env bash -# Use this script to test if a given TCP host/port are available -# Source : https://github.com/vishnubob/wait-for-it - -WAITFORIT_cmdname=${0##*/} - -echoerr() { if [[ $WAITFORIT_QUIET -ne 1 ]]; then echo "$@" 1>&2; fi } - -usage() -{ - cat << USAGE >&2 -Usage: - $WAITFORIT_cmdname host:port [-s] [-t timeout] [-- command args] - -h HOST | --host=HOST Host or IP under test - -p PORT | --port=PORT TCP port under test - Alternatively, you specify the host and port as host:port - -s | --strict Only execute subcommand if the test succeeds - -q | --quiet Don't output any status messages - -t TIMEOUT | --timeout=TIMEOUT - Timeout in seconds, zero for no timeout - -- COMMAND ARGS Execute command with args after the test finishes -USAGE - exit 1 -} - -wait_for() -{ - if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then - echoerr "$WAITFORIT_cmdname: waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT" - else - echoerr "$WAITFORIT_cmdname: waiting for $WAITFORIT_HOST:$WAITFORIT_PORT without a timeout" - fi - WAITFORIT_start_ts=$(date +%s) - while : - do - if [[ $WAITFORIT_ISBUSY -eq 1 ]]; then - nc -z $WAITFORIT_HOST $WAITFORIT_PORT - WAITFORIT_result=$? - else - (echo -n > /dev/tcp/$WAITFORIT_HOST/$WAITFORIT_PORT) >/dev/null 2>&1 - WAITFORIT_result=$? - fi - if [[ $WAITFORIT_result -eq 0 ]]; then - WAITFORIT_end_ts=$(date +%s) - echoerr "$WAITFORIT_cmdname: $WAITFORIT_HOST:$WAITFORIT_PORT is available after $((WAITFORIT_end_ts - WAITFORIT_start_ts)) seconds" - break - fi - sleep 1 - done - return $WAITFORIT_result -} - -wait_for_wrapper() -{ - # In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692 - if [[ $WAITFORIT_QUIET -eq 1 ]]; then - timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --quiet --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT & - else - timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT & - fi - WAITFORIT_PID=$! - trap "kill -INT -$WAITFORIT_PID" INT - wait $WAITFORIT_PID - WAITFORIT_RESULT=$? - if [[ $WAITFORIT_RESULT -ne 0 ]]; then - echoerr "$WAITFORIT_cmdname: timeout occurred after waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT" - fi - return $WAITFORIT_RESULT -} - -# process arguments -while [[ $# -gt 0 ]] -do - case "$1" in - *:* ) - WAITFORIT_hostport=(${1//:/ }) - WAITFORIT_HOST=${WAITFORIT_hostport[0]} - WAITFORIT_PORT=${WAITFORIT_hostport[1]} - shift 1 - ;; - --child) - WAITFORIT_CHILD=1 - shift 1 - ;; - -q | --quiet) - WAITFORIT_QUIET=1 - shift 1 - ;; - -s | --strict) - WAITFORIT_STRICT=1 - shift 1 - ;; - -h) - WAITFORIT_HOST="$2" - if [[ $WAITFORIT_HOST == "" ]]; then break; fi - shift 2 - ;; - --host=*) - WAITFORIT_HOST="${1#*=}" - shift 1 - ;; - -p) - WAITFORIT_PORT="$2" - if [[ $WAITFORIT_PORT == "" ]]; then break; fi - shift 2 - ;; - --port=*) - WAITFORIT_PORT="${1#*=}" - shift 1 - ;; - -t) - WAITFORIT_TIMEOUT="$2" - if [[ $WAITFORIT_TIMEOUT == "" ]]; then break; fi - shift 2 - ;; - --timeout=*) - WAITFORIT_TIMEOUT="${1#*=}" - shift 1 - ;; - --) - shift - WAITFORIT_CLI=("$@") - break - ;; - --help) - usage - ;; - *) - echoerr "Unknown argument: $1" - usage - ;; - esac -done - -if [[ "$WAITFORIT_HOST" == "" || "$WAITFORIT_PORT" == "" ]]; then - echoerr "Error: you need to provide a host and port to test." - usage -fi - -WAITFORIT_TIMEOUT=${WAITFORIT_TIMEOUT:-15} -WAITFORIT_STRICT=${WAITFORIT_STRICT:-0} -WAITFORIT_CHILD=${WAITFORIT_CHILD:-0} -WAITFORIT_QUIET=${WAITFORIT_QUIET:-0} - -# Check to see if timeout is from busybox? -WAITFORIT_TIMEOUT_PATH=$(type -p timeout) -WAITFORIT_TIMEOUT_PATH=$(realpath $WAITFORIT_TIMEOUT_PATH 2>/dev/null || readlink -f $WAITFORIT_TIMEOUT_PATH) - -WAITFORIT_BUSYTIMEFLAG="" -if [[ $WAITFORIT_TIMEOUT_PATH =~ "busybox" ]]; then - WAITFORIT_ISBUSY=1 - # Check if busybox timeout uses -t flag - # (recent Alpine versions don't support -t anymore) - if timeout &>/dev/stdout | grep -q -e '-t '; then - WAITFORIT_BUSYTIMEFLAG="-t" - fi -else - WAITFORIT_ISBUSY=0 -fi - -if [[ $WAITFORIT_CHILD -gt 0 ]]; then - wait_for - WAITFORIT_RESULT=$? - exit $WAITFORIT_RESULT -else - if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then - wait_for_wrapper - WAITFORIT_RESULT=$? - else - wait_for - WAITFORIT_RESULT=$? - fi -fi - -if [[ $WAITFORIT_CLI != "" ]]; then - if [[ $WAITFORIT_RESULT -ne 0 && $WAITFORIT_STRICT -eq 1 ]]; then - echoerr "$WAITFORIT_cmdname: strict mode, refusing to execute subprocess" - exit $WAITFORIT_RESULT - fi - exec "${WAITFORIT_CLI[@]}" -else - exit $WAITFORIT_RESULT -fi \ No newline at end of file