plutoapi-v2/src/models/rapla-middleware/icalgenerator/icalgenerator.service.ts

223 lines
5.4 KiB
TypeScript

const fetch = require('node-fetch');
export const getiCalFile = async (user: string, file: string, showBlockers: boolean, electiveModule: string, profileModule: string): Promise<string> => {
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'},
{name: 'Digitale Audiosignalverarbeitung'},
{name: 'Psychologische Grundlagen für Informatiker'},
{name: 'Erklärbare Künstliche Intelligenz'},
{name: 'Innovation Management'}
];
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
}