diff options
author | Minteck <contact@minteck.org> | 2023-01-10 14:54:04 +0100 |
---|---|---|
committer | Minteck <contact@minteck.org> | 2023-01-10 14:54:04 +0100 |
commit | 99c1d9af689e5325f3cf535c4007b3aeb8325229 (patch) | |
tree | e663b3c2ebdbd67c818ac0c5147f0ce1d2463cda /school/node_modules/pronote-api/src/fetch/pronote | |
parent | 9871b03912fc28ad38b4037ebf26a78aa937baba (diff) | |
download | pluralconnect-99c1d9af689e5325f3cf535c4007b3aeb8325229.tar.gz pluralconnect-99c1d9af689e5325f3cf535c4007b3aeb8325229.tar.bz2 pluralconnect-99c1d9af689e5325f3cf535c4007b3aeb8325229.zip |
Update - This is an automated commit
Diffstat (limited to 'school/node_modules/pronote-api/src/fetch/pronote')
15 files changed, 965 insertions, 0 deletions
diff --git a/school/node_modules/pronote-api/src/fetch/pronote/absences.js b/school/node_modules/pronote-api/src/fetch/pronote/absences.js new file mode 100644 index 0000000..19bf2dc --- /dev/null +++ b/school/node_modules/pronote-api/src/fetch/pronote/absences.js @@ -0,0 +1,164 @@ +const parse = require('../../data/types'); +const { toPronote } = require('../../data/objects'); +const { toPronoteDate } = require('../../data/dates'); +const { fromPronoteHours } = require('../../data/dates'); + +const navigate = require('./navigate'); + +const PAGE_NAME = 'PagePresence'; +const TAB_ID = 19; +const ACCOUNTS = ['student', 'parent']; + +async function getAbsences(session, user, period, from, to) +{ + const absences = await navigate(session, user, PAGE_NAME, TAB_ID, ACCOUNTS, { + DateDebut: { + _T: 7, + V: toPronoteDate(from) + }, + DateFin: { + _T: 7, + V: toPronoteDate(to) + }, + periode: period.name ? toPronote(period) : period + }); + + if (!absences) { + return null; + } + + return { + authorizations: (a => ({ + absences: a.absence, + fillAbsenceReason: a.saisieMotifAbsence, + delays: a.retard, + fillDelayReason: a.saisieMotifRetard, + punishments: a.punition, + exclusions: a.exclusion, + sanctions: a.sanction, + conservatoryMesures: a.mesureConservatoire, + infirmary: a.infirmerie, + mealAbsences: a.absenceRepas, + internshipAbsences: a.absenceInternat, + observations: a.observation, + incidents: a.incident, + totalHoursMissed: a.totalHeuresManquees + }))(absences.autorisations), + events: parse(absences.listeAbsences, a => parseEvent(a), false), + subjects: parse(absences.Matieres, ({ + P, regroupement, dansRegroupement, suivi, absence, excluCours, excluEtab + }) => ({ + position: P, + group: regroupement, + inGroup: dansRegroupement, + hoursAssisted: suivi / 3600, + hoursMissed: absence / 3600, + lessonExclusions: excluCours, + establishmentExclusions: excluEtab + })), + recaps: parse(absences.listeRecapitulatifs, ({ NombreTotal, NbrHeures, NombreNonJustifie }) => ({ + count: NombreTotal, + unjustifiedCount: NombreNonJustifie, + hours: fromPronoteHours(NbrHeures) + })), + sanctions: parse(absences.listeSanctionUtilisateur) // TODO: Check values + }; +} + +function parseEvent(a) +{ + switch (a.page.Absence) { + case 13: + return { + type: 'absence', + ...parseAbsence(a) + }; + case 14: + return { + type: 'delay', + ...parseDelay(a) + }; + case 41: + return { + type: 'punishment', + ...parsePunishment(a) + }; + case 45: + return { + type: 'other', + ...parseOther(a) + }; + default: + return { + type: 'unknown', + ...a + }; + } +} + +function parseAbsence(a) +{ + return { + from: parse(a.dateDebut), + to: parse(a.dateFin), + opened: a.ouverte, + solved: a.reglee, + justified: a.justifie, + hours: fromPronoteHours(a.NbrHeures), + days: a.NbrJours, + reasons: parse(a.listeMotifs) + } +} + +function parseDelay(a) +{ + return { + date: parse(a.date), + solved: a.reglee, + justified: a.justifie, + justification: a.justification, + duration: a.duree, + reasons: parse(a.listeMotifs) + }; +} + +function parsePunishment(a) +{ + return { + date: parse(a.dateDemande), + isExclusion: a.estUneExclusion, + isNotDuringLesson: a.horsCours, + homework: a.travailAFaire, + isBoundToIncident: a.estLieAUnIncident, + circumstances: a.circonstances, + duration: a.duree, + giver: parse(a.demandeur), + isSchedulable: a.estProgrammable, + reasons: parse(a.listeMotifs), + schedule: parse(a.programmation, ({ date, placeExecution, duree }) => ({ + date: parse(date), + position: placeExecution, + duration: duree + })), + nature: a.nature && parse(a.nature, ({ estProgrammable, estAvecARParent }) => ({ + isSchedulable: estProgrammable, + requiresParentsMeeting: estAvecARParent + })) + } +} + +function parseOther(a) +{ + return { + date: parse(a.date), + giver: parse(a.demandeur, ({ estProfPrincipal, mail }) => ({ + isHeadTeacher: estProfPrincipal, + mail + })), + comment: a.commentaire, + read: a.estLue, + subject: parse(a.matiere) + }; +} + +module.exports = getAbsences; diff --git a/school/node_modules/pronote-api/src/fetch/pronote/auth.js b/school/node_modules/pronote-api/src/fetch/pronote/auth.js new file mode 100644 index 0000000..9c1d566 --- /dev/null +++ b/school/node_modules/pronote-api/src/fetch/pronote/auth.js @@ -0,0 +1,43 @@ +const request = require('../../request'); +const { cipher } = require('../../cipher'); + +async function getId(session, username, fromCas) +{ + const { donnees: id } = await request(session, 'Identification', { + donnees: { + genreConnexion: 0, + genreEspace: session.type.id, + identifiant: username, + pourENT: fromCas, + enConnexionAuto: false, + demandeConnexionAuto: false, + demandeConnexionAppliMobile: false, + demandeConnexionAppliMobileJeton: false, + uuidAppliMobile: '', + loginTokenSAV: '' + } + }); + + return { + scramble: id.alea, + challenge: id.challenge + }; +} + +async function getAuthKey(session, challenge, key) +{ + const { donnees: auth } = await request(session, 'Authentification', { + donnees: { + connexion: 0, + challenge: cipher(session, challenge, { key }), + espace: session.type.id + } + }); + + return auth.cle; +} + +module.exports = { + getId, + getAuthKey +}; diff --git a/school/node_modules/pronote-api/src/fetch/pronote/contents.js b/school/node_modules/pronote-api/src/fetch/pronote/contents.js new file mode 100644 index 0000000..7525e3d --- /dev/null +++ b/school/node_modules/pronote-api/src/fetch/pronote/contents.js @@ -0,0 +1,60 @@ +const parse = require('../../data/types'); +const { fromPronote } = require('../../data/objects'); + +const navigate = require('./navigate'); + +const PAGE_NAME = 'PageCahierDeTexte'; +const TAB_ID = 89; +const ACCOUNTS = ['student', 'parent']; + +async function getContents(session, user, fromWeek = 1, toWeek = null) +{ + if (!toWeek || toWeek < fromWeek) { + toWeek = fromWeek; + } + + const contents = await navigate(session, user, PAGE_NAME, TAB_ID, ACCOUNTS, { + domaine: { + _T: 8, + V: `[${fromWeek}..${toWeek}]` + } + }); + + if (!contents) { + return null; + } + + return { + lessons: parse(contents.ListeCahierDeTextes, ({ + cours, verrouille, listeGroupes, Matiere, CouleurFond, listeProfesseurs, Date, DateFin, + listeContenus, listeElementsProgrammeCDT + }) => ({ + lesson: parse(cours), + locked: verrouille, + groups: parse(listeGroupes), // TODO: Check values + subject: parse(Matiere), + color: CouleurFond, + teachers: parse(listeProfesseurs), + from: parse(Date), + to: parse(DateFin), + content: parse(listeContenus, ({ + descriptif, categorie, parcoursEducatif, ListePieceJointe, training + }) => ({ + description: parse(descriptif), + category: parse(categorie), + path: parcoursEducatif, + files: parse(ListePieceJointe), + training: parse(training).ListeExecutionsQCM.map(o => fromPronote(o)) // TODO: Check values + })), + skills: parse(listeElementsProgrammeCDT) + })), + resources: (({ listeRessources, listeMatieres }) => ({ + resources: parse(listeRessources), // TODO: Check values + subjects: parse(listeMatieres) // TODO: Check values + }))(parse(contents.ListeRessourcesPedagogiques)), + // TODO: Check values + numericalResources: parse(parse(contents.ListeRessourcesNumeriques).listeRessources) + }; +} + +module.exports = getContents; diff --git a/school/node_modules/pronote-api/src/fetch/pronote/evaluations.js b/school/node_modules/pronote-api/src/fetch/pronote/evaluations.js new file mode 100644 index 0000000..c9065fd --- /dev/null +++ b/school/node_modules/pronote-api/src/fetch/pronote/evaluations.js @@ -0,0 +1,49 @@ +const parse = require('../../data/types'); +const { toPronote } = require('../../data/objects'); + +const navigate = require('./navigate'); + +const PAGE_NAME = 'DernieresEvaluations'; +const TAB_ID = 201; +const ACCOUNTS = ['student', 'parent']; + +async function getEvaluations(session, user, period) +{ + const evaluations = await navigate(session, user, PAGE_NAME, TAB_ID, ACCOUNTS, { + periode: period.name ? toPronote(period) : period + }); + + if (!evaluations) { + return null; + } + + return parse(evaluations.listeEvaluations, ({ + listeNiveauxDAcquisitions, listePaliers, matiere, individu, coefficient, descriptif, date, periode + }) => ({ + title: descriptif, + acquisitionLevels: parse(listeNiveauxDAcquisitions, ({ + abbreviation, ordre, pilier, coefficient, domaine, item + }) => ({ + position: ordre, + value: abbreviation, + pillar: parse(pilier, ({ strPrefixes }) => ({ + prefixes: strPrefixes.split(', ') + })), + coefficient, + domain: parse(domaine), + item: item && parse(item) || null + })), + levels: parse(listePaliers), + subject: parse(matiere, ({ couleur, ordre, serviceConcerne }) => ({ + position: ordre, + service: parse(serviceConcerne), + color: couleur + })), + teacher: parse(individu), + coefficient, + date: parse(date), + period: parse(periode) + })); +} + +module.exports = getEvaluations; diff --git a/school/node_modules/pronote-api/src/fetch/pronote/files.js b/school/node_modules/pronote-api/src/fetch/pronote/files.js new file mode 100644 index 0000000..2871fbe --- /dev/null +++ b/school/node_modules/pronote-api/src/fetch/pronote/files.js @@ -0,0 +1,16 @@ +const navigate = require('./navigate'); + +const PAGE_NAME = 'RessourcePedagogique'; +const TAB_ID = 99; +const ACCOUNTS = ['student']; + +async function getFiles(session, user) +{ + return await navigate(session, user, PAGE_NAME, TAB_ID, ACCOUNTS, { + avecRessourcesPronote: true, + avecRessourcesEditeur: false + }); +} + + +module.exports = getFiles; diff --git a/school/node_modules/pronote-api/src/fetch/pronote/homeworks.js b/school/node_modules/pronote-api/src/fetch/pronote/homeworks.js new file mode 100644 index 0000000..7d13c48 --- /dev/null +++ b/school/node_modules/pronote-api/src/fetch/pronote/homeworks.js @@ -0,0 +1,43 @@ +const parse = require('../../data/types'); + +const navigate = require('./navigate'); + +const PAGE_NAME = 'PageCahierDeTexte'; +const TAB_ID = 88; +const ACCOUNTS = ['student', 'parent']; + +async function getHomeworks(session, user, fromWeek = 1, toWeek = null) +{ + if (!toWeek || toWeek < fromWeek) { + toWeek = fromWeek; + } + + const homeworks = await navigate(session, user, PAGE_NAME, TAB_ID, ACCOUNTS, { + domaine: { + _T: 8, + V: `[${fromWeek}..${toWeek}]` + } + }); + + if (!homeworks) { + return null; + } + + return parse(homeworks.ListeTravauxAFaire, ({ + descriptif, PourLe, TAFFait, niveauDifficulte, duree, cours, DonneLe, + Matiere, CouleurFond, ListePieceJointe + }) => ({ + description: parse(descriptif), + lesson: parse(cours), + subject: parse(Matiere), + givenAt: parse(DonneLe), + for: parse(PourLe), + done: TAFFait, + difficultyLevel: niveauDifficulte, + duration: duree, + color: CouleurFond, + files: parse(ListePieceJointe) + })); +} + +module.exports = getHomeworks; diff --git a/school/node_modules/pronote-api/src/fetch/pronote/infos.js b/school/node_modules/pronote-api/src/fetch/pronote/infos.js new file mode 100644 index 0000000..6e05ce1 --- /dev/null +++ b/school/node_modules/pronote-api/src/fetch/pronote/infos.js @@ -0,0 +1,33 @@ +const parse = require('../../data/types'); +const navigate = require('./navigate'); + +const PAGE_NAME = 'PageActualites'; +const TAB_ID = 8; +const ACCOUNTS = ['student', 'parent']; + +async function getInfos(session, user) +{ + const infos = await navigate(session, user, PAGE_NAME, TAB_ID, ACCOUNTS, { + estAuteur: false + }); + + if (!infos) { + return null; + } + + return { + categories: parse(infos.listeCategories, ({ estDefaut }) => ({ + isDefault: estDefaut + })), + infos: parse(infos.listeActualites, ({ dateDebut, elmauteur, listeQuestions }) => ({ + date: parse(dateDebut), + author: parse(elmauteur), + content: parse(listeQuestions, ({ texte, listePiecesJointes }) => ({ + text: parse(texte), + files: parse(listePiecesJointes) + })) + })) + }; +} + +module.exports = getInfos; diff --git a/school/node_modules/pronote-api/src/fetch/pronote/keepAlive.js b/school/node_modules/pronote-api/src/fetch/pronote/keepAlive.js new file mode 100644 index 0000000..89705ec --- /dev/null +++ b/school/node_modules/pronote-api/src/fetch/pronote/keepAlive.js @@ -0,0 +1,8 @@ +const request = require('../../request'); + +async function keepAlive(session) +{ + await request(session, 'Presence'); +} + +module.exports = keepAlive; diff --git a/school/node_modules/pronote-api/src/fetch/pronote/logout.js b/school/node_modules/pronote-api/src/fetch/pronote/logout.js new file mode 100644 index 0000000..ede23e7 --- /dev/null +++ b/school/node_modules/pronote-api/src/fetch/pronote/logout.js @@ -0,0 +1,8 @@ +const request = require('../../request'); + +async function logout(session) +{ + await request(session, 'SaisieDeconnexion'); +} + +module.exports = logout; diff --git a/school/node_modules/pronote-api/src/fetch/pronote/marks.js b/school/node_modules/pronote-api/src/fetch/pronote/marks.js new file mode 100644 index 0000000..dcb7644 --- /dev/null +++ b/school/node_modules/pronote-api/src/fetch/pronote/marks.js @@ -0,0 +1,71 @@ +const parse = require('../../data/types'); +const { toPronote } = require('../../data/objects'); + +const navigate = require('./navigate'); + +const PAGE_NAME = 'DernieresNotes'; +const TAB_ID = 198; +const ACCOUNTS = ['student', 'parent']; + +async function getMarks(session, user, period) +{ + const marks = await navigate(session, user, PAGE_NAME, TAB_ID, ACCOUNTS, { + Periode: period.name ? toPronote(period) : period + }); + + if (!marks) { + return null; + } + + const result = {}; + + if (marks.moyGenerale) { + result.studentAverage = parse(marks.moyGenerale); + result.studentAverageScale = parse(marks.baremeMoyGenerale); + result.defaultStudentAverageScale = parse(marks.baremeMoyGeneraleParDefaut); + } + + if (marks.moyGeneraleClasse) { + result.studentClassAverage = parse(marks.moyGeneraleClasse); + } + + return { + ...result, + subjects: marks.avecDetailService && parse(marks.listeServices, ({ + ordre, estServiceEnGroupe, + moyEleve, baremeMoyEleve, baremeMoyEleveParDefaut, moyClasse, moyMax, moyMin, + couleur + }) => ({ + position: ordre, + isGroupSubject: estServiceEnGroupe, + studentAverage: parse(moyEleve), + studentAverageScale: parse(baremeMoyEleve), + defaultStudentAverageScale: parse(baremeMoyEleveParDefaut), + studentClassAverage: parse(moyClasse), + maxAverage: parse(moyMax), + minAverage: parse(moyMin), + color: couleur + })) || [], + marks: marks.avecDetailDevoir && parse(marks.listeDevoirs, ({ + note, bareme, baremeParDefaut, date, service, periode, moyenne, estEnGroupe, noteMax, noteMin, + commentaire, coefficient + }) => ({ + subject: parse(service, ({ couleur }) => ({ + color: couleur + })), + title: commentaire, + value: parse(note), + scale: parse(bareme), + average: parse(moyenne), + defaultScale: parse(baremeParDefaut), + coefficient, + min: parse(noteMin) || -1, + max: parse(noteMax) || -1, + date: parse(date), + period: parse(periode), + isGroupMark: estEnGroupe + })) || [] + }; +} + +module.exports = getMarks; diff --git a/school/node_modules/pronote-api/src/fetch/pronote/menu.js b/school/node_modules/pronote-api/src/fetch/pronote/menu.js new file mode 100644 index 0000000..988c168 --- /dev/null +++ b/school/node_modules/pronote-api/src/fetch/pronote/menu.js @@ -0,0 +1,42 @@ +const { toPronoteDate } = require('../../data/dates'); +const parse = require('../../data/types'); + +const navigate = require('./navigate'); + +const PAGE_NAME = 'PageMenus'; +const TAB_ID = 10; +const ACCOUNTS = ['student', 'parent']; + +async function getMenu(session, user, day = new Date()) +{ + const menu = await navigate(session, user, PAGE_NAME, TAB_ID, ACCOUNTS, { + date: { + _T: 7, + V: toPronoteDate(day) + } + }); + + if (!menu) { + return null; + } + + return { + hasLunch: menu.AvecRepasMidi, + hasDiner: menu.AvecRepasSoir, + filledWeeks: parse(menu.DomaineDePresence), + menus: parse(menu.ListeJours, false).map(({ Date, ListeRepas }) => ({ + date: parse(Date), + meals: parse(ListeRepas, ({ ListePlats }) => ({ + content: parse(ListePlats, ({ ListeAliments }) => ({ + lines: parse(ListeAliments, ({ listeLabelsAlimentaires }) => ({ + labels: parse(listeLabelsAlimentaires, ({ couleur }) => ({ + color: couleur + })) + })) + })) + })) + })) + }; +} + +module.exports = getMenu; diff --git a/school/node_modules/pronote-api/src/fetch/pronote/navigate.js b/school/node_modules/pronote-api/src/fetch/pronote/navigate.js new file mode 100644 index 0000000..edaa3d4 --- /dev/null +++ b/school/node_modules/pronote-api/src/fetch/pronote/navigate.js @@ -0,0 +1,23 @@ +const { toPronote } = require('../../data/objects'); +const request = require('../../request'); + +async function navigate(session, user, page, tab, accounts, data) +{ + if (session.user.hiddenTabs.includes(tab) || !accounts.includes(session.type.name)) { + return null; + } + + const content = { + _Signature_: { + membre: toPronote(user), + onglet: tab + } + }; + if (data) { + content.donnees = data; + } + + return (await request(session, page, content)).donnees; +} + +module.exports = navigate; diff --git a/school/node_modules/pronote-api/src/fetch/pronote/params.js b/school/node_modules/pronote-api/src/fetch/pronote/params.js new file mode 100644 index 0000000..12fc2e9 --- /dev/null +++ b/school/node_modules/pronote-api/src/fetch/pronote/params.js @@ -0,0 +1,141 @@ +const parse = require('../../data/types'); +const { fromPronote } = require('../../data/objects'); + +const request = require('../../request'); + +const { getUUID } = require('../../cipher'); + +async function getParams(session) +{ + const { donnees: params } = await request(session, 'FonctionParametres', { + donnees: { Uuid: getUUID(session, session.aesIV) } + }); + + const general = params.General; + if (!general) { + return; + } + return { + navigatorId: params.identifiantNav, + fonts: parse(params.listePolices, false).map(o => o.L), + withMember: params.avecMembre, + forNewCaledonia: params.pourNouvelleCaledonie, + loginImageId: params.genreImageConnexion, + loginImageUrl: params.urlImageConnexion, + cssLogo: params.logoProduitCss, + theme: params.Theme, + serverTime: parse(params.DateServeurHttp), + mobileURL: params.URLMobile, + mobileSupport: params.AvecEspaceMobile, + title: params.Nom, + indexEducationWebsite: parse(general.urlSiteIndexEducation), + version: general.versionPN, + versionFull: general.version, + year: ~~general.millesime, + language: { id: general.langID, name: general.langue }, + supportedLanguages: parse(general.listeLangues, false).map(({ langID, description }) => ({ + id: langID, + name: description + })), + infoPage: general.lienMentions, + hasForum: general.avecForum, + helpURL: parse(general.UrlAide), + videosURL: parse(general.urlAccesVideos), + twitterURL: parse(general.urlAccesTwitter), + withLoginOptions: general.AvecChoixConnexion, + establishment: general.NomEtablissement, + displayWeeks: general.afficherSemainesCalendaires, + schoolYear: general.AnneeScolaire, + firstCycle: parse(general.dateDebutPremierCycle), + firstDay: parse(general.PremiereDate), + firstMonday: parse(general.PremierLundi), + lastDay: parse(general.DerniereDate), + ticksPerDay: general.PlacesParJour, + ticksPerHour: general.PlacesParHeure, + sequenceDuration: general.DureeSequence, + ticksForHalfDayAbsence: general.PlaceDemiJourneeAbsence, + hasLunch: general.activationDemiPension, + lunchStart: general.debutDemiPension, + lunchEnd: general.finDemiPension, + withPlainAfternoonHours: general.AvecHeuresPleinesApresMidi, + firstOrLastWorkingDay: parse(general.JourOuvre), + workingDays: parse(general.JoursOuvres), + lunchDays: parse(general.JoursDemiPension), + parentsChat: general.ActivationMessagerieEntreParents, + workingDaysPerCycle: general.joursOuvresParCycle, + firstDayOfWeek: general.premierJourSemaine, + timetableGridsInCycle: general.grillesEDTEnCycle, + workingDaysCycle: parse(general.setOfJoursCycleOuvre), + halfWorkingDays: general.DemiJourneesOuvrees.map(parse), + frequenciesRanges: general.DomainesFrequences.map(parse), + frequenciesLabels: general.LibellesFrequences, + defaultMarkMax: parse(general.BaremeNotation), + allowedAnnotations: parse(general.listeAnnotationsAutorisees), + acquisitionLevels: parse(general.ListeNiveauxDAcquisitions, ({ + listePositionnements, positionJauge, actifPour, abbreviation, raccourci, + couleur, ponderation, nombrePointsBrevet, estAcqui, estNotantPourTxReussite + }) => ({ + positions: parse(listePositionnements, ({ abbreviation, abbreviationAvecPrefixe }) => ({ + shortName: abbreviation, + shortNameWithPrefix: abbreviationAvecPrefixe + }), 'count'), + triggerPosition: positionJauge, + activeFor: parse(actifPour), + shortName: abbreviation, + shortPath: raccourci, + color: couleur, + weighting: parse(ponderation), + brevetPoints: parse(nombrePointsBrevet), + acquired: estAcqui, + countsForSuccess: estNotantPourTxReussite + }), 'count'), + displayAcquisitionShortLabel: general.AfficherAbbreviationNiveauDAcquisition, + withEvaluationHistory: general.AvecEvaluationHistorique, + withoutIntermediaryLevelAutoValidation: general.SansValidationNivIntermediairesDsValidAuto, + onlySchoolYearEvaluationsInAutoValidation: general.NeComptabiliserQueEvalsAnneeScoDsValidAuto, + CECRLLevelsSupport: general.AvecGestionNiveauxCECRL, + langActivityColor: general.couleurActiviteLangagiere, + minMarkMCQ: general.minBaremeQuestionQCM, + maxMarkMCQ: general.maxBaremeQuestionQCM, + maxPointsMCQ: general.maxNbPointQCM, + skillsGridLabelSize: general.tailleLibelleElementGrilleCompetence, + homeworkCommentSize: general.tailleCommentaireDevoir, + officeEnabled: general.O365_Actif, + officeFederatedMode: general.O365_ModeFederated, + officeTutorial: parse(general.O365_UrlTuto_Office), + oneDriveTutorial: parse(general.O365_UrlTuto_OneDrive), + connexionInfoRetrieval: general.AvecRecuperationInfosConnexion, + font: general.Police, + fontSize: general.TaillePolice, + attachedStudents: general.AvecElevesRattaches, + phoneMask: general.maskTelephone, + maxECTS: general.maxECTS, + maxAppreciationSizes: general.TailleMaxAppreciation, + publicHolidays: parse(general.listeJoursFeries, ({ dateDebut, dateFin }) => ({ + from: parse(dateDebut), + to: parse(dateFin) + })), + displaySequences: general.afficherSequences, + firstHour: parse(general.PremiereHeure), + hours: parse(general.ListeHeures, ({ A }) => ({ + round: A === undefined + }), 'count'), + endHours: parse(general.ListeHeuresFin, ({ A }) => ({ + round: A === undefined + }), 'count'), + sequences: general.sequences, + periods: general.ListePeriodes.map(p => fromPronote(p, ({ G, periodeNotation, dateDebut, dateFin }) => ({ + kind: G === 1 ? 'trimester' : (G === 2 ? 'semester' : (G === 3 ? 'year' : 'other')), + notationPeriod: periodeNotation, + from: parse(dateDebut), + to: parse(dateFin) + }), false)), + logo: parse(general.logo), + breaks: parse(general.recreations, ({ place }) => ({ + position: place + })), + appCookieName: general.nomCookieAppli + }; +} + +module.exports = getParams; diff --git a/school/node_modules/pronote-api/src/fetch/pronote/timetable.js b/school/node_modules/pronote-api/src/fetch/pronote/timetable.js new file mode 100644 index 0000000..a98b9ce --- /dev/null +++ b/school/node_modules/pronote-api/src/fetch/pronote/timetable.js @@ -0,0 +1,81 @@ +const parse = require('../../data/types'); +const { toPronote, fromPronote } = require('../../data/objects'); + +const navigate = require('./navigate'); + +const PAGE_NAME = 'PageEmploiDuTemps'; +const TAB_ID = 16; +const ACCOUNTS = ['student', 'parent']; + +async function getTimetable(session, user, week) +{ + const student = toPronote(session.user); + const timetable = await navigate(session, user, PAGE_NAME, TAB_ID, ACCOUNTS, { + avecAbsencesEleve: false, // TODO: Test what those parameters do + avecAbsencesRessource: true, + avecConseilDeClasse: true, + avecDisponibilites: true, + avecInfosPrefsGrille: true, + avecRessourceLibrePiedHoraire: false, + estEDTPermanence: false, + numeroSemaine: week, // *Clown emoji* + NumeroSemaine: week, + ressource: student, + Ressource: student + }); + + if (!timetable || !timetable.ListeCours) { + return null; + } + + let iCalURL = null; + if (timetable.avecExportICal) { + const id = timetable.ParametreExportiCal; + iCalURL = `${session.server}ical/Edt.ics?icalsecurise=${id}&version=${session.params.version}`; + } + + return { + hasCancelledLessons: timetable.avecCoursAnnule, + iCalURL, + lessons: timetable.ListeCours.map(o => fromPronote(o, ({ + place, duree, DateDuCours, CouleurFond, ListeContenus, AvecTafPublie, Statut, estAnnule, estRetenue, + dispenseEleve + }) => ({ + position: place, + duration: duree, + date: parse(DateDuCours), + status: Statut, + color: CouleurFond, + content: parse(ListeContenus), + hasHomework: AvecTafPublie, + isCancelled: !!estAnnule, + isDetention: !!estRetenue, + remoteLesson: !!dispenseEleve && dispenseEleve.V.maison + }))), + // I was unable to witness a filled "absences.joursCycle", so didn't include it + breaks: parse(timetable.recreations, ({ place }) => ({ + position: place + })) + }; +} + +async function getFilledDaysAndWeeks(session, user) +{ + const daysData = await navigate(session, user, PAGE_NAME + '_DomainePresence', TAB_ID, ACCOUNTS, { + Ressource: toPronote(session.user) + }); + + if (!daysData) { + return null; + } + + return { + filledWeeks: parse(daysData.Domaine), + filledDays: parse(daysData.joursPresence) + } +} + +module.exports = { + getTimetable, + getFilledDaysAndWeeks +}; diff --git a/school/node_modules/pronote-api/src/fetch/pronote/user.js b/school/node_modules/pronote-api/src/fetch/pronote/user.js new file mode 100644 index 0000000..54f62be --- /dev/null +++ b/school/node_modules/pronote-api/src/fetch/pronote/user.js @@ -0,0 +1,183 @@ +const request = require('../../request'); + +const parse = require('../../data/types'); +const { getFileURL } = require('../../data/files'); +const { fromPronote } = require('../../data/objects'); + +async function getUser(session) +{ + const { donnees: user } = await request(session, 'ParametresUtilisateur'); + const { data, authorizations } = getSpecificData(session, user); + + const res = user.ressource; + const aut = user.autorisations; + + return { + ...fromPronote(res), + ...data, + establishmentsInfo: parse(user.listeInformationsEtablissements, ({ Logo, Coordonnees }) => ({ + logoID: parse(Logo), + address: [Coordonnees.Adresse1, Coordonnees.Adresse2], + postalCode: Coordonnees.CodePostal, + postalLabel: Coordonnees.LibellePostal, + city: Coordonnees.LibelleVille, + province: Coordonnees.Province, + country: Coordonnees.Pays, + website: Coordonnees.SiteInternet + })), + userSettings: (({ version, EDT, theme, Communication }) => ({ + version, + timetable: { + displayCanceledLessons: EDT.afficherCoursAnnules, + invertAxis: EDT.axeInverseEDT, + invertWeeklyPlanAxis: EDT.axeInversePlanningHebdo, + invertDayPlanAxis: EDT.axeInversePlanningJour, + invertDay2PlanAxis: EDT.axeInversePlanningJour2, + dayCount: EDT.nbJours, + resourceCount: EDT.nbRessources, + daysInTimetable: EDT.nbJoursEDT, + sequenceCount: EDT.nbSequences + }, + theme: theme.theme, + unreadDiscussions: Communication.DiscussionNonLues + }))(user.parametresUtilisateur), + sessionAuthorizations: { + twitterManagement: user.autorisationsSession.fonctionnalites.gestionTwitter, + expandedAttestation: user.autorisationsSession.fonctionnalites.attestationEtendue + }, + authorizations: { + discussions: aut.AvecDiscussion, + teachersDiscussions: aut.AvecDiscussionProfesseurs, + timetableVisibleWeeks: parse(aut.cours.domaineConsultationEDT), + canEditLessons: parse(aut.cours.domaineModificationCours), + hideClassParts: aut.cours.masquerPartiesDeClasse, + maxEstablishmentFileSize: aut.tailleMaxDocJointEtablissement, + editPassword: aut.compte.avecSaisieMotDePasse, + editPersonalInfo: aut.compte.avecInformationsPersonnelles, + canPrint: aut.autoriserImpression, + ...authorizations + }, + minPasswordSize: user.reglesSaisieMDP.min, + maxPasswordSize: user.reglesSaisieMDP.max, + passwordRules: parse(user.reglesSaisieMDP.regles), + kioskAccess: user.autorisationKiosque, + tabs: user.listeOnglets.map(parseTab), + hiddenTabs: user.listeOngletsInvisibles, + notifiedTabs: user.listeOngletsNotification + }; +} + +function parseTab({ G: id, Onglet: subs }) +{ + return { id, subs: (subs || []).map(parseTab) }; +} + +function getSpecificData(session, data) +{ + switch (session.type.name) + { + case 'student': + return getStudentData(session, data); + case 'parent': + return getParentData(session, data); + case 'teacher': + + break; + case 'administration': + + break; + default: + return {}; + } +} + +function getStudentData(session, data) +{ + return { + data: getStudent(session, data.ressource), + authorizations: { + maxUserWorkFileSize: data.autorisations.tailleMaxRenduTafEleve + } + }; +} + +function getStudent(session, res) +{ + const avatar = {}; + if (res.avecPhoto) { + avatar.avatar = getFileURL(session, { + id: res.N, + name: 'photo.jpg' + }); + } + + return { + ...fromPronote(res), + establishment: parse(res.Etablissement), + ...avatar, + studentClass: fromPronote(res.classeDEleve), + classHistory: parse(res.listeClassesHistoriques, ({ AvecNote, AvecFiliere }) => ({ + hadMarks: AvecNote, + hadOptions: AvecFiliere + })), + groups: parse(res.listeGroupes), + tabsPillars: parse(res.listeOngletsPourPiliers, ({ listePaliers }) => ({ + levels: parse(listePaliers, ({ listePiliers }) => ({ + pillars: parse(listePiliers, ({ estPilierLVE, estSocleCommun, Service }) => ({ + isForeignLanguage: estPilierLVE, + isCoreSkill: estSocleCommun, + subject: Service && parse(Service) + })) + })) + }), 'tab'), + tabsPeriods: parse(res.listeOngletsPourPeriodes, ({ listePeriodes, periodeParDefaut }) => ({ + periods: parse(listePeriodes, ({ GenreNotation }) => ({ + isCorePeriod: GenreNotation === 1 + })), + defaultPeriod: parse(periodeParDefaut) + }), 'tab') + }; +} + +function getParentData(session, data) +{ + const res = data.ressource; + const aut = data.autorisations; + + return { + data: { + isDelegate: res.estDelegue, + isBDMember: res.estMembreCA, + canDiscussWithManagers: res.avecDiscussionResponsables, + absencesReasons: parse(data.listeMotifsAbsences), + delaysReasons: parse(data.listeMotifsRetards), + classDelegates: parse(res.listeClassesDelegue), + students: res.listeRessources.map(r => fromPronote(r, ({ listeSessions }) => ({ + ...getStudent(session, r), + sessions: parse(listeSessions, ({ date, strHeureDebut, strHeureFin }) => ({ + from: getDateWithHours(parse(date), strHeureDebut), + to: getDateWithHours(parse(date), strHeureFin) + })) + }))) + }, + authorizations: { + staffDiscussion: aut.AvecDiscussionPersonnels, + parentsDiscussion: aut.AvecDiscussionParents, + editStudentPassword: aut.compte.avecSaisieMotDePasseEleve, + editCoordinates: aut.compte.avecSaisieInfosPersoCoordonnees, + editAuthorizations: aut.compte.avecSaisieInfosPersoAutorisations + } + }; +} + +function getDateWithHours(date, hours) +{ + const h = hours.indexOf('h'); + + date.setHours(date.getHours() + ~~hours.substring(0, h)); + date.setMinutes(date.getMinutes() + ~~hours.substring(h)); + + return date; +} + +module.exports = getUser; |