const fetch = require('node-fetch'); export const getiCalFile = async (user: string, file: string, showBlockers: boolean, electiveModule: string, profileModule: string): Promise => { try { let iCalFileContents = ''; let baseUrl = 'https://rapla.dhbw-karlsruhe.de/rapla?page=ical'; baseUrl += '&user=' + user; baseUrl += '&file=' + file; const response = await fetch(baseUrl); let body = await response.text(); // Parse the ical file let iCalFile = parseIcal(body); // Now remove unwanted shit from the iCal file if (!showBlockers) { iCalFile = removeBlockers(iCalFile); } if (electiveModule !== '') { iCalFile = removeElective(iCalFile, electiveModule); } if (profileModule !== '') { iCalFile = removeProfile(iCalFile, profileModule); } // Turn into one file again let resultingFile = serializeIcal(iCalFile); return resultingFile; } catch (err) { throw err; } }; export const parseIcal = function (icalContents: string): iCalFile { const fileHeaderRegex: RegExp = /^BEGIN:VCALENDAR.*?BEGIN:VEVENT$/ms; const eventRegex: RegExp = /^BEGIN:VEVENT.*?END:VEVENT$/msg; let headerMatch = fileHeaderRegex.exec(icalContents); let header = ''; if (headerMatch) { header = headerMatch[0]; } header = header.substr(0, header.lastIndexOf('\n') + 1); let events: iCalEvent[] = []; let match: any; while (match = eventRegex.exec(icalContents)) { if (match) { events.push({ content: match[0], duration: getDuration(match[0]) }); } } return { head: header, body: events }; }; export const getDuration = function (event: string): number { let startRegex: RegExp = /DTSTART.*?(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})Z?\r/gm; let endRegex: RegExp = /DTEND.*?(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})Z?\r/gm; let startMatch = startRegex.exec(event); let startDtYear = 0; let startDtMonth = 0; let startDtDay = 0; let startDtHour = 0; let startDtMinute = 0; if (startMatch) { startDtYear = parseInt(startMatch[1]); startDtMonth = parseInt(startMatch[2]); startDtDay = parseInt(startMatch[3]); startDtHour = parseInt(startMatch[4]); startDtMinute = parseInt(startMatch[5]); } let endMatch = endRegex.exec(event); let endDtYear = 0; let endDtMonth = 0; let endDtDay = 0; let endDtHour = 0; let endDtMinute = 0; if (endMatch) { endDtYear = parseInt(endMatch[1]); endDtMonth = parseInt(endMatch[2]); endDtDay = parseInt(endMatch[3]); endDtHour = parseInt(endMatch[4]); endDtMinute = parseInt(endMatch[5]); } let startDt = new Date(startDtYear, startDtMonth - 1, startDtDay, startDtHour, startDtMinute); let endDt = new Date(endDtYear, endDtMonth - 1, endDtDay, endDtHour, endDtMinute); let hourDifference = endDt.getHours() - startDt.getHours(); let minuteDifference = 0; if (hourDifference === 0) { minuteDifference = endDt.getMinutes() - startDt.getMinutes(); } return hourDifference + (minuteDifference / 60); }; export const serializeIcal = function (ical: iCalFile): string { let resString = ical.head; ical.body.forEach((event) => { resString += event.content + '\n'; }); resString += 'END:VCALENDAR\n'; return resString; }; export const removeBlockers = function (ical: iCalFile): iCalFile { let remainingEvents: iCalEvent[] = []; ical.body.forEach((event) => { if ( !event.content.includes('SUMMARY:Beginn Theorie') && !event.content.includes('SUMMARY:Präsenz') && event.duration < 10 && event.duration > 0.25 ) { remainingEvents.push(event); } }); ical.body = remainingEvents; return ical; }; export const removeElective = function (ical: iCalFile, chosenElective: string): iCalFile { let remainingEvents: iCalEvent[] = []; let electiveToRemove = [ {name: 'ERP-Systeme'}, {name: 'Ethik für Informatiker'}, {name: 'Evolutionäre Algorithmen'}, {name: 'Forensik'}, {name: 'Kryptographische Verfahren'}, {name: 'Robotik'}, {name: 'Web-Services'}, {name: 'High Performance Computing'} ]; electiveToRemove.splice(parseInt(chosenElective), 1); ical.body.forEach((event) => { let addEvent = true; electiveToRemove.forEach((module) => { if (event.content.includes(module.name)) { addEvent = false; } }); if (addEvent) { remainingEvents.push(event); } }); ical.body = remainingEvents; return ical; }; export const removeProfile = function (ical: iCalFile, chosenProfile: string): iCalFile { let remainingEvents: iCalEvent[] = []; let profileToRemove = [ {names: ['.Grundlagen der KI (KI und BV)', 'Bildverarbeitung (KI und BV)']}, {names: ['Bildverarbeitung', 'Computergraphik']}, {names: ['Interaktive Systeme', 'Grundlagen der KI']}, {names: ['e Business', 'angewandtes Projektmanagement']}, {names: ['Kommunikations und Netztechnik II']} ]; profileToRemove.splice(parseInt(chosenProfile), 1); ical.body.forEach((event) => { let addEvent = true; profileToRemove.forEach((module) => { module.names.forEach((name) => { if (event.content.includes(name)) { addEvent = false; } }); }); if (addEvent) { remainingEvents.push(event); } }); ical.body = remainingEvents; return ical; }; export interface iCalFile { head: string; body: iCalEvent[]; } export interface iCalEvent { content: string; duration: number; // Duration in hours }