getGradeRanking method
Fetches grade ranking data for all semesters.
Returns ranking entries including class, group, and department levels.
Semester information is spans multiple ranking type rows using rowspan.
Implementation
Future<List<GradeRankingDto>> getGradeRanking() async {
final response = await _studentQueryDio.get('QryRank.jsp');
final document = parse(response.data);
final table = document.querySelector('table');
if (table == null) return [];
final semesterPattern = RegExp(r'(\d+)\s*-\s*(\d+)');
final results = <GradeRankingDto>[];
SemesterDto? currentSemester;
var currentEntries = <GradeRankingEntryDto>[];
for (final row in table.querySelectorAll('tr')) {
final cells = row.querySelectorAll('td').toList();
int dataStart;
if (cells.length == 8) {
// Starting new semester block
if (currentSemester != null && currentEntries.isNotEmpty) {
results.add((semester: currentSemester, entries: currentEntries));
currentEntries = [];
}
final semesterText = cells[0].nodes
.where((node) => node.nodeType == Node.TEXT_NODE)
.firstOrNull
?.text;
final match = semesterPattern.firstMatch(semesterText ?? '');
if (match == null) continue;
currentSemester = (
year: int.parse(match.group(1)!),
term: int.parse(match.group(2)!),
);
dataStart = 1;
} else if (cells.length == 7) {
dataStart = 0;
} else {
continue;
}
final type = _parseRankingType(cells[dataStart].text);
if (type == null) continue;
final semesterRank = int.tryParse(cells[dataStart + 1].text.trim());
final semesterTotal = int.tryParse(cells[dataStart + 2].text.trim());
final grandTotalRank = int.tryParse(cells[dataStart + 4].text.trim());
final grandTotalTotal = int.tryParse(cells[dataStart + 5].text.trim());
if (semesterRank == null ||
semesterTotal == null ||
grandTotalRank == null ||
grandTotalTotal == null) {
continue;
}
currentEntries.add((
type: type,
semesterRank: semesterRank,
semesterTotal: semesterTotal,
grandTotalRank: grandTotalRank,
grandTotalTotal: grandTotalTotal,
));
}
if (currentSemester != null && currentEntries.isNotEmpty) {
results.add((semester: currentSemester, entries: currentEntries));
}
return results;
}