code-sketch / app.py
duqing2026's picture
修改端口
4c2d124
Raw
History Blame Contribute Delete
4.96 kB
import os
import re
from flask import Flask, jsonify, send_from_directory, render_template, request
app = Flask(__name__)
PROBLEMS_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'problems')
def parse_problem_metadata(filename):
filepath = os.path.join(PROBLEMS_DIR, filename)
with open(filepath, 'r', encoding='utf-8') as f:
content = f.read()
# 默认标题为文件名
title = filename
# 尝试解析 @title
# 匹配 /** ... @title 标题 ... */ 或 // @title 标题
title_match = re.search(r'@title\s+(.+)', content)
if title_match:
title = title_match.group(1).strip()
# 解析 @category
category_match = re.search(r'@category\s+(.+)', content)
category = category_match.group(1).strip() if category_match else '练习题'
# 解析 @pinned
pinned_match = re.search(r'@pinned\s+(.+)', content)
is_pinned = (pinned_match.group(1).strip().lower() == 'true') if pinned_match else False
return {
'id': filename,
'title': title,
'category': category,
'pinned': is_pinned,
'content': content,
'ctime': os.path.getctime(filepath)
}
@app.route('/')
def index():
return render_template('index.html')
@app.route('/api/problems', methods=['GET'])
def get_problems():
files = [f for f in os.listdir(PROBLEMS_DIR) if f.endswith('.js') or f.endswith('.ts')]
# 按创建时间倒序排序 (最新的在最前)
files.sort(key=lambda x: os.path.getctime(os.path.join(PROBLEMS_DIR, x)), reverse=True)
problems = []
for f in files:
try:
problems.append(parse_problem_metadata(f))
except Exception as e:
print(f"Error parsing {f}: {e}")
return jsonify(problems)
@app.route('/api/problems', methods=['POST'])
def create_problem():
data = request.json
filename = data.get('filename')
category = data.get('category', '练习题')
if not filename:
return jsonify({'error': 'Filename is required'}), 400
if not (filename.endswith('.js') or filename.endswith('.ts')):
filename += '.js'
filepath = os.path.join(PROBLEMS_DIR, filename)
if os.path.exists(filepath):
return jsonify({'error': 'File already exists'}), 409
# 默认模板
content = f"""/**
* @title {filename}
* @category {category}
* @description 在此处添加题目描述
*/
function solve() {{
// TODO: Implement solution
}}
console.log(solve());
"""
try:
with open(filepath, 'w', encoding='utf-8') as f:
f.write(content)
return jsonify(parse_problem_metadata(filename)), 201
except Exception as e:
return jsonify({'error': str(e)}), 500
@app.route('/api/problems/<path:filename>', methods=['GET'])
def get_problem_content(filename):
return send_from_directory(PROBLEMS_DIR, filename)
@app.route('/api/problems/<path:filename>', methods=['PUT'])
def update_problem(filename):
filepath = os.path.join(PROBLEMS_DIR, filename)
if not os.path.exists(filepath):
return jsonify({'error': 'File not found'}), 404
data = request.json
# Handle Rename
new_filename = data.get('new_filename')
if new_filename:
if not (new_filename.endswith('.js') or new_filename.endswith('.ts')):
new_filename += '.js'
new_filepath = os.path.join(PROBLEMS_DIR, new_filename)
if os.path.exists(new_filepath) and new_filename != filename:
return jsonify({'error': 'Target filename already exists'}), 409
try:
os.rename(filepath, new_filepath)
return jsonify(parse_problem_metadata(new_filename))
except Exception as e:
return jsonify({'error': str(e)}), 500
# Handle Content Update
content = data.get('content')
if content is not None:
try:
with open(filepath, 'w', encoding='utf-8') as f:
f.write(content)
# 返回新的 metadata 以便前端更新标题
return jsonify(parse_problem_metadata(filename))
except Exception as e:
return jsonify({'error': str(e)}), 500
return jsonify({'error': 'No valid operation specified'}), 400
@app.route('/api/problems/<path:filename>', methods=['DELETE'])
def delete_problem(filename):
filepath = os.path.join(PROBLEMS_DIR, filename)
if not os.path.exists(filepath):
return jsonify({'error': 'File not found'}), 404
try:
os.remove(filepath)
return jsonify({'message': 'Deleted successfully'})
except Exception as e:
return jsonify({'error': str(e)}), 500
if __name__ == '__main__':
# 确保 problems 目录存在
if not os.path.exists(PROBLEMS_DIR):
os.makedirs(PROBLEMS_DIR)
app.run(host='0.0.0.0', port=7860, debug=True)