diff --git a/instance/Picture_Puzzle_web.db b/instance/Picture_Puzzle_web.db index fee7441..61ec0da 100644 Binary files a/instance/Picture_Puzzle_web.db and b/instance/Picture_Puzzle_web.db differ diff --git a/main.py b/main.py index 01ff867..0580b5e 100644 --- a/main.py +++ b/main.py @@ -1,14 +1,25 @@ from flask import Flask, render_template, redirect, request, session, url_for, g from flask_sqlalchemy import SQLAlchemy +from sqlalchemy.orm import relationship from flask_admin import Admin, AdminIndexView, expose, BaseView from flask_admin.contrib.sqla import ModelView +from flask_wtf import FlaskForm +from flask_wtf.file import FileField, FileAllowed +from wtforms import StringField, TextAreaField, SelectField +from wtforms.validators import InputRequired +from werkzeug.utils import secure_filename from functools import wraps +from datetime import datetime +import os +import logging app = Flask(__name__) app.secret_key = 'bebra' app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///Picture_Puzzle_web.db' +app.config['UPLOAD_FOLDER'] = 'uploads' +app.config['ALLOWED_EXTENSIONS'] = {'png', 'jpg', 'jpeg', 'gif', 'mp4', 'waw'} db = SQLAlchemy(app) - +logging.basicConfig(level=logging.DEBUG) class User(db.Model): __tablename__ = 'user' id = db.Column(db.Integer, primary_key=True) @@ -25,29 +36,48 @@ class Post(db.Model): image = db.Column(db.String(100), nullable=False) class ForumCategory(db.Model): + __tablename__ = 'forumcategory' 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): + __tablename__ = 'forumpost' id = db.Column(db.Integer, primary_key=True) - category_id = db.Column(db.Integer, db.ForeignKey('forum_category.id'), nullable=False) + category_id = db.Column(db.Integer, db.ForeignKey('forumcategory.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)) + creation_date = db.Column(db.DateTime, default=datetime.now) + media = db.relationship('Media', backref='forumpost', lazy=True) text = db.Column(db.Text, nullable=False) edited = db.Column(db.Boolean, default=False) class ForumComment(db.Model): + __tablename__ = 'forumcomment' id = db.Column(db.Integer, primary_key=True) - post_id = db.Column(db.Integer, db.ForeignKey('forum_post.id'), nullable=False) + post_id = db.Column(db.Integer, db.ForeignKey('forumpost.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)) + media = db.Column(db.Integer) # Assuming 'media' is a column containing media IDs text = db.Column(db.Text, nullable=False) edited = db.Column(db.Boolean, default=False) + # Define a primaryjoin expression + post = relationship("ForumPost", primaryjoin="foreign(ForumComment.post_id) == remote(ForumPost.id)") + +class Media(db.Model): + __tablename__ = 'media' + id = db.Column(db.Integer, primary_key=True) + post_id = db.Column(db.Integer, db.ForeignKey('forumpost.id'), nullable=False) + filename = db.Column(db.String(100), nullable=False) + +class CreatePostForm(FlaskForm): + category_id = SelectField('Category', validators=[InputRequired()], coerce=int) + post_name = StringField('Post Title', validators=[InputRequired()]) + created_by = StringField('Your Name', validators=[InputRequired()]) + text = TextAreaField('Post Content', validators=[InputRequired()]) + media = FileField('Insert Media', validators=[FileAllowed(app.config['ALLOWED_EXTENSIONS'])]) + def admin_login_required(view_func): @wraps(view_func) def decorated_function(*args, **kwargs): @@ -64,13 +94,24 @@ class MyAdminIndexView(AdminIndexView): 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 ForumCategoryAdminView(ModelView): + can_export = True + export_types = ['csv'] + +class ForumPostAdminView(ModelView): + can_export = True + export_types = ['csv'] + +class ForumCommentAdminView(ModelView): + can_export = True + export_types = ['csv'] class LogoutView(BaseView): @expose('/') @@ -81,6 +122,9 @@ class LogoutView(BaseView): 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(ForumCategoryAdminView(ForumCategory, db.session)) +admin.add_view(ForumPostAdminView(ForumPost, db.session)) +admin.add_view(ForumCommentAdminView(ForumComment, db.session)) admin.add_view(LogoutView(name='Logout', endpoint='admin_logout')) @app.before_request @@ -173,51 +217,77 @@ def post(alias): 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) + return render_template('forums.html', categories=categories) -@app.route('/forums/') -def category(category_id): +@app.route('/forums/') +def category(category_name): + category_name = category_name.capitalize() + print("Received category name:", category_name) + category = ForumCategory.query.filter_by(category_name=category_name).first() + if category: + posts = ForumPost.query.filter_by(category_id=category.id).limit(10).all() + return render_template('category.html', category=category, posts=posts) + else: + return "Category not found", 404 + +@app.route('/forums//create_post', methods=['GET', 'POST']) +def create_post(category_id): + form = CreatePostForm() 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 + + # Provide choices for category_id field + form.category_id.choices = [(category.id, category.category_name) for category in ForumCategory.query.all()] + + if form.validate_on_submit(): + post_name = form.post_name.data + created_by = form.created_by.data + text = form.text.data + media_files = request.files.getlist('media') + + media_filenames = [] + for file in media_files: + if file: + filename = secure_filename(file.filename) # type: ignore + file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename)) + media_filenames.append(filename) + + new_post = ForumPost( + category_id=category_id, + post_name=post_name, + created_by=created_by, + text=text, + creation_date=datetime.now(), + edited=False + ) # 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) + + for filename in media_filenames: + new_media = Media(post_id=new_post.id, filename=filename) # type: ignore + db.session.add(new_media) + + db.session.commit() + + return redirect(url_for('category', category_id=category_id)) + + return render_template('create_post.html', form=form, category=category) -@app.route('/forums/create_comment', methods=['POST']) # type: ignore -def create_comment(): +@app.route('/forums/', methods=['GET', 'POST']) +def view_post(post_id): + post = ForumPost.query.get_or_404(post_id) + comments = ForumComment.query.filter_by(post_id=post_id).all() 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 + 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)) + return redirect(url_for('view_post', post_id=post_id)) + return render_template('post.html', post=post, comments=comments) @app.route('/forums/upvote_post/') def upvote_post(post_id): diff --git a/templates/base.html b/templates/base.html index 0495710..67d46f3 100644 --- a/templates/base.html +++ b/templates/base.html @@ -24,8 +24,7 @@ Docs