Compare commits

..

12 Commits
main ... dev

Binary file not shown.

@ -1,10 +1,18 @@
from flask import Flask from flask import Flask
from flask_sqlalchemy import SQLAlchemy # type: ignore from flask_sqlalchemy import SQLAlchemy # type: ignore
from flask_bcrypt import Bcrypt # type: ignore
from flask_login import LoginManager # type: ignore
app = Flask(__name__) app = Flask(__name__)
app.config['SECRET_KEY'] = 'db3746b2ffa650b3804e4316d227f853' app.config['SECRET_KEY'] = 'db3746b2ffa650b3804e4316d227f853'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///blogsite.db' app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///blogsite.db'
db = SQLAlchemy(app) db = SQLAlchemy(app)
bcrypt = Bcrypt(app)
login_manager = LoginManager(app)
login_manager.login_view = 'login'
from blogapp import routes from blogapp import routes

@ -1,11 +1,14 @@
from flask_wtf import FlaskForm from flask_wtf import FlaskForm
from flask_wtf.file import FileField, FileAllowed
from flask_login import current_user #type: ignore
from wtforms import StringField, PasswordField, SubmitField, BooleanField from wtforms import StringField, PasswordField, SubmitField, BooleanField
from wtforms.validators import DataRequired, Length, Email, EqualTo from wtforms.validators import DataRequired, Length, Email, EqualTo, ValidationError
from blogapp.models import User
class RegistrationForm(FlaskForm): class RegistrationForm(FlaskForm):
username = StringField('Username', username = StringField('Username',
validators=[DataRequired(), Length(min=2, max=20)]) validators=[DataRequired(), Length(min=4, max=20)])
email = StringField('Email', email = StringField('Email',
validators=[DataRequired(), Email()]) validators=[DataRequired(), Email()])
@ -14,6 +17,15 @@ class RegistrationForm(FlaskForm):
validators=[DataRequired(), EqualTo('password')]) validators=[DataRequired(), EqualTo('password')])
submit =SubmitField('Sign Up') submit =SubmitField('Sign Up')
def validate_username(self, username):
user = User.query.filter_by(username=username.data).first()
if user:
raise ValidationError('That username is taken. Please choose a different one')
def validate_email(self, email):
user = User.query.filter_by(email=email.data).first()
if user:
raise ValidationError('That email is taken. Please choose a different one')
class LoginForm(FlaskForm): class LoginForm(FlaskForm):
email = StringField('Email', email = StringField('Email',
@ -22,3 +34,24 @@ class LoginForm(FlaskForm):
password = PasswordField('Password' , validators=[DataRequired()]) password = PasswordField('Password' , validators=[DataRequired()])
remember = BooleanField('Remember Me') remember = BooleanField('Remember Me')
submit =SubmitField('Login') submit =SubmitField('Login')
class UpdateAccountForm(FlaskForm):
username = StringField('Username',
validators=[DataRequired(), Length(min=4, max=20)])
email = StringField('Email',
validators=[DataRequired(), Email()])
picture = FileField('Update Profile Picture', validators=[FileAllowed(['jpg','png','jpeg'])])
submit =SubmitField('Update')
def validate_username(self, username):
if username.data != current_user.username:
user = User.query.filter_by(username=username.data).first()
if user:
raise ValidationError('That username is taken. Please choose a different one')
def validate_email(self, email):
if email.data != current_user.email:
user = User.query.filter_by(email=email.data).first()
if user:
raise ValidationError('That email is taken. Please choose a different one')

@ -1,13 +1,17 @@
from datetime import datetime from datetime import datetime
from blogapp import db from blogapp import db, login_manager
from flask_login import UserMixin # type: ignore
@login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))
class User(db.Model): class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(20), unique=True, nullable=False) username = db.Column(db.String(20), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False) email = db.Column(db.String(120), unique=True, nullable=False)
image_file = db.Column(db.String(20), nullable=False, image_file = db.Column(db.String(20), nullable=False,
default='default.jpg') default='default.svg')
password = db.Column(db.String(60), nullable=False) password = db.Column(db.String(60), nullable=False)
posts = db.relationship('Post', backref='author', lazy=True) posts = db.relationship('Post', backref='author', lazy=True)

@ -1,27 +1,25 @@
from flask import render_template, url_for, flash, redirect import os
from blogapp import app import secrets
from blogapp.forms import RegistrationForm, LoginForm from PIL import Image #type: ignore
from flask import render_template, url_for, flash, redirect, request
from blogapp import app, db, bcrypt
from blogapp.forms import RegistrationForm, LoginForm, UpdateAccountForm
from blogapp.models import User, Post from blogapp.models import User, Post
from flask_login import login_user, current_user, logout_user, login_required # type: ignore
posts = [ pagetitle = [
{
'pagetitle': 'home page'
}
]
navbaritems = [
{ {
'name': 'home', 'title': 'home'
'url': 'home'
}, },
{ {
'name': 'login', 'title': 'login'
'url': 'login'
}, },
{ {
'name': 'register', 'title': 'register'
'url': 'register' },
{
'title': 'account'
} }
] ]
@ -29,30 +27,74 @@ navbaritems = [
@app.route("/") @app.route("/")
@app.route("/home") @app.route("/home")
def home(): def home():
return render_template('home.html', posts=posts, navbaritems=navbaritems) return render_template('home.html', title='home', pagetitle=pagetitle)
@app.route("/about")
def about():
return render_template('about.html', title='About', posts=posts, navbaritems=navbaritems)
@app.route("/register", methods=['GET', 'POST']) @app.route("/register", methods=['GET', 'POST'])
def register(): def register():
if current_user.is_authenticated:
return redirect(url_for('home'))
form = RegistrationForm() form = RegistrationForm()
if form.validate_on_submit(): if form.validate_on_submit():
flash(f'Account created for {form.username.data}!') hashed_password = bcrypt.generate_password_hash(
return redirect(url_for('home')) form.password.data).decode('utf-8')
return render_template('register.html', title='Register', form=form) user = User(username=form.username.data,
email=form.email.data, password=hashed_password)
db.session.add(user)
db.session.commit()
flash(f'Your account has been created !!')
return redirect(url_for('login'))
return render_template('register.html', title='register', form=form, pagetitle=pagetitle)
@app.route("/login", methods=['GET', 'POST']) @app.route("/login", methods=['GET', 'POST'])
def login(): def login():
if current_user.is_authenticated:
return redirect(url_for('home'))
form = LoginForm() form = LoginForm()
if form.validate_on_submit(): if form.validate_on_submit():
if form.email.data == 'admin' and form.password.data == 'admin': user = User.query.filter_by(email=form.email.data).first()
flash('You have been log in !') if user and bcrypt.check_password_hash(user.password, form.password.data):
return redirect(url_for('home')) login_user(user, remember=form.remember.data)
next_page = request.args.get('next')
return redirect(next_page) if next_page else redirect(url_for('home'))
else: else:
flash('Login Unsuccessful') flash('Login Unsuccessful. Please check email and password')
return render_template('login.html', title='Login', form=form) return render_template('login.html', title='login', form=form, pagetitle=pagetitle)
@app.route("/logout")
def logout():
logout_user()
return redirect(url_for('home'))
def save_picture(form_picture):
random_hex = secrets.token_hex(8)
_, f_ext = os.path.splitext(form_picture.filename)
picture_fn = random_hex + f_ext
picture_path = os.path.join(app.root_path, 'static/profil_pics', picture_fn)
output_size = (125,125)
i = Image.open(form_picture)
i.thumbnail(output_size)
i.save(picture_path)
return picture_fn
@app.route("/account", methods=['GET', 'POST'])
@login_required
def account():
form = UpdateAccountForm()
if form.validate_on_submit():
if form.picture.data:
picture_file = save_picture(form.picture.data)
current_user.image_file = picture_file
current_user.username = form.username.data
current_user.email = form.email.data
db.session.commit()
flash('Your account has been updated')
return redirect(url_for('account'))
elif request.method == 'GET':
form.username.data = current_user.username
form.email.data = current_user.email
image_file = url_for('static', filename='profil_pics/' + current_user.image_file)
return render_template('account.html', title='account', pagetitle=pagetitle,
image_file=image_file, form=form)

@ -0,0 +1,9 @@
.invalid {
color:red;
}
.round-image{
width: 100px;
height:100px;
border-radius: 50%;
}

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M399 384.2C376.9 345.8 335.4 320 288 320l-64 0c-47.4 0-88.9 25.8-111 64.2c35.2 39.2 86.2 63.8 143 63.8s107.8-24.7 143-63.8zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zm256 16a72 72 0 1 0 0-144 72 72 0 1 0 0 144z"/></svg>

After

Width:  |  Height:  |  Size: 445 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

@ -1,10 +0,0 @@
{% extends "layout.html" %}
{% block content %}
{% for post in posts %}
<p> {{ post.universe }} </p>
<p> {{ post.powerlevel }} </p>
<i> {{ post.date_posted }} </i>
{% endfor %}
{% endblock content %}

@ -0,0 +1,60 @@
{% extends "layout.html" %}
{% block content %}
<img src="{{ image_file }}" class="round-image" alt="">
<h2> Welcome {{ current_user.username }} </h2>
<div>
<form method="POST" action="" enctype="multipart/form-data">
{{ form.hidden_tag() }}
<br>
<fieldset>
<legend>Account Info</legend>
<div>
{{ form.username.label() }}
{% if form.username.errors %}
{{ form.username()}}
<div class="invalid">
{% for error in form.username.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.username() }}
{% endif %}
</div>
<br>
<div>
{{ form.email.label() }}
{% if form.email.errors %}
{{ form.email() }}
<div class="invalid">
{% for error in form.email.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.email() }}
{% endif %}
</div>
<br>
<div>
{{ form.picture.label() }}
{{ form.picture() }}
{% if form.picture.errors %}
{% for error in form.picture.errors %}
<br><span class="invalid">{{ error }}</span><br>
{% endfor %}
{% endif %}
</div>
</fieldset>
<div>
{{ form.submit() }}
</div>
</form>
</div>
{% endblock content %}

@ -1,8 +1,6 @@
{% extends "layout.html" %} {% extends "layout.html" %}
{% block content %} {% block content %}
{% for post in posts %}
<h1>{{ post.pagetitle }}</h1>
{% endfor %}
{% endblock content %} {% endblock content %}

@ -13,28 +13,44 @@
<body> <body>
<header>
{% block navbar %} {% block navbar %}
{% for post in navbaritems %} <ul>
<li><a href="{{ post.url }}"> {{ post.name }} </a></li> <li><a href="{{ url_for('home') }}"> home </a></li>
{% endfor %} {% if current_user.is_authenticated %}
<li><a href="{{ url_for('account') }}"> account </a></li>
<li><a href="{{ url_for('logout') }}"> logout </a></li>
{% else %}
<li><a href="{{ url_for('login') }}"> login </a></li>
<li><a href="{{ url_for('register') }}">register</a></li>
{% endif %}
</ul>
{% endblock %} {% endblock %}
</header>
<main>
{% for head in pagetitle %}
{% if title == head.title %}
<h1>{{ head.title }}</h1>
{% endif %}
{% endfor %}
<div>
{% with messages = get_flashed_messages(with_categories=true) %} {% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %} {% if messages %}
{% for caterogy, message in messages %} {% for caterogy, message in messages %}
<div> <div class="alert alert-{{ category }}">
{{ message }} {{ message }}
</div> </div>
{% endfor %} {% endfor %}
{% endif %} {% endif %}
{% endwith %} {% endwith %}
<div>
{% block content %} {% block content %}
{% endblock %} {% endblock %}
</div> </div>
</main>
</body> </body>
</html> </html>

@ -5,14 +5,15 @@
<div> <div>
<form method="POST" action=""> <form method="POST" action="">
{{ form.hidden_tag() }} {{ form.hidden_tag() }}
<br>
<fieldset> <fieldset>
<legend>Login</legend> <legend>Login</legend>
<div> <div>
{{ form.email.label() }} {{ form.email.label() }}
{% if form.email.errors %} {% if form.email.errors %}
{{ form.email() }} {{ form.email() }}
<div> <div class="invalid">
{% for errors in form.email.errors %} {% for error in form.email.errors %}
<span>{{ error }}</span> <span>{{ error }}</span>
{% endfor %} {% endfor %}
</div> </div>
@ -27,8 +28,8 @@
{{ form.password.label() }} {{ form.password.label() }}
{% if form.password.errors %} {% if form.password.errors %}
{{ form.password()}} {{ form.password()}}
<div> <div class="invalid">
{% for errors in form.password.errors %} {% for error in form.password.errors %}
<span>{{ error }}</span> <span>{{ error }}</span>
{% endfor %} {% endfor %}
</div> </div>

@ -1,20 +1,19 @@
{% extends "layout.html" %} {% extends "layout.html" %}
{% block content %} {% block content %}
<div> <div>
<form method="POST" action=""> <form method="POST" action="">
{{ form.hidden_tag() }} {{ form.hidden_tag() }}
<br>
<fieldset> <fieldset>
<legend>Join Today</legend> <legend>Join Today</legend>
<div> <div>
{{ form.username.label() }} {{ form.username.label() }}
{% if form.username.errors %} {% if form.username.errors %}
{{ form.username()}} {{ form.username()}}
<div> <div class="invalid">
{% for errors in form.username.errors %} {% for error in form.username.errors %}
<span>{{ error }}</span> <span>{{ error }}</span>
{% endfor %} {% endfor %}
</div> </div>
@ -27,8 +26,8 @@
{{ form.email.label() }} {{ form.email.label() }}
{% if form.email.errors %} {% if form.email.errors %}
{{ form.email() }} {{ form.email() }}
<div> <div class="invalid">
{% for errors in form.email.errors %} {% for error in form.email.errors %}
<span>{{ error }}</span> <span>{{ error }}</span>
{% endfor %} {% endfor %}
</div> </div>
@ -43,13 +42,13 @@
{{ form.password.label() }} {{ form.password.label() }}
{% if form.password.errors %} {% if form.password.errors %}
{{ form.password() }} {{ form.password() }}
<div> <div class="invalid">
{% for errors in form.password.errors %} {% for error in form.password.errors %}
<span>{{ error }}</span> <span>{{ error }}</span>
{% endfor %} {% endfor %}
</div> </div>
{% else %} {% else %}
{{ form.password() }} {{ form.password(class="form-control") }}
{% endif %} {% endif %}
</div> </div>
@ -59,8 +58,8 @@
{{ form.confirm_password.label() }} {{ form.confirm_password.label() }}
{% if form.confirm_password.errors %} {% if form.confirm_password.errors %}
{{ form.confirm_password()}} {{ form.confirm_password()}}
<div> <div class="invalid">
{% for errors in form.confirm_password.errors %} {% for error in form.confirm_password.errors %}
<span>{{ error }}</span> <span>{{ error }}</span>
{% endfor %} {% endfor %}
</div> </div>

Binary file not shown.

@ -2,4 +2,4 @@
from blogapp import app from blogapp import app
if __name__ == '__main__': if __name__ == '__main__':
app.run(debug=True, host="0.0.0.0", port=8700) app.run(debug=True, port=8700)

Loading…
Cancel
Save