Compare commits
11 Commits
b92f1c8c29
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
61cc64742f | ||
|
|
df67c3c2c5 | ||
|
|
8c5dc7db04 | ||
|
|
5cf306a56e | ||
|
|
45023185a1 | ||
|
|
1f5fcbe3c8 | ||
|
|
47c4afa99e | ||
|
|
0e275a5bc6 | ||
|
|
6c7aa018cd | ||
|
|
05a1b85801 | ||
|
|
3b4ccefa66 |
5
.gitignore
vendored
5
.gitignore
vendored
@@ -1,2 +1,5 @@
|
|||||||
node_modules
|
node_modules
|
||||||
vars.js
|
vars.js
|
||||||
|
.idea
|
||||||
|
*.xlsx
|
||||||
|
utils/results.json
|
||||||
5
.idea/.gitignore
generated
vendored
5
.idea/.gitignore
generated
vendored
@@ -1,5 +0,0 @@
|
|||||||
# Default ignored files
|
|
||||||
/shelf/
|
|
||||||
/workspace.xml
|
|
||||||
# Editor-based HTTP Client requests
|
|
||||||
/httpRequests/
|
|
||||||
1
.idea/.name
generated
1
.idea/.name
generated
@@ -1 +0,0 @@
|
|||||||
index.js
|
|
||||||
8
.idea/modules.xml
generated
8
.idea/modules.xml
generated
@@ -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
12
.idea/sisa_crawl.iml
generated
@@ -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
6
.idea/vcs.xml
generated
@@ -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>
|
|
||||||
35
appendResultsToExcel.js
Normal file
35
appendResultsToExcel.js
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
const xlsx = require("xlsx");
|
||||||
|
const fs = require("fs");
|
||||||
|
|
||||||
|
function appendToExcel(newResult, filename) {
|
||||||
|
let workbook;
|
||||||
|
|
||||||
|
// Load existing file if it exists
|
||||||
|
if (fs.existsSync(filename)) {
|
||||||
|
workbook = xlsx.readFile(filename);
|
||||||
|
} else {
|
||||||
|
workbook = xlsx.utils.book_new();
|
||||||
|
}
|
||||||
|
|
||||||
|
const sheetName = "Results";
|
||||||
|
let worksheet = workbook.Sheets[sheetName];
|
||||||
|
|
||||||
|
// If the worksheet doesn't exist, create it
|
||||||
|
if (!worksheet) {
|
||||||
|
worksheet = xlsx.utils.json_to_sheet([]);
|
||||||
|
xlsx.utils.book_append_sheet(workbook, worksheet, sheetName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get existing data from the worksheet
|
||||||
|
const data = xlsx.utils.sheet_to_json(worksheet);
|
||||||
|
data.push(newResult); // Add new result
|
||||||
|
|
||||||
|
// Update worksheet with new data
|
||||||
|
const updatedWorksheet = xlsx.utils.json_to_sheet(data);
|
||||||
|
workbook.Sheets[sheetName] = updatedWorksheet;
|
||||||
|
|
||||||
|
// Write updated workbook to file
|
||||||
|
xlsx.writeFile(workbook, filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = appendToExcel;
|
||||||
13
config.js
Normal file
13
config.js
Normal 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
108
coursesEnrolled.js
Normal 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;
|
||||||
@@ -1,6 +1,13 @@
|
|||||||
|
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 CELL_SELECTOR_OPEN = "a[title='Sectie samenvouwen Algemene opleidingsonderdelen']";
|
||||||
|
const STUDENT_NAME_CELL_SELECTOR = 'span[id="DERIVED_SCC_SUM_PERSON_NAME$5$"]';
|
||||||
|
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.
|
||||||
@@ -35,22 +42,49 @@ 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
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
if (!cell) {
|
|
||||||
|
let cell_keuze = await contentFrame.$(STPKT_KEUZE_CELL_SELECTOR)
|
||||||
|
if (!cell_keuze) {
|
||||||
|
cell_keuze = contentFrame.$(STPKT_KEUZE_CELL_SELECTOR_OPEN)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cell ) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"Cell inside function isStartPakketAvailable is not defined"
|
"Cell inside function isStartPakketAvailable is not defined"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const isCollapsed = await isAriaExpandedFalse(cell);
|
|
||||||
|
|
||||||
console.log(`Aria-expanded: ${isCollapsed}`);
|
//object vars
|
||||||
|
const isCollapsed_main = isCollapsed_main_before_function ? await isAriaExpandedFalse(cell) : isCollapsed_main_before_function;
|
||||||
|
const isCollapsed_keuze = await getIsCollapsedKeuze(cell_keuze);
|
||||||
|
const isCollapsed = isCollapsed_main && isCollapsed_keuze;
|
||||||
|
const studName = await getStudName(contentFrame);
|
||||||
|
const studId = await getStudId(contentFrame);
|
||||||
|
const containsVZP = await hasVZP(cell)
|
||||||
|
const containsVZP_keuze = await hasVZP(cell_keuze)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
isCollapsed: isCollapsed,
|
isCollapsed: isCollapsed,
|
||||||
// Add more properties here in the future as needed
|
isCollapsed_main: isCollapsed_main,
|
||||||
|
isCollapsed_keuze: isCollapsed_keuze,
|
||||||
|
studName: studName,
|
||||||
|
studId: studId,
|
||||||
|
containsVZP: containsVZP,
|
||||||
|
containsVZP_keuze: containsVZP_keuze,
|
||||||
|
// more properties here
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,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(
|
||||||
@@ -69,4 +103,48 @@ async function isAriaExpandedFalse(node) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getIsCollapsedKeuze(cell_keuze) {
|
||||||
|
if (!isPromise(cell_keuze)) {
|
||||||
|
return await isAriaExpandedFalse(cell_keuze);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getStudName(frame) {
|
||||||
|
const cell = await frame.$(STUDENT_NAME_CELL_SELECTOR);
|
||||||
|
if (!cell) {
|
||||||
|
throw new Error("Cell student name is not defined");
|
||||||
|
}
|
||||||
|
return await getNodeTextContent(cell);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getStudId(frame) {
|
||||||
|
const cell = await frame.$(STUDENT_ID_CELL_SELECTOR);
|
||||||
|
if (!cell) {
|
||||||
|
throw new Error("Cell student id is not defined");
|
||||||
|
}
|
||||||
|
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
6
ispromise.js
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
function isPromise(obj) {
|
||||||
|
return obj && typeof obj.then === 'function';
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = isPromise;
|
||||||
@@ -2,17 +2,30 @@
|
|||||||
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");
|
||||||
const isStartPakketAvailable = require("./evaluateStartPakket");
|
const isStartPakketAvailable = require("./evaluateStartPakket");
|
||||||
|
const fs = require("fs");
|
||||||
|
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");
|
||||||
|
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
|
||||||
|
let results = [];
|
||||||
|
const filename = "DashboardResults.xlsx";
|
||||||
|
|
||||||
// Get all open pages (tabs)
|
// Get all open pages (tabs)
|
||||||
const pages = await browser.pages();
|
const pages = await browser.pages();
|
||||||
console.log(`Found ${pages.length} open pages on the browser.`);
|
console.log(`Found ${pages.length} open pages on the browser.`);
|
||||||
@@ -23,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();
|
||||||
|
|
||||||
@@ -32,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;
|
||||||
@@ -45,21 +55,46 @@ 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.`);
|
||||||
|
|
||||||
|
// Initialize Excel file if it doesn't exist
|
||||||
|
if (!fs.existsSync(filename)) {
|
||||||
|
saveResultsToExcel([], filename); // Create empty file
|
||||||
|
console.log(`Initialized new Excel file: ${filename}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// process links
|
||||||
for (let i = 0; i < links.length; i++) {
|
for (let i = 0; i < links.length; i++) {
|
||||||
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) {
|
||||||
|
console.log(
|
||||||
|
"Simulating break, waiting 10 seconds to stay under the radar :)"
|
||||||
|
);
|
||||||
|
await wait(10000);
|
||||||
|
}
|
||||||
|
|
||||||
const [newPagePromise] = await Promise.all([
|
const [newPagePromise] = await Promise.all([
|
||||||
new Promise((resolve) =>
|
new Promise((resolve) =>
|
||||||
@@ -70,24 +105,55 @@ async function iterateOverDashboardTable() {
|
|||||||
),
|
),
|
||||||
links[i].click(), // Simulate the click
|
links[i].click(), // Simulate the click
|
||||||
]);
|
]);
|
||||||
|
let result;
|
||||||
|
|
||||||
const newPage = await newPagePromise;
|
const newPage = await newPagePromise;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const evaluationResult = await isStartPakketAvailable(newPage);
|
const evaluationResult = await isStartPakketAvailable(newPage);
|
||||||
|
const coursesResult = await courseEnrolled(newPage)
|
||||||
|
|
||||||
if (evaluationResult.isCollapsed) {
|
//Save results for Excel
|
||||||
console.log(`Evaluation succeeded for link ${i + 1}`);
|
result = {
|
||||||
} else {
|
LinkNumber: i + 1,
|
||||||
console.log(`Evaluation failed for link ${i + 1}`);
|
StudentName: evaluationResult.studName || "N/A",
|
||||||
}
|
StudentID: evaluationResult.studId || "N/A",
|
||||||
|
IsCollapsed: evaluationResult.isCollapsed ? "Yes" : "No",
|
||||||
|
IsCollapsedKeuze: evaluationResult.isCollapsed_keuze ? "Yes" : "No",
|
||||||
|
IsCollapsedMain: evaluationResult.isCollapsed_main ? "Yes" : "No",
|
||||||
|
ContainsVZP: evaluationResult.containsVZP ? "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) {
|
} catch (error) {
|
||||||
console.error(`Error processing link ${i + 1}:`, error.message);
|
console.error(`Error processing link ${i + 1}:`, error.message);
|
||||||
|
// Save error for Excel
|
||||||
|
result = {
|
||||||
|
LinkNumber: i + 1,
|
||||||
|
StudentName: "Error",
|
||||||
|
StudentID: "Error",
|
||||||
|
IsCollapsed: "Error",
|
||||||
|
IsCollapsedKeuze: "Error",
|
||||||
|
IsCollapsedMain: "Error",
|
||||||
|
ContainsVZP: "Error",
|
||||||
|
ContainsVZPKeuze: "Error",
|
||||||
|
ErrorStr: error.message,
|
||||||
|
};
|
||||||
|
} finally {
|
||||||
|
await newPage.close();
|
||||||
}
|
}
|
||||||
|
results.push(result);
|
||||||
await newPage.close();
|
appendToExcel(result, filename);
|
||||||
|
updateResultsDatabase(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
console.log("All links processed.");
|
console.log("All links processed.");
|
||||||
|
saveResultsToExcel(results, config.excelFilename);
|
||||||
|
console.log("Results saved successfully to DashboardResults.xlsx");
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = iterateOverDashboardTable();
|
module.exports = iterateOverDashboardTable();
|
||||||
|
|||||||
106
package-lock.json
generated
106
package-lock.json
generated
@@ -9,7 +9,8 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"inquirer": "^12.1.0",
|
"inquirer": "^12.1.0",
|
||||||
"puppeteer": "^23.7.0"
|
"puppeteer": "^23.7.0",
|
||||||
|
"xlsx": "^0.18.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/code-frame": {
|
"node_modules/@babel/code-frame": {
|
||||||
@@ -333,6 +334,15 @@
|
|||||||
"@types/node": "*"
|
"@types/node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/adler-32": {
|
||||||
|
"version": "1.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.3.1.tgz",
|
||||||
|
"integrity": "sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/agent-base": {
|
"node_modules/agent-base": {
|
||||||
"version": "7.1.1",
|
"version": "7.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz",
|
||||||
@@ -525,6 +535,19 @@
|
|||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/cfb": {
|
||||||
|
"version": "1.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/cfb/-/cfb-1.2.2.tgz",
|
||||||
|
"integrity": "sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"adler-32": "~1.3.0",
|
||||||
|
"crc-32": "~1.2.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/chardet": {
|
"node_modules/chardet": {
|
||||||
"version": "0.7.0",
|
"version": "0.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
|
||||||
@@ -568,6 +591,15 @@
|
|||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/codepage": {
|
||||||
|
"version": "1.15.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/codepage/-/codepage-1.15.0.tgz",
|
||||||
|
"integrity": "sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/color-convert": {
|
"node_modules/color-convert": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||||
@@ -612,6 +644,18 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/crc-32": {
|
||||||
|
"version": "1.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz",
|
||||||
|
"integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"bin": {
|
||||||
|
"crc32": "bin/crc32.njs"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/data-uri-to-buffer": {
|
"node_modules/data-uri-to-buffer": {
|
||||||
"version": "6.0.2",
|
"version": "6.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz",
|
||||||
@@ -801,6 +845,15 @@
|
|||||||
"pend": "~1.2.0"
|
"pend": "~1.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/frac": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/frac/-/frac-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/fs-extra": {
|
"node_modules/fs-extra": {
|
||||||
"version": "11.2.0",
|
"version": "11.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz",
|
||||||
@@ -1370,6 +1423,18 @@
|
|||||||
"integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==",
|
"integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==",
|
||||||
"license": "BSD-3-Clause"
|
"license": "BSD-3-Clause"
|
||||||
},
|
},
|
||||||
|
"node_modules/ssf": {
|
||||||
|
"version": "0.11.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/ssf/-/ssf-0.11.2.tgz",
|
||||||
|
"integrity": "sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"frac": "~1.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/streamx": {
|
"node_modules/streamx": {
|
||||||
"version": "2.20.1",
|
"version": "2.20.1",
|
||||||
"resolved": "https://registry.npmjs.org/streamx/-/streamx-2.20.1.tgz",
|
"resolved": "https://registry.npmjs.org/streamx/-/streamx-2.20.1.tgz",
|
||||||
@@ -1514,6 +1579,24 @@
|
|||||||
"integrity": "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==",
|
"integrity": "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/wmf": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/wmf/-/wmf-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/word": {
|
||||||
|
"version": "0.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/word/-/word-0.3.0.tgz",
|
||||||
|
"integrity": "sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/wrap-ansi": {
|
"node_modules/wrap-ansi": {
|
||||||
"version": "7.0.0",
|
"version": "7.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||||
@@ -1558,6 +1641,27 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/xlsx": {
|
||||||
|
"version": "0.18.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/xlsx/-/xlsx-0.18.5.tgz",
|
||||||
|
"integrity": "sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"adler-32": "~1.3.0",
|
||||||
|
"cfb": "~1.2.1",
|
||||||
|
"codepage": "~1.15.0",
|
||||||
|
"crc-32": "~1.2.1",
|
||||||
|
"ssf": "~0.11.2",
|
||||||
|
"wmf": "~1.0.1",
|
||||||
|
"word": "~0.3.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"xlsx": "bin/xlsx.njs"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/y18n": {
|
"node_modules/y18n": {
|
||||||
"version": "5.0.8",
|
"version": "5.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"inquirer": "^12.1.0",
|
"inquirer": "^12.1.0",
|
||||||
"puppeteer": "^23.7.0"
|
"puppeteer": "^23.7.0",
|
||||||
|
"xlsx": "^0.18.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
32
saveResultsToExcel.js
Normal file
32
saveResultsToExcel.js
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
const xlsx = require("xlsx");
|
||||||
|
|
||||||
|
function saveResultsToExcel(data, filename) {
|
||||||
|
const workbook = xlsx.utils.book_new(); // Create a new workbook
|
||||||
|
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
|
||||||
|
xlsx.writeFile(workbook, filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = saveResultsToExcel;
|
||||||
7
todo.md
Normal file
7
todo.md
Normal 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.
|
||||||
13
utils/parseCourseResults.js
Normal file
13
utils/parseCourseResults.js
Normal 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
169
utils/results.json
Normal 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 & 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
|
||||||
|
}
|
||||||
|
]
|
||||||
39
utils/updateResultsDatabase.js
Normal file
39
utils/updateResultsDatabase.js
Normal 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
28
vars.js
@@ -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
|
|
||||||
};
|
|
||||||
Reference in New Issue
Block a user