def on_creneau(self, creneau: Union[Creneau, PasDeCreneau]): lieu = creneau.lieu centre = None is_blocked_center = lambda center: (is_reserved_center(center) or is_in_blocklist(center, blocklist)) if not any(centre_opendata["url"] == lieu.url for centre_opendata in self.opendata): self.opendata.append({ "departement": lieu.departement, "plateforme": lieu.plateforme.value, "nom": lieu.nom, "url": lieu.url }) if not is_blocked_center(self.centre(lieu)): if isinstance(creneau, PasDeCreneau): self.centres_indisponibles[ creneau.lieu.internal_id] = self.centre(lieu).default() return if lieu.internal_id not in self.centres_disponibles: self.centres_disponibles[lieu.internal_id] = self.centre( lieu).default() centre = self.centres_disponibles[lieu.internal_id] else: self.centres_bloques_mais_disponibles[ lieu.internal_id] = self.centre(lieu).default() if centre is not None: centre["appointment_count"] += 1 if not centre["prochain_rdv"] or centre[ "prochain_rdv"] > creneau.horaire: centre["prochain_rdv"] = creneau.horaire if not creneau.type_vaccin: return if not isinstance(creneau.type_vaccin, list): creneau.type_vaccin = [creneau.type_vaccin] for vaccine in creneau.type_vaccin: if vaccine is not None: if isinstance(vaccine, Vaccine): vaccine = vaccine.value if not any([ vaccine in one_vaccine for one_vaccine in centre["vaccine_type"] ]): centre["vaccine_type"].append(vaccine)
def export_data(centres_cherchés, outpath_format='data/output/{}.json'): compte_centres = 0 compte_centres_avec_dispo = 0 bloqués_doctolib = 0 centres_open_data = [] par_departement = { code: { 'version': 1, 'last_updated': dt.datetime.now(tz=pytz.timezone('Europe/Paris')).isoformat(), 'centres_disponibles': [], 'centres_indisponibles': [] } for code in departementUtils.import_departements() } # This should be duplicate free, they are already checked in for centre in centres_cherchés: centre.nom = centre.nom.strip() if is_reserved_center(centre): continue compte_centres += 1 code_departement = centre.departement if code_departement not in par_departement: logger.warning( f"le centre {centre.nom} ({code_departement}) n'a pas pu être rattaché à un département connu" ) continue erreur = centre.erreur centres_open_data.append( copy_omit_keys(centre.default(), [ 'prochain_rdv', 'internal_id', 'metadata', 'location', 'appointment_count', 'erreur', 'ville', 'type', 'vaccine_type' ])) if centre.prochain_rdv is None or centre.appointment_count == 0: par_departement[code_departement]['centres_indisponibles'].append( centre.default()) if isinstance(erreur, BlockedByDoctolibError): par_departement[code_departement]['doctolib_bloqué'] = True bloqués_doctolib += 1 else: compte_centres_avec_dispo += 1 par_departement[code_departement]['centres_disponibles'].append( centre.default()) outpath = outpath_format.format("info_centres") with open(outpath, "w") as info_centres: json.dump(par_departement, info_centres, indent=2) outpath = outpath_format.format("centres_open_data") with open(outpath, 'w') as centres_file: json.dump(centres_open_data, centres_file, indent=2) for code_departement, disponibilités in par_departement.items(): disponibilités['last_updated'] = dt.datetime.now( tz=pytz.timezone('Europe/Paris')).isoformat() if 'centres_disponibles' in disponibilités: disponibilités['centres_disponibles'] = sorted(deduplicates_names( disponibilités['centres_disponibles']), key=sort_center) disponibilités["centres_indisponibles"] = deduplicates_names( disponibilités['centres_indisponibles']) outpath = outpath_format.format(code_departement) logger.debug(f'writing result to {outpath} file') with open(outpath, "w") as outfile: outfile.write(json.dumps(disponibilités, indent=2)) return compte_centres, compte_centres_avec_dispo, bloqués_doctolib
def export_data(centres_cherchés: Iterator[CenterInfo], last_scrap, outpath_format="data/output/{}.json"): compte_centres = 0 compte_centres_avec_dispo = 0 bloqués_doctolib = 0 centres_open_data = [] internal_ids = [] par_departement = { code: { "version": 1, "last_updated": dt.datetime.now(tz=pytz.timezone("Europe/Paris")).isoformat(), "last_scrap": last_scrap, "centres_disponibles": [], "centres_indisponibles": [], } for code in departementUtils.import_departements() } blocklist = get_blocklist_urls() # This should be duplicate free, they are already checked in is_blocked_center = lambda center: (is_reserved_center(center) or is_in_blocklist(center, blocklist)) for centre in centres_cherchés: if is_blocked_center(centre): if centre.has_available_appointments(): logger.warn( f"{centre.nom} {centre.internal_id} has available appointments but is blocked" ) continue compte_centres += 1 centre.nom = centre.nom.strip() if centre.departement not in par_departement: logger.warning( f"Center {centre.nom} ({centre.departement}) could not be attached to a valid department" ) continue erreur = centre.erreur if centre.internal_id and centre.internal_id in internal_ids: # pragma: no cover logger.warning( f"Found a duplicated internal_id: {centre.nom} ({centre.departement}) -> {centre.internal_id}" ) continue internal_ids.append(centre.internal_id) skipped_keys = [ "prochain_rdv", "internal_id", "metadata", "location", "appointment_count", "appointment_schedules", "erreur", "ville", "type", "vaccine_type", "appointment_by_phone_only", "last_scan_with_availabilities", ] centres_open_data.append(copy_omit_keys(centre.default(), skipped_keys)) if centre.has_available_appointments(): compte_centres_avec_dispo += 1 par_departement[centre.departement]["centres_disponibles"].append( centre.default()) else: par_departement[ centre.departement]["centres_indisponibles"].append( centre.default()) if isinstance(erreur, BlockedByDoctolibError): par_departement[centre.departement]["doctolib_bloqué"] = True bloqués_doctolib += 1 outpath = outpath_format.format("info_centres") with open(outpath, "w") as info_centres: json.dump(par_departement, info_centres, indent=2) outpath = outpath_format.format("centres_open_data") with open(outpath, "w") as centres_file: json.dump(centres_open_data, centres_file, indent=2) for departement, disponibilités in par_departement.items(): disponibilités["last_updated"] = dt.datetime.now( tz=pytz.timezone("Europe/Paris")).isoformat() if "centres_disponibles" in disponibilités: disponibilités["centres_disponibles"] = sorted(deduplicates_names( disponibilités["centres_disponibles"]), key=sort_center) disponibilités["centres_indisponibles"] = deduplicates_names( disponibilités["centres_indisponibles"]) outpath = outpath_format.format(departement) logger.debug(f"writing result to {outpath} file") with open(outpath, "w") as outfile: outfile.write(json.dumps(disponibilités, indent=2)) return compte_centres, compte_centres_avec_dispo, bloqués_doctolib
def export_pool(centres_cherchés: Iterator[CenterInfo], platform: str, outpath_format="data/output/pool/{}.json"): compte_centres = 0 compte_centres_avec_dispo = 0 bloqués_doctolib = 0 centres_open_data = [] internal_ids = [] global_data = { "version": 1, "pool": platform, "last_updated": dt.datetime.now(tz=pytz.timezone("Europe/Paris")).isoformat(), "centres_disponibles": [], "centres_indisponibles": [], } blocklist = get_blocklist_urls() # This should be duplicate free, they are already checked in is_blocked_center = lambda center: (is_reserved_center(center) or is_in_blocklist(center, blocklist)) blocked_centers = [ center for center in centres_cherchés if is_blocked_center(center) ] exported_centers = [ center for center in centres_cherchés if not is_blocked_center(center) ] for centre in blocked_centers: if centre.has_available_appointments(): # pragma: no cover logger.warn( f"{centre.nom} {centre.internal_id} has available appointments but is blocked" ) for centre in exported_centers: compte_centres += 1 centre.nom = centre.nom.strip() erreur = centre.erreur if not centre.plateforme: continue if centre.plateforme.lower() != platform: continue if centre.internal_id and centre.internal_id in internal_ids: # pragma: no cover logger.warning( f"Found a duplicated internal_id: {centre.nom} ({centre.departement}) -> {centre.internal_id}" ) continue internal_ids.append(centre.internal_id) skipped_keys = [ "prochain_rdv", "internal_id", "metadata", "location", "appointment_count", "appointment_schedules", "erreur", "ville", "type", "vaccine_type", "appointment_by_phone_only", "last_scan_with_availabilities", ] centres_open_data.append(copy_omit_keys(centre.default(), skipped_keys)) if centre.has_available_appointments(): compte_centres_avec_dispo += 1 global_data["centres_disponibles"].append(centre.default()) else: global_data["centres_indisponibles"].append(centre.default()) if isinstance(erreur, BlockedByDoctolibError): global_data["doctolib_bloqué"] = True bloqués_doctolib += 1 global_data["centres_disponibles"] = sorted(deduplicates_names( global_data["centres_disponibles"]), key=sort_center) global_data["centres_indisponibles"] = deduplicates_names( global_data["centres_indisponibles"]) outpath = outpath_format.format(platform) with open(outpath, "w") as info_centres: json.dump(global_data, info_centres, indent=2) return compte_centres, compte_centres_avec_dispo, bloqués_doctolib