#!/usr/bin/env python3 """ Script pour rechercher un athlète dans les résultats FFA Peut utiliser les fichiers CSV ou chercher directement depuis l'URL FFA """ import pandas as pd import os import sys import argparse import logging sys.path.insert(0, os.path.join(os.path.dirname(__file__), '../src')) from ffa_scraper import FFAScraper from ffa_analyzer import FFADataAnalyzer from datetime import datetime logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s' ) def search_athlete_csv(nom, prenom=None, data_dir="data"): """Rechercher un athlète dans les fichiers CSV""" results_path = os.path.join(data_dir, 'resultats', 'results.csv') if not os.path.exists(results_path): logging.error(f"Fichier de résultats introuvable: {results_path}") return [] try: df = pd.read_csv(results_path, encoding='utf-8-sig') # Filtre par nom (obligatoire) mask = df['nom'].str.contains(nom, case=False, na=False) # Filtre par prénom (optionnel) if prenom: mask &= df['prenom'].str.contains(prenom, case=False, na=False) results = df[mask].to_dict('records') logging.info(f"Trouvé {len(results)} résultats pour {nom} {prenom or ''}") return results except Exception as e: logging.error(f"Erreur lors de la recherche dans les CSV: {e}") return [] def search_athlete_live(nom, prenom=None, max_pages=5): """Rechercher un athlète en direct depuis le site FFA""" scraper = FFAScraper() logging.info(f"Recherche en direct pour {nom} {prenom or ''}...") logging.warning("Note: Cela peut prendre du temps car il faut scraper les résultats") # Récupérer les courses et leurs résultats total_pages, total_courses, _ = scraper._detect_pagination_info() if not total_pages: logging.error("Impossible de détecter les données") return [] max_pages = min(max_pages, total_pages) logging.info(f"Analyse de {max_pages} pages...") all_results = [] courses = scraper.get_courses_list(max_pages=max_pages, use_multithreading=True) for course in courses: if course.get('resultats_url'): results = scraper.get_course_results(course['resultats_url']) # Filtrer les résultats pour cet athlète for result in results: match_nom = nom.lower() in result.get('nom', '').lower() match_prenom = not prenom or prenom.lower() in result.get('prenom', '').lower() if match_nom and match_prenom: # Ajouter des infos de la course result['course_nom'] = course.get('nom', '') result['course_date'] = course.get('date', '') result['course_lieu'] = course.get('lieu', '') all_results.append(result) logging.info(f"Trouvé {len(all_results)} résultats en direct") return all_results def display_athlete_results(results, show_details=False, limit=None): """Afficher les résultats d'un athlète""" if not results: print("\n❌ Aucun résultat trouvé pour cet athlète") return # Identifier l'athlète athlete_nom = results[0].get('nom', 'Inconnu') athlete_prenom = results[0].get('prenom', '') print(f"\n{'='*80}") print(f"🏃 RÉSULTATS POUR {athlete_prenom} {athlete_nom}") print(f"{'='*80}\n") if limit: results = results[:limit] # Afficher les informations générales print(f"Club: {results[0].get('club', 'Inconnu')}") print(f"Total des courses: {len(results)}") if show_details: # Calculer des statistiques podiums = 0 victoires = 0 places = [] for result in results: try: place = int(result.get('place', 0)) if place == 1: victoires += 1 podiums += 1 elif place <= 3: podiums += 1 places.append(place) except: pass print(f"Victoires: {victoires}") print(f"Podiums: {podiums}") if places: avg_place = sum(places) / len(places) print(f"Place moyenne: {avg_place:.2f}") print(f"\n{'='*80}\n") # Afficher les résultats individuels print(f"{'📋 LISTE DES COURSES':<}") print(f"{'='*80}\n") for i, result in enumerate(results, 1): print(f"{i}. {result.get('course_nom', result.get('course_url', 'Inconnu'))}") if result.get('course_date'): print(f" 📅 Date: {result['course_date']}") if result.get('course_lieu'): print(f" 📍 Lieu: {result['course_lieu']}") print(f" 🏆 Place: {result.get('place', 'N/A')}") print(f" ⏱️ Temps: {result.get('temps', result.get('resultat', 'N/A'))}") print(f" 🏷️ Catégorie: {result.get('categorie', 'N/A')}") if show_details: if result.get('points'): print(f" 🎯 Points: {result['points']}") if result.get('niveau'): print(f" 📊 Niveau: {result['niveau']}") print() print(f"{'='*80}") def export_results_csv(results, nom, prenom=None, output_dir="data"): """Exporter les résultats d'un athlète en CSV""" os.makedirs(os.path.join(output_dir, 'exports'), exist_ok=True) if prenom: filename = f"athlete_{nom}_{prenom}_results.csv" else: filename = f"athlete_{nom}_results.csv" filepath = os.path.join(output_dir, 'exports', filename.replace(" ", "_")) df = pd.DataFrame(results) df.to_csv(filepath, index=False, encoding='utf-8-sig') logging.info(f"Exporté {len(results)} résultats dans {filepath}") return filepath def main(): parser = argparse.ArgumentParser(description='Rechercher un athlète dans les résultats FFA') parser.add_argument('nom', help='Nom de l\'athlète à rechercher') parser.add_argument('--prenom', help='Prénom de l\'athlète (optionnel)') parser.add_argument('--csv', action='store_true', default=True, help='Utiliser les fichiers CSV existants (défaut)') parser.add_argument('--live', action='store_true', help='Récupérer les données en direct depuis le site FFA') parser.add_argument('--data-dir', default='data', help='Répertoire des données CSV') parser.add_argument('--max-pages', type=int, default=5, help='Nombre maximum de pages à scraper en mode live (défaut: 5)') parser.add_argument('--details', action='store_true', help='Afficher les détails complets') parser.add_argument('--limit', type=int, help='Limiter le nombre de résultats affichés') parser.add_argument('--export', action='store_true', help='Exporter les résultats en CSV') args = parser.parse_args() # Recherche if args.live: print(f"\n🔍 Mode live: recherche en direct sur le site FFA...") results = search_athlete_live(args.nom, args.prenom, args.max_pages) else: print(f"\n📂 Mode CSV: recherche dans {args.data_dir}/") results = search_athlete_csv(args.nom, args.prenom, args.data_dir) # Affichage display_athlete_results(results, show_details=args.details, limit=args.limit) # Export if args.export and results: filepath = export_results_csv(results, args.nom, args.prenom, args.data_dir) print(f"\n💾 Exporté dans: {filepath}") if __name__ == "__main__": main()