From 0f0f1484189e77b73c5d311970f5b776ead21aef Mon Sep 17 00:00:00 2001 From: key Date: Wed, 2 Aug 2023 18:13:01 +0200 Subject: [PATCH] Implemented bluorints for flask --- webinterface/minibase/__init__.py | 49 +++-- .../__pycache__/__init__.cpython-311.pyc | Bin 1358 -> 1850 bytes .../__pycache__/config.cpython-311.pyc | Bin 0 -> 1066 bytes .../__pycache__/forms.cpython-311.pyc | Bin 6719 -> 0 bytes .../__pycache__/models.cpython-311.pyc | Bin 3997 -> 4060 bytes .../__pycache__/route.cpython-311.pyc | Bin 14619 -> 0 bytes webinterface/minibase/config.py | 16 ++ webinterface/minibase/main/__init.py__ | 0 .../main/__pycache__/routes.cpython-311.pyc | Bin 0 -> 1464 bytes webinterface/minibase/main/routes.py | 21 ++ webinterface/minibase/models.py | 8 +- webinterface/minibase/posts/__init.py__ | 0 .../posts/__pycache__/forms.cpython-311.pyc | Bin 0 -> 918 bytes .../posts/__pycache__/routes.cpython-311.pyc | Bin 0 -> 4328 bytes webinterface/minibase/posts/forms.py | 10 + webinterface/minibase/posts/routes.py | 55 ++++++ webinterface/minibase/route.py | 183 ------------------ webinterface/minibase/site.db | Bin 32768 -> 32768 bytes webinterface/minibase/templates/home.html | 8 +- webinterface/minibase/templates/layout.html | 16 +- webinterface/minibase/templates/login.html | 4 +- webinterface/minibase/templates/post.html | 6 +- webinterface/minibase/templates/register.html | 2 +- .../minibase/templates/user_posts.html | 8 +- webinterface/minibase/users/__init.py__ | 0 .../users/__pycache__/forms.cpython-311.pyc | Bin 0 -> 6163 bytes .../users/__pycache__/routes.cpython-311.pyc | Bin 0 -> 8815 bytes .../users/__pycache__/utils.cpython-311.pyc | Bin 0 -> 1991 bytes webinterface/minibase/{ => users}/forms.py | 11 +- webinterface/minibase/users/routes.py | 106 ++++++++++ webinterface/minibase/users/utils.py | 28 +++ 31 files changed, 298 insertions(+), 233 deletions(-) create mode 100644 webinterface/minibase/__pycache__/config.cpython-311.pyc delete mode 100644 webinterface/minibase/__pycache__/forms.cpython-311.pyc delete mode 100644 webinterface/minibase/__pycache__/route.cpython-311.pyc create mode 100644 webinterface/minibase/config.py create mode 100644 webinterface/minibase/main/__init.py__ create mode 100644 webinterface/minibase/main/__pycache__/routes.cpython-311.pyc create mode 100644 webinterface/minibase/main/routes.py create mode 100644 webinterface/minibase/posts/__init.py__ create mode 100644 webinterface/minibase/posts/__pycache__/forms.cpython-311.pyc create mode 100644 webinterface/minibase/posts/__pycache__/routes.cpython-311.pyc create mode 100644 webinterface/minibase/posts/forms.py create mode 100644 webinterface/minibase/posts/routes.py delete mode 100644 webinterface/minibase/route.py create mode 100644 webinterface/minibase/users/__init.py__ create mode 100644 webinterface/minibase/users/__pycache__/forms.cpython-311.pyc create mode 100644 webinterface/minibase/users/__pycache__/routes.cpython-311.pyc create mode 100644 webinterface/minibase/users/__pycache__/utils.cpython-311.pyc rename webinterface/minibase/{ => users}/forms.py (91%) create mode 100644 webinterface/minibase/users/routes.py create mode 100644 webinterface/minibase/users/utils.py diff --git a/webinterface/minibase/__init__.py b/webinterface/minibase/__init__.py index c9ac9c9a..d02dfb5a 100644 --- a/webinterface/minibase/__init__.py +++ b/webinterface/minibase/__init__.py @@ -3,23 +3,40 @@ from flask_sqlalchemy import SQLAlchemy from flask_bcrypt import Bcrypt from flask_login import LoginManager from flask_mail import Mail -import os +from minibase.config import Config -app = Flask(__name__) -app.config['SECRET_KEY'] = '5791628bb0b13ce0c676dfde280ba245' -app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db' -db = SQLAlchemy(app) -bcrypt = Bcrypt(app) -login_manager = LoginManager(app) +# (DATABASE) Definition +db = SQLAlchemy() + +# (PASSWORD) Hashign Program to save paswords safely +bcrypt = Bcrypt() + +# (LOGIN) Login manage plugin configuration +login_manager = LoginManager() login_manager.login_view = 'login' -login_manager.login_message_category = 'info' +login_manager.login_message_category = 'info' #Boostrap Info Message -app.config['MAIL_SERVER']= 'smtp.googlemail.com' -app.config['MAIL_PORT']= 465 -app.config['MAIL_USE_TLS']= False -app.config['MAIL_USE_SSL']= True -app.config['MAIL_USERNAME']= 'kerem.yollu@gmail.com' -app.config['MAIL_PASSWORD']= 'eoilsjxjwmnfjbbj' -mail = Mail(app) +# (EMAIL AGENT) Definition +mail = Mail() -from minibase import route +def create_minibase(config_class=Config): + # (FLASK) Main Flask Application + app = Flask(__name__) + app.config.from_object(Config) + # (DATABASE) Initialisation + db.init_app(app) + # (PASSWORD) Initialisation + bcrypt.init_app(app) + # (LOGIN) Initialisation + login_manager.init_app(app) + # (EMAIL AGENT) Initialisation + mail.init_app(app) + # (FLASK) Importing adn then registering blueprints + from minibase.users.routes import users + from minibase.posts.routes import posts + from minibase.main.routes import main + app.register_blueprint(users) + app.register_blueprint(posts) + app.register_blueprint(main) + # Retunr The ccreated app + return app diff --git a/webinterface/minibase/__pycache__/__init__.cpython-311.pyc b/webinterface/minibase/__pycache__/__init__.cpython-311.pyc index c6ad3d3ab3b0cbb0411f5936a34b8237982f7ea8..382b7812cd84223f309be1669f06b983f6d760d8 100644 GIT binary patch literal 1850 zcmb7E&1)M+6ra()UCH{iT}2fMscbc1M2L0h2R)QRYv>_~6H1^55m;8*k+R9IR-Iit z2yECGgB!@fg_iVE@F}I_-{`5QRT1s7g<@!R=*{3;PJOfMwIZ7ocX%58-sgP0-_DPP zLYCn8()&gK0|@y`D9K2jfa9MLJSRHQsYxu_qEz6NnX;so6k*8(OK!;#22-)pt#pKC zGh@xQ<|3?^Su5AdQIaA|dVv*RChL$^9&Pd&TLEq9Gq$3hW<|A>BXMna3fqEeR0p$Ym9~MBEqd_UZl-H&rOux8jgiuYBjJ1`(n-FBf!9R zTmit+jDBN*i(ZBqRqbmQQ`J!E#Qe#1xoxR-`yuPNTy!=}>FqFM^bJ?l27^#(M@$S0 z5zkaBCSp|83@=$2*VY`i8ZEoZ?G2YXJTJ;jebG)5UqSfFr+H#?iA(SxT;!~0I4Azjf*@-#%W26S06PW*cNL(V#8+7aGS|e&Bv^b z#Tf5u9X7S9YIIa}bubJ|9nLhDsYwcd2a8rj^}liQ$Ru0(F7vectm&-vl7gz=nbIZ&kFA9r1l3RSRTW&56k~;dw&E=V_5QG z=`dIHZXV+~$(_bqq1+YkQcRlp2&>LlrWQX?93N;B=3{fr4=(OM%*CdNDqMX2VK%m4 zn@ye;hEj65t8q&s&T;W+^0JsNMOiV~HVyVTteg;!ISxL7Y6lzCv-yyVzC;cBiSU}h zS8;lk`Pj1c4U>Js8>otR&G`+dBZ*QPkhlF=3CM~+D*>tbvl5VN{;UM#ia#p>sr$2X zq!4A^YdyKYd*4f;lAZs$^0fM_>M5u!T;0!qQ~b8*6@n{uuP`RnVC9DRzlP3C-gBR9 T?rwT;xV&;i%Cz*xDLVJR+uo@P literal 1358 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 diff --git a/webinterface/minibase/__pycache__/models.cpython-311.pyc b/webinterface/minibase/__pycache__/models.cpython-311.pyc index 6f89b6b82ef80b02662c737ceb68a2682f0c1b1a..e00fef2981897ccc6440560be44025c7013496be 100644 GIT binary patch delta 1120 zcmZuvOHb5L6uup%GwrmMhcJLdz_&#p3O?|OAwF>7BS8~0o2GIvSnafU+DQm5B+-p- z47s{AF)mQ!$`BJ*{s1>V!h&37>B60ET)6U_PE<_1X}{ic&Ua4F>rv0=9_Oj!lo+1j z*|+@3g43zJUf8kgmc}^a`LI|uDn@qKL$g|{l&V(6(wHb*v&n}JFWg~^_zYwLa+gt3@M9=`QcY0P*g@=9xYiw$f&d(rTR*2Jv|=GqG@`wr$*j$ctu z7*7Y0SM?)*T7au5^HL(V1V4v`=dCM!r>UDtw;U ziXu>W*MMzwHwm^QC_RjQo~V2jM*=KTQ>(#2a2u4K#@9sz{iGuQgxb{G+Y3$dLUDI@ zC#fzY%(E|RbNOJ8EZZaUQBk>lMA66#nh=%Yc_3!M^X44t;^1#_vwUm}nUwcASA)&+ zlX1LbCpi=*QV61H*oOk_CpaL7%`L+NWVDmiPlL&-NUz2mhRAvl;W-0}l>M<@6jkOd z-8IWvDYK9~xzOCU^rm!FYwt$sBD5lYBO+{&E%y1*y?Dhj>uHdNLRs8Tg*Ou? zso*ezrZu%?zn*h0pz%*x{qnKx?x~m60*5HVNaL#R3c916Ak8pA0S^_k_`Ud3jri^M3 z1y_8WLzYT`bkXs-Xume2%+G8?N-TF&AOI)jPAq{!R9$ vaikjaS}2aeCFIjSBtPWKb%SHu-?RTbD{RyIf1j2A(a`ssAsZX-<*DXhTfqf# delta 1033 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 K^jV}?*7X-yxH94Z literal 0 HcmV?d00001 diff --git a/webinterface/minibase/main/routes.py b/webinterface/minibase/main/routes.py new file mode 100644 index 00000000..33ddd5f5 --- /dev/null +++ b/webinterface/minibase/main/routes.py @@ -0,0 +1,21 @@ +from flask import render_template, request, Blueprint +from minibase.models import Post + +# Declaring a blueprint +main = Blueprint('main', __name__) + +#Redirect from / and also /home routes to the / +@main.route("/") +@main.route("/home") +def home(): + # (PAGINATION) Defines the page number that we will start with + page = request.args.get('page', 1, type=int) + # (POSTS) Query posts usin SQLAlchemy + posts = Post.query.order_by(Post.date_posted.asc()).paginate(per_page=2) + # (HTML) Renders the template for templates/home.html + return render_template('home.html', posts=posts) + + +@main.route("/about") +def about(): + return render_template('about.html', title='About') diff --git a/webinterface/minibase/models.py b/webinterface/minibase/models.py index f1027200..8fc03a9b 100644 --- a/webinterface/minibase/models.py +++ b/webinterface/minibase/models.py @@ -1,7 +1,9 @@ from itsdangerous import TimedJSONWebSignatureSerializer as Serializer from datetime import datetime -from minibase import db, login_manager, app +from minibase import db, login_manager from flask_login import UserMixin +from flask import url_for, current_app + @login_manager.user_loader @@ -17,12 +19,12 @@ class User(db.Model, UserMixin): posts = db.relationship('Post', backref='author', lazy=True) def get_reset_token(self, expires_sec=1800): - s = Serializer(app.config['SECRET_KEY'], expires_sec) + s = Serializer(current_app.config['SECRET_KEY'], expires_sec) return s.dumps({'user_id': self.id}).decode('utf-8') @staticmethod def verify_reset_token(token): - s = Serializer(app.config['SECRET_KEY']) + s = Serializer(current_app.config['SECRET_KEY']) try: user_id = s.loads(token)['user_id'] except: diff --git a/webinterface/minibase/posts/__init.py__ b/webinterface/minibase/posts/__init.py__ new file mode 100644 index 00000000..e69de29b diff --git a/webinterface/minibase/posts/__pycache__/forms.cpython-311.pyc b/webinterface/minibase/posts/__pycache__/forms.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8277c37b52d73a51fd10ae08a2f04d4c7d986f2a GIT binary patch literal 918 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 literal 0 HcmV?d00001 diff --git a/webinterface/minibase/posts/forms.py b/webinterface/minibase/posts/forms.py new file mode 100644 index 00000000..e433ce9a --- /dev/null +++ b/webinterface/minibase/posts/forms.py @@ -0,0 +1,10 @@ +from flask_wtf import FlaskForm +from wtforms import StringField, SubmitField, TextAreaField +from wtforms.validators import DataRequired + +class postForm(FlaskForm): + title = StringField('Title', + validators=[DataRequired()]) + content = TextAreaField('Content', + validators=[DataRequired()]) + submit = SubmitField('Post') diff --git a/webinterface/minibase/posts/routes.py b/webinterface/minibase/posts/routes.py new file mode 100644 index 00000000..b3ed2eba --- /dev/null +++ b/webinterface/minibase/posts/routes.py @@ -0,0 +1,55 @@ +from flask import (render_template, url_for, flash, + redirect, request, abort, Blueprint) +from flask_login import current_user, login_required +from minibase import db +from minibase.models import Post +from minibase.posts.forms import postForm + +# Declaring a blueprint +posts = Blueprint('posts', __name__) + +@posts.route("/post/new", methods=['GET', 'POST']) +@login_required +def new_post(): + form = postForm() + if form.validate_on_submit(): + post = Post(title=form.title.data, content=form.content.data, author=current_user) + db.session.add(post) + db.session.commit() + flash('Your post has been created', 'success') + return redirect(url_for('main.home')) + return render_template('create_post.html', title='Create Post', legend='Create Post', form=form) + +@posts.route("/post/") +def post(post_id): + post = Post.query.get_or_404(post_id) + return render_template('post.html', title=post.title, post=post) + +@posts.route("/post//update", methods=['GET', 'POST']) +@login_required +def post_update(post_id): + post = Post.query.get_or_404(post_id) + if post.author != current_user: + abort(403) + form = postForm() + if form.validate_on_submit(): + post.title = form.title.data + post.content = form.content.data + db.session.commit() + flash('Your post has been updated', 'success') + return redirect(url_for('posts.post', post_id=post.id)) + elif request.method == 'GET': + form.title.data = post.title + form.content.data = post.content + return render_template('create_post.html', title='Update Post', legend='Update Post', form=form) + +@posts.route("/post//delete", methods=['POST']) +@login_required +def post_delete(post_id): + post = Post.query.get_or_404(post_id) + if post.author != current_user: + abort(403) + db.session.delete(post) + db.session.commit() + flash('Your post has been deleted', 'success') + return redirect(url_for('main.home')) diff --git a/webinterface/minibase/route.py b/webinterface/minibase/route.py deleted file mode 100644 index 4d241c02..00000000 --- a/webinterface/minibase/route.py +++ /dev/null @@ -1,183 +0,0 @@ -import os -import secrets -from PIL import Image -from flask import render_template, url_for, flash, redirect, request, abort -from minibase import app, db, bcrypt, mail -from minibase.forms import registrationForm, loginForm, updateAccountForm, postForm, requestResetForm, resetPasswordForm -from minibase.models import User, Post -from flask_login import login_user, current_user, logout_user, login_required -from flask_mail import Message - -#Redirect from / and also /home routes to the / -@app.route("/") -@app.route("/home") -def home(): - page = request.args.get('page', 1, type=int) - posts = Post.query.order_by(Post.date_posted.asc()).paginate(per_page=2) - return render_template('home.html', posts=posts) - - -@app.route("/about") -def about(): - return render_template('about.html', title='About') - -@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(): - hashed_pw = bcrypt.generate_password_hash(form.password.data).decode('utf-8') - user = User(username=form.username.data, email=form.email.data, password=hashed_pw) - db.session.add(user) - db.session.commit() - flash(f'Your account has benn created you can now log in!','success') - return redirect(url_for('login')) - - return render_template('register.html', title='Register', form=form) - -@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(): - 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. Please chek your Email and Password!','danger') - return render_template('login.html', title='Login', form=form) - -@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/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!', 'success') - 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='pics/'+ current_user.image_file) - return render_template('account.html', title='Account', image_file = image_file, form=form) - -@app.route("/post/new", methods=['GET', 'POST']) -@login_required -def new_post(): - form = postForm() - if form.validate_on_submit(): - post = Post(title=form.title.data, content=form.content.data, author=current_user) - db.session.add(post) - db.session.commit() - flash('Your post has been created', 'success') - return redirect(url_for('home')) - return render_template('create_post.html', title='Create Post', legend='Create Post', form=form) - -@app.route("/post/") -def post(post_id): - post = Post.query.get_or_404(post_id) - return render_template('post.html', title=post.title, post=post) - -@app.route("/post//update", methods=['GET', 'POST']) -@login_required -def post_update(post_id): - post = Post.query.get_or_404(post_id) - if post.author != current_user: - abort(403) - form = postForm() - if form.validate_on_submit(): - post.title = form.title.data - post.content = form.content.data - db.session.commit() - flash('Your post has been updated', 'success') - return redirect(url_for('post', post_id=post.id)) - elif request.method == 'GET': - form.title.data = post.title - form.content.data = post.content - return render_template('create_post.html', title='Update Post', legend='Update Post', form=form) - -@app.route("/post//delete", methods=['POST']) -@login_required -def post_delete(post_id): - post = Post.query.get_or_404(post_id) - if post.author != current_user: - abort(403) - db.session.delete(post) - db.session.commit() - flash('Your post has been deleted', 'success') - return redirect(url_for('home')) - -@app.route("/user/") -def user_posts(username): - user = User.query.filter_by(username=username).first_or_404() - page = request.args.get('page', 1, type=int) - posts = Post.query.filter_by(author=user)\ - .order_by(Post.date_posted.asc())\ - .paginate(page=page, per_page=2) - return render_template('user_posts.html', posts=posts, user=user) - - -def send_reset_email(user): - token = user.get_reset_token() - msg = Message('Password Reset Request', - sender='noreply@demo.com', - recipients=[user.email]) - msg.body = f'''To reset your password, visit the following link: -{url_for('reset_token', token=token, _external=True)} -If you didn't make this request, then simply ingnore this email and no chancges will be made. -''' - mail.send(msg) - -@app.route("/reset_password", methods=['GET', 'POST']) -def reset_request(): - if current_user.is_authenticated: - return redirect(url_for('home')) - form = requestResetForm() - if form.validate_on_submit(): - user = User.query.filter_by(email=form.email.data).first() - send_reset_email(user) - flash('An Email has benn sent with instruction to reset your password', 'warning') - return render_template('reset_request.html', title='Reset Password', form=form) - -@app.route("/reset_password/", methods=['GET', 'POST']) -def reset_token(token): - if current_user.is_authenticated: - return redirect(url_for('home')) - user = User.verify_reset_token(token) - if user is None: - flash('That is an invalid or expired token', 'warning') - return redirect(url_for('reset_request')) - form = resetPasswordForm() - if form.validate_on_submit(): - hashed_pw = bcrypt.generate_password_hash(form.password.data).decode('utf-8') - user.password = hashed_pw - db.session.commit() - flash(f'Your password has benn udated','success') - return redirect(url_for('login')) - return render_template('reset_token.html', title='Reset Password', form=form) diff --git a/webinterface/minibase/site.db b/webinterface/minibase/site.db index 2cf6104d308143a75a7fa1da5aed42400a11cf78..026ba31746726dfddb6c68613814d3f8dd0ea5cc 100644 GIT binary patch delta 77 zcmZo@U}|V!njp=nI8nx#QE_9!LVr%?i41HE#taO`leq#kMZ*}`7}OnO8G}=E5_1(o h3sMqGQd1_+3wGYz9l*xS!heY&U}B@s=7+)ZIsg`m7B~O^ delta 64 zcmZo@U}|V!njp=nFj2;tQDI}kLVr&FOAKrb-3-hVCvyd8PMi?2xjTT3nb(hzjX~To UmN7UrCoy-jM}YI@hr#kX08sZ5!T
-

{{ post.title }}

+

{{ post.title }}

{{ post.content }}

@@ -17,9 +17,9 @@ {% for page_num in posts.iter_pages(left_edge=1, right_edge=1, left_current=1, right_current=2) %} {% if page_num %} {% if posts.page == page_num %} - {{ page_num }} + {{ page_num }} {% else %} - {{ page_num }} + {{ page_num }} {% endif %} {% else %} ... diff --git a/webinterface/minibase/templates/layout.html b/webinterface/minibase/templates/layout.html index 7672370d..27afe0ec 100644 --- a/webinterface/minibase/templates/layout.html +++ b/webinterface/minibase/templates/layout.html @@ -17,24 +17,24 @@