SarahXia0405 commited on
Commit
ec485a2
·
verified ·
1 Parent(s): 9470e5c

Create syllabus_utils.py

Browse files
Files changed (1) hide show
  1. syllabus_utils.py +92 -0
syllabus_utils.py ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # syllabus_utils.py
2
+ """
3
+ 工具函数:
4
+ - 解析 Syllabus(.docx / .pdf)
5
+ - 提取课程大纲 topics
6
+ """
7
+
8
+ import os
9
+ from typing import List
10
+
11
+ from docx import Document
12
+ from pypdf import PdfReader
13
+
14
+ from config import DEFAULT_COURSE_TOPICS
15
+
16
+
17
+ def parse_syllabus_docx(path: str) -> List[str]:
18
+ """
19
+ 从 .docx 文件中提取课程大纲。
20
+ 这里做一个简单版本:按段落抽取,过滤空行。
21
+ 后面如果你想按 Week 0/1/2 更精细地切,可以再优化这里。
22
+ """
23
+ doc = Document(path)
24
+ paragraphs = [p.text.strip() for p in doc.paragraphs if p.text and p.text.strip()]
25
+
26
+ # 如果包含 "Week" 这样的前缀,用这些段落作为 topics
27
+ week_like = [p for p in paragraphs if p.lower().startswith("week ")]
28
+ if week_like:
29
+ return week_like
30
+
31
+ # 否则就截取前若干行当作大纲
32
+ return paragraphs[: len(DEFAULT_COURSE_TOPICS)] or DEFAULT_COURSE_TOPICS
33
+
34
+
35
+ def parse_syllabus_pdf(path: str) -> List[str]:
36
+ """
37
+ 简单版 PDF 解析:
38
+ - 把所有页面的文本抽出来
39
+ - 按空行切成 chunk
40
+ - 返回非空 chunk 列表
41
+ """
42
+ reader = PdfReader(path)
43
+ pages_text = []
44
+ for page in reader.pages:
45
+ text = page.extract_text() or ""
46
+ if text.strip():
47
+ pages_text.append(text)
48
+
49
+ full_text = "\n".join(pages_text)
50
+
51
+ # 按空行分段
52
+ raw_chunks = [chunk.strip() for chunk in full_text.split("\n\n")]
53
+ chunks = [c for c in raw_chunks if c]
54
+
55
+ # 作为 syllabus 使用时,我们只取前若干段作为“课程大纲”
56
+ return chunks[: len(DEFAULT_COURSE_TOPICS)] or DEFAULT_COURSE_TOPICS
57
+
58
+
59
+ def extract_course_topics_from_file(file_obj, doc_type: str) -> List[str]:
60
+ """
61
+ 根据上传文件和 doc_type 提取课程大纲 topics。
62
+ - 只有 doc_type == "Syllabus" 时才尝试从文件解析;否则用默认大纲。
63
+ - 支持 .docx + .pdf
64
+ """
65
+ if file_obj is None:
66
+ return DEFAULT_COURSE_TOPICS
67
+
68
+ if doc_type != "Syllabus":
69
+ # 不是 Syllabus,就不要动课程大纲(可以用默认)
70
+ return DEFAULT_COURSE_TOPICS
71
+
72
+ # Gradio File 对象通常有 .name 属性(临时文件路径)
73
+ file_path = getattr(file_obj, "name", None)
74
+ if not file_path:
75
+ return DEFAULT_COURSE_TOPICS
76
+
77
+ ext = os.path.splitext(file_path)[1].lower()
78
+
79
+ try:
80
+ if ext == ".docx":
81
+ topics = parse_syllabus_docx(file_path)
82
+ elif ext == ".pdf":
83
+ topics = parse_syllabus_pdf(file_path)
84
+ else:
85
+ print(f"[Syllabus] Unsupported file type for syllabus: {ext}")
86
+ topics = DEFAULT_COURSE_TOPICS
87
+ except Exception as e:
88
+ print(f"[Syllabus] parse error: {repr(e)}")
89
+ topics = DEFAULT_COURSE_TOPICS
90
+
91
+ # 最后兜底,避免返回空列表
92
+ return topics or DEFAULT_COURSE_TOPICS