2020-11-26 12:28:55 +01:00
|
|
|
const https = require("https");
|
|
|
|
const config = require("worker_threads").workerData;
|
|
|
|
const models = require("../models");
|
|
|
|
|
2020-12-12 21:52:55 +01:00
|
|
|
const reg_event = /(?:(?:BEGIN:VEVENT\nDTSTAMP:(?:[A-Z0-9]*?)\nDTSTART:([A-Z0-9]*?)\nDTEND:([A-Z0-9]*?)\nSUMMARY: {0,}([a-zéèàA-Z0-9-. \, \\/ô]*?)\nLOCATION:([a-zA-Zéèà0-9-. \,\\]*?)\nDESCRIPTION:(?:\\n){0,}((?:(?:LP(?:[ a-zA-Z0-9\\]*?))\\n){1,})((?:(?:[A-Z]*) (?:[A-Z]*)(?: (?:[A-Z]*)){0,}\\n){0,})(?:.*?)\nEND:VEVENT)|(?:BEGIN:VEVENT\nDTSTAMP:(?:[A-Z0-9]*?)\nDTSTART:([A-Z0-9]*?)\nDTEND:([A-Z0-9]*?)\nSUMMARY: {0,}((?:S(?:[A-Z0-9-]*)|M(?:[A-Z0-9-]*)(?:\/M(?:[A-Z0-9-]*)){0,}|Conférence)[a-zéèàA-Z0-9-. \, \\/]*?)\nLOCATION:([a-zA-Zéèà0-9-. \,\\]*?)\nDESCRIPTION:(?:\\n){0,}((?:(?:G[0-9]S[0-9]|S[0-9]|ASPE)\\n){0,})((?:(?:[A-Z]*) (?:[A-Z]*)(?: (?:[A-Z]*)){0,}\\n){0,})(?:.*?)\nEND:VEVENT))/gs;
|
2020-11-26 12:28:55 +01:00
|
|
|
const reg_location = /((?:[SH0-9][0-9]{2})|(?:(?:Préfa |Amphi)[0-9]))/g;
|
2020-12-12 18:28:44 +01:00
|
|
|
const reg_teachers = /^(?:((?:[a-zA-Z]*[ -]{0,}){0,}) ([a-zA-Z]*))$/m;
|
2020-11-26 12:28:55 +01:00
|
|
|
const reg_date = /([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2})([0-9]{2})([0-9]{2})Z/;
|
2020-12-12 21:52:55 +01:00
|
|
|
const reg_group = /(?:(LP)[ -]{0,}(.*)|(?:(G[0-9])(S[0-9])))/;
|
2020-11-26 12:28:55 +01:00
|
|
|
const base_url = config["edt"];
|
2020-12-12 21:52:55 +01:00
|
|
|
const capitalizeFirstLetter = (string) => string.charAt(0).toUpperCase() + string.slice(1).toLowerCase();
|
|
|
|
|
2020-11-26 12:28:55 +01:00
|
|
|
|
|
|
|
function fetchEvents(days = 1, TS_Start = new Date()) {
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
let start = new Date(TS_Start);
|
|
|
|
if (start == "Invalid Date")
|
|
|
|
start = new Date();
|
|
|
|
let end = new Date(start);
|
|
|
|
end.setDate(end.getDate() + days);
|
|
|
|
|
|
|
|
let url = base_url + start.getFullYear() + "-" + start.getMonth() + "-" + start.getDate() + "&lastDate=" + end.getFullYear() + "-" + end.getMonth() + "-" + end.getDate();
|
|
|
|
https.get(url, (resp) => {
|
|
|
|
let data = "";
|
|
|
|
resp.on("data", (chunk) => {
|
|
|
|
data += chunk;
|
|
|
|
});
|
|
|
|
resp.on("end", () => {
|
|
|
|
let output = [];
|
|
|
|
data = data.replace(/\r/g, "");
|
|
|
|
let m;
|
|
|
|
while ((m = reg_event.exec(data)) !== null) {
|
|
|
|
if (m.index === reg_event.lastIndex) {
|
|
|
|
reg_event.lastIndex++;
|
|
|
|
}
|
|
|
|
let event = [];
|
2020-12-12 21:52:55 +01:00
|
|
|
let semester = [];
|
|
|
|
let group = [];
|
2020-11-26 12:28:55 +01:00
|
|
|
/*
|
|
|
|
m = [
|
|
|
|
FullMatch,
|
|
|
|
StartTime,
|
|
|
|
EndTime,
|
|
|
|
EventDescription ( SubjectID,Name,Class?) ,
|
|
|
|
Location,
|
|
|
|
ClassGroup,
|
|
|
|
Teacher(s)
|
|
|
|
]
|
|
|
|
*/
|
|
|
|
if (m[1] !== undefined) {
|
|
|
|
// LPXXXX
|
|
|
|
} else {
|
|
|
|
m.splice(1, 6);
|
|
|
|
// GXSX | SX | ASPE
|
|
|
|
}
|
2020-12-12 21:52:55 +01:00
|
|
|
let csplit = m[5].split("\\n");
|
|
|
|
csplit.pop();
|
|
|
|
csplit.forEach(e => {
|
|
|
|
if (e === "ASPE") {
|
|
|
|
semester.push(e);
|
|
|
|
}else if(/^S[0-9]$/.test(e)) {
|
|
|
|
semester.push(e);
|
|
|
|
}else{
|
|
|
|
let groupSplit = reg_group.exec(e);
|
|
|
|
if (groupSplit[1] === 'LP') {
|
|
|
|
group.push([groupSplit[2], groupSplit[1]]);
|
|
|
|
} else {
|
|
|
|
group.push([groupSplit[3], groupSplit[4]]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2020-11-26 12:28:55 +01:00
|
|
|
event["title"] = m[3];
|
2020-12-12 21:52:55 +01:00
|
|
|
event["semesters"] = semester;
|
|
|
|
event["groups"] = group;
|
2020-11-26 12:28:55 +01:00
|
|
|
/*
|
|
|
|
Date
|
|
|
|
*/
|
|
|
|
let d1 = reg_date.exec(m[1]);
|
|
|
|
let d2 = reg_date.exec(m[2]);
|
|
|
|
event["startDate"] = new Date(d1[1] + "-" + d1[2] + "-" + d1[3] + "T" + d1[4] + ":" + d1[5] + ":" + d1[6] + ".00Z");
|
|
|
|
event["endDate"] = new Date(d2[1] + "-" + d2[2] + "-" + d2[3] + "T" + d2[4] + ":" + d2[5] + ":" + d2[6] + ".00Z");
|
|
|
|
/*
|
|
|
|
Location
|
|
|
|
*/
|
|
|
|
event["locations"] = [];
|
|
|
|
let loc;
|
|
|
|
while ((loc = reg_location.exec(m[4])) !== null) {
|
|
|
|
if (loc.index === reg_location.lastIndex) {
|
|
|
|
reg_location.lastIndex++;
|
|
|
|
}
|
|
|
|
event["locations"].push(loc[1]);
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
Teachers
|
|
|
|
*/
|
2020-12-12 21:52:55 +01:00
|
|
|
event['teachers'] = [];
|
2020-12-12 18:28:44 +01:00
|
|
|
let fullTeachers = m[6].split('\\n');
|
|
|
|
fullTeachers.forEach(e => {
|
|
|
|
if(e !== ""){
|
|
|
|
let splittedTeachers = reg_teachers.exec(e);
|
|
|
|
event['teachers'].push([splittedTeachers[1],splittedTeachers[2]]);
|
|
|
|
}
|
|
|
|
});
|
2020-11-26 12:28:55 +01:00
|
|
|
output.push(event);
|
|
|
|
}
|
|
|
|
resolve(output);
|
|
|
|
});
|
|
|
|
}).on("error", (err) => {
|
|
|
|
reject(err);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function compare(a, b) {
|
|
|
|
if (a.length !== b.length) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
let set = {};
|
|
|
|
a.forEach((i) => {
|
|
|
|
if (set[i] !== undefined) {
|
|
|
|
set[i]++;
|
|
|
|
} else {
|
|
|
|
set[i] = 1;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
let difference = b.every((i) => {
|
|
|
|
if (set[i] === undefined) {
|
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
set[i]--;
|
|
|
|
if (set[i] === 0) {
|
|
|
|
delete set[i];
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
return Object.keys(set) == 0 && difference;
|
|
|
|
}
|
|
|
|
|
|
|
|
function compareGroups(list1, list2) {
|
2020-12-12 21:52:55 +01:00
|
|
|
return compare(list1.map(g => g[0] + " " + g[1]), list2.map(g => g.number + " " + g.Semester.name));
|
2020-11-26 12:28:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
function compareTeachers(list1, list2) {
|
2020-12-12 21:52:55 +01:00
|
|
|
return compare(list1.map(t => t[0].toUpperCase() + " " + t[1].toUpperCase()), list2.map(t => t.lastName.toUpperCase() + " " + t.firstName.toUpperCase()));
|
2020-11-26 12:28:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
function compareSemesters(list1, list2) {
|
|
|
|
return compare(list1, list2.map(s => s.name));
|
|
|
|
}
|
|
|
|
|
|
|
|
async function updateDatabase() {
|
|
|
|
let events = await fetchEvents(365, new Date(2020, 9, 1));
|
|
|
|
for (let event of await models.Event.findAll({
|
|
|
|
include: [{
|
|
|
|
model: models.Group,
|
|
|
|
include: {model: models.Semester, required: true}
|
|
|
|
}, models.User, models.Semester]
|
|
|
|
})) {
|
2020-12-12 21:52:55 +01:00
|
|
|
let ev = events.find(e => (e.title === event.name && e.startDate.getTime() === event.startDate.getTime() &&
|
2020-11-26 12:28:55 +01:00
|
|
|
e.endDate.getTime() === event.endDate.getTime() && e.locations.join(", ") === event.locations &&
|
2020-12-12 21:52:55 +01:00
|
|
|
compareGroups(e.groups, event.Groups) && compareTeachers(e.teachers, event.Users) &&
|
|
|
|
compareSemesters(e.semesters, event.Semesters)));
|
|
|
|
if (!ev)
|
2020-11-26 12:28:55 +01:00
|
|
|
await event.destroy();
|
|
|
|
else
|
2020-12-12 21:52:55 +01:00
|
|
|
events = events.filter(e => e !== ev);
|
2020-11-26 12:28:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
for (let event of events) {
|
|
|
|
let e = await models.Event.create({
|
|
|
|
name: event.title,
|
|
|
|
startDate: event.startDate,
|
|
|
|
endDate: event.endDate,
|
|
|
|
locations: event.locations.join(", ")
|
|
|
|
});
|
|
|
|
|
|
|
|
let teachers = [];
|
|
|
|
for (let teacher of event.teachers) {
|
2020-12-12 21:52:55 +01:00
|
|
|
let t = await models.User.findOne({where: {permissions: 2, lastName: teacher[0].toUpperCase(), firstName: capitalizeFirstLetter(teacher[1])}});
|
2020-11-26 12:28:55 +01:00
|
|
|
if (!t)
|
|
|
|
t = await models.User.create({
|
2020-12-12 21:52:55 +01:00
|
|
|
email: teacher[1].toLowerCase().replaceAll(" ", "-") + "." + teacher[0].toLowerCase().replaceAll(" ", "-") + "@univ-lyon1.fr",
|
|
|
|
firstName: capitalizeFirstLetter(teacher[1]),
|
|
|
|
lastName: teacher[0].toUpperCase(),
|
2020-11-26 12:28:55 +01:00
|
|
|
permissions: 2,
|
|
|
|
passwordHash: Math.round((Math.pow(36, 12 + 1) - Math.random() * Math.pow(36, 12))).toString(36).slice(1)
|
|
|
|
});
|
|
|
|
teachers.push(t);
|
|
|
|
}
|
|
|
|
await e.addUsers(teachers);
|
|
|
|
|
|
|
|
let semesters = [];
|
2020-12-12 21:52:55 +01:00
|
|
|
for (let semester of event.semesters) {
|
2020-11-26 12:28:55 +01:00
|
|
|
let s = await models.Semester.findOne({where: {name: semester, year: event.startDate.getFullYear()}});
|
|
|
|
if (!s)
|
|
|
|
s = await models.Semester.create({
|
|
|
|
name: semester,
|
|
|
|
year: event.startDate.getFullYear()
|
|
|
|
});
|
|
|
|
semesters.push(s);
|
|
|
|
}
|
|
|
|
await e.addSemesters(semesters);
|
|
|
|
|
|
|
|
let groups = [];
|
2020-12-12 21:52:55 +01:00
|
|
|
for (let group of event.groups) {
|
|
|
|
let s = await models.Semester.findOne({where: {name: group[1], year: event.startDate.getFullYear()}});
|
2020-11-26 12:28:55 +01:00
|
|
|
if (!s)
|
|
|
|
s = await models.Semester.create({
|
2020-12-12 21:52:55 +01:00
|
|
|
name: group[1],
|
2020-11-26 12:28:55 +01:00
|
|
|
year: event.startDate.getFullYear()
|
|
|
|
});
|
|
|
|
|
2020-12-12 21:52:55 +01:00
|
|
|
let g = await models.Group.findOne({where: {number: group[0], SemesterId: s.id}});
|
2020-11-26 12:28:55 +01:00
|
|
|
if (!g)
|
|
|
|
g = await models.Group.create({
|
2020-12-12 21:52:55 +01:00
|
|
|
number: group[0],
|
2020-11-26 12:28:55 +01:00
|
|
|
SemesterId: s.id
|
|
|
|
});
|
|
|
|
groups.push(g);
|
|
|
|
}
|
|
|
|
await e.addGroups(groups);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
updateDatabase().then(() => setInterval(updateDatabase, 30000));
|