reddy-api-srm 1.0.6 → 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/parser/parseCalender.js +59 -25
- package/package.json +2 -2
|
@@ -37,54 +37,88 @@ exports.parseCalendar = parseCalendar;
|
|
|
37
37
|
const cheerio = __importStar(require("cheerio"));
|
|
38
38
|
async function parseCalendar(response) {
|
|
39
39
|
try {
|
|
40
|
+
let htmlContent = null;
|
|
41
|
+
// Method 1: zmlvalue approach (Zoho Page Builder pages)
|
|
40
42
|
const $outer = cheerio.load(response);
|
|
41
43
|
const zmlValue = $outer("div.zc-pb-embed-placeholder-content").attr("zmlvalue");
|
|
42
|
-
if (
|
|
44
|
+
if (zmlValue) {
|
|
45
|
+
htmlContent = zmlValue;
|
|
46
|
+
}
|
|
47
|
+
// Method 2: pageSanitizer.sanitize approach (Zoho Report pages)
|
|
48
|
+
if (!htmlContent) {
|
|
49
|
+
const match = response.match(/pageSanitizer\.sanitize\('(.*)'\);/s);
|
|
50
|
+
if (match && match[1]) {
|
|
51
|
+
htmlContent = match[1]
|
|
52
|
+
.replace(/\\x([0-9A-Fa-f]{2})/g, (_, hex) => String.fromCharCode(parseInt(hex, 16)))
|
|
53
|
+
.replace(/\\\\/g, "")
|
|
54
|
+
.replace(/\\'/g, "'");
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (!htmlContent) {
|
|
43
58
|
return { error: "Failed to extract calendar details", status: 404 };
|
|
44
59
|
}
|
|
45
|
-
const $inner = cheerio.load(
|
|
46
|
-
|
|
60
|
+
const $inner = cheerio.load(htmlContent);
|
|
61
|
+
// Try multiple selectors for the calendar table
|
|
62
|
+
let $mainTable = $inner("table[bgcolor='#FAFCFE']");
|
|
63
|
+
if ($mainTable.length === 0) $mainTable = $inner("table[bgcolor='#fafcfe']");
|
|
64
|
+
if ($mainTable.length === 0) {
|
|
65
|
+
// Find the largest table that looks like a calendar
|
|
66
|
+
let bestTable = null;
|
|
67
|
+
let bestThCount = 0;
|
|
68
|
+
$inner("table").each((_, el) => {
|
|
69
|
+
const thCount = $inner(el).find("th").length;
|
|
70
|
+
if (thCount > bestThCount) {
|
|
71
|
+
bestThCount = thCount;
|
|
72
|
+
bestTable = $inner(el);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
if (bestTable && bestThCount > 3) $mainTable = bestTable;
|
|
76
|
+
}
|
|
47
77
|
if ($mainTable.length === 0) {
|
|
48
78
|
return { error: "Could not find the main calendar table.", status: 500 };
|
|
49
79
|
}
|
|
50
80
|
const $headerRow = $mainTable.find("tr").first();
|
|
51
81
|
const $ths = $headerRow.find("th");
|
|
52
82
|
const monthsData = [];
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
83
|
+
// Auto-detect columns per month by trying common values
|
|
84
|
+
let colsPerMonth = 5;
|
|
85
|
+
const MONTH_NAMES = ["january","february","march","april","may","june","july","august","september","october","november","december"];
|
|
86
|
+
for (const cols of [5, 4, 6, 3]) {
|
|
87
|
+
const candidate = [];
|
|
88
|
+
for (let i = 0;; i++) {
|
|
89
|
+
const idx = i * cols + Math.floor(cols / 2);
|
|
90
|
+
if (idx >= $ths.length) break;
|
|
91
|
+
let name = $ths.eq(idx).find("strong").text().trim();
|
|
92
|
+
if (!name) name = $ths.eq(idx).text().trim();
|
|
93
|
+
if (name && MONTH_NAMES.includes(name.toLowerCase())) {
|
|
94
|
+
candidate.push(name);
|
|
95
|
+
} else {
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
60
98
|
}
|
|
61
|
-
|
|
99
|
+
if (candidate.length > 0) {
|
|
100
|
+
colsPerMonth = cols;
|
|
101
|
+
candidate.forEach(m => monthsData.push({ month: m, days: [] }));
|
|
62
102
|
break;
|
|
63
103
|
}
|
|
64
104
|
}
|
|
105
|
+
if (monthsData.length === 0) {
|
|
106
|
+
return { error: "Could not parse month headers from calendar.", status: 500 };
|
|
107
|
+
}
|
|
65
108
|
const $dataRows = $mainTable.find("tr").slice(1).toArray();
|
|
66
109
|
$dataRows.forEach((rowElement) => {
|
|
67
110
|
const $tds = $inner(rowElement).find("td");
|
|
68
111
|
monthsData.forEach((month, monthIndex) => {
|
|
69
|
-
const offset = monthIndex *
|
|
112
|
+
const offset = monthIndex * colsPerMonth;
|
|
70
113
|
if (offset + 3 >= $tds.length)
|
|
71
114
|
return;
|
|
72
115
|
const date = $tds.eq(offset).text().trim();
|
|
73
116
|
if (!date)
|
|
74
117
|
return;
|
|
75
|
-
const day = $tds
|
|
76
|
-
|
|
77
|
-
.text()
|
|
78
|
-
|
|
79
|
-
const event = $tds
|
|
80
|
-
.eq(offset + 2)
|
|
81
|
-
.find("strong")
|
|
82
|
-
.text()
|
|
83
|
-
.trim();
|
|
84
|
-
const dayOrder = $tds
|
|
85
|
-
.eq(offset + 3)
|
|
86
|
-
.text()
|
|
87
|
-
.trim();
|
|
118
|
+
const day = $tds.eq(offset + 1).text().trim();
|
|
119
|
+
const event = $tds.eq(offset + 2).find("strong").text().trim()
|
|
120
|
+
|| $tds.eq(offset + 2).text().trim();
|
|
121
|
+
const dayOrder = $tds.eq(offset + 3).text().trim();
|
|
88
122
|
month.days.push({ date, day, event, dayOrder });
|
|
89
123
|
});
|
|
90
124
|
});
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "reddy-api-srm",
|
|
3
3
|
"description": "SRMIST KTR Academia portal",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.7",
|
|
5
5
|
"main": "dist/src/index.js",
|
|
6
6
|
"types": "dist/src/index.d.ts",
|
|
7
7
|
"exports": {
|
|
@@ -51,4 +51,4 @@
|
|
|
51
51
|
"axios": "^1.11.0",
|
|
52
52
|
"cheerio": "^1.1.2"
|
|
53
53
|
}
|
|
54
|
-
}
|
|
54
|
+
}
|