diff --git a/parcoursup/api.js b/parcoursup/api.js index 8766324..d7a6f82 100644 --- a/parcoursup/api.js +++ b/parcoursup/api.js @@ -1,3 +1,8 @@ +// Échapper les apostrophes dans les valeurs injectées dans la clause where +function echapperValeur(valeur) { + return String(valeur).replace(/'/g, "\\'") +} + // Construire l'URL de requête vers l'API Parcoursup export function construireURL(requete, limite = 20, decalage = 0, filtres = {}) { @@ -9,19 +14,19 @@ export function construireURL(requete, limite = 20, decalage = 0, filtres = {}) var conditions = [] if (requete && requete.trim() !== "") { - conditions.push("search(lib_for_voe_ins, '" + requete + "')") + conditions.push("search(lib_for_voe_ins, '" + echapperValeur(requete.trim()) + "')") } if (filtres.filiere && filtres.filiere !== "") { - conditions.push("fili='" + filtres.filiere + "'") + conditions.push("fili='" + echapperValeur(filtres.filiere) + "'") } if (filtres.selectivite && filtres.selectivite !== "") { - conditions.push("select_form='" + filtres.selectivite + "'") + conditions.push("select_form='" + echapperValeur(filtres.selectivite) + "'") } if (filtres.region && filtres.region !== "") { - conditions.push("region_etab_aff='" + filtres.region + "'") + conditions.push("region_etab_aff='" + echapperValeur(filtres.region) + "'") } if (filtres.tauxMin && filtres.tauxMin > 0) { @@ -33,7 +38,7 @@ export function construireURL(requete, limite = 20, decalage = 0, filtres = {}) } if (conditions.length > 0) { - url += "&where=" + conditions.join(" AND ") + url += "&where=" + encodeURIComponent(conditions.join(" AND ")) } return url @@ -46,7 +51,7 @@ export async function chargerFormations(requete, limite = 20, decalage = 0, filt var reponse = await fetch(url) if (!reponse.ok) { - throw new Error("Erreur HTTP") + throw new Error("Erreur HTTP " + reponse.status) } return await reponse.json() @@ -64,9 +69,10 @@ export async function chargerHistoriqueFormation(codUai, nomFormation) { 2025: "fr-esr-parcoursup" } - var historique = [] - var nomCourt = nomFormation.substring(0, 40).replace(/'/g, "\\'") - var annees = [2020, 2021, 2022, 2023, 2024, 2025] + var historique = [] + 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++) { @@ -75,11 +81,14 @@ export async function chargerHistoriqueFormation(codUai, nomFormation) { 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=cod_uai%3D'" + codUai + "' AND search(lib_for_voe_ins, '" + nomCourt + "')" - + "&select=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" + + "&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) @@ -119,4 +128,4 @@ export async function chargerHistoriqueFormation(codUai, nomFormation) { } return historique -} +} \ No newline at end of file diff --git a/parcoursup/api.js~ b/parcoursup/api.js~ deleted file mode 100644 index a6b10da..0000000 --- a/parcoursup/api.js~ +++ /dev/null @@ -1,21 +0,0 @@ -export function buildURL(query) { - let url = - "https://data.enseignementsup-recherche.gouv.fr/api/explore/v2.1/catalog/datasets/fr-esr-parcoursup/records?limit=10" - - if (query && query.trim() !== "") { - url += "&where=search(lib_for_voe_ins, '" + query + "')" - } - - return url - } - - export async function fetchFormations(query) { - const url = buildURL(query) - const response = await fetch(url) - - if (!response.ok) { - throw new Error("Erreur HTTP") - } - - return await response.json() - } \ No newline at end of file diff --git a/parcoursup/formation.js~ b/parcoursup/formation.js~ deleted file mode 100644 index a7931d1..0000000 --- a/parcoursup/formation.js~ +++ /dev/null @@ -1,23 +0,0 @@ -export function createFormation(raw) { - let taux = 0 - - if (raw.voe_tot && raw.voe_tot > 0) { - taux = Math.round((raw.acc_tot / raw.voe_tot) * 100) - } - - return { - id: raw.cod_uai + "-" + raw.lib_for_voe_ins, - nom: raw.lib_for_voe_ins, - etablissement: raw.g_ea_lib_vx, - ville: raw.ville_etab, - departement: raw.dep, - filiere: raw.fili, - selectivite: raw.select_form, - capacite: raw.capa_fin, - candidats: raw.voe_tot, - admis: raw.acc_tot, - tauxAcces: taux, - latitude: raw.g_olocalisation_des_formations ? raw.g_olocalisation_des_formations.lat : null, - longitude: raw.g_olocalisation_des_formations ? raw.g_olocalisation_des_formations.lon : null - } - } \ No newline at end of file diff --git a/parcoursup/index.html~ b/parcoursup/index.html~ deleted file mode 100644 index 321d43e..0000000 --- a/parcoursup/index.html~ +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - Parcoursup - test API - - -

Mini projet Parcoursup

-

Recherche de formations Parcoursup

- - - - -
En attente...
- - - - - \ No newline at end of file diff --git a/parcoursup/main.js~ b/parcoursup/main.js~ deleted file mode 100644 index a8b42ab..0000000 --- a/parcoursup/main.js~ +++ /dev/null @@ -1,81 +0,0 @@ -import { fetchFormations } from "./api.js" -import { createFormation } from "./formation.js" - -let lastFormations = [] - -const button = document.getElementById("btn-test") -const output = document.getElementById("output") -const searchInput = document.getElementById("search") - -function showDetail(index) { - const f = lastFormations[index] - - output.innerHTML = ` -
-

${f.nom}

-

Établissement : ${f.etablissement}

-

Ville : ${f.ville}

-

Département : ${f.departement}

-

Filière : ${f.filiere}

-

Sélectivité : ${f.selectivite}

-

Capacité : ${f.capacite}

-

Candidats : ${f.candidats}

-

Admis : ${f.admis}

-

Taux d'accès : ${f.tauxAcces}%

- -
- ` - - const backBtn = document.getElementById("back-btn") - backBtn.addEventListener("click", testAPI) -} - -window.showDetail = showDetail - -async function testAPI() { - output.textContent = "Chargement..." - - try { - const query = searchInput.value - - const data = await fetchFormations(query) - - if (data.results && data.results.length > 0) { - const formations = [] - - for (let i = 0; i < data.results.length; i++) { - const raw = data.results[i] - const formation = createFormation(raw) - formations.push(formation) - } - - lastFormations = formations - - let html = "" - - for (let i = 0; i < formations.length; i++) { - const f = formations[i] - - html += ` -
-

${f.nom}

-

Établissement : ${f.etablissement}

-

Ville : ${f.ville} (${f.departement})

-

Filière : ${f.filiere}

-

Taux d'accès : ${f.tauxAcces}%

- -
- ` - } - - output.innerHTML = html - } else { - output.textContent = "Aucun résultat trouvé" - } - } catch (error) { - console.error("Erreur :", error) - output.textContent = "Erreur lors de la requête" - } -} - -button.addEventListener("click", testAPI) \ No newline at end of file