From 25f968b2a1a0ab556aecd5e559f4e8ac9daafa0c Mon Sep 17 00:00:00 2001 From: SIMAOMARTA Date: Tue, 30 Jun 2026 22:48:41 +0100 Subject: [PATCH] fix: support for reading students email --- .../parsers/parser_course_unit_info.dart | 38 ++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/packages/uni_app/lib/controller/parsers/parser_course_unit_info.dart b/packages/uni_app/lib/controller/parsers/parser_course_unit_info.dart index f8be2f519..503b71755 100644 --- a/packages/uni_app/lib/controller/parsers/parser_course_unit_info.dart +++ b/packages/uni_app/lib/controller/parsers/parser_course_unit_info.dart @@ -1,5 +1,6 @@ import 'dart:convert'; +import 'package:html/dom.dart' as dom; import 'package:html/parser.dart'; import 'package:http/http.dart' as http; import 'package:uni/controller/fetchers/course_units_fetcher/course_units_info_fetcher.dart'; @@ -166,7 +167,8 @@ List parseCourseUnitClasses( final columns = row.querySelectorAll('td.k.t'); final studentName = columns[0].children[0].innerHtml; final studentNumber = int.tryParse(columns[1].innerHtml.trim()) ?? 0; - final studentMail = columns[2].innerHtml; + final studentMail = + _extractStudentEmail(columns[2]) ?? studentNumber.toString(); final studentPhoto = Uri.parse( '${baseUrl}fotografias_service.foto?pct_cod=$studentNumber', @@ -213,3 +215,37 @@ Map parseOccurences(http.Response response) { } return result; } + +String? _decodeCloudflareEmail(String encodedHex) { + try { + final key = int.parse(encodedHex.substring(0, 2), radix: 16); + final buffer = StringBuffer(); + for (var i = 2; i < encodedHex.length; i += 2) { + final charCode = + int.parse(encodedHex.substring(i, i + 2), radix: 16) ^ key; + buffer.writeCharCode(charCode); + } + final decoded = buffer.toString(); + return decoded.contains('@') ? decoded : null; + } catch (_) { + return null; + } +} + +String? _extractStudentEmail(dom.Element cell) { + final cfEl = cell.querySelector('[data-cfemail]'); + final cfEncoded = cfEl?.attributes['data-cfemail']; + if (cfEncoded != null) { + final decoded = _decodeCloudflareEmail(cfEncoded); + if (decoded != null) { + return decoded; + } + } + + final text = cell.text.trim(); + if (text.contains('@')) { + return text; + } + + return null; +}