getSyllabus method
Fetches the detailed syllabus for a course offering.
Returns syllabus information including course objectives, textbooks, grading policy, and weekly plan.
The courseNumber should be a course offering number (e.g., "346774"),
and syllabusId should be obtained from the syllabusId field of a
ScheduleDto.
Throws an Exception if the syllabus tables are not found.
Implementation
Future<SyllabusDto> getSyllabus({
required String courseNumber,
required String syllabusId,
}) async {
final response = await _courseDio.get(
'ShowSyllabus.jsp',
queryParameters: {'snum': courseNumber, 'code': syllabusId},
);
final document = parse(response.data);
final tables = document.querySelectorAll('table');
if (tables.length < 2) {
throw Exception('Syllabus tables not found.');
}
// Table 0: Header table (課程基本資料)
// Row 1 contains: semester, number, name, phase, credits, hours, type,
// instructor, classes, enrolled, withdrawn, remarks
final headerRow = tables[0].querySelectorAll('tr')[1];
final headerCells = headerRow.querySelectorAll('td');
final typeSymbol = _parseCellText(headerCells[6]);
final type = CourseType.values.firstWhereOrNull(
(t) => t.symbol == typeSymbol,
);
final enrolled = int.tryParse(headerCells[9].text.trim());
final withdrawn = int.tryParse(headerCells[10].text.trim());
// Table 1: Syllabus table (教學大綱與進度)
// Rows 0-2: Label and value both in th elements
// Rows 3+: Label in th, value in td (some with textarea)
final syllabusRows = tables[1].querySelectorAll('tr');
final email = _parseCellText(syllabusRows[1].querySelectorAll('th')[1]);
final lastUpdatedText = _parseCellText(
syllabusRows[2].querySelectorAll('th')[1],
);
final lastUpdated = DateTime.tryParse(lastUpdatedText ?? '');
// Rows 3-5 have textarea elements for long content
final objective = _parseTextareaValue(syllabusRows[3]);
final weeklyPlan = _parseTextareaValue(syllabusRows[4]);
final evaluation = _parseTextareaValue(syllabusRows[5]);
final materials = _parseTextareaValue(syllabusRows[6]);
final remarksTd = syllabusRows[10].querySelector('td');
final remarks = remarksTd != null ? _parseCellText(remarksTd) : null;
return (
type: type,
enrolled: enrolled,
withdrawn: withdrawn,
email: email,
lastUpdated: lastUpdated,
objective: objective,
weeklyPlan: weeklyPlan,
evaluation: evaluation,
materials: materials,
remarks: remarks,
);
}