Compare commits

...

12 Commits
main ... dev

Binary file not shown.

@ -1,10 +1,18 @@
from flask import Flask
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.config['SECRET_KEY'] = 'db3746b2ffa650b3804e4316d227f853'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///blogsite.db'
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.file import FileField, FileAllowed
from flask_login import current_user #type: ignore
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):
username = StringField('Username',
validators=[DataRequired(), Length(min=2, max=20)])
validators=[DataRequired(), Length(min=4, max=20)])
email = StringField('Email',
validators=[DataRequired(), Email()])
@ -14,6 +17,15 @@ class RegistrationForm(FlaskForm):
validators=[DataRequired(), EqualTo('password')])
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):
email = StringField('Email',
@ -21,4 +33,25 @@ class LoginForm(FlaskForm):
password = PasswordField('Password' , validators=[DataRequired()])
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 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)
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')
default='default.svg')
password = db.Column(db.String(60), nullable=False)
posts = db.relationship('Post', backref='author', lazy=True)

@ -1,27 +1,25 @@
from flask import render_template, url_for, flash, redirect
from blogapp import app
from blogapp.forms import RegistrationForm, LoginForm
import os
import secrets
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 flask_login import login_user, current_user, logout_user, login_required # type: ignore
posts = [
{
'pagetitle': 'home page'
}
]
navbaritems = [
pagetitle = [
{
'name': 'home',
'url': 'home'
'title': 'home'
},
{
'name': 'login',
'url': 'login'
'title': 'login'
},
{
'name': 'register',
'url': 'register'
'title': 'register'
},
{
'title': 'account'
}
]
@ -29,30 +27,74 @@ navbaritems = [
@app.route("/")
@app.route("/home")
def home():
return render_template('home.html', posts=posts, navbaritems=navbaritems)
@app.route("/about")
def about():
return render_template('about.html', title='About', posts=posts, navbaritems=navbaritems)
return render_template('home.html', title='home', pagetitle=pagetitle)
@app.route("/register", methods=['GET', 'POST'])
def register():
if current_user.is_authenticated:
return redirect(url_for('home'))
form = RegistrationForm()
if form.validate_on_submit():
flash(f'Account created for {form.username.data}!')
return redirect(url_for('home'))
return render_template('register.html', title='Register', form=form)
hashed_password = bcrypt.generate_password_hash(
form.password.data).decode('utf-8')
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'])
def login():
if current_user.is_authenticated:
return redirect(url_for('home'))
form = LoginForm()
if form.validate_on_submit():
if form.email.data == 'admin' and form.password.data == 'admin':
flash('You have been log in !')
return redirect(url_for('home'))
user = User.query.filter_by(email=form.email.data).first()
if user and bcrypt.check_password_hash(user.password, form.password.data):
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:
flash('Login Unsuccessful')
return render_template('login.html', title='Login', form=form)
flash('Login Unsuccessful. Please check email and password')
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" %}
{% block content %}
{% for post in posts %}
<h1>{{ post.pagetitle }}</h1>
{% endfor %}
{% endblock content %}

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

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

@ -1,72 +1,71 @@
{% extends "layout.html" %}
{% block content %}
<div>
<form method="POST" action="">
{{ form.hidden_tag() }}
<br>
<fieldset>
<legend>Join Today</legend>
<div>
{{ form.username.label() }}
{% if form.username.errors %}
{{ form.username()}}
<div>
{% for errors in form.username.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.username() }}
{% endif %}
{% 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>
{% for errors in form.email.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.email() }}
{% endif %}
{% 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.password.label() }}
{% if form.password.errors %}
{{ form.password()}}
<div>
{% for errors in form.password.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.password() }}
{% endif %}
{% if form.password.errors %}
{{ form.password() }}
<div class="invalid">
{% for error in form.password.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.password(class="form-control") }}
{% endif %}
</div>
<br>
<div>
{{ form.confirm_password.label() }}
{% if form.confirm_password.errors %}
{{ form.confirm_password()}}
<div>
{% for errors in form.confirm_password.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.confirm_password() }}
{% endif %}
{% if form.confirm_password.errors %}
{{ form.confirm_password()}}
<div class="invalid">
{% for error in form.confirm_password.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.confirm_password() }}
{% endif %}
</div>
</fieldset>
<div>

Binary file not shown.

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

Binary file not shown.

Binary file not shown.
Loading…
Cancel
Save