255 lines
9.1 KiB
Python
255 lines
9.1 KiB
Python
from flask import Flask, render_template, redirect, request, session, url_for, g
|
|
from flask_sqlalchemy import SQLAlchemy
|
|
from flask_admin import Admin, AdminIndexView, expose, BaseView
|
|
from flask_admin.contrib.sqla import ModelView
|
|
from functools import wraps
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = 'bebra'
|
|
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///Picture_Puzzle_web.db'
|
|
db = SQLAlchemy(app)
|
|
|
|
class User(db.Model):
|
|
__tablename__ = 'user'
|
|
id = db.Column(db.Integer, primary_key=True)
|
|
username = db.Column(db.String(100), unique=True, nullable=False)
|
|
password = db.Column(db.String(100), nullable=False)
|
|
email = db.Column(db.String(100), unique=True, nullable=False)
|
|
|
|
class Post(db.Model):
|
|
__tablename__ = 'post'
|
|
id = db.Column(db.Integer, primary_key=True)
|
|
date_created = db.Column(db.String(100), unique=False, nullable=False)
|
|
alias = db.Column(db.String(100), unique=True, nullable=False)
|
|
title = db.Column(db.String(100), nullable=False)
|
|
image = db.Column(db.String(100), nullable=False)
|
|
|
|
class ForumCategory(db.Model):
|
|
id = db.Column(db.Integer, primary_key=True)
|
|
category_name = db.Column(db.String(100), nullable=False)
|
|
description = db.Column(db.String(200))
|
|
|
|
class ForumPost(db.Model):
|
|
id = db.Column(db.Integer, primary_key=True)
|
|
category_id = db.Column(db.Integer, db.ForeignKey('forum_category.id'), nullable=False)
|
|
post_name = db.Column(db.String(100), nullable=False)
|
|
created_by = db.Column(db.String(100), nullable=False)
|
|
creation_date = db.Column(db.DateTime, nullable=False)
|
|
media = db.Column(db.String(100))
|
|
text = db.Column(db.Text, nullable=False)
|
|
edited = db.Column(db.Boolean, default=False)
|
|
|
|
class ForumComment(db.Model):
|
|
id = db.Column(db.Integer, primary_key=True)
|
|
post_id = db.Column(db.Integer, db.ForeignKey('forum_post.id'), nullable=False)
|
|
created_by = db.Column(db.String(100), nullable=False)
|
|
creation_date = db.Column(db.DateTime, nullable=False)
|
|
media = db.Column(db.String(100))
|
|
text = db.Column(db.Text, nullable=False)
|
|
edited = db.Column(db.Boolean, default=False)
|
|
|
|
def admin_login_required(view_func):
|
|
@wraps(view_func)
|
|
def decorated_function(*args, **kwargs):
|
|
if not session.get('admin_logged_in'):
|
|
return redirect(url_for('admin_login'))
|
|
return view_func(*args, **kwargs)
|
|
return decorated_function
|
|
|
|
class MyAdminIndexView(AdminIndexView):
|
|
@expose('/')
|
|
@admin_login_required
|
|
def index(self):
|
|
return self.render('admin/index.html')
|
|
|
|
class UserAdminView(ModelView):
|
|
column_exclude_list = ['password']
|
|
form_excluded_columns = ['password']
|
|
can_export = True
|
|
export_types = ['csv']
|
|
|
|
class PostAdminView(ModelView):
|
|
can_export = True
|
|
export_types = ['csv']
|
|
|
|
class LogoutView(BaseView):
|
|
@expose('/')
|
|
def index(self):
|
|
session.pop("admin_logged_in", None)
|
|
return redirect(url_for("index"))
|
|
|
|
admin = Admin(app, name='Admin Panel', template_mode='bootstrap3', index_view=MyAdminIndexView())
|
|
admin.add_view(UserAdminView(User, db.session))
|
|
admin.add_view(PostAdminView(Post, db.session))
|
|
admin.add_view(LogoutView(name='Logout', endpoint='admin_logout'))
|
|
|
|
@app.before_request
|
|
def check_admin_login():
|
|
if request.path.startswith('/admin/') and not session.get('admin_logged_in'):
|
|
if request.path != '/admin/login' and request.path != '/admin/logout':
|
|
return redirect(url_for('admin_login'))
|
|
|
|
ADMIN_USERNAME = 'user'
|
|
ADMIN_PASSWORD = '1234321'
|
|
|
|
@app.before_request
|
|
def before_request():
|
|
g.user = None
|
|
if 'username' in session:
|
|
user = User.query.filter_by(username=session['username']).first()
|
|
g.user = user
|
|
|
|
@app.route("/admin/login", methods=["GET", "POST"])
|
|
def admin_login():
|
|
if request.method == "POST":
|
|
username = request.form["username"]
|
|
password = request.form["password"]
|
|
if username == ADMIN_USERNAME and password == ADMIN_PASSWORD:
|
|
session["admin_logged_in"] = True
|
|
return redirect(url_for("admin.index"))
|
|
else:
|
|
return render_template("admin/login.html", error_msg="Invalid credentials")
|
|
return render_template("admin/login.html", error_msg=None)
|
|
|
|
@app.route("/admin/logout")
|
|
def admin_logout():
|
|
session.pop("admin_logged_in", None)
|
|
return redirect(url_for("admin_login"))
|
|
|
|
@app.route("/register", methods=["GET", "POST"])
|
|
def register():
|
|
if request.method == "POST":
|
|
username = request.form["username"]
|
|
email = request.form["email"]
|
|
password = request.form["password"]
|
|
|
|
existing_user = User.query.filter_by(email=email).first()
|
|
if existing_user:
|
|
error_msg = "Email already exists"
|
|
return render_template("auth/register.html", error_msg=error_msg)
|
|
|
|
existing_username = User.query.filter_by(username=username).first()
|
|
if existing_username:
|
|
error_msg = "Username already exists"
|
|
return render_template("auth/register.html", error_msg=error_msg)
|
|
|
|
new_user = User(username=username, email=email, password=password) # type: ignore
|
|
db.session.add(new_user)
|
|
db.session.commit()
|
|
return redirect(url_for("login"))
|
|
|
|
return render_template("auth/register.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, password=password).first()
|
|
if user:
|
|
session["username"] = username
|
|
return redirect(url_for("index"))
|
|
return render_template("auth/login.html")
|
|
|
|
@app.route("/logout")
|
|
def logout():
|
|
session.pop("username", None)
|
|
return redirect(url_for("index"))
|
|
|
|
@app.route("/")
|
|
def index():
|
|
latest_posts = Post.query.all()[::-1]
|
|
return render_template("index.html", latest_posts=latest_posts)
|
|
|
|
@app.route("/posts")
|
|
def all_posts():
|
|
all_posts = Post.query.all()[::-1]
|
|
return render_template("posts.html", posts=all_posts)
|
|
|
|
@app.route("/posts/<alias>")
|
|
def post(alias):
|
|
post_info = Post.query.filter_by(alias=alias).first()
|
|
if post_info:
|
|
return render_template(f"{alias}.html", post_info=post_info)
|
|
else:
|
|
return "Post not found", 404
|
|
|
|
@app.route('/forums')
|
|
def forums():
|
|
categories = ForumCategory.query.all()
|
|
posts = ForumPost.query.all()
|
|
comments = ForumComment.query.all()
|
|
return render_template('forums.html', categories=categories, posts=posts, comments=comments)
|
|
|
|
@app.route('/forums/<int:category_id>')
|
|
def category(category_id):
|
|
category = ForumCategory.query.get_or_404(category_id)
|
|
posts = ForumPost.query.filter_by(category_id=category_id).all()
|
|
return render_template('category.html', category=category, posts=posts)
|
|
|
|
@app.route('/forums/<int:post_id>')
|
|
def new_post(post_id):
|
|
post = ForumPost.query.get_or_404(post_id)
|
|
comments = ForumComment.query.filter_by(post_id=post_id).all()
|
|
return render_template('post.html', post=post, comments=comments)
|
|
|
|
@app.route('/forums/create_post', methods=['GET', 'POST'])
|
|
def create_post():
|
|
if request.method == 'POST':
|
|
category_id = request.form['category_id']
|
|
post_name = request.form['post_name']
|
|
created_by = request.form['created_by']
|
|
text = request.form['text']
|
|
new_post = ForumPost(category_id=category_id, post_name=post_name, created_by=created_by, text=text) # type: ignore
|
|
db.session.add(new_post)
|
|
db.session.commit()
|
|
return redirect(url_for('forums'))
|
|
else:
|
|
categories = ForumCategory.query.all()
|
|
return render_template('create_post.html', categories=categories)
|
|
|
|
@app.route('/forums/create_comment', methods=['POST']) # type: ignore
|
|
def create_comment():
|
|
if request.method == 'POST':
|
|
post_id = request.form['post_id']
|
|
created_by = request.form['created_by']
|
|
text = request.form['text']
|
|
new_comment = ForumComment(post_id=post_id, created_by=created_by, text=text) # type: ignore
|
|
db.session.add(new_comment)
|
|
db.session.commit()
|
|
return redirect(url_for('post', post_id=post_id))
|
|
|
|
@app.route('/forums/upvote_post/<int:post_id>')
|
|
def upvote_post(post_id):
|
|
post = ForumPost.query.get_or_404(post_id)
|
|
post.upvotes += 1
|
|
db.session.commit()
|
|
return redirect(url_for('post', post_id=post_id))
|
|
|
|
@app.route('/forums/downvote_post/<int:post_id>')
|
|
def downvote_post(post_id):
|
|
post = ForumPost.query.get_or_404(post_id)
|
|
post.downvotes += 1
|
|
db.session.commit()
|
|
return redirect(url_for('post', post_id=post_id))
|
|
|
|
@app.route('/forums/upvote_comment/<int:comment_id>')
|
|
def upvote_comment(comment_id):
|
|
comment = ForumComment.query.get_or_404(comment_id)
|
|
comment.upvotes += 1
|
|
db.session.commit()
|
|
return redirect(url_for('post', post_id=comment.post_id))
|
|
|
|
@app.route('/forums/downvote_comment/<int:comment_id>')
|
|
def downvote_comment(comment_id):
|
|
comment = ForumComment.query.get_or_404(comment_id)
|
|
comment.downvotes += 1
|
|
db.session.commit()
|
|
return redirect(url_for('post', post_id=comment.post_id))
|
|
|
|
@app.route("/about")
|
|
def about():
|
|
return render_template("about.html")
|
|
|
|
if __name__ == '__main__':
|
|
app.run(debug=True) |