import filedb from moderation import moderate #dummy_moderate as moderate #moderate # Using dummy moderation for testing purposes from flask import Flask, request, jsonify,send_file,session, redirect,url_for from werkzeug.utils import secure_filename import os import secrets app = Flask(__name__, static_folder='frontend/static', static_url_path='/static') app.config['UPLOAD_FOLDER'] = 'uploads_temp/' # Temporary upload folder, filedb will store it anyway os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True) app.secret_key = secrets.token_hex(16) # For session management @app.route('/api/post_content/', methods=['GET']) def get_post_content(post_id): # Returns the content file of a post try: post = filedb.get_post(post_id) if post.contentloc and os.path.isfile(post.contentloc): return send_file(post.contentloc) else: return jsonify({'error': 'Content not found'}), 404 except filedb.PostNotFoundError: return jsonify({'error': 'Post not found'}), 404 @app.route('/api/post/', methods=['GET']) def get_post(post_id): # Returns metadata of a post try: post = filedb.get_post(post_id) return jsonify({ 'id': post.id, 'title': post.title, 'content_type': post.contentType, 'tags': post.tags, 'date_created': post.dateCreated, 'creator_id': post.creator }), 200 except filedb.PostNotFoundError: return jsonify({'error': 'Post not found'}), 404 @app.route('/api/publish/post', methods=['POST']) def publish_post(): if 'user_id' not in session: return jsonify({'error': 'Authentication required'}), 401 if 'title' not in request.form or 'tags' not in request.form or 'file' not in request.files: return jsonify({'error': 'Missing required fields'}), 400 title = request.form['title'] tags = request.form.getlist('tags') file = request.files['file'] if file.filename == '': return jsonify({'error': 'No selected file'}), 400 filename = secure_filename(file.filename) temp_path = os.path.join(app.config['UPLOAD_FOLDER'], filename) os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True) file.save(temp_path) if not moderate(temp_path): os.remove(temp_path) return jsonify({'error': 'Stop uploading porn'}), 400 post_id = filedb.createPost(title, temp_path, session['user_id'], tags) os.remove(temp_path) return jsonify({'message': 'Post created', 'post_id': post_id}), 201 @app.route('/api/getUser/', methods=['GET']) def get_user(user_id): try: user = filedb.lookup(user_id) return jsonify({ 'id': user.id, 'username': user.username }), 200 except FileNotFoundError: return jsonify({'error': 'User not found'}), 404 @app.route('/api/create_post', methods=['POST']) def create_post(): if 'user_id' not in session: return jsonify({'error': 'Authentication required'}), 401 if 'title' not in request.form or 'tags' not in request.form or 'file' not in request.files: return jsonify({'error': 'Missing required fields'}), 400 title = request.form['title'] tags = request.form.getlist('tags') file = request.files['file'] if file.filename == '': return jsonify({'error': 'No selected file'}), 400 filename = secure_filename(file.filename) temp_path = os.path.join(app.config['UPLOAD_FOLDER'], filename) os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True) file.save(temp_path) if not moderate(temp_path): os.remove(temp_path) return jsonify({'error': 'Content failed moderation'}), 400 post_id = filedb.createPost(title, temp_path, session['user_id'], tags) os.remove(temp_path) return jsonify({'message': 'Post created', 'post_id': post_id}), 201 @app.route('/api/login', methods=['POST']) def login(): if 'username' not in request.form or 'password' not in request.form: return jsonify({'error': 'Missing username or password'}), 400 username = request.form['username'] password = request.form['password'] try: user = filedb.lookupByUsername(username) if filedb.verify_password(user.password_hash,password): session['user_id'] = user.id return jsonify({'message': 'Login successful'}), 200 else: return jsonify({'error': 'Invalid credentials'}), 401 except FileNotFoundError: return jsonify({'error': 'Invalid credentials'}), 401 @app.route('/api/register', methods=['POST']) def register(): if int(request.headers.get("Content-Length",0)) > 1000: return jsonify({'error': 'WHAT THE FUCK'}), 400 erikoer = request.get_data(parse_form_data=True) # please force form i beg formdata = request.form.to_dict() print(formdata) # Debugging line to see incoming form data cuz idk why it doesn't work print(request.form) # i want to die this is a blank immutablemulti dict print(erikoer) if 'username' not in formdata or 'password' not in formdata: return jsonify({'error': 'Missing username or password'}), 400 # WHAT THE FUCK # FORMDATA IS EMPTY WTF # DEVTOOLS SHOWS THE FORMDATA IS SENT CORRECTLY # flask waht is wrong with you username = formdata['username'] password = formdata['password'] try: filedb.lookupByUsername(username) return jsonify({'error': 'Username already taken'}), 400 except FileNotFoundError: user_id = filedb.createUser(username,password) session['user_id'] = user_id return jsonify({'message': 'Registration successful', 'user_id': user_id}), 201 @app.route('/api/logout', methods=['POST']) def logout(): session.pop('user_id', None) return jsonify({'message': 'Logged out'}), 200 # Frontend serving @app.route('/') def index(): return send_file('frontend/index.html') @app.route('/post/') def serve_post_page(post_id): return send_file('frontend/post.html') @app.route('/user/') def serve_user_page(user_id): return send_file('frontend/user.html') @app.route("/login") @app.route("/login/") def serve_login_page(): return send_file('frontend/login.html') @app.route("/register") @app.route("/register/") def serve_register_page(): return send_file('frontend/register.html') @app.route('/publish/post') def serve_publish_post_page(): if 'user_id' not in session: return redirect('/login', code=302) return send_file('frontend/publish_post.html') # thanks to gpt for helping me with this code and making the frontend # Thanks to openai for the API that makes moderation possible, even if it's not used right now ## SSR endpoints cuz we need extra functionality NOW and js is too boring to write @app.route('/ssr/usr') def ssr_user(): out_html = "

Users


" for user in filedb.listUsers(): out_html += f'{user.username}

' return out_html @app.route('/ssr/post') def ssr_post(): out_html = "

Posts


" for post in filedb.listPosts(): lookup = "???" try: lookup = filedb.lookup(post.creator).username except: pass out_html += f'{post.title} by {lookup}

' return out_html def has_no_empty_params(rule): defaults = rule.defaults if rule.defaults is not None else () arguments = rule.arguments if rule.arguments is not None else () return len(defaults) >= len(arguments) ssr_endpoint_meta = [ ("/ssr/usr","List all users"), ("/ssr/post","List all posts"), ] @app.route("/ssr/") # Get all ssr endpoints (auto generate) def auto(): htm = "

Additional stuff:

" htm += "

This page may seem advanced. Fear not, just use the description to navigate.

" for rule in app.url_map.iter_rules(): # Filter out rules we can't navigate to in a browser # and rules that require parameters if "GET" in rule.methods and has_no_empty_params(rule): if rule.endpoint.startswith("ssr_"): url = url_for(rule.endpoint, **(rule.defaults or {})) desc = next((desc for path,desc in ssr_endpoint_meta if path == url), "No description") htm += f'{url} - {desc}
' return htm @app.after_request def wrap(response): # Get the path of the request path = request.path if path.startswith("/ssr/") and response.content_type == "text/html; charset=utf-8": # Wrap the response in a basic HTML structure original_content = response.get_data(as_text=True) with open("frontend/cont.html","r",encoding="utf-8") as f: cont_html = f.read() new_content = cont_html.replace("", original_content) response.set_data(new_content) return response