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/") 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/') 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/') 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/') 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/') 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/') 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/') 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)