From 5cf306a56e964c631029cca03f562a8fe3c297ab Mon Sep 17 00:00:00 2001 From: bdaneels Date: Thu, 10 Apr 2025 16:48:13 +0200 Subject: [PATCH] adding coursesEnrolled.js as a functionality to check what courses have been taken up. --- config.js | 13 +++++++++++++ coursesEnrolled.js | 14 +++++++------- iterateOverDashboardTable.js | 29 +++++++++++++++-------------- saveResultsToExcel.js | 23 ++++++++++++++++++++++- utils/parseCourseResults.js | 13 +++++++++++++ 5 files changed, 70 insertions(+), 22 deletions(-) create mode 100644 config.js create mode 100644 utils/parseCourseResults.js diff --git a/config.js b/config.js new file mode 100644 index 0000000..a21702f --- /dev/null +++ b/config.js @@ -0,0 +1,13 @@ +module.exports = { + excelFilename: "DashboardResults.xlsx", + //Selectors for the dashboard page + tableBodySelector: "#QQ_RPT_OIS_TEMP\\$scroll\\$0 tbody", + iframeSelector: 'iframe[title="Hoofdinhoud"]', + + + //Selectors for the AA-page + uitvouwenSelector: 'input[id="DERIVED_SAA_DPR_SSS_EXPAND_ALL"]', + collapsArrowSelector:'a.PSHYPERLINK.PTCOLLAPSE_ARROW', + excludeFromCollapsingSelector: 'a[title="Sectie samenvouwen AFSTUDEERVEREISTEN BACHELOR GESCHIEDENIS"]', + excludedTitle: 'Sectie samenvouwen AFSTUDEERVEREISTEN BACHELOR GESCHIEDENIS', +} \ No newline at end of file diff --git a/coursesEnrolled.js b/coursesEnrolled.js index d96c03c..8bcb686 100644 --- a/coursesEnrolled.js +++ b/coursesEnrolled.js @@ -1,6 +1,7 @@ const puppeteer = require('puppeteer'); const IFRAME_SELECTOR = 'iframe[title="Hoofdinhoud"]'; const wait = require("./wait"); +const config = require("./config.js"); //Er zijn een aantal helperfuncties die nog verwijderd moeten worden //zo is de functie van de contentFrame te verwijderen want staat dubbel in evaluatestartpakket.js @@ -23,17 +24,18 @@ async function coursesEnrolled(page) { console.log("Current URL:", page.url()); */ let contentFrame= await getContentFrame(page); - const uitvouwenButton = await contentFrame.$('input[id="DERIVED_SAA_DPR_SSS_EXPAND_ALL"]'); + const uitvouwenButton = await contentFrame.$(config.uitvouwenSelector); if (uitvouwenButton) { await uitvouwenButton.click(); console.log("uitvouwen button clicked"); await wait(2000); contentFrame= await getContentFrame(page) } - const collapseArrows = await contentFrame.$$('a.PSHYPERLINK.PTCOLLAPSE_ARROW'); - const excludedArrow = await contentFrame.$('a[title="Sectie samenvouwen AFSTUDEERVEREISTEN BACHELOR GESCHIEDENIS"]'); - const excludedTbody = await excludedArrow.evaluate(el => el.closest('tbody')); + //logic to collapse all sections except the one with the excluded title + const collapseArrows = await contentFrame.$$(config.collapsArrowSelector); + const excludedArrow = await contentFrame.$(config.excludeFromCollapsingSelector); + const excludedTbody = await excludedArrow.evaluate(el => el.closest('tbody')); for (const arrow of collapseArrows) { const isExcluded = await arrow.evaluate((el, excludedTbody) => { const title = el.getAttribute('title'); @@ -81,10 +83,8 @@ async function coursesEnrolled(page) { } ); - console.log(rowData); const totalStudiepunten = sumStudiepunten(rowData); - console.log(`Total studiepunten: ${totalStudiepunten}`); - //return rowData; + return {rowData, totalStudiepunten}; } diff --git a/iterateOverDashboardTable.js b/iterateOverDashboardTable.js index a8440bb..421ae71 100644 --- a/iterateOverDashboardTable.js +++ b/iterateOverDashboardTable.js @@ -12,11 +12,13 @@ const saveResultsToExcel = require("./saveResultsToExcel"); const appendToExcel = require("./appendResultsToExcel"); const wait = require("./wait"); const courseEnrolled = require("./coursesEnrolled"); +const parseCourseResults = require('./utils/parseCourseResults'); +const config = require("./config.js"); async function iterateOverDashboardTable() { /*connection to local host */ const browser = await puppeteer.connect({ - browserURL: "http://localhost:9222", // Connect to the browser's debugging address + browserURL: "http://localhost:9222" }); //array to store results for Excel export @@ -33,7 +35,7 @@ async function iterateOverDashboardTable() { // Select the table body by ID const iframeElement = await page.waitForSelector( - 'iframe[title="Hoofdinhoud"]' + config.iframeSelector ); const iframe = await iframeElement.contentFrame(); @@ -42,11 +44,8 @@ async function iterateOverDashboardTable() { return; } - // Select the table body within the iframe - const tableBodySelector = "#QQ_RPT_OIS_TEMP\\$scroll\\$0 tbody"; - // Check if the table exists inside the iframe - const tableExists = await iframe.$(tableBodySelector); + const tableExists = await iframe.$(config.tableBodySelector); if (!tableExists) { console.log("Table not found inside iframe!"); return; @@ -55,7 +54,7 @@ async function iterateOverDashboardTable() { // Get all rows within the table body const links = await iframe.$$( - `${tableBodySelector} tr span[title="AA-rapport"] a` + `${config.tableBodySelector} tr span[title="AA-rapport"] a` ); console.log(`Found ${links.length} AA-links to process.`); @@ -70,12 +69,12 @@ async function iterateOverDashboardTable() { console.log(`Processing link ${i + 1}`); const iframeElement = await page.waitForSelector( - 'iframe[title="Hoofdinhoud"]' + config.iframeSelector ); const iframe = await iframeElement.contentFrame(); const links = await iframe.$$( - `${tableBodySelector} tr span[title="AA-rapport"] a` + `${config.tableBodySelector} tr span[title="AA-rapport"] a` ); // Get the parent row of the current link const parentRow = await links[i].evaluateHandle((link) => @@ -111,6 +110,7 @@ async function iterateOverDashboardTable() { try { const evaluationResult = await isStartPakketAvailable(newPage); + const coursesResult = await courseEnrolled(newPage) //Save results for Excel result = { @@ -121,8 +121,11 @@ async function iterateOverDashboardTable() { IsCollapsedKeuze: evaluationResult.isCollapsed_keuze ? "Yes" : "No", IsCollapsedMain: evaluationResult.isCollapsed_main ? "Yes" : "No", ContainsVZP: evaluationResult.containsVZP ? "Yes" : "No", - ContainsVZPKeuze: evaluationResult.containsVZP_keuze ? "Yes" : "No" + ContainsVZPKeuze: evaluationResult.containsVZP_keuze ? "Yes" : "No", + coursesResult: parseCourseResults(coursesResult.rowData), + totalStudiepunten: coursesResult.totalStudiepunten }; + console.log("Courses enrolled: ", coursesResult.rowData); console.log(`Link ${i + 1} processed successfully.`); } catch (error) { console.error(`Error processing link ${i + 1}:`, error.message); @@ -139,17 +142,15 @@ async function iterateOverDashboardTable() { ErrorStr: error.message, }; } finally { - //await newPage.close(); + await newPage.close(); } results.push(result); appendToExcel(result, filename); - await courseEnrolled(newPage) - await newPage.close() } console.log("All links processed."); - saveResultsToExcel(results, "DashboardResults.xlsx"); + saveResultsToExcel(results, config.excelFilename); console.log("Results saved successfully to DashboardResults.xlsx"); } diff --git a/saveResultsToExcel.js b/saveResultsToExcel.js index 3b30840..89d806d 100644 --- a/saveResultsToExcel.js +++ b/saveResultsToExcel.js @@ -1,7 +1,28 @@ const xlsx = require("xlsx"); + function saveResultsToExcel(data, filename) { const workbook = xlsx.utils.book_new(); // Create a new workbook - const worksheet = xlsx.utils.json_to_sheet(data); // Convert data to worksheet + const worksheetData = []; + + data.forEach(item => { + const courses = item.coursesResult.split('. ').filter(course => course.trim() !== ''); + courses.forEach(course => { + worksheetData.push({ + LinkNumber: item.LinkNumber, + StudentName: item.StudentName, + StudentID: item.StudentID, + IsCollapsed: item.IsCollapsed, + IsCollapsedKeuze: item.IsCollapsedKeuze, + IsCollapsedMain: item.IsCollapsedMain, + ContainsVZP: item.ContainsVZP, + ContainsVZPKeuze: item.ContainsVZPKeuze, + Course: course.trim(), + TotalStudiepunten: item.totalStudiepunten + }); + }); + }); + + const worksheet = xlsx.utils.json_to_sheet(worksheetData); // Convert data to worksheet xlsx.utils.book_append_sheet(workbook, worksheet, "Results"); // Add worksheet to workbook // Write workbook to file diff --git a/utils/parseCourseResults.js b/utils/parseCourseResults.js new file mode 100644 index 0000000..b6f54d4 --- /dev/null +++ b/utils/parseCourseResults.js @@ -0,0 +1,13 @@ + +const parseCourseResults = (listOfObj) => { + result = listOfObj.map(obj => { + const studiegidsNummer = obj.studiegidsNummer.slice(-10); + return `${studiegidsNummer} ${obj.opleidingsOnderdeel} - ${obj.studiepunten}SP, `; + }); + + + return result.join("\n"); + +} + +module.exports = parseCourseResults; \ No newline at end of file