Inital commit
This commit is contained in:
commit
6a52b0cba5
|
@ -0,0 +1,3 @@
|
||||||
|
venv
|
||||||
|
config.py
|
||||||
|
__pycache__
|
|
@ -0,0 +1,43 @@
|
||||||
|
# BirdQuizz
|
||||||
|
|
||||||
|
Identify Bird Song !
|
||||||
|
|
||||||
|
|
||||||
|
# Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://forge.chapril.org/UncleSamulus/BirdQuizz.git
|
||||||
|
cd BirdQuizz
|
||||||
|
python3 -m venv
|
||||||
|
. venv/bin/activate
|
||||||
|
pip install -r requirements.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
## Database configuration
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo mysql
|
||||||
|
```
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE DATABASE birdquizz;
|
||||||
|
GRANT ALL ON birdquizz.* TO birdquizz@localhost IDENTIFIED BY 'secret';
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cp config.py.example config.py
|
||||||
|
```
|
||||||
|
|
||||||
|
## Database migration
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python3
|
||||||
|
```
|
||||||
|
|
||||||
|
```python3
|
||||||
|
from app import *
|
||||||
|
app.app_context().push()
|
||||||
|
db.create_all()
|
||||||
|
```
|
|
@ -0,0 +1,68 @@
|
||||||
|
from flask import Flask
|
||||||
|
from flask import render_template
|
||||||
|
from flask import session
|
||||||
|
from flask import request
|
||||||
|
from flask import redirect
|
||||||
|
from flask import url_for
|
||||||
|
|
||||||
|
from werkzeug.security import generate_password_hash, check_password_hash
|
||||||
|
|
||||||
|
from config import secret_key, database_uri
|
||||||
|
from model import db, User
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
app.secret_key = secret_key
|
||||||
|
|
||||||
|
app.config['SQLALCHEMY_DATABASE_URI'] = database_uri
|
||||||
|
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
|
||||||
|
|
||||||
|
db.init_app(app)
|
||||||
|
|
||||||
|
@app.route("/")
|
||||||
|
def home():
|
||||||
|
if 'username' in session:
|
||||||
|
return render_template("index.html", username=session["username"])
|
||||||
|
else:
|
||||||
|
return render_template("index.html")
|
||||||
|
|
||||||
|
@app.route("/signup", methods=["GET", "POST"])
|
||||||
|
def signup():
|
||||||
|
if request.method == "POST":
|
||||||
|
username = request.form['username']
|
||||||
|
email = request.form['email']
|
||||||
|
password = request.form['password']
|
||||||
|
registered_user = User.query.filter_by(username=username).first()
|
||||||
|
if registered_user is None:
|
||||||
|
password_hash = generate_password_hash(password)
|
||||||
|
registered_user = User(username=username, email=email, password=password_hash)
|
||||||
|
db.session.add(registered_user)
|
||||||
|
db.session.commit()
|
||||||
|
else:
|
||||||
|
return render_template("auth/signup.html", message="Username already used. Try with an other.")
|
||||||
|
return redirect(url_for("login"))
|
||||||
|
elif request.method == "GET":
|
||||||
|
return render_template("auth/signup.html")
|
||||||
|
|
||||||
|
@app.route("/login", methods=["GET", "POST"])
|
||||||
|
def login():
|
||||||
|
if request.method == "POST":
|
||||||
|
username = request.form['username']
|
||||||
|
password = request.form['password']
|
||||||
|
user = User.query.filter_by(username=username).first()
|
||||||
|
if user is None:
|
||||||
|
return render_template("auth/login.html", message="No user with this username already registered")
|
||||||
|
else:
|
||||||
|
password_hash = user.password
|
||||||
|
if check_password_hash(password_hash, password):
|
||||||
|
session["username"] = username
|
||||||
|
return redirect(url_for("home"))
|
||||||
|
else:
|
||||||
|
return render_template("auth/login.html", message="Password incorrect. Try again")
|
||||||
|
if request.method == "GET":
|
||||||
|
return render_template("auth/login.html")
|
||||||
|
|
||||||
|
@app.route("/logout")
|
||||||
|
def logout():
|
||||||
|
# Remove username from the session if it's there
|
||||||
|
session.pop("username", None)
|
||||||
|
return redirect(url_for("home"))
|
|
@ -0,0 +1,7 @@
|
||||||
|
secret_key = b'secret'
|
||||||
|
|
||||||
|
db_user = "birdquizz"
|
||||||
|
db_pass = "secret" # change this
|
||||||
|
db_name = "birdquizz"
|
||||||
|
|
||||||
|
database_uri = f"mysql+mysqlconnector://{db_user}:{db_pass}@localhost/{db_name}"
|
|
@ -0,0 +1,11 @@
|
||||||
|
from flask_sqlalchemy import SQLAlchemy
|
||||||
|
|
||||||
|
db = SQLAlchemy()
|
||||||
|
|
||||||
|
class User(db.Model):
|
||||||
|
__tablename__ = 'user'
|
||||||
|
|
||||||
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
|
username = db.Column(db.String(64), unique=True)
|
||||||
|
email = db.Column(db.String(64), unique=True, index=True)
|
||||||
|
password = db.Column(db.String(128))
|
|
@ -0,0 +1,12 @@
|
||||||
|
click==8.1.3
|
||||||
|
Flask==2.1.2
|
||||||
|
Flask-SQLAlchemy==2.5.1
|
||||||
|
greenlet==1.1.2
|
||||||
|
itsdangerous==2.1.2
|
||||||
|
Jinja2==3.1.2
|
||||||
|
MarkupSafe==2.1.1
|
||||||
|
mysql-connector-python==8.0.29
|
||||||
|
protobuf==3.20.1
|
||||||
|
PyMySQL==1.0.2
|
||||||
|
SQLAlchemy==1.4.36
|
||||||
|
Werkzeug==2.1.2
|
|
@ -0,0 +1,4 @@
|
||||||
|
body {
|
||||||
|
background-color: black;
|
||||||
|
color: white;
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
{% if message is defined %}
|
||||||
|
<p class="message">
|
||||||
|
{{ message }}
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<form action="/login" method="POST">
|
||||||
|
<label for="username">Username</label>
|
||||||
|
<input type="text" name="username" id="username">
|
||||||
|
<label for="password">Password</label>
|
||||||
|
<input type="password" name="password" id="password">
|
||||||
|
<input type="submit" value="Login">
|
||||||
|
</form>
|
||||||
|
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,21 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
{% if message is defined %}
|
||||||
|
<p class="message">
|
||||||
|
{{ message }}
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<form action="/signup" method="POST">
|
||||||
|
<label for="username">Username</label>
|
||||||
|
<input type="text" name="username" id="username">
|
||||||
|
<label for="email">Email</label>
|
||||||
|
<input type="email" name="email" id="email">
|
||||||
|
<label for="password">Password</label>
|
||||||
|
<input type="password" name="password" id="password">
|
||||||
|
<input type="submit" value="Sign up">
|
||||||
|
</form>
|
||||||
|
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,24 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>{% block title %}BirdQuizz{% endblock %}</title>
|
||||||
|
<link rel="stylesheet" href="{{ url_for('static', filename='styles/style.css') }}">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<header>
|
||||||
|
<h1>BirdQuizz</h1>
|
||||||
|
{% if username is defined %}
|
||||||
|
<p>Welcome <span class="username">{{ username }}</span></p>
|
||||||
|
{% endif %}
|
||||||
|
</header>
|
||||||
|
<main>
|
||||||
|
{% block content %}{% endblock %}
|
||||||
|
</main>
|
||||||
|
<footer>
|
||||||
|
© 2022 - Samuel ORTION
|
||||||
|
</footer>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,5 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
Welcome to BirdQuizz !
|
||||||
|
{% endblock %}
|
Loading…
Reference in New Issue