#!/usr/bin/env python3 """ Script pour extraire les coordonnées géographiques du fichier ICS de l'agenda du libre. Le fichier ICS contient des coordonnées dans les propriétés X-ALT-DESC;FMTTYPE=text/html sous forme d'attributs data-latitude et data-longitude. """ import re import json from typing import List, Dict, Tuple def extract_coordinates_from_ics(ics_file_path: str) -> List[Dict]: """ Extrait les coordonnées géographiques du fichier ICS. Args: ics_file_path: Chemin vers le fichier ICS Returns: Liste de dictionnaires contenant les coordonnées et informations associées """ coordinates = [] with open(ics_file_path, 'r', encoding='utf-8') as file: content = file.read() # Recherche des patterns data-latitude et data-longitude # Pattern pour capturer les coordonnées dans le HTML pattern = r'data-latitude="([^"]+)"[^>]*data-longitude="([^"]+)"' matches = re.findall(pattern, content) for i, (lat, lon) in enumerate(matches): try: lat_float = float(lat) lon_float = float(lon) # Vérifier que les coordonnées sont valides if -90 <= lat_float <= 90 and -180 <= lon_float <= 180: coordinates.append({ 'id': i + 1, 'latitude': lat_float, 'longitude': lon_float, 'source': 'agendadulibre_ics' }) except ValueError: # Ignorer les coordonnées invalides continue return coordinates def find_events_with_coordinates(ics_file_path: str) -> List[Dict]: """ Trouve les événements qui ont des coordonnées dans le fichier ICS. Args: ics_file_path: Chemin vers le fichier ICS Returns: Liste des événements avec leurs coordonnées """ events = [] with open(ics_file_path, 'r', encoding='utf-8') as file: content = file.read() # Diviser le contenu en événements individuels event_blocks = content.split('BEGIN:VEVENT') for i, block in enumerate(event_blocks[1:], 1): # Ignorer le premier bloc (en-tête) # Rechercher les coordonnées dans ce bloc d'événement lat_match = re.search(r'data-latitude="([^"]+)"', block) lon_match = re.search(r'data-longitude="([^"]+)"', block) if lat_match and lon_match: try: lat = float(lat_match.group(1)) lon = float(lon_match.group(1)) # Vérifier que les coordonnées sont valides if -90 <= lat <= 90 and -180 <= lon <= 180: # Extraire d'autres informations de l'événement summary_match = re.search(r'SUMMARY:(.+)', block) location_match = re.search(r'LOCATION:(.+)', block) description_match = re.search(r'DESCRIPTION:(.+)', block) event = { 'event_id': i, 'latitude': lat, 'longitude': lon, 'summary': summary_match.group(1).strip() if summary_match else '', 'location': location_match.group(1).strip() if location_match else '', 'description': description_match.group(1).strip() if description_match else '', 'source': 'agendadulibre_ics' } events.append(event) except ValueError: continue return events def main(): """Fonction principale pour extraire et afficher les coordonnées.""" ics_file = 'agendadulibre_events.ics' print("🔍 Extraction des coordonnées du fichier ICS...") # Extraire toutes les coordonnées all_coordinates = extract_coordinates_from_ics(ics_file) print(f"📍 {len(all_coordinates)} coordonnées trouvées") # Extraire les événements avec coordonnées events_with_coords = find_events_with_coordinates(ics_file) print(f"🎯 {len(events_with_coords)} événements avec coordonnées trouvés") # Afficher quelques exemples print("\n📋 Exemples d'événements avec coordonnées :") for event in events_with_coords[:5]: print(f" • {event['summary']}") print(f" 📍 {event['latitude']}, {event['longitude']}") print(f" 📍 Lieu: {event['location']}") print() # Sauvegarder les résultats with open('extracted_coordinates.json', 'w', encoding='utf-8') as f: json.dump(events_with_coords, f, indent=2, ensure_ascii=False) print(f"💾 Résultats sauvegardés dans 'extracted_coordinates.json'") # Statistiques unique_coords = set((event['latitude'], event['longitude']) for event in events_with_coords) print(f"📊 {len(unique_coords)} coordonnées uniques") if __name__ == "__main__": main()