Compare commits

..

7 Commits

17 changed files with 481 additions and 102 deletions

3
.gitignore vendored
View File

@@ -1,4 +1,5 @@
node_modules node_modules
vars.js vars.js
.idea .idea
*.xlsx *.xlsx
utils/results.json

5
.idea/.gitignore generated vendored
View File

@@ -1,5 +0,0 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/

1
.idea/.name generated
View File

@@ -1 +0,0 @@
index.js

8
.idea/modules.xml generated
View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/sisa_crawl.iml" filepath="$PROJECT_DIR$/.idea/sisa_crawl.iml" />
</modules>
</component>
</project>

12
.idea/sisa_crawl.iml generated
View File

@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
<excludeFolder url="file://$MODULE_DIR$/temp" />
<excludeFolder url="file://$MODULE_DIR$/tmp" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

6
.idea/vcs.xml generated
View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

13
config.js Normal file
View File

@@ -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',
}

108
coursesEnrolled.js Normal file
View File

@@ -0,0 +1,108 @@
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
//de iframeselector is eveneens van belang om te verwijderen want staat ook dubbel in evaluatestartpakket.js
async function coursesEnrolled(page) {
/*connection to local host
const browser = await puppeteer.connect({
browserURL: "http://localhost:9222", // Connect to the browser's debugging address
});
// Get all open pages (tabs)
const pages = await browser.pages();
console.log(`Found ${pages.length} open pages on the browser.`);
// Interact with the last tab (or any tab of choice)
let page = pages[pages.length - 1]; // Choose the last opened tab
console.log("Current URL:", page.url()); */
let contentFrame= await getContentFrame(page);
const uitvouwenButton = await contentFrame.$(config.uitvouwenSelector);
if (uitvouwenButton) {
await uitvouwenButton.click();
console.log("uitvouwen button clicked");
await wait(2000);
contentFrame= await getContentFrame(page)
}
//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');
const tbody = el.closest('tbody');
return title === 'Sectie samenvouwen AFSTUDEERVEREISTEN BACHELOR GESCHIEDENIS' || tbody === excludedTbody;
}, excludedTbody);
if (!isExcluded) {
const isStillInDOM = await arrow.evaluate(el => document.body.contains(el));
if (isStillInDOM) {
await arrow.click();
await wait(500); // Adjust the wait time as needed
}
}
}
contentFrame= await getContentFrame(page)
const rowData = await contentFrame.$$eval(
'span',
(spans) => {
const uniqueEntries = new Set();
return spans
.filter((span) => span.innerText.trim().includes('Academiejaar'))
.map((span) => {
const tr = span.closest('tr');
if (!tr) return null;
const tds = tr.querySelectorAll('td');
const getInnerHtml = (element) => {
const aElement = element.querySelector('a');
return aElement ? aElement.innerHTML.trim() : element.innerHTML.trim();
};
const studiegidsNummer = tds[0] ? getInnerHtml(tds[0].querySelector('span')) : '';
const opleidingsOnderdeel = tds[1] ? getInnerHtml(tds[1].querySelector('span')) : '';
const studiepunten = tds[2] ? getInnerHtml(tds[2].querySelector('span')) : '';
if (uniqueEntries.has(studiegidsNummer)) return null;
uniqueEntries.add(studiegidsNummer);
return {
studiegidsNummer,
opleidingsOnderdeel,
studiepunten,
};
})
.filter((entry) => entry);
}
);
const totalStudiepunten = sumStudiepunten(rowData);
return {rowData, totalStudiepunten};
}
function sumStudiepunten(rowData) {
return rowData.reduce((total, row) => {
const studiepunten = parseFloat(row.studiepunten) || 0;
return total + studiepunten;
}, 0);
}
async function getContentFrame(page) {
await page.waitForSelector(IFRAME_SELECTOR);
const iframe = await page.$(IFRAME_SELECTOR);
if (!iframe) {
throw new Error("Could not find iframe on the AA-page");
}
console.log("iframe found on AA-page");
return await iframe.contentFrame();
}
module.exports = coursesEnrolled;

View File

@@ -1,10 +1,13 @@
// Vars const isPromise = require("./ispromise")
const IFRAME_SELECTOR = 'iframe[title="Hoofdinhoud"]'; const IFRAME_SELECTOR = 'iframe[title="Hoofdinhoud"]';
const CELL_SELECTOR = const CELL_SELECTOR =
'a[title="Sectie uitvouwen Algemene opleidingsonderdelen"]'; 'a[title="Sectie uitvouwen Algemene opleidingsonderdelen"]';
const STUDENT_NAME_CELL_SELECTOR = 'span[id="DERIVED_SCC_SUM_PERSON_NAME$5$"]' const CELL_SELECTOR_OPEN = "a[title='Sectie samenvouwen Algemene opleidingsonderdelen']";
const STUDENT_ID_CELL_SELECTOR = 'span[id="SCC_PERS_SA_VW_EMPLID"]' const STUDENT_NAME_CELL_SELECTOR = 'span[id="DERIVED_SCC_SUM_PERSON_NAME$5$"]';
const STPKT_KEUZE_CELL_SELECTOR = 'a[title="Sectie uitvouwen Keuzeopleidingsonderdelen"]' const STUDENT_ID_CELL_SELECTOR = 'span[id="SCC_PERS_SA_VW_EMPLID"]';
const STPKT_KEUZE_CELL_SELECTOR = 'a[title="Sectie uitvouwen Keuzeopleidingsonderdelen"]';
const STPKT_KEUZE_CELL_SELECTOR_OPEN = 'a[title="Sectie samenvouwen Keuzeopleidingsonderdelen"]'
/** /**
* Extracted function to get the text content of a node. * Extracted function to get the text content of a node.
@@ -39,9 +42,23 @@ async function getContentFrame(page) {
*/ */
async function isStartPakketAvailable(page) { async function isStartPakketAvailable(page) {
const contentFrame = await getContentFrame(page); const contentFrame = await getContentFrame(page);
await contentFrame.waitForSelector(CELL_SELECTOR); let cell
const cell = await contentFrame.$(CELL_SELECTOR); let isCollapsed_main_before_function = true
const cell_keuze = await contentFrame.$(STPKT_KEUZE_CELL_SELECTOR) try {
await contentFrame.waitForSelector(CELL_SELECTOR, { timeout: 5000 }); // Adjust timeout as needed
cell = await contentFrame.$(CELL_SELECTOR);
} catch (error) {
console.warn("CELL_SELECTOR not found, trying CELL_SELECTOR_OPEN");
await contentFrame.waitForSelector(CELL_SELECTOR_OPEN, { timeout: 5000 }); // Adjust timeout as needed
cell = await contentFrame.$(CELL_SELECTOR_OPEN);
isCollapsed_main_before_function = false
}
let cell_keuze = await contentFrame.$(STPKT_KEUZE_CELL_SELECTOR)
if (!cell_keuze) {
cell_keuze = contentFrame.$(STPKT_KEUZE_CELL_SELECTOR_OPEN)
}
if (!cell ) { if (!cell ) {
throw new Error( throw new Error(
@@ -49,12 +66,15 @@ async function isStartPakketAvailable(page) {
); );
} }
//object vars //object vars
const isCollapsed_main = await isAriaExpandedFalse(cell); const isCollapsed_main = isCollapsed_main_before_function ? await isAriaExpandedFalse(cell) : isCollapsed_main_before_function;
const isCollapsed_keuze = await getIsCollapsedKeuze(cell_keuze); const isCollapsed_keuze = await getIsCollapsedKeuze(cell_keuze);
const isCollapsed = isCollapsed_main && isCollapsed_keuze; const isCollapsed = isCollapsed_main && isCollapsed_keuze;
const studName = await getStudName(contentFrame); const studName = await getStudName(contentFrame);
const studId = await getStudId(contentFrame); const studId = await getStudId(contentFrame);
const containsVZP = await hasVZP(cell)
const containsVZP_keuze = await hasVZP(cell_keuze)
return { return {
isCollapsed: isCollapsed, isCollapsed: isCollapsed,
@@ -62,6 +82,8 @@ async function isStartPakketAvailable(page) {
isCollapsed_keuze: isCollapsed_keuze, isCollapsed_keuze: isCollapsed_keuze,
studName: studName, studName: studName,
studId: studId, studId: studId,
containsVZP: containsVZP,
containsVZP_keuze: containsVZP_keuze,
// more properties here // more properties here
}; };
} }
@@ -73,7 +95,7 @@ async function isStartPakketAvailable(page) {
* @returns {Promise<boolean>} True if the `aria-expanded` attribute is 'false', false otherwise. * @returns {Promise<boolean>} True if the `aria-expanded` attribute is 'false', false otherwise.
*/ */
async function isAriaExpandedFalse(node) { async function isAriaExpandedFalse(node) {
if (!node) { if (isPromise(node)) {
throw new Error("Node is not defined"); throw new Error("Node is not defined");
} }
return await node.evaluate( return await node.evaluate(
@@ -82,7 +104,7 @@ async function isAriaExpandedFalse(node) {
} }
async function getIsCollapsedKeuze(cell_keuze) { async function getIsCollapsedKeuze(cell_keuze) {
if (cell_keuze) { if (!isPromise(cell_keuze)) {
return await isAriaExpandedFalse(cell_keuze); return await isAriaExpandedFalse(cell_keuze);
} else { } else {
return false; return false;
@@ -105,4 +127,24 @@ async function getStudId(frame) {
return await getNodeTextContent(cell); return await getNodeTextContent(cell);
} }
/**
* Checks if the closest parent of the given node contains the 'VZP' string.
*
* @param {ElementHandle} node - The node to find the closest parent of.
* @returns {Promise<boolean>} True if the closest parent contains 'VZP', false otherwise.
*/
async function hasVZP(node) {
if (isPromise(node) ){
return false;
}
return await node.evaluate((element) => {
let parent = element.closest('table');
if (parent) {
return parent.textContent.includes('VZP')
;
}
return false;
});
}
module.exports = isStartPakketAvailable; module.exports = isStartPakketAvailable;

6
ispromise.js Normal file
View File

@@ -0,0 +1,6 @@
function isPromise(obj) {
return obj && typeof obj.then === 'function';
}
module.exports = isPromise;

View File

@@ -2,6 +2,7 @@
open chrome in debug modus open chrome in debug modus
start chrome --remote-debugging-port=9222 --user-data-dir="C:\ChromeDebug" start chrome --remote-debugging-port=9222 --user-data-dir="C:\ChromeDebug"
navigeer naar het dashboard en roep de lijst met startpakket studenten op die relevant zijn voor de test navigeer naar het dashboard en roep de lijst met startpakket studenten op die relevant zijn voor de test
wees er zeker van dat de tab waarin je moet werken de meest rechtse tab is in de tabbladenbalk
start dan het script start dan het script
*/ */
const puppeteer = require("puppeteer"); const puppeteer = require("puppeteer");
@@ -9,17 +10,21 @@ const isStartPakketAvailable = require("./evaluateStartPakket");
const fs = require("fs"); const fs = require("fs");
const saveResultsToExcel = require("./saveResultsToExcel"); const saveResultsToExcel = require("./saveResultsToExcel");
const appendToExcel = require("./appendResultsToExcel"); const appendToExcel = require("./appendResultsToExcel");
const wait = require("./wait"); const wait = require("./wait");
const courseEnrolled = require("./coursesEnrolled");
const parseCourseResults = require('./utils/parseCourseResults');
const config = require("./config.js");
const updateResultsDatabase = require("./utils/updateResultsDatabase");
async function iterateOverDashboardTable() { async function iterateOverDashboardTable() {
/*connection to local host */ /*connection to local host */
const browser = await puppeteer.connect({ 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 //array to store results for Excel export
let results = [] let results = [];
const filename = "DashboardResults.xlsx" const filename = "DashboardResults.xlsx";
// Get all open pages (tabs) // Get all open pages (tabs)
const pages = await browser.pages(); const pages = await browser.pages();
@@ -31,7 +36,7 @@ async function iterateOverDashboardTable() {
// Select the table body by ID // Select the table body by ID
const iframeElement = await page.waitForSelector( const iframeElement = await page.waitForSelector(
'iframe[title="Hoofdinhoud"]' config.iframeSelector
); );
const iframe = await iframeElement.contentFrame(); const iframe = await iframeElement.contentFrame();
@@ -40,11 +45,8 @@ async function iterateOverDashboardTable() {
return; 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 // Check if the table exists inside the iframe
const tableExists = await iframe.$(tableBodySelector); const tableExists = await iframe.$(config.tableBodySelector);
if (!tableExists) { if (!tableExists) {
console.log("Table not found inside iframe!"); console.log("Table not found inside iframe!");
return; return;
@@ -53,7 +55,7 @@ async function iterateOverDashboardTable() {
// Get all rows within the table body // Get all rows within the table body
const links = await iframe.$$( 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.`); console.log(`Found ${links.length} AA-links to process.`);
@@ -68,18 +70,30 @@ async function iterateOverDashboardTable() {
console.log(`Processing link ${i + 1}`); console.log(`Processing link ${i + 1}`);
const iframeElement = await page.waitForSelector( const iframeElement = await page.waitForSelector(
'iframe[title="Hoofdinhoud"]' config.iframeSelector
); );
const iframe = await iframeElement.contentFrame(); const iframe = await iframeElement.contentFrame();
const links = await iframe.$$( 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) =>
link.closest("tr")
);
const rowContainsBeëindigd = await parentRow.evaluate((row) =>
row.innerText.includes("Beëindigd")
); );
if (rowContainsBeëindigd) {
console.log(`Skipping link ${i + 1} as the row contains 'Beëindigd'`);
continue;
}
if ((i + 1) % 10 === 0) { if ((i + 1) % 10 === 0) {
console.log('Simulating break, waiting 10 seconds to stay under the radar :)') console.log(
await wait(10000) "Simulating break, waiting 10 seconds to stay under the radar :)"
);
await wait(10000);
} }
const [newPagePromise] = await Promise.all([ const [newPagePromise] = await Promise.all([
@@ -97,43 +111,49 @@ async function iterateOverDashboardTable() {
try { try {
const evaluationResult = await isStartPakketAvailable(newPage); const evaluationResult = await isStartPakketAvailable(newPage);
const coursesResult = await courseEnrolled(newPage)
//Save results for Excel //Save results for Excel
result = ({ result = {
LinkNumber: i +1, LinkNumber: i + 1,
StudentName: evaluationResult.studName || 'N/A', StudentName: evaluationResult.studName || "N/A",
StudentID: evaluationResult.studId || "N/A", StudentID: evaluationResult.studId || "N/A",
IsCollapsed: evaluationResult.isCollapsed ? "Yes" : "No", IsCollapsed: evaluationResult.isCollapsed ? "Yes" : "No",
IsCollapsedKeuze: evaluationResult.isCollapsed_keuze ? "Yes" : "No", IsCollapsedKeuze: evaluationResult.isCollapsed_keuze ? "Yes" : "No",
IsCollapsedMain: evaluationResult.isCollapsed_main ? "Yes" : "No", IsCollapsedMain: evaluationResult.isCollapsed_main ? "Yes" : "No",
}) ContainsVZP: evaluationResult.containsVZP ? "Yes" : "No",
console.log(`Link ${i + 1 } processed successfully.`); 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) { } catch (error) {
console.error(`Error processing link ${i + 1}:`, error.message); console.error(`Error processing link ${i + 1}:`, error.message);
// Save error for Excel // Save error for Excel
result = ({ result = {
LinkNumber: i + 1, LinkNumber: i + 1,
StudentName: "Error", StudentName: "Error",
StudentID: "Error", StudentID: "Error",
IsCollapsed: "Error", IsCollapsed: "Error",
IsCollapsedKeuze: "Error", IsCollapsedKeuze: "Error",
IsCollapsedMain: "Error", IsCollapsedMain: "Error",
ContainsVZP: "Error",
ContainsVZPKeuze: "Error",
ErrorStr: error.message, ErrorStr: error.message,
}); };
} } finally {
finally {
await newPage.close(); await newPage.close();
} }
results.push(result); results.push(result);
appendToExcel(result, filename); appendToExcel(result, filename);
updateResultsDatabase(result)
} }
console.log("All links processed.");
saveResultsToExcel(results, "DashboardResults.xlsx");
console.log("Results saved successfully to DashboardResults.xlsx");
console.log("All links processed.");
saveResultsToExcel(results, config.excelFilename);
console.log("Results saved successfully to DashboardResults.xlsx");
} }
module.exports = iterateOverDashboardTable(); module.exports = iterateOverDashboardTable();

View File

@@ -1,7 +1,28 @@
const xlsx = require("xlsx"); const xlsx = require("xlsx");
function saveResultsToExcel(data, filename) { function saveResultsToExcel(data, filename) {
const workbook = xlsx.utils.book_new(); // Create a new workbook 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 xlsx.utils.book_append_sheet(workbook, worksheet, "Results"); // Add worksheet to workbook
// Write workbook to file // Write workbook to file

7
todo.md Normal file
View File

@@ -0,0 +1,7 @@
# TODO
## High Priority
- [ ] adviesrapport geeft geen buizen weer voor het huidige aj. Vakken verschijnen dan ook niet in de functie
coursesenrolled. Hoe oplossen? Rapport deliberatie?
- dit is eig geen probleem voor het begin van het aj wanneer nog geen examenperiode heeft
plaatsgevonden.

View File

@@ -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;

169
utils/results.json Normal file
View File

@@ -0,0 +1,169 @@
[
{
"LinkNumber": 1,
"StudentName": "William Van Dessel",
"StudentID": "20001044",
"IsCollapsed": "Yes",
"IsCollapsedKeuze": "Yes",
"IsCollapsedMain": "Yes",
"ContainsVZP": "No",
"ContainsVZPKeuze": "No",
"coursesResult": "1010FLWGES Gesch. van de middeleeuwen - 6.00SP, \n1011FLWGES Gesch. van de nieuwe tijd - 6.00SP, \n1014FLWGES Inleiding wereldgeschiedenis - 6.00SP, \n1053FLWGES Hist oef 1 - 6.00SP, ",
"totalStudiepunten": 24
},
{
"LinkNumber": 2,
"StudentName": "Joren Van Roy",
"StudentID": "20141999",
"IsCollapsed": "No",
"IsCollapsedKeuze": "Yes",
"IsCollapsedMain": "No",
"ContainsVZP": "No",
"ContainsVZPKeuze": "No",
"coursesResult": "1011FLWGES Gesch. van de nieuwe tijd - 6.00SP, \n1014FLWGES Inleiding wereldgeschiedenis - 6.00SP, \n1300PSWSOC Inleiding tot de Sociologie - 6.00SP, \n1087FLWGES Central and Eastern Europe - 3.00SP, \n1013FLWGES Eigentijdse geschiedenis - 6.00SP, \n1200PSWPOL Inleiding tot de Politicologie - 6.00SP, \n1104TEWVSG Inl. tot het recht - 6.00SP, \n1300PSWSFP Samenleving, feiten, problemen - 6.00SP, \n1302TEWVSG Levensbesch., mens en markt - 3.00SP, ",
"totalStudiepunten": 48
},
{
"LinkNumber": 4,
"StudentName": "Zeynep Öcbe",
"StudentID": "20193168",
"IsCollapsed": "No",
"IsCollapsedKeuze": "No",
"IsCollapsedMain": "No",
"ContainsVZP": "No",
"ContainsVZPKeuze": "No",
"coursesResult": "1011FLWGES Gesch. van de nieuwe tijd - 6.00SP, \n1014FLWGES Inleiding wereldgeschiedenis - 6.00SP, \n1053FLWGES Hist oef 1 - 6.00SP, \n1067FLWGES Byzantijnse gesch. - 3.00SP, \n1001IOBGJU Global Justice - 3.00SP, ",
"totalStudiepunten": 24
},
{
"LinkNumber": 5,
"StudentName": "Jens Aelbrecht",
"StudentID": "20213047",
"IsCollapsed": "No",
"IsCollapsedKeuze": "Yes",
"IsCollapsedMain": "No",
"ContainsVZP": "No",
"ContainsVZPKeuze": "No",
"coursesResult": "1002FLWGES Inleiding tot de economie - 6.00SP, \n1005FLWGES Oefeningen paleografie - 3.00SP, \n1011FLWGES Gesch. van de nieuwe tijd - 6.00SP, \n1014FLWGES Inleiding wereldgeschiedenis - 6.00SP, \n1053FLWGES Hist oef 1 - 6.00SP, \n1300PSWSOC Sociologie - 6.00SP, \n1054FLWGES Inleiding wijsbegeerte - 6.00SP, \n1067FLWGES Byzantijnse gesch. - 3.00SP, \n1000PSWPUB Publiekrecht - 3.00SP, \n1013FLWGES Eigentijdse geschiedenis - 6.00SP, \n1200PSWPOL Politicologie - 6.00SP, \n1001CPGVKA Levensbeschouwing &amp; wet - 3.00SP, ",
"totalStudiepunten": 60
},
{
"LinkNumber": 6,
"StudentName": "Hadi Dagher",
"StudentID": "20221279",
"IsCollapsed": "No",
"IsCollapsedKeuze": "No",
"IsCollapsedMain": "No",
"ContainsVZP": "No",
"ContainsVZPKeuze": "No",
"coursesResult": "1002FLWGES Inleiding tot de economie - 6.00SP, \n1005FLWGES Oefeningen paleografie - 3.00SP, \n1053FLWGES Hist oef 1 - 6.00SP, \n1011FLWGES Gesch. van de nieuwe tijd - 6.00SP, \n1014FLWGES Inleiding wereldgeschiedenis - 6.00SP, ",
"totalStudiepunten": 27
},
{
"LinkNumber": 7,
"StudentName": "Casper Janssens",
"StudentID": "20221960",
"IsCollapsed": "No",
"IsCollapsedKeuze": "Yes",
"IsCollapsedMain": "No",
"ContainsVZP": "No",
"ContainsVZPKeuze": "No",
"coursesResult": "1002FLWGES Inleiding tot de economie - 6.00SP, \n1003FLWGES Historische methode - 6.00SP, \n1005FLWGES Oefeningen paleografie - 3.00SP, \n1010FLWGES Gesch. van de middeleeuwen - 6.00SP, \n1011FLWGES Gesch. van de nieuwe tijd - 6.00SP, \n1014FLWGES Inleiding wereldgeschiedenis - 6.00SP, \n1053FLWGES Hist oef 1 - 6.00SP, \n1000RECPOL Politicologie - 3.00SP, \n1300PSWSOC Sociologie - 6.00SP, \n1000RECGPR Geschiedenis privaatrecht - 6.00SP, \n1200RECTEN Taalgebruik Engels - 3.00SP, ",
"totalStudiepunten": 57
},
{
"LinkNumber": 8,
"StudentName": "Hanne De Win",
"StudentID": "20223846",
"IsCollapsed": "No",
"IsCollapsedKeuze": "Yes",
"IsCollapsedMain": "No",
"ContainsVZP": "No",
"ContainsVZPKeuze": "No",
"coursesResult": "1002FLWGES Inleiding tot de economie - 6.00SP, \n1003FLWGES Historische methode - 6.00SP, \n1005FLWGES Oefeningen paleografie - 3.00SP, \n1011FLWGES Gesch. van de nieuwe tijd - 6.00SP, \n1014FLWGES Inleiding wereldgeschiedenis - 6.00SP, \n1053FLWGES Hist oef 1 - 6.00SP, \n1102FLWTLT Geschiedenis van de film 1 - 3.00SP, \n1300PSWSOC Sociologie - 6.00SP, \n1082FLWGES Geschiedenis van België - 3.00SP, ",
"totalStudiepunten": 45
},
{
"LinkNumber": 9,
"StudentName": "Axl Legon",
"StudentID": "20223927",
"IsCollapsed": "Yes",
"IsCollapsedKeuze": "Yes",
"IsCollapsedMain": "Yes",
"ContainsVZP": "No",
"ContainsVZPKeuze": "No",
"coursesResult": "1067FLWGES Byzantijnse gesch. - 3.00SP, \n1083FLWGES Gesch. van de Nederlanden - 3.00SP, \n1002FLWGES Inleiding tot de economie - 6.00SP, \n1300PSWSOC Sociologie - 6.00SP, \n1054FLWGES Inleiding wijsbegeerte - 6.00SP, \n1003FLWGES Historische methode - 6.00SP, \n1005FLWGES Oefeningen paleografie - 3.00SP, \n1072FLWGES Inleiding historiografie - 3.00SP, \n1053FLWGES Hist oef 1 - 6.00SP, \n1010FLWGES Gesch. van de middeleeuwen - 6.00SP, \n1011FLWGES Gesch. van de nieuwe tijd - 6.00SP, \n1014FLWGES Inleiding wereldgeschiedenis - 6.00SP, \n1066FLWGES History islamic world - 6.00SP, \n1082FLWGES Geschiedenis van België - 3.00SP, \n1200PSWPOL Politicologie - 6.00SP, \n1002FLWALG Keuzeruimte - 3.00SP, ",
"totalStudiepunten": 78
},
{
"LinkNumber": 11,
"StudentName": "Error",
"StudentID": "Error",
"IsCollapsed": "Error",
"IsCollapsedKeuze": "Error",
"IsCollapsedMain": "Error",
"ContainsVZP": "Error",
"ContainsVZPKeuze": "Error",
"ErrorStr": "Cannot read properties of null (reading 'evaluate')"
},
{
"LinkNumber": 12,
"StudentName": "Tom Grohmann",
"StudentID": "20230664",
"IsCollapsed": "No",
"IsCollapsedKeuze": "Yes",
"IsCollapsedMain": "No",
"ContainsVZP": "No",
"ContainsVZPKeuze": "No",
"coursesResult": "1002FLWGES Inleiding tot de economie - 6.00SP, \n1005FLWGES Oefeningen paleografie - 3.00SP, \n1011FLWGES Gesch. van de nieuwe tijd - 6.00SP, \n1014FLWGES Inleiding wereldgeschiedenis - 6.00SP, \n1053FLWGES Hist oef 1 - 6.00SP, \n1067FLWGES Byzantijnse gesch. - 3.00SP, ",
"totalStudiepunten": 30
},
{
"LinkNumber": 14,
"StudentName": "Lien Arras",
"StudentID": "20231250",
"IsCollapsed": "No",
"IsCollapsedKeuze": "Yes",
"IsCollapsedMain": "No",
"ContainsVZP": "No",
"ContainsVZPKeuze": "No",
"coursesResult": "1002FLWGES Inleiding tot de economie - 6.00SP, \n1005FLWGES Oefeningen paleografie - 3.00SP, \n1011FLWGES Gesch. van de nieuwe tijd - 6.00SP, \n1014FLWGES Inleiding wereldgeschiedenis - 6.00SP, \n1053FLWGES Hist oef 1 - 6.00SP, \n1038FLWGES Inleiding tot het Latijn - 3.00SP, ",
"totalStudiepunten": 30
},
{
"LinkNumber": 15,
"StudentName": "Oliwier Rogozinski",
"StudentID": "20232813",
"IsCollapsed": "Yes",
"IsCollapsedKeuze": "Yes",
"IsCollapsedMain": "Yes",
"ContainsVZP": "No",
"ContainsVZPKeuze": "No",
"coursesResult": "1002FLWGES Inleiding tot de economie - 6.00SP, \n1003FLWGES Historische methode - 6.00SP, \n1005FLWGES Oefeningen paleografie - 3.00SP, \n1010FLWGES Gesch. van de middeleeuwen - 6.00SP, \n1011FLWGES Gesch. van de nieuwe tijd - 6.00SP, \n1014FLWGES Inleiding wereldgeschiedenis - 6.00SP, \n1053FLWGES Hist oef 1 - 6.00SP, \n1066FLWGES History islamic world - 6.00SP, \n1300PSWSOC Sociologie - 6.00SP, \n1054FLWGES Inleiding wijsbegeerte - 6.00SP, \n1083FLWGES Gesch. van de Nederlanden - 3.00SP, ",
"totalStudiepunten": 60
},
{
"LinkNumber": 16,
"StudentName": "Milan Van De Velde",
"StudentID": "20233391",
"IsCollapsed": "No",
"IsCollapsedKeuze": "No",
"IsCollapsedMain": "No",
"ContainsVZP": "No",
"ContainsVZPKeuze": "No",
"coursesResult": "1002FLWGES Inleiding tot de economie - 6.00SP, \n1005FLWGES Oefeningen paleografie - 3.00SP, \n1011FLWGES Gesch. van de nieuwe tijd - 6.00SP, \n1014FLWGES Inleiding wereldgeschiedenis - 6.00SP, \n1053FLWGES Hist oef 1 - 6.00SP, \n1300PSWSOC Sociologie - 6.00SP, ",
"totalStudiepunten": 33
},
{
"LinkNumber": 17,
"StudentName": "Briek Piessens",
"StudentID": "20233905",
"IsCollapsed": "Yes",
"IsCollapsedKeuze": "Yes",
"IsCollapsedMain": "Yes",
"ContainsVZP": "No",
"ContainsVZPKeuze": "No",
"coursesResult": "1002FLWGES Inleiding tot de economie - 6.00SP, \n1003FLWGES Historische methode - 6.00SP, \n1005FLWGES Oefeningen paleografie - 3.00SP, \n1010FLWGES Gesch. van de middeleeuwen - 6.00SP, \n1011FLWGES Gesch. van de nieuwe tijd - 6.00SP, \n1014FLWGES Inleiding wereldgeschiedenis - 6.00SP, \n1053FLWGES Hist oef 1 - 6.00SP, \n1066FLWGES History islamic world - 6.00SP, \n1300PSWSOC Sociologie - 6.00SP, \n1054FLWGES Inleiding wijsbegeerte - 6.00SP, \n1118FLWTLA Taal tussen natuur en cultuur - 3.00SP, \n1104FLWTLN Cultuurgesch.v/d Lage Landen 2 - 3.00SP, \n1101FLWTLN Nederlandse TB1: basisvaardigh - 6.00SP, ",
"totalStudiepunten": 69
}
]

View File

@@ -0,0 +1,39 @@
const fs = require("fs");
const path = require("path");
const resultsFilePath = path.join(__dirname, "results.json");
// Flag to track if the file has been reset
let isFileReset = false;
function updateResultsDatabase(newResult) {
// Check if the file needs to be reset
if (!isFileReset) {
if (fs.existsSync(resultsFilePath)) {
const fileContent = fs.readFileSync(resultsFilePath, "utf-8");
if (fileContent.trim()) {
// Reset the file to an empty array
fs.writeFileSync(resultsFilePath, JSON.stringify([], null, 2));
console.log("Old data removed from results.json.");
}
}
isFileReset = true; // Mark the file as reset
}
// Read existing results or initialize an empty array
let results = [];
if (fs.existsSync(resultsFilePath)) {
const fileContent = fs.readFileSync(resultsFilePath, "utf-8");
if (fileContent.trim()) {
results = JSON.parse(fileContent);
}
}
// Add the new result to the array
results.push(newResult);
// Write the updated results back to the file
fs.writeFileSync(resultsFilePath, JSON.stringify(results, null, 2));
}
module.exports = updateResultsDatabase;

28
vars.js
View File

@@ -1,28 +0,0 @@
/* Top Level Vars*/
const email = 'bdaneels@ad.ua.ac.be'
const password = 'Heideggershut18891'
const webpage = 'https://sisaweb.uantwerpen.be'
const runId = 'bd'
const dasbhoardInschrijvingenURL = 'https://app.sisaweb.uantwerpen.be/psc/csprd_3/EMPLOYEE/SA/c/QQ_INSCHRIJVINGEN.QQ_OVERZ_ING_STDL.GBL?NavColl=true'
/* Dashboard Form Vars*/
const career = 'BACA'
const program = 'B0011'
const academicYear = '2240'
module.exports = {
email,
password,
webpage,
runId,
dasbhoardInschrijvingenURL,
career,
program,
academicYear
};