Corriger l'import des vacances scolaires officielles
Some checks are pending
CI - Tests et Syntax / lint-and-test (push) Waiting to run
Some checks are pending
CI - Tests et Syntax / lint-and-test (push) Waiting to run
This commit is contained in:
parent
dfc182a8a9
commit
82cd35d4ae
1 changed files with 21 additions and 9 deletions
|
|
@ -1,12 +1,13 @@
|
||||||
"""Service d'import des vacances scolaires depuis l'API gouvernementale."""
|
"""Service d'import des vacances scolaires depuis l'API gouvernementale."""
|
||||||
import requests
|
import requests
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
from zoneinfo import ZoneInfo
|
||||||
from app_new.extensions import db
|
from app_new.extensions import db
|
||||||
from app_new.core.models import CollegeClosure
|
from app_new.core.models import CollegeClosure
|
||||||
|
|
||||||
|
|
||||||
# API du gouvernement pour les vacances scolaires
|
# API du gouvernement pour les vacances scolaires
|
||||||
API_URL = "https://data.education.gouv.fr/api/v2/catalog/datasets/fr-en-calendrier-scolaire-scolaires/exports/json"
|
API_URL = "https://data.education.gouv.fr/api/explore/v2.1/catalog/datasets/fr-en-calendrier-scolaire/records"
|
||||||
|
|
||||||
|
|
||||||
def fetch_vacances_scolaires(zone="A", annee=None):
|
def fetch_vacances_scolaires(zone="A", annee=None):
|
||||||
|
|
@ -25,15 +26,15 @@ def fetch_vacances_scolaires(zone="A", annee=None):
|
||||||
|
|
||||||
# L'API du gouvernement filtre par zone et année
|
# L'API du gouvernement filtre par zone et année
|
||||||
params = {
|
params = {
|
||||||
"where": f"zones='{zone}'",
|
"where": f"zones='Zone {zone}' AND annee_scolaire='{annee}-{annee + 1}'",
|
||||||
"order_by": "start_date",
|
"order_by": "start_date",
|
||||||
"limit": 50
|
"limit": 100,
|
||||||
}
|
}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
response = requests.get(API_URL, params=params, timeout=30)
|
response = requests.get(API_URL, params=params, timeout=30)
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
data = response.json()
|
data = response.json().get("results", [])
|
||||||
|
|
||||||
vacances = []
|
vacances = []
|
||||||
for item in data:
|
for item in data:
|
||||||
|
|
@ -43,13 +44,16 @@ def fetch_vacances_scolaires(zone="A", annee=None):
|
||||||
|
|
||||||
if start and end:
|
if start and end:
|
||||||
# Filtrer pour l'année scolaire demandée
|
# Filtrer pour l'année scolaire demandée
|
||||||
start_date = datetime.fromisoformat(start.replace("Z", "+00:00"))
|
start_date = datetime.fromisoformat(start.replace("Z", "+00:00")).astimezone(ZoneInfo("Europe/Paris"))
|
||||||
if start_date.year >= annee - 1:
|
if start_date.year >= annee - 1:
|
||||||
raw_end_date = datetime.fromisoformat(end.replace("Z", "+00:00")).date()
|
raw_end_date = datetime.fromisoformat(end.replace("Z", "+00:00")).astimezone(ZoneInfo("Europe/Paris")).date()
|
||||||
end_date = raw_end_date - timedelta(days=1)
|
# Les fermetures ponctuelles (ex. pont de l'Ascension)
|
||||||
|
# sont représentées par le même début et la même fin.
|
||||||
|
end_date = raw_end_date if raw_end_date == start_date.date() else raw_end_date - timedelta(days=1)
|
||||||
# Pour l'agent, le 31 août reste une journée de vacances
|
# Pour l'agent, le 31 août reste une journée de vacances
|
||||||
# (la rentrée des enseignants ne déclenche pas la reprise).
|
# (la rentrée des enseignants ne déclenche pas la reprise).
|
||||||
if "grandes vacances" in description.lower() and raw_end_date.month == 8:
|
is_summer = "grandes vacances" in description.lower() or "vacances d'été" in description.lower()
|
||||||
|
if is_summer and raw_end_date.month == 8:
|
||||||
end_date = raw_end_date
|
end_date = raw_end_date
|
||||||
vacances.append({
|
vacances.append({
|
||||||
"start_date": start_date.date(),
|
"start_date": start_date.date(),
|
||||||
|
|
@ -63,7 +67,15 @@ def fetch_vacances_scolaires(zone="A", annee=None):
|
||||||
# Lorsque l'API fournit plusieurs calendriers (enseignants, élèves),
|
# Lorsque l'API fournit plusieurs calendriers (enseignants, élèves),
|
||||||
# retenir la rentrée la plus tardive : la permanence reste possible
|
# retenir la rentrée la plus tardive : la permanence reste possible
|
||||||
# jusqu'à la veille de la rentrée des élèves.
|
# jusqu'à la veille de la rentrée des élèves.
|
||||||
grandes = [item for item in vacances if "grandes vacances" in item["description"].lower()]
|
# Une ligne existe par académie et parfois par population. Dédupliquer
|
||||||
|
# en conservant la date de rentrée la plus tardive (élèves).
|
||||||
|
deduped = {}
|
||||||
|
for item in vacances:
|
||||||
|
key = (item["description"], item["start_date"])
|
||||||
|
if key not in deduped or item["end_date"] > deduped[key]["end_date"]:
|
||||||
|
deduped[key] = item
|
||||||
|
vacances = list(deduped.values())
|
||||||
|
grandes = [item for item in vacances if "grandes vacances" in item["description"].lower() or "vacances d'été" in item["description"].lower()]
|
||||||
if grandes:
|
if grandes:
|
||||||
max_end = max(item["end_date"] for item in grandes)
|
max_end = max(item["end_date"] for item in grandes)
|
||||||
for item in grandes:
|
for item in grandes:
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue