From adc7b9b71a27372717c441049dfbc64211ba9ff6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Wikle=20DUBARD?= <loic97429@gmail.com> Date: Sat, 23 Nov 2019 15:52:36 +0100 Subject: [PATCH] login+register page done --- __pycache__/forms.cpython-37.pyc | Bin 0 -> 1133 bytes app.py | 62 +++++++++++++++++++++++-- forms.py | 26 +++++++++++ requirements.txt | 4 +- templates/layout.html | 21 ++++++--- templates/login.html | 56 +++++++++++++++++++++++ templates/register.html | 75 +++++++++++++++++++++++++++++++ 7 files changed, 234 insertions(+), 10 deletions(-) create mode 100644 __pycache__/forms.cpython-37.pyc create mode 100644 forms.py create mode 100644 templates/login.html create mode 100644 templates/register.html diff --git a/__pycache__/forms.cpython-37.pyc b/__pycache__/forms.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e5766b1011bb1053214f523730cde9a5988bf640 GIT binary patch literal 1133 zcmZuwOLNmO5SILYrG)Y-aOu^DHW!Wz)9H(W>6A{=UNplPH&Rj$mYvEDg<Qk6zk(A# z312z&FK}X4c3K#aN1J^~yZXM(Zm$;*Sc~|_`)?*8Khan%3zQw$)dvuqaGDcI8KtNj zxgkwvN{d<2X0~*gqy1*?N{@NcXTA(rAVU^X@|tjq+g}N{1znmf0^8v(*sivF+#8YD zzkw<wrj37?r`5;9QpwnA!cncVVtSZ~oHxCbw5qO3#alBR&Cg|4w??#Embpj^ZNb54 zKdsZDxSVH7@Wwe3#k9U?>;su*dE*{j&eQy~9AnAVazWXFU0r|>gi%hIAxut%wIssk z1~<8NZA=YrUmMJUh@&I!l5{>#`0ymio>H9?fbHp=ko!y8WksULgC%8aJcMUQO@An+ zSyijF&dLIx&AhWps3Mi(#(-9C9)gIC#*|qBBK-^)1)tJ9<7r*0O8F3OycINy{$5#3 zG9@=xp2nMXur1tCHZ3;KX2<cp#!C_`kt9u!B(mi59Q7zk5SlikU?PY@T$HDa%)7qY znzleN6^@BoM}ecn`s22KvZ|_VJnK}NtnWlU#Z(l(UJO)O)`R_WJeQ)VtHH_e-P?n` z)6rm@XYw3)-x`<c_+l%a%?1-drrMr;Q6U_~b}FptQHwr?-G|SBZ{5)Gzlgn^;~hBg zFR_|FLsRN<v!f4fq|*YT0ugc>ek1MxVQ%9emD5Z!rE!R<>chqAJ_zOwg%t8!sD%Sr zn{SHaxThXq7+F-0P~4%4)Tt*Z?m%?FWS;7-(cq~KOu5Ca)t;g6IS9P7Lg*0-#KEK5 ze;ltde}ey|<f@)193|$0hB&r8=%UDu(nZ(1;PxNGbxXc}s%BUNtSkJlrN(>N4$~`& OeIZeiv0-eO{oZf8jt2e! literal 0 HcmV?d00001 diff --git a/app.py b/app.py index 29a2ca2..08d3510 100755 --- a/app.py +++ b/app.py @@ -1,17 +1,38 @@ #!/usr/bin/python3 -from flask import Flask, render_template, url_for +from flask import Flask, render_template, url_for, flash, redirect +from flask_sqlalchemy import SQLAlchemy import requests +from forms import RegistrationForm, LoginForm import asyncio from bs4 import BeautifulSoup as bs4 app_name = "Climbing Coach" app = Flask(app_name) +app.config['SECRET_KEY'] = '6009555f5e50514b882adf5c6a42ea7b' +app.config['SQLALCHEMY_DATABASE_URI'] = "sqlite:///site.db" +db = SQLAlchemy(app) + + +class User(db.Model): + id = db.Column(db.Integer, primary_key=True) + username = db.Column(db.String(20), unique=True, nullable=False) + email = db.Column(db.String(120), unique=True, nullable=False) + image_file = db.Column(db.String(20), nullable=False, default='default.jpg') + password = db.Column(db.String(60), nullable=False) + posts = db.relationship('Post', backref='author', lazy=True) + + def __repr__(self): + return f"User('{self.username}', '{self.email}', '{self.image_file}')" def get_news(): - r = requests.get("https://www.8a.nu/rss/Main.aspx?CountryCode=GLOBAL").content + """ Parse le flux rss de 8a.nu """ + r = requests.get( + "https://www.8a.nu/rss/Main.aspx?CountryCode=GLOBAL").content soup = bs4(r, "html.parser") - news = [{"title": e.title.text, "description": e.description.text, "date_posted": e.pubdate.text} for e in soup.find_all("item")] + news = [{"title": e.title.text, "description": e.description.text, + "date_posted": e.pubdate.text.replace(" 00:00:00 GMT", "") + } for e in soup.find_all("item")] # print(news) return news @@ -28,6 +49,41 @@ def about(): return render_template("about.html", title=app_name + " - About") +@app.route("/register", methods=['GET', 'POST']) +def register(): + form = RegistrationForm() + if form.validate_on_submit(): + flash(f"Account created for { form.email.data } !", "success") + return redirect(url_for('home')) + return render_template('register.html', + title=app_name + " - Register", form=form) + + +@app.route("/login", methods=['GET', 'POST']) +def login(): + form = LoginForm() + + if form.validate_on_submit(): + if form.email.data == "test@test.com" and form.password.data == "test": + # TODO: replace fake test login with database login + flash(f"You have been logged in !", "success") + return redirect(url_for('home')) + else: + flash(f"Login Unsuccessful. Please check username and password", "danger") + return render_template('login.html', + title=app_name + " - Login", form=form) + + +@app.route("/planning") +def planning(): + return "TODO" + + +@app.route("/meteo") +def meteo(): + return "TODO" + + if __name__ == '__main__': # get_news() app.run(debug=True) diff --git a/forms.py b/forms.py new file mode 100644 index 0000000..2dd6a69 --- /dev/null +++ b/forms.py @@ -0,0 +1,26 @@ +from flask_wtf import FlaskForm + +from wtforms import StringField, PasswordField, SubmitField, BooleanField + +from wtforms.validators import DataRequired, Length, Email, EqualTo + + +class RegistrationForm(FlaskForm): + username = StringField('Username', + validators=[DataRequired(), Length(min=2, max=20)]) + email = StringField('Email', + validators=[DataRequired(), Email()]) + password = PasswordField('Password', validators=[DataRequired()]) + confirm_password = PasswordField( + 'Confirm Password', + validators=[DataRequired(), EqualTo('password')] + ) + submit = SubmitField('Sign Up') + + +class LoginForm(FlaskForm): + email = StringField('Email', + validators=[DataRequired(), Email()]) + password = PasswordField('Password', validators=[DataRequired()]) + remember = BooleanField('Remember') + submit = SubmitField('Log In') diff --git a/requirements.txt b/requirements.txt index dd195e9..895e049 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,4 +3,6 @@ flask requests fpdf asyncio -beautifulsoup4 \ No newline at end of file +beautifulsoup4 +flask-wtf +flask-sqlalchemy \ No newline at end of file diff --git a/templates/layout.html b/templates/layout.html index 163f2c3..7178d53 100644 --- a/templates/layout.html +++ b/templates/layout.html @@ -22,15 +22,15 @@ </button> <div class="collapse navbar-collapse" id="navbarToggle"> <div class="navbar-nav mr-auto"> - <a class="nav-item nav-link" href="/">Home</a> - <a class="nav-item nav-link" href="/planning">Planning</a> - <a class="nav-item nav-link" href="/meteo">Check the Weather</a> - <a class="nav-item nav-link" href="/about">About</a> + <a class="nav-item nav-link" href="{{ url_for('home') }}">Home</a> + <a class="nav-item nav-link" href="{{ url_for('planning') }}">Planning</a> + <a class="nav-item nav-link" href="{{ url_for('meteo') }}">Check the Weather</a> + <a class="nav-item nav-link" href="{{ url_for('about') }}">About</a> </div> <!-- Navbar Right Side --> <div class="navbar-nav"> - <a class="nav-item nav-link" href="/login">Login</a> - <a class="nav-item nav-link" href="/register">Register</a> + <a class="nav-item nav-link" href="{{ url_for('login') }}">Login</a> + <a class="nav-item nav-link" href="{{ url_for('register') }}">Register</a> </div> </div> </div> @@ -40,6 +40,15 @@ <main role="main" class="container"> <div class="row"> <div class="col-md-8"> + {% with messages = get_flashed_messages(with_categories=true) %} + {% if messages %} + {% for category, message in messages %} + <div class="alert alert-{{ category }}"> + {{ message }} + </div> + {% endfor %} + {% endif %} + {% endwith %} {% block content %}{% endblock %} </div> <div class="col-md-8"> diff --git a/templates/login.html b/templates/login.html new file mode 100644 index 0000000..c6db788 --- /dev/null +++ b/templates/login.html @@ -0,0 +1,56 @@ +{% extends "layout.html" %} +{% block content %} + <div class="content-section"> + <form method="POST" action=""> + {{ form.hidden_tag() }} + <fieldset class="form-group"> + <legend class="border-bottom mb-4">Join Today</legend> + + <div class="form-group"> + {{ form.email.label(class="form-control-label") }} + + {% if form.email.errors %} + {{ form.email(class="form-control form-control-lg is-invalid") }} + <div class="invalid-feedback"> + {% for error in form.email.errors %} + <span>{{ error }} </span> + {% endfor %} + </div> + {% endif %} + + {{ form.email(class="form-control form-control-lg") }} + </div> + <div class="form-group"> + {{ form.password.label(class="form-control-label") }} + + {% if form.password.errors %} + {{ form.password(class="form-control form-control-lg is-invalid") }} + <div class="invalid-feedback"> + {% for error in form.password.errors %} + <span>{{ error }} </span> + {% endfor %} + </div> + {% endif %} + + {{ form.password(class="form-control form-control-lg") }} + </div> + + <div class="form-check"> + {{ form.remember(class="form-check-input") }} + {{ form.remember.label(class="form-check-label") }} + </div> + </fieldset> + <div class="form-group"> + {{ form.submit(class="btn btn-outline-info ") }} + </div> + <small class="text-muted ml-2"> + <a href="#">Forgot Password ?</a> + </small> + </form> + </div> + <div class="border-top pt-3"> + <small class="text-muted"> + Need an account ? <a class="ml-2" href="{{ url_for('register') }}">Sign Up Now</a> + </small> + </div> +{% endblock content %} \ No newline at end of file diff --git a/templates/register.html b/templates/register.html new file mode 100644 index 0000000..564ed6d --- /dev/null +++ b/templates/register.html @@ -0,0 +1,75 @@ +{% extends "layout.html" %} +{% block content %} + <div class="content-section"> + <form method="POST" action=""> + {{ form.hidden_tag() }} + <fieldset class="form-group"> + <legend class="border-bottom mb-4">Join Today</legend> + <div class="form-group"> + {{ form.username.label(class="form-control-label") }} + + {% if form.username.errors %} + {{ form.username(class="form-control form-control-lg is-invalid") }} + <div class="invalid-feedback"> + {% for error in form.username.errors %} + <span>{{ error }} </span> + {% endfor %} + </div> + {% endif %} + + {{ form.username(class="form-control form-control-lg") }} + </div> + <div class="form-group"> + {{ form.email.label(class="form-control-label") }} + + {% if form.email.errors %} + {{ form.email(class="form-control form-control-lg is-invalid") }} + <div class="invalid-feedback"> + {% for error in form.email.errors %} + <span>{{ error }} </span> + {% endfor %} + </div> + {% endif %} + + {{ form.email(class="form-control form-control-lg") }} + </div> + <div class="form-group"> + {{ form.password.label(class="form-control-label") }} + + {% if form.password.errors %} + {{ form.password(class="form-control form-control-lg is-invalid") }} + <div class="invalid-feedback"> + {% for error in form.password.errors %} + <span>{{ error }} </span> + {% endfor %} + </div> + {% endif %} + + {{ form.password(class="form-control form-control-lg") }} + </div> + <div class="form-group"> + {{ form.confirm_password.label(class="form-control-label") }} + + {% if form.confirm_password.errors %} + {{ form.confirm_password(class="form-control form-control-lg is-invalid") }} + <div class="invalid-feedback"> + {% for error in form.confirm_password.errors %} + <span>{{ error }} </span> + {% endfor %} + </div> + {% endif %} + + {{ form.confirm_password(class="form-control form-control-lg") }} + </div> + </fieldset> + <div class="form-group"> + {{ form.submit(class="btn btn-outline-info ") }} + </div> + </form> + </div> + <div class="border-top pt-3"> + <small class="text-muted"> + Already have an account ? <a class="ml-2" href="{{ url_for('login') }}">Log In</a> + </small> + </div> +{% endblock content %} \ No newline at end of file -- GitLab