Spaces:
Sleeping
Sleeping
File size: 4,955 Bytes
adb7761 b0fefeb adb7761 b0fefeb adb7761 b0fefeb adb7761 b0fefeb adb7761 b0fefeb adb7761 b0fefeb adb7761 b0fefeb adb7761 4c2d124 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | 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)
|