fuck you all
This commit is contained in:
71
app.py
71
app.py
@@ -1,11 +1,17 @@
|
||||
from markupsafe import Markup
|
||||
from flask import Flask, render_template, request, redirect, url_for
|
||||
import markdown as md
|
||||
|
||||
from models import db, Problem, Solution
|
||||
from utils import run_code_against_tests
|
||||
from leaderboard import create_leaderboard_table, log_leaderboard, get_leaderboard
|
||||
|
||||
|
||||
import os
|
||||
from problem_loader import load_problems_from_json, schedule_problem_reload
|
||||
## from problem_loader import load_problems_from_json, schedule_problem_reload
|
||||
from problem_scanner import start_problem_scanner
|
||||
import sqlite3
|
||||
from pathlib import Path
|
||||
|
||||
app = Flask(__name__)
|
||||
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///db.sqlite3'
|
||||
@@ -17,18 +23,23 @@ db.init_app(app)
|
||||
def setup():
|
||||
db.create_all()
|
||||
create_leaderboard_table() # Ensure leaderboard table exists
|
||||
# Load problems from JSON at startup
|
||||
json_path = os.path.join(os.path.dirname(__file__), 'problems.json')
|
||||
load_problems_from_json(json_path)
|
||||
# Schedule reload every 10 hours
|
||||
schedule_problem_reload(app, json_path, interval_hours=10)
|
||||
# Problems are now loaded from manifests by the background scanner. No need to load problems.json.
|
||||
|
||||
# Start the background thread to scan problems
|
||||
start_problem_scanner()
|
||||
|
||||
@app.route('/')
|
||||
def index():
|
||||
problems = Problem.query.all()
|
||||
db_path = Path(__file__).parent / 'problems.sqlite3'
|
||||
conn = sqlite3.connect(db_path)
|
||||
c = conn.cursor()
|
||||
c.execute('SELECT folder, description, test_code FROM problems')
|
||||
problems = c.fetchall()
|
||||
conn.close()
|
||||
# Get leaderboard entries
|
||||
leaderboard = get_leaderboard()
|
||||
# Map problem_id to title for leaderboard display
|
||||
problem_titles = {p.id: p.title for p in problems}
|
||||
# Map folder to title for display
|
||||
problem_titles = {folder: folder.replace('_', ' ').title() for folder, _, _ in problems}
|
||||
return render_template('index.html', problems=problems, leaderboard=leaderboard, problem_titles=problem_titles)
|
||||
|
||||
@app.route('/problem/new', methods=['GET', 'POST'])
|
||||
@@ -43,16 +54,29 @@ def new_problem():
|
||||
return redirect(url_for('index'))
|
||||
return render_template('new_problem.html')
|
||||
|
||||
@app.route('/problem/<int:problem_id>', methods=['GET', 'POST'])
|
||||
def view_problem(problem_id):
|
||||
problem = Problem.query.get_or_404(problem_id)
|
||||
@app.route('/problem/<folder>', methods=['GET', 'POST'])
|
||||
def view_problem(folder):
|
||||
db_path = Path(__file__).parent / 'problems.sqlite3'
|
||||
conn = sqlite3.connect(db_path)
|
||||
c = conn.cursor()
|
||||
c.execute('SELECT folder, description, test_code FROM problems WHERE folder = ?', (folder,))
|
||||
row = c.fetchone()
|
||||
conn.close()
|
||||
if not row:
|
||||
return 'Problem not found', 404
|
||||
problem = {
|
||||
'folder': row[0],
|
||||
'description': row[1],
|
||||
'test_code': row[2],
|
||||
'title': row[0].replace('_', ' ').title()
|
||||
}
|
||||
result = None
|
||||
if request.method == 'POST':
|
||||
user_code = request.form['user_code']
|
||||
username = request.form.get('username', '').strip() or 'Anonymous'
|
||||
import tracemalloc
|
||||
tracemalloc.start()
|
||||
run_result = run_code_against_tests(user_code, problem.test_code)
|
||||
run_result = run_code_against_tests(user_code, problem['test_code'])
|
||||
current, peak = tracemalloc.get_traced_memory()
|
||||
tracemalloc.stop()
|
||||
memory_used = peak // 1024 # in KB
|
||||
@@ -61,10 +85,13 @@ def view_problem(problem_id):
|
||||
import ast
|
||||
try:
|
||||
tree = ast.parse(user_code)
|
||||
# Get the last line number in the user's code
|
||||
if hasattr(tree, 'body') and tree.body:
|
||||
last_node = tree.body[-1]
|
||||
line_number = getattr(last_node, 'lineno', None)
|
||||
# Find the highest line number in the AST (for multi-function/user code)
|
||||
def get_max_lineno(node):
|
||||
max_lineno = getattr(node, 'lineno', 0)
|
||||
for child in ast.iter_child_nodes(node):
|
||||
max_lineno = max(max_lineno, get_max_lineno(child))
|
||||
return max_lineno
|
||||
line_number = get_max_lineno(tree)
|
||||
except Exception:
|
||||
pass
|
||||
# If there was an error, try to get the error line number from the traceback
|
||||
@@ -77,13 +104,13 @@ def view_problem(problem_id):
|
||||
line_number = tb_lines[-1].lineno
|
||||
except Exception:
|
||||
pass
|
||||
log_leaderboard(username, problem.id, run_result['runtime'], memory_used, line_number)
|
||||
solution = Solution(problem_id=problem.id, user_code=user_code, passed=run_result['passed'], output=run_result['output'])
|
||||
db.session.add(solution)
|
||||
db.session.commit()
|
||||
log_leaderboard(username, problem['folder'], run_result['runtime'], memory_used, line_number)
|
||||
result = run_result
|
||||
|
||||
return render_template('problem.html', problem=problem, result=result)
|
||||
|
||||
@app.template_filter('markdown')
|
||||
def markdown_filter(text):
|
||||
return Markup(md.markdown(text or '', extensions=['extra', 'sane_lists']))
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(debug=True)
|
||||
|
||||
Reference in New Issue
Block a user