Commit 9c86bc34 authored by Erwan BOUSSE's avatar Erwan BOUSSE
Browse files

Split ts in two files

parent 609b1a51
Pipeline #18626 passed with stages
in 49 seconds
......@@ -71,7 +71,7 @@
</div>
</div>
<button onclick="edtextractor.extractAndPrint()">Lancer</button>
<button onclick="edtextractor.run()">Lancer</button>
<h2>Résultats :</h2>
......
import { XMLHttpRequest } from 'xmlhttprequest-ts'
import { DOMParser } from 'xmldom'
let ICAL = require("ical.js")
import { extractAndPrint, Mode } from './edtextractorlib'
export function extractAndPrint(): void {
export function run(): void {
// Get inputs from HTML
let firstName = (document.getElementById("fname") as HTMLInputElement).value
let lastName = (document.getElementById("lname") as HTMLInputElement).value
let courseId = (document.getElementById("courseID") as HTMLInputElement).value
wrapExec(() => { extractAndPrintInternal(firstName, lastName, courseId, getMode(), webLog, webFlush) }, webLog)
}
function extractAndPrintInternal(firstName: string, lastName: string, courseId: string, mode: Mode, log: (string) => void, flush: () => void): void {
flush()
switch (mode) {
case Mode.PERSON_AND_COURSE:
extractAndPrintPersonAndCourse(firstName, lastName, courseId, log)
break;
case Mode.PERSON:
extractAndPrintPerson(firstName, lastName, log)
break;
case Mode.COURSE:
extractAndPrintCourse(courseId, log)
break;
default: log("Informations invalides")
}
}
function isEmptyOrNull(s: string) {
return s == undefined || s == ""
}
function extractAndPrintPersonAndCourse(firstName: string, lastName: string, courseId: string, log) {
if (isEmptyOrNull(firstName) || isEmptyOrNull(lastName) || isEmptyOrNull(courseId)) {
log("Informations invalides")
} else {
log(`Synthèse des heures de ${firstName} ${lastName} pour l'UE ${courseId}…`)
getEventsPersonAsync(firstName, lastName, log, (allEvents: any[]) => {
let sortedEvents = sortEventsPerCourseID(allEvents)
let courseEvents = sortedEvents.get(courseId)
let matiere: string = getCourseFromEvent(courseEvents[0])
let intervenant: string = getPersonFromEvent(courseEvents[0])
log()
log(`== UE : « ${matiere} »`)
log(`== Intervenant : « ${intervenant} »`)
printDurationsFromEvents(courseEvents, log)
})
}
}
function extractAndPrintPerson(firstName: string, lastName: string, log): void {
if (isEmptyOrNull(firstName) || isEmptyOrNull(lastName)) {
log("Informations invalides")
} else {
log(`Synthèse des heures de ${firstName} ${lastName}…`)
getEventsPersonAsync(firstName, lastName, log, (allEvents) => {
let sortedEvents = sortEventsPerCourseID(allEvents)
for (let courseId of sortedEvents.keys()) {
let courseEvents = sortedEvents.get(courseId)
let matiere: string = getCourseFromEvent(courseEvents[0])
log()
log(`== UE : « ${matiere} »`)
printDurationsFromEvents(courseEvents, log)
}
})
}
}
function extractAndPrintCourse(courseID: string, log): void {
if (isEmptyOrNull(courseID)) {
log("Informations invalides")
} else {
log(`Synthèse des heures de l'UE ${courseID}…`)
getEventsCourseAsync(courseID, log, (allEvents) => {
let sortedEvents = sortEventsPerPerson(allEvents)
let matiere: string = getCourseFromEvent(allEvents[0])
log()
log(`== UE : « ${matiere} »`)
for (let person of sortedEvents.keys()) {
log()
log(`=== Intervenant : « ${person} »`)
let courseEvents = sortedEvents.get(person)
printDurationsFromEvents(courseEvents, log)
}
})
}
}
function sortEventsPerCourseID(events: any[]): Map<string, any[]> {
let result: Map<string, any[]> = new Map<string, any[]>()
for (let event of events) {
let courseID = getCourseIDFromEvent(event)
if (!result.has(courseID)) {
result.set(courseID, [])
}
result.get(courseID).push(event)
}
return result
}
function sortEventsPerPerson(events: any[]): Map<string, any[]> {
let result: Map<string, any[]> = new Map<string, any[]>()
for (let event of events) {
let person = getPersonFromEvent(event)
if (!result.has(person)) {
result.set(person, [])
}
result.get(person).push(event)
}
return result
}
function getAllURLsFromCelcatPageAsync(url: string, then: (allICS: Map<string, string>) => void, log) {
httpGetAsync(url, (responseText: string) => {
if (isEmptyOrNull(responseText)) {
log("")
log("Impossible d'analyser le fichier ICS. Arrêt.")
log("")
return
}
let domparser: DOMParser = new DOMParser();
let parsedContent = domparser.parseFromString(responseText, 'text/html')
let options: HTMLCollection = parsedContent.getElementsByTagName("option")
let allURLs: Map<string, string> = new Map<string, string>()
for (let i = 0; i < options.length; i++) {
let option = options[i]
let valueAtt = option.attributes.getNamedItem("value")
if (valueAtt) {
allURLs.set(option.textContent.toLowerCase(), "https://edt.univ-nantes.fr/sciences/" + valueAtt.value.replace("html", "ics"))
}
}
then(allURLs)
}, log)
}
function getEventsPersonAsync(firstName: string, lastName: string, log: (string: any) => void, then: (allEvents: any[]) => void): void {
let url: string = "https://edt.univ-nantes.fr/sciences/sindex.html"
getAllURLsFromCelcatPageAsync(url, (allURLs) => {
let fullName: string = `${lastName}, ${firstName}`
let icsURL: string = allURLs.get(fullName.toLowerCase())
getEventsFromICSAsync(icsURL, log, (allEvents) => {
then(allEvents)
})
}, log)
}
function getEventsCourseAsync(courseID: string, log: (string: any) => void, then: (allEvents: any[]) => void): void {
let url: string = "https://edt.univ-nantes.fr/sciences/mindex.html"
getAllURLsFromCelcatPageAsync(url, (allURLs) => {
for (let key of allURLs.keys()) {
if (key.includes(courseID.toLowerCase())) {
let icsURL = allURLs.get(key)
getEventsFromICSAsync(icsURL, log, (allEvents) => {
then(allEvents)
})
break
}
}
}, log)
}
function getEventsFromICSAsync(url: string, log, then) {
log("Récupération de l'emploi du temps depuis " + url)
httpGetAsync(url, (responseText) => {
let icsContent: string = responseText
let jcalData = ICAL.parse(icsContent);
let structuredData = new ICAL.Component(jcalData);
let allEvents = (structuredData.getAllSubcomponents("vevent") as Array<any>).map(vevent => new ICAL.Event(vevent))
log(allEvents.length + " créneaux trouvés dans cet ICS.")
then(allEvents)
}, log)
}
function httpGetAsync(url: string, then, log) {
let xmlHttp: XMLHttpRequest = new XMLHttpRequest();
xmlHttp.open("GET", url)
xmlHttp.send()
xmlHttp.onloadend = () => {
wrapExec(() => {
then(xmlHttp.responseText)
}, log)
}
xmlHttp.onerror = (err) => {
logErr(err + "", log)
log("Si vous n'avez pas activé l'extension CORS Everywhere, le problème vient peut-être de là.")
}
}
function getPersonFromEvent(event: any): string {
let enseignantResult = event.description.match('Personnel : (.*)\n')
if (enseignantResult) {
return enseignantResult[1]
} else {
return "Intervenant(s) inconnu(s)"
}
}
function getCourseFromEvent(event: any): string {
let matiereResult = event.description.match('Matière : (.*\\))')
if (matiereResult) {
return matiereResult[1]
} else {
return "UE(s) inconnue(s)"
}
}
function getEventTypeFromEvent(event: any): string {
let courseTypeResult = event.summary.match('^(.*?) -')
if (courseTypeResult) {
return courseTypeResult[1]
} else {
return "Évènement(s) inconnu(s)"
}
}
function getCourseIDFromEvent(event: any): string {
let courseIDResult = event.summary.match('\\((X.*?)\\)')
if (courseIDResult) {
return courseIDResult[1]
} else {
return "UE(s) inconnue(s)"
}
}
function printDurationsFromEvents(events, log) {
// Sort events per course type
let structuredEvents: Map<string, Array<any>> = new Map<string, Array<any>>()
for (let event of events) {
let eventType = getEventTypeFromEvent(event)
if (!structuredEvents.has(eventType)) {
structuredEvents.set(eventType, [])
}
structuredEvents.get(eventType).push(event)
}
// Sum durations for each course type
for (let eventType of structuredEvents.keys()) {
let events = structuredEvents.get(eventType)
let durationSeconds = events.map(event => event.duration.toSeconds() as number).reduce((d1, d2) => d1 + d2)
let durationHours: string = (durationSeconds / 3600).toFixed(2)
let durationPretty: string = prettyDuration(durationSeconds)
log(`− ${eventType} : ${durationPretty} (${durationHours})`)
}
}
function prettyDuration(durationSeconds: number): string {
let duration = ICAL.Duration.fromSeconds(durationSeconds)
let durationHours = duration.days * 24 + duration.hours
let durationMinutes = duration.minutes == 0 ? "00" : duration.minutes
let durationPretty: string = `${durationHours}h${durationMinutes}`
return durationPretty
extractAndPrint(firstName, lastName, courseId, getMode(), webLog, webFlush)
}
function webLog(message: string) {
message = message ? message : ""
console.log(message)
let resultsPlaceholder = document.getElementById("output") as HTMLTextAreaElement
resultsPlaceholder.value += message + "\n"
}
function webFlush() {
let resultsPlaceholder = document.getElementById("output") as HTMLTextAreaElement
resultsPlaceholder.value = ""
}
enum Mode {
PERSON_AND_COURSE,
PERSON,
COURSE
}
function getMode(): Mode {
let personAndCourseRadio = document.getElementById("personAndCourseRadio") as HTMLInputElement
let personRadio = document.getElementById("personRadio") as HTMLInputElement
let courseRadio = document.getElementById("courseRadio") as HTMLInputElement
if (personAndCourseRadio.checked) {
return Mode.PERSON_AND_COURSE
} else if (personRadio.checked) {
return Mode.PERSON
} else if (courseRadio.checked) {
return Mode.COURSE
}
}
function hideAll(): void {
document.getElementById("firstNameDiv").style.display = 'none'
document.getElementById("lastNameDiv").style.display = 'none'
......@@ -338,24 +49,28 @@ export function initPage(): void {
modeChanged()
}
function logErr(message: string, log) {
log("")
log("##### Erreur rencontrée : " + message)
log("")
function webLog(message: string) {
message = message ? message : ""
console.log(message)
let resultsPlaceholder = document.getElementById("output") as HTMLTextAreaElement
resultsPlaceholder.value += message + "\n"
}
function wrapExec(f, log) {
try {
f()
} catch (e) {
logErr(e, log)
}
function webFlush() {
let resultsPlaceholder = document.getElementById("output") as HTMLTextAreaElement
resultsPlaceholder.value = ""
}
//extractAndPrintInternal("erwan", "bousse", "X4IP120", console.log, () => { })
//extractAndPrintInternal("erwan", "bousse", "", console.log, () => { })
//extractAndPrintInternal("", "", "X4IP120", console.log, () => { })
//extractAndPrintInternal("", "", "X12I040", console.log, () => { })
//extractAndPrintInternal("", "", "X3IA040", console.log, () => { })
//extractAndPrintInternal("", "", "X3IA040", console.log, () => { })
//extractAndPrintInternal("Emmanuel", "Desmontils", "X2IM030", Mode.PERSON, console.log, () => { })
\ No newline at end of file
function getMode(): Mode {
let personAndCourseRadio = document.getElementById("personAndCourseRadio") as HTMLInputElement
let personRadio = document.getElementById("personRadio") as HTMLInputElement
let courseRadio = document.getElementById("courseRadio") as HTMLInputElement
if (personAndCourseRadio.checked) {
return Mode.PERSON_AND_COURSE
} else if (personRadio.checked) {
return Mode.PERSON
} else if (courseRadio.checked) {
return Mode.COURSE
}
}
import { XMLHttpRequest } from 'xmlhttprequest-ts'
import { DOMParser } from 'xmldom'
let ICAL = require("ical.js")
export function extractAndPrint(firstName: string, lastName: string, courseId: string, mode: Mode, log: (string) => void, flush: () => void): void {
wrapExec(() => {
flush()
switch (mode) {
case Mode.PERSON_AND_COURSE:
extractAndPrintPersonAndCourse(firstName, lastName, courseId, log)
break;
case Mode.PERSON:
extractAndPrintPerson(firstName, lastName, log)
break;
case Mode.COURSE:
extractAndPrintCourse(courseId, log)
break;
default: log("Informations invalides")
}
}, log)
}
function isEmptyOrNull(s: string) {
return s == undefined || s == ""
}
function extractAndPrintPersonAndCourse(firstName: string, lastName: string, courseId: string, log) {
if (isEmptyOrNull(firstName) || isEmptyOrNull(lastName) || isEmptyOrNull(courseId)) {
log("Informations invalides")
} else {
log(`Synthèse des heures de ${firstName} ${lastName} pour l'UE ${courseId}…`)
getEventsPersonAsync(firstName, lastName, log, (allEvents: any[]) => {
let sortedEvents = sortEventsPerCourseID(allEvents)
let courseEvents = sortedEvents.get(courseId)
let matiere: string = getCourseFromEvent(courseEvents[0])
let intervenant: string = getPersonFromEvent(courseEvents[0])
log()
log(`== UE : « ${matiere} »`)
log(`== Intervenant : « ${intervenant} »`)
printDurationsFromEvents(courseEvents, log)
})
}
}
function extractAndPrintPerson(firstName: string, lastName: string, log): void {
if (isEmptyOrNull(firstName) || isEmptyOrNull(lastName)) {
log("Informations invalides")
} else {
log(`Synthèse des heures de ${firstName} ${lastName}…`)
getEventsPersonAsync(firstName, lastName, log, (allEvents) => {
let sortedEvents = sortEventsPerCourseID(allEvents)
for (let courseId of sortedEvents.keys()) {
let courseEvents = sortedEvents.get(courseId)
let matiere: string = getCourseFromEvent(courseEvents[0])
log()
log(`== UE : « ${matiere} »`)
printDurationsFromEvents(courseEvents, log)
}
})
}
}
function extractAndPrintCourse(courseID: string, log): void {
if (isEmptyOrNull(courseID)) {
log("Informations invalides")
} else {
log(`Synthèse des heures de l'UE ${courseID}…`)
getEventsCourseAsync(courseID, log, (allEvents) => {
let sortedEvents = sortEventsPerPerson(allEvents)
let matiere: string = getCourseFromEvent(allEvents[0])
log()
log(`== UE : « ${matiere} »`)
for (let person of sortedEvents.keys()) {
log()
log(`=== Intervenant : « ${person} »`)
let courseEvents = sortedEvents.get(person)
printDurationsFromEvents(courseEvents, log)
}
})
}
}
function sortEventsPerCourseID(events: any[]): Map<string, any[]> {
let result: Map<string, any[]> = new Map<string, any[]>()
for (let event of events) {
let courseID = getCourseIDFromEvent(event)
if (!result.has(courseID)) {
result.set(courseID, [])
}
result.get(courseID).push(event)
}
return result
}
function sortEventsPerPerson(events: any[]): Map<string, any[]> {
let result: Map<string, any[]> = new Map<string, any[]>()
for (let event of events) {
let person = getPersonFromEvent(event)
if (!result.has(person)) {
result.set(person, [])
}
result.get(person).push(event)
}
return result
}
function getAllURLsFromCelcatPageAsync(url: string, then: (allICS: Map<string, string>) => void, log) {
httpGetAsync(url, (responseText: string) => {
if (isEmptyOrNull(responseText)) {
log("")
log("Impossible d'analyser le fichier ICS. Arrêt.")
log("")
return
}
let domparser: DOMParser = new DOMParser();
let parsedContent = domparser.parseFromString(responseText, 'text/html')
let options: HTMLCollection = parsedContent.getElementsByTagName("option")
let allURLs: Map<string, string> = new Map<string, string>()
for (let i = 0; i < options.length; i++) {
let option = options[i]
let valueAtt = option.attributes.getNamedItem("value")
if (valueAtt) {
allURLs.set(option.textContent.toLowerCase(), "https://edt.univ-nantes.fr/sciences/" + valueAtt.value.replace("html", "ics"))
}
}
then(allURLs)
}, log)
}
function getEventsPersonAsync(firstName: string, lastName: string, log: (string: any) => void, then: (allEvents: any[]) => void): void {
let url: string = "https://edt.univ-nantes.fr/sciences/sindex.html"
getAllURLsFromCelcatPageAsync(url, (allURLs) => {
let fullName: string = `${lastName}, ${firstName}`
let icsURL: string = allURLs.get(fullName.toLowerCase())
getEventsFromICSAsync(icsURL, log, (allEvents) => {
then(allEvents)
})
}, log)
}
function getEventsCourseAsync(courseID: string, log: (string: any) => void, then: (allEvents: any[]) => void): void {
let url: string = "https://edt.univ-nantes.fr/sciences/mindex.html"
getAllURLsFromCelcatPageAsync(url, (allURLs) => {
for (let key of allURLs.keys()) {
if (key.includes(courseID.toLowerCase())) {
let icsURL = allURLs.get(key)
getEventsFromICSAsync(icsURL, log, (allEvents) => {
then(allEvents)
})
break
}
}
}, log)
}
function getEventsFromICSAsync(url: string, log, then) {
log("Récupération de l'emploi du temps depuis " + url)
httpGetAsync(url, (responseText) => {
let icsContent: string = responseText
let jcalData = ICAL.parse(icsContent);
let structuredData = new ICAL.Component(jcalData);
let allEvents = (structuredData.getAllSubcomponents("vevent") as Array<any>).map(vevent => new ICAL.Event(vevent))
log(allEvents.length + " créneaux trouvés dans cet ICS.")
then(allEvents)
}, log)
}
function httpGetAsync(url: string, then, log) {
let xmlHttp: XMLHttpRequest = new XMLHttpRequest();
xmlHttp.open("GET", url)
xmlHttp.send()
xmlHttp.onloadend = () => {
wrapExec(() => {
then(xmlHttp.responseText)
}, log)
}
xmlHttp.onerror = (err) => {
logErr(err + "", log)
log("Si vous n'avez pas activé l'extension CORS Everywhere, le problème vient peut-être de là.")
}
}
function getPersonFromEvent(event: any): string {
let enseignantResult = event.description.match('Personnel : (.*)\n')
if (enseignantResult) {
return enseignantResult[1]
} else {
return "Intervenant(s) inconnu(s)"
}
}
function getCourseFromEvent(event: any): string {
let matiereResult = event.description.match('Matière : (.*\\))')
if (matiereResult) {
return matiereResult[1]
} else {
return "UE(s) inconnue(s)"
}
}
function getEventTypeFromEvent(event: any): string {
let courseTypeResult = event.summary.match('^(.*?) -')
if (courseTypeResult) {
return courseTypeResult[1]
} else {
return "Évènement(s) inconnu(s)"
}
}
function getCourseIDFromEvent(event: any): string {
let courseIDResult = event.summary.match('\\((X.*?)\\)')
if (courseIDResult) {
return courseIDResult[1]
} else {
return "UE(s) inconnue(s)"
}
}
function printDurationsFromEvents(events, log) {
// Sort events per course type