ISMIS Helper: cross-browser build, CI, PDF fixes, Chrome download fix
build-extension / build (push) Successful in 37s
build-extension / build (push) Successful in 37s
Squash merge of feat/ismis-helper into prod.
This commit was merged in pull request #1.
This commit is contained in:
+97
@@ -0,0 +1,97 @@
|
||||
(function (root, factory) {
|
||||
if (typeof module === 'object' && module.exports) {
|
||||
module.exports = factory();
|
||||
} else {
|
||||
root.ISMIStools = Object.assign(root.ISMIStools || {}, factory());
|
||||
}
|
||||
})(typeof self !== 'undefined' ? self : this, function () {
|
||||
'use strict';
|
||||
|
||||
function cleanText(s) {
|
||||
return String(s == null ? '' : s)
|
||||
.replace(/<[^>]+>/g, ' ')
|
||||
.replace(/ /gi, ' ')
|
||||
.replace(/\s+/g, ' ')
|
||||
.trim();
|
||||
}
|
||||
|
||||
function extractRows(html) {
|
||||
const rows = [];
|
||||
const trRe = /<tr[^>]*>([\s\S]*?)<\/tr>/gi;
|
||||
let trMatch;
|
||||
while ((trMatch = trRe.exec(html)) !== null) {
|
||||
const rowHtml = trMatch[1];
|
||||
if (/<th/i.test(rowHtml)) continue;
|
||||
const tds = [];
|
||||
const tdRe = /<td[^>]*>([\s\S]*?)<\/td>/gi;
|
||||
let tdMatch;
|
||||
while ((tdMatch = tdRe.exec(rowHtml)) !== null) {
|
||||
tds.push(cleanText(tdMatch[1]));
|
||||
}
|
||||
rows.push(tds);
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
function parseStudyLoadTable(html) {
|
||||
return extractRows(html)
|
||||
.filter((tds) => tds.length >= 6)
|
||||
.map((tds) => ({
|
||||
group: tds[0],
|
||||
courseCode: tds[1],
|
||||
schedule: tds[2],
|
||||
faculty: tds[3],
|
||||
units: tds[4],
|
||||
status: tds[5]
|
||||
}));
|
||||
}
|
||||
|
||||
function parseProfilePage(html) {
|
||||
const result = {};
|
||||
const h3Match = /<h3[^>]*>([\s\S]*?)<\/h3>/i.exec(html);
|
||||
const bMatch = (h3Match && /<b>([\s\S]*?)<\/b>/i.exec(h3Match[1])) ||
|
||||
/<b>([\s\S]*?)<\/b>/i.exec(html);
|
||||
if (bMatch) result.program = cleanText(bMatch[1]);
|
||||
|
||||
const smallMatch = /<small>([\s\S]*?)<\/small>/i.exec(html);
|
||||
if (smallMatch) {
|
||||
const lines = smallMatch[1].split(/<br\s*\/?>/i).map(cleanText).filter(Boolean);
|
||||
result.semester = lines[lines.length - 1] || '';
|
||||
}
|
||||
|
||||
const kvRe = /<td[^>]*>([\s\S]*?)<\/td>\s*<td[^>]*class=["'][^"']*\bbold\b[^"']*["'][^>]*>([\s\S]*?)<\/td>/gi;
|
||||
let m;
|
||||
while ((m = kvRe.exec(html)) !== null) {
|
||||
const key = cleanText(m[1]);
|
||||
const val = cleanText(m[2]);
|
||||
if (/full name/i.test(key)) result.fullName = val;
|
||||
else if (/student id/i.test(key)) result.studentId = val;
|
||||
else if (/year level/i.test(key)) result.yearLevel = val;
|
||||
else if (/student type/i.test(key)) result.studentType = val;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function parseOfferedCourses(html) {
|
||||
return extractRows(html)
|
||||
.filter((tds) => tds.length >= 2)
|
||||
.map((tds) => ({
|
||||
courseCode: tds[0].replace(/\s*-\s*Group\s*\d+$/i, '').trim(),
|
||||
description: tds[1]
|
||||
}));
|
||||
}
|
||||
|
||||
function filterStudyLoadCourses(courses) {
|
||||
return (courses || []).filter(
|
||||
(c) => String(c.status || '').trim().toUpperCase() !== 'DISSOLVED'
|
||||
);
|
||||
}
|
||||
|
||||
function sumUnits(courses) {
|
||||
return (courses || [])
|
||||
.reduce((sum, c) => sum + (parseFloat(c.units) || 0), 0)
|
||||
.toFixed(2);
|
||||
}
|
||||
|
||||
return { parseStudyLoadTable, parseProfilePage, parseOfferedCourses, filterStudyLoadCourses, sumUnits };
|
||||
});
|
||||
Reference in New Issue
Block a user