Files
public-html2/parcoursup/api.js
T
2026-04-01 22:17:05 +02:00

178 lines
6.3 KiB
JavaScript

// Échapper les apostrophes dans les valeurs injectées dans la clause where
// ---------------------------------------------------------------
// Cette fonction est utilisée pour prévenir les problèmes de syntaxe
// quand on insère une valeur dans une requête Parcoursup qui nécessite
// des guillemets simples.
function echapperValeur(valeur) {
// force en string (undefined/null -> "undefined"/"null"), puis remplace toutes
// les apostrophes par une version échappée (\').
return String(valeur).replace(/'/g, "\\'");
}
// Construire l'URL de requête vers l'API Parcoursup
// --------------------------------------------------
// - filtre par recherche texte + plusieurs paramètres de filtre
// - limit / offset pour pagination
// - where encodé (via encodeURIComponent)
export function construireURL(requete, limite = 20, decalage = 0, filtres = {}) {
var url = "https://data.enseignementsup-recherche.gouv.fr/api/explore/v2.1/catalog/datasets/fr-esr-parcoursup/records?";
// pagination simple
url += "limit=" + limite;
url += "&offset=" + decalage;
var conditions = [];
// recherche libre
if (requete && requete.trim() !== "") {
conditions.push("search(lib_for_voe_ins, '" + echapperValeur(requete.trim()) + "')");
}
// ===== FILTRE FILIÈRE =====
// Ce bloc filtre les formations par type (BTS, BUT, Licence, CPGE, etc.)
// Il est OPTIONNEL : si l'user ne choisit pas de filière, on le saute.
// CONDITION : "Si l'user a choisi une filière ET qu'elle n'est pas vide"
if (filtres.filiere && filtres.filiere !== "") {
// if (filtres.filiere && ...)
// ↑ vérifie que filtres.filiere EXISTE (n'est pas undefined/null)
//
// if (... && filtres.filiere !== "")
// ↑ ET vérifie que la filière NE S'PAS VIDE (pas "")
//
// RÉSUMÉ : si les 2 conditions sont vraies, on rentre dans le bloc
// ACTION : construire et ajouter le filtre filière
conditions.push("fili='" + echapperValeur(filtres.filiere) + "'");
//
// Exemple si l'user choisit "BTS" :
// - filtres.filiere = "BTS"
// - echapperValeur("BTS") = "BTS" (pas d'apostrophe, inchangé)
// - condition.push ajoute : "fili='BTS'" au tableau conditions
// - Résultat : conditions = [..., "fili='BTS'"]
//
// Cette condition sera fusionnée avec les autres via AND
// Exemple d'URL finale : ...where=search(...) AND fili='BTS' AND region='IDF'
}
if (filtres.selectivite && filtres.selectivite !== "") {
conditions.push("select_form='" + echapperValeur(filtres.selectivite) + "'");
}
if (filtres.region && filtres.region !== "") {
conditions.push("region_etab_aff='" + echapperValeur(filtres.region) + "'");
}
if (filtres.tauxMin && filtres.tauxMin > 0) {
conditions.push("taux_acces_ens>=" + filtres.tauxMin);
}
if (filtres.tauxMax && filtres.tauxMax < 100) {
conditions.push("taux_acces_ens<=" + filtres.tauxMax);
}
// si on a des conditions, on les ajoute dans paramètre where encodé
if (conditions.length > 0) {
url += "&where=" + encodeURIComponent(conditions.join(" AND "));
}
return url;
}
// Charger les formations depuis l'API Parcoursup
// ----------------------------------------------
// Appelle l'URL construite ci-dessus via fetch, parse le JSON.
export async function chargerFormations(requete, limite = 20, decalage = 0, filtres = {}) {
var url = construireURL(requete, limite, decalage, filtres);
var reponse = await fetch(url);
// vérifie le code HTTP; si erreur, lève une exception pour le remonté à l'appelant
if (!reponse.ok) {
throw new Error("Erreur HTTP " + reponse.status);
}
return await reponse.json();
}
// Charger l'historique d'une formation sur plusieurs années
// ---------------------------------------------------------
// - appelle plusieurs versions du dataset (2020..2025)
// - récupère le premier résultat valide pour chaque année
// - calcule un taux d'accès (acc_tot / voe_tot)
export async function chargerHistoriqueFormation(codUai, nomFormation) {
var jeuDeDonnees = {
2020: "fr-esr-parcoursup_2020",
2021: "fr-esr-parcoursup_2021",
2022: "fr-esr-parcoursup_2022",
2023: "fr-esr-parcoursup_2023",
2024: "fr-esr-parcoursup_2024",
2025: "fr-esr-parcoursup"
};
var historique = [];
// on échappe aussi cod_uai et nom pour la requête (sécurité sintaxe)
var nomCourt = echapperValeur((nomFormation || "").substring(0, 40));
var codeUai = echapperValeur(codUai);
var annees = [2020, 2021, 2022, 2023, 2024, 2025];
for (var i = 0; i < annees.length; i++) {
var annee = annees[i];
var dataset = jeuDeDonnees[annee];
try {
var where =
"cod_uai='" + codeUai + "' AND search(lib_for_voe_ins, '" + nomCourt + "')";
var url = "https://data.enseignementsup-recherche.gouv.fr/api/explore/v2.1/catalog/datasets/"
+ dataset + "/records?"
+ "limit=5"
+ "&where=" + encodeURIComponent(where)
+ "&select=" + encodeURIComponent("cod_uai,lib_for_voe_ins,voe_tot,acc_tot,pct_sansmention,pct_ab,pct_b,pct_tb,pct_tbf,pct_bg,pct_bt,pct_bp");
var reponse = await fetch(url);
if (reponse.ok) {
var donnees = await reponse.json();
if (donnees.results && donnees.results.length > 0) {
var ligne = donnees.results[0];
var taux = 0;
if (ligne.voe_tot && ligne.voe_tot > 0) {
taux = Math.round((ligne.acc_tot / ligne.voe_tot) * 100);
}
// ajoute un objet historique pour cette année
historique.push({
annee: annee,
tauxAcces: taux,
candidats: ligne.voe_tot || 0,
admis: ligne.acc_tot || 0,
pctSansMention: ligne.pct_sansmention || 0,
pctAB: ligne.pct_ab || 0,
pctB: ligne.pct_b || 0,
pctTB: ligne.pct_tb || 0,
pctTBF: ligne.pct_tbf || 0,
pctGeneral: ligne.pct_bg || 0,
pctTechno: ligne.pct_bt || 0,
pctPro: ligne.pct_bp || 0
});
}
}
} catch (e) {
// si un appel échoue, on affiche l'erreur et on continue la boucle
console.warn("Erreur pour l'année " + annee + " :", e);
}
}
return historique;
}