378 lines
12 KiB
Python
378 lines
12 KiB
Python
import os
|
||
import re
|
||
|
||
CLASS_DIR = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), '.claude', 'memory', 'class')
|
||
|
||
def extract_file_info(file_path):
|
||
parts = os.path.normpath(file_path).split(os.sep)
|
||
filename = os.path.basename(file_path)
|
||
|
||
class_name = ''
|
||
for i, p in enumerate(parts):
|
||
if p == 'summaries' and i >= 1:
|
||
class_name = parts[i-1]
|
||
break
|
||
|
||
date_match = re.match(r'(\d{4})(\d{2})(\d{2})_', filename)
|
||
date_str = ''
|
||
if date_match:
|
||
date_str = f'{date_match.group(1)}-{date_match.group(2)}-{date_match.group(3)}'
|
||
|
||
course_match = re.search(r'(AICODE03|SPIKE|DISC|CREATE|MECH|TUBE|INVENT|WEDO)-(\d+)', filename)
|
||
course_code = ''
|
||
if course_match:
|
||
prefix = course_match.group(1)
|
||
if prefix == 'WEDO':
|
||
prefix = 'CREATE'
|
||
num = course_match.group(2).zfill(3)
|
||
course_code = f'{prefix}-{num}'
|
||
|
||
return {
|
||
'class_name': class_name,
|
||
'date': date_str,
|
||
'course_code': course_code,
|
||
'filename': filename,
|
||
}
|
||
|
||
def is_new_format(text):
|
||
return '## 本周课评状态' in text and '## 本周班级整体情况' in text
|
||
|
||
def is_v2_format(text):
|
||
return '## 本周概览' in text
|
||
|
||
def is_v3_format(text):
|
||
return '课评状态面板' in text or '## 📊' in text
|
||
|
||
def detect_format(text):
|
||
if is_new_format(text):
|
||
return 'v1'
|
||
if is_v2_format(text):
|
||
return 'v2'
|
||
if is_v3_format(text):
|
||
return 'v3'
|
||
return 'unknown'
|
||
|
||
def extract_week(text):
|
||
m = re.search(r'第(\d+)周', text)
|
||
return m.group(1) if m else ''
|
||
|
||
def extract_theme(text):
|
||
lines = text.split('\n')
|
||
for line in lines:
|
||
if '课程主题' in line:
|
||
m = re.search(r'[::]\s*(.*)', line)
|
||
if m:
|
||
return m.group(1).strip()
|
||
return ''
|
||
|
||
def extract_name_from_header(text):
|
||
text = re.sub(r'\s*[((][^))]*[))]', '', text)
|
||
text = re.sub(r'\s*[-—]\s*.*', '', text)
|
||
text = re.sub(r'^\d+[.、]\s*', '', text)
|
||
text = re.sub(r'\s*☑.*', '', text)
|
||
text = re.sub(r'\[.*?\]', '', text)
|
||
return text.strip()
|
||
|
||
def extract_student_feedbacks(text):
|
||
feedbacks = []
|
||
lines = text.split('\n')
|
||
i = 0
|
||
current_student = {}
|
||
content = []
|
||
in_feedback = False
|
||
|
||
while i < len(lines):
|
||
line = lines[i]
|
||
stripped = line.strip()
|
||
|
||
if any(stripped.startswith(p) for p in ['## 班级整体观察', '## 本周班级整体情况', '## 教师周记', '## 数据统计', '## 本周概览', '## 详细课评']):
|
||
if current_student and current_student.get('name'):
|
||
current_student['content'] = '\n'.join(content).strip()
|
||
feedbacks.append(current_student)
|
||
current_student = {}
|
||
content = []
|
||
in_feedback = False
|
||
|
||
if re.match(r'^###\s+\S', stripped) and '### 课程信息' not in stripped and '### 学生表现' not in stripped and '### 快速统计' not in stripped and '### 学生状态' not in stripped and '### 课程目标' not in stripped:
|
||
if current_student and current_student.get('name'):
|
||
current_student['content'] = '\n'.join(content).strip()
|
||
feedbacks.append(current_student)
|
||
|
||
full_line = stripped
|
||
student_name = extract_name_from_header(full_line)
|
||
if student_name:
|
||
current_student = {'name': student_name}
|
||
content = []
|
||
in_feedback = True
|
||
i += 1
|
||
continue
|
||
|
||
if in_feedback:
|
||
content.append(line)
|
||
|
||
i += 1
|
||
|
||
if current_student and current_student.get('name'):
|
||
current_student['content'] = '\n'.join(content).strip()
|
||
feedbacks.append(current_student)
|
||
|
||
return feedbacks
|
||
|
||
def extract_v2_feedbacks(text):
|
||
feedbacks = []
|
||
lines = text.split('\n')
|
||
i = 0
|
||
current_student = None
|
||
content = []
|
||
in_detail = False
|
||
|
||
while i < len(lines):
|
||
line = lines[i]
|
||
stripped = line.strip()
|
||
|
||
if stripped.startswith('## 班级整体观察') or stripped.startswith('## 教师周记') or stripped.startswith('## 数据统计') or stripped.startswith('## 本周班级整体情况'):
|
||
if current_student:
|
||
current_student['content'] = '\n'.join(content).strip()
|
||
feedbacks.append(current_student)
|
||
current_student = None
|
||
content = []
|
||
in_detail = False
|
||
|
||
if stripped == '## 详细课评':
|
||
in_detail = True
|
||
i += 1
|
||
continue
|
||
|
||
if in_detail and re.match(r'^###\s+\S', stripped):
|
||
if current_student:
|
||
current_student['content'] = '\n'.join(content).strip()
|
||
feedbacks.append(current_student)
|
||
|
||
full_line = stripped[4:]
|
||
student_name = extract_name_from_header(full_line)
|
||
if student_name:
|
||
current_student = {'name': student_name}
|
||
content = []
|
||
i += 1
|
||
continue
|
||
|
||
if in_detail and current_student:
|
||
content.append(line)
|
||
|
||
i += 1
|
||
|
||
if current_student:
|
||
current_student['content'] = '\n'.join(content).strip()
|
||
feedbacks.append(current_student)
|
||
|
||
return feedbacks
|
||
|
||
def extract_overall(text):
|
||
overall_lines = []
|
||
lines = text.split('\n')
|
||
in_overall = False
|
||
capturing = False
|
||
|
||
for line in lines:
|
||
stripped = line.strip()
|
||
if stripped == '## 班级整体观察' or stripped == '## 本周班级整体情况':
|
||
in_overall = True
|
||
capturing = True
|
||
continue
|
||
if stripped in ['## 教师周记', '## 数据统计', '## 详细课评', '## 本周概览', '## 本周课评状态']:
|
||
capturing = False
|
||
continue
|
||
if in_overall and capturing:
|
||
overall_lines.append(line)
|
||
|
||
return '\n'.join(overall_lines).strip()
|
||
|
||
def v2_to_v1(text, file_info):
|
||
week = extract_week(text)
|
||
theme = extract_theme(text)
|
||
feedbacks = extract_v2_feedbacks(text)
|
||
overall = extract_overall(text)
|
||
|
||
lines = []
|
||
lines.append(f'# {file_info["class_name"]} 第{week}周汇总')
|
||
lines.append('')
|
||
lines.append(f'> 课程代码:{file_info["course_code"]}')
|
||
if theme:
|
||
lines.append(f'> 课程主题:{theme}')
|
||
lines.append(f'> 上课日期:{file_info["date"]}')
|
||
lines.append(f'> 班级人数:待确认')
|
||
lines.append('')
|
||
lines.append('---')
|
||
lines.append('')
|
||
lines.append('## 本周课评状态')
|
||
lines.append('')
|
||
lines.append('| 学生 | 状态 | 类型 | 档案位置 | 操作 |')
|
||
lines.append('|:-----|:----:|:----:|:---------|:----:|')
|
||
for fb in feedbacks:
|
||
lines.append(f'| {fb["name"]} | ✅ 已保存 | 常规学生 | 本班 | [查看] |')
|
||
lines.append('')
|
||
lines.append('---')
|
||
lines.append('')
|
||
lines.append('## 学生课评列表')
|
||
lines.append('')
|
||
for fb in feedbacks:
|
||
lines.append(f'### {fb["name"]} - 常规学生 ✅')
|
||
lines.append('')
|
||
if fb.get('content'):
|
||
lines.append(fb['content'])
|
||
lines.append('')
|
||
lines.append('**教师备注**:')
|
||
lines.append('- 状态:已保存')
|
||
lines.append('- 个人档案:已同步')
|
||
lines.append('- 亮点:待补充')
|
||
lines.append('')
|
||
lines.append('---')
|
||
lines.append('')
|
||
|
||
lines.append('## 本周班级整体情况')
|
||
lines.append('')
|
||
if overall:
|
||
lines.append(overall)
|
||
else:
|
||
lines.append('### 课程目标达成度')
|
||
lines.append('- **知识点掌握**:待补充')
|
||
lines.append('- **技能操作**:待补充')
|
||
lines.append('')
|
||
lines.append('### 共性亮点')
|
||
lines.append('1. ')
|
||
lines.append('')
|
||
lines.append('### 共性问题')
|
||
lines.append('1. 无明显共性问题')
|
||
|
||
lines.append('')
|
||
lines.append('---')
|
||
lines.append('')
|
||
lines.append(f'*生成时间:{file_info["date"]}*')
|
||
|
||
return '\n'.join(lines)
|
||
|
||
def v3_to_v1(text, file_info):
|
||
week = extract_week(text)
|
||
theme = extract_theme(text)
|
||
feedbacks = extract_student_feedbacks(text)
|
||
overall = extract_overall(text)
|
||
|
||
lines = []
|
||
lines.append(f'# {file_info["class_name"]} 第{week}周汇总')
|
||
lines.append('')
|
||
lines.append(f'> 课程代码:{file_info["course_code"]}')
|
||
if theme:
|
||
lines.append(f'> 课程主题:{theme}')
|
||
lines.append(f'> 上课日期:{file_info["date"]}')
|
||
lines.append(f'> 班级人数:待确认')
|
||
lines.append('')
|
||
lines.append('---')
|
||
lines.append('')
|
||
lines.append('## 本周课评状态')
|
||
lines.append('')
|
||
lines.append('| 学生 | 状态 | 类型 | 档案位置 | 操作 |')
|
||
lines.append('|:-----|:----:|:----:|:---------|:----:|')
|
||
for fb in feedbacks:
|
||
lines.append(f'| {fb["name"]} | ✅ 已保存 | 常规学生 | 本班 | [查看] |')
|
||
lines.append('')
|
||
lines.append('---')
|
||
lines.append('')
|
||
lines.append('## 学生课评列表')
|
||
lines.append('')
|
||
for fb in feedbacks:
|
||
lines.append(f'### {fb["name"]} - 常规学生 ✅')
|
||
lines.append('')
|
||
if fb.get('content'):
|
||
lines.append(fb['content'])
|
||
lines.append('')
|
||
lines.append('**教师备注**:')
|
||
lines.append('- 状态:已保存')
|
||
lines.append('- 个人档案:已同步')
|
||
lines.append('- 亮点:待补充')
|
||
lines.append('')
|
||
lines.append('---')
|
||
lines.append('')
|
||
|
||
lines.append('## 本周班级整体情况')
|
||
lines.append('')
|
||
if overall:
|
||
lines.append(overall)
|
||
else:
|
||
lines.append('### 课程目标达成度')
|
||
lines.append('- **知识点掌握**:待补充')
|
||
lines.append('- **技能操作**:待补充')
|
||
lines.append('')
|
||
lines.append('### 共性亮点')
|
||
lines.append('1. ')
|
||
lines.append('')
|
||
lines.append('### 共性问题')
|
||
lines.append('1. 无明显共性问题')
|
||
|
||
lines.append('')
|
||
lines.append('---')
|
||
lines.append('')
|
||
lines.append(f'*生成时间:{file_info["date"]}*')
|
||
|
||
return '\n'.join(lines)
|
||
|
||
def process_summary(file_path, force=False):
|
||
with open(file_path, 'r', encoding='utf-8') as f:
|
||
text = f.read()
|
||
|
||
file_info = extract_file_info(file_path)
|
||
fmt = detect_format(text)
|
||
|
||
if fmt == 'v1' and not force:
|
||
return False
|
||
|
||
if fmt == 'v1' and force:
|
||
pass
|
||
elif fmt == 'v2':
|
||
pass
|
||
elif fmt == 'v3':
|
||
pass
|
||
else:
|
||
return False
|
||
|
||
new_text = v2_to_v1(text, file_info) if fmt in ['v1', 'v2'] else v3_to_v1(text, file_info)
|
||
|
||
with open(file_path, 'w', encoding='utf-8') as f:
|
||
f.write(new_text)
|
||
return True
|
||
|
||
def main():
|
||
import sys
|
||
force = '--force' in sys.argv
|
||
|
||
updated = 0
|
||
skipped = 0
|
||
errors = 0
|
||
|
||
for root, dirs, files in os.walk(CLASS_DIR):
|
||
if 'summaries' not in root.split(os.sep):
|
||
continue
|
||
|
||
for f in files:
|
||
if not f.endswith('.md'):
|
||
continue
|
||
file_path = os.path.join(root, f)
|
||
try:
|
||
if process_summary(file_path):
|
||
updated += 1
|
||
rel = os.path.relpath(file_path, CLASS_DIR)
|
||
print(f' ✅ 已更新: {rel}')
|
||
else:
|
||
skipped += 1
|
||
except Exception as e:
|
||
errors += 1
|
||
rel = os.path.relpath(file_path, CLASS_DIR)
|
||
print(f' ❌ 错误: {rel} - {e}')
|
||
|
||
print(f'\n{"="*50}')
|
||
print(f'更新完成!')
|
||
print(f' ✅ 已更新: {updated} 个文件')
|
||
print(f' ⏭️ 已跳过(已是最新格式): {skipped} 个文件')
|
||
print(f' ❌ 错误: {errors} 个文件')
|
||
|
||
if __name__ == '__main__':
|
||
main() |