from werkzeug.utils import secure_filename from flask import Flask, request, render_template, request, jsonify, redirect, url_for, flash import os from flask_sqlalchemy import SQLAlchemy from flask_login import UserMixin , login_user, current_user, login_required, logout_user , LoginManager #Configs app = Flask(__name__, static_url_path='/static') basedir = os.path.abspath(os.path.dirname(__file__)) app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'database') app.config["SECRET_KEY"] = "thisisase" db = SQLAlchemy(app) login_manager = LoginManager() login_manager.init_app(app) #End of models definition #Code snippets from:https://www.geeksforgeeks.org/how-to-add-authentication-to-your-app-with-flask-login/ #accessed on 22nd decemeber #Used base login and register feature to add authentication to the app to allow other features @login_manager.user_loader def loader_user(user_id): return Users.query.get(user_id) #Models definition class Users(UserMixin, db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(250), unique=True, nullable=False) password = db.Column(db.String(250), nullable=False) class Projects(db.Model): # Correctly inherit from db.Model __tablename__ = 'projects' # Explicit table name id = db.Column(db.Integer, primary_key=True, autoincrement=True) name = db.Column(db.String(100), nullable=False) proj_type = db.Column(db.String(50), nullable=False) photo_url = db.Column(db.String(200), nullable=True) description = db.Column(db.String(500), nullable=True) link = db.Column(db.String(200), nullable=True) class Comments(db.Model): id = db.Column(db.Integer, primary_key=True, autoincrement=True) text = db.Column(db.Text, nullable=False) user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False) project_id = db.Column(db.Integer, db.ForeignKey('projects.id'), nullable=False) user = db.relationship('Users', backref='comments') project = db.relationship('Projects', backref='comments') with app.app_context(): db.create_all() UPLOAD_FOLDER = os.path.join(basedir, 'static/uploads') ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'} app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 @app.route('/') #loads template for frontpage as well as display projects def frontpage(): projects = Projects.query.all() return render_template('front-page.html', projects=projects) #loads template for about @app.route('/about') def about(): return render_template('about.html') #loads template for projects @app.route('/projects', methods=['GET', 'POST']) def projects(): projects = Projects.query.all() # Create a dictionary to store comments organized by project_id comments_dict = {} # Get all comments with their associated users comments_query = db.session.query(Comments, Users)\ .join(Users, Comments.user_id == Users.id)\ .order_by(Comments.project_id)\ .all() print(comments_query) # Organize comments by project_id for comment, user in comments_query: if comment.project_id not in comments_dict: comments_dict[comment.project_id] = [] comment_data = { 'id': comment.id, 'text': comment.text, 'username': user.username, 'user_id': comment.user_id, 'project_id': comment.project_id } comments_dict[comment.project_id].append(comment_data) return render_template('projects.html' , projects=projects,comments=comments_dict) #Section for uploading photo #Code adapted from: https://openjavascript.info/2022/06/08/how-to-upload-a-file-using-the-fetch-api/ # Accessed on 12/12/2024 # This code allowed me to upload a photo file to the server which has been adapted to link to other projects @app.route('/upload', methods=['POST']) #Photo upload def upload_photo(): if request.method =='POST': mrx = request.files['photo_url'] file_path = os.path.join(app.config['UPLOAD_FOLDER'], secure_filename(mrx.filename)) mrx.save(file_path) file_url = f'/static/uploads/{mrx.filename}' return jsonify({'file_url': file_url}) #Section for adding projects @app.route('/add_project', methods=['POST']) def add_project(): obj = request.json print(obj) new_project = Projects( name=obj['name'], proj_type=obj['proj_type'], description=obj['description'], photo_url=obj['photo_url'], link=obj['proj_link']) db.session.add(new_project) db.session.commit() return jsonify({ 'id': new_project.id, 'name': new_project.name, 'proj_type': new_project.proj_type, 'description': new_project.description, 'photo_url': new_project.photo_url, 'link': new_project.link }) #section to delete projects @app.route('/delete_project', methods=['POST']) def delete_project(): if request.method =='POST': project_id = request.form['project_id'] project = Projects.query.get(project_id) db.session.delete(project) db.session.commit() flash('Project deleted successfully!', 'success') else: flash('Project not deleted!', 'error') return redirect(url_for('projects')) return redirect(url_for('projects')) #a section to add comments @app.route('/comment', methods=['POST']) def comment(): if request.method =='POST': if not current_user.is_authenticated: flash('You need to be logged in to comment','error') return redirect(url_for('projects')) comment = Comments( text = request.form['comment'], user_id = current_user.id, project_id = request.form['project_id']) db.session.add(comment) db.session.commit() flash('Comment added successfully!', 'success') return redirect(url_for('projects')) #authentication @app.route('/register', methods=['GET', 'POST']) def register(): print(f"Request method: {request.method}") if request.method == 'POST': user = Users(username=request.form.get('username'), password=request.form.get('password')) db.session.add(user) db.session.commit() flash('User registered successfully!', 'success') return redirect(url_for('login')) return render_template('register.html') #End of models definition #Code snippets from:https://www.geeksforgeeks.org/how-to-add-authentication-to-your-app-with-flask-login/ #accessed on 22nd decemeber #Used base login and register feature to add authentication to the app to allow other features @app.route('/login', methods=["GET", "POST"]) def login(): if request.method == "POST": user = Users.query.filter_by( username=request.form.get('username')).first() if user.password == request.form.get('password'): login_user(user) flash('You were successfully logged in!', 'success') print('Flashed: success') return redirect(url_for('projects')) else: flash('Login failed! Please check your credentials and try again.', 'error') print('Flashed: error') return redirect(url_for('login')) return render_template('login.html') @app.route('/logout') def logout(): logout_user() flash('You were successfully logged out!', 'success') return redirect(url_for('login')) #end of authentication if __name__ == '__main__': port = int(os.environ.get('PORT', 8080)) app.run(host='0.0.0.0', port=port ,debug=True)