oedb-backend/extractors/extract_coordinates_from_ics.py
2025-10-04 19:26:00 +02:00

136 lines
5 KiB
Python

#!/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()