#!/usr/bin/env python3 """ Script pour lister tous les clubs présents dans les résultats FFA Utilise les fichiers CSV générés par le scraper ou les données live 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 collections import defaultdict logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s' ) def list_clubs_from_csv(data_dir="data"): """Lister tous les clubs à partir des 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}") print("\n💡 Pour générer les résultats, utilisez:") print(" python ffa_cli.py scrape --fetch-details") return [] try: df = pd.read_csv(results_path, encoding='utf-8-sig') logging.info(f"Chargé {len(df)} résultats") # Extraire les clubs uniques clubs_info = df.groupby('club').agg({ 'nom': lambda x: x.nunique(), # Nombre d'athlètes uniques 'dept': lambda x: x.mode()[0] if len(x.mode()) > 0 else '', 'ligue': lambda x: x.mode()[0] if len(x.mode()) > 0 else '' }).reset_index() clubs_info.columns = ['club', 'athletes_count', 'departement', 'ligue'] clubs_info = clubs_info.sort_values('athletes_count', ascending=False) return clubs_info.to_dict('records') except Exception as e: logging.error(f"Erreur lors de la lecture des CSV: {e}") return [] def list_clubs_live(): """Lister les clubs depuis l'URL FFA (besoin de scraping live)""" scraper = FFAScraper() logging.info("Récupération des données en direct depuis le site FFA...") logging.warning("Note: Cette méthode nécessite un scraping complet, ce qui peut prendre du temps") # Récupérer les résultats depuis le site # Pour simplifier, nous récupérons quelques courses et extrayons les clubs total_pages, total_courses, _ = scraper._detect_pagination_info() if not total_pages: logging.error("Impossible de détecter les données") return [] # Limiter à quelques pages pour éviter trop de temps max_pages = min(5, total_pages) logging.info(f"Analyse de {max_pages} pages pour extraire les clubs...") clubs = defaultdict(lambda: { 'count': 0, 'athletes': set(), 'dept': '', 'ligue': '' }) # Scraper les courses et récupérer les résultats 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']) for result in results: club = result.get('club', 'Inconnu') clubs[club]['count'] += 1 clubs[club]['athletes'].add(f"{result.get('prenom', '')} {result.get('nom', '')}") if not clubs[club]['dept'] and result.get('dept'): clubs[club]['dept'] = result['dept'] if not clubs[club]['ligue'] and result.get('ligue'): clubs[club]['ligue'] = result['ligue'] # Convertir en liste et trier clubs_list = [] for club, info in clubs.items(): clubs_list.append({ 'club': club, 'athletes_count': len(info['athletes']), 'results_count': info['count'], 'departement': info['dept'], 'ligue': info['ligue'] }) clubs_list.sort(key=lambda x: x['athletes_count'], ascending=False) return clubs_list def display_clubs(clubs, limit=None, show_details=False): """Afficher la liste des clubs""" if not clubs: print("\n❌ Aucun club trouvé") return print(f"\n{'='*80}") print(f"📊 LISTE DES CLUBS ({len(clubs)} clubs trouvés)") print(f"{'='*80}\n") if limit: clubs = clubs[:limit] for i, club in enumerate(clubs, 1): print(f"{i:3d}. {club['club']}") print(f" Athlètes: {club['athletes_count']}") if show_details: if 'results_count' in club: print(f" Résultats totaux: {club['results_count']}") if club.get('departement'): print(f" Département: {club['departement']}") if club.get('ligue'): print(f" Ligue: {club['ligue']}") print() print(f"{'='*80}") def export_clubs_csv(clubs, filename="clubs_list_export.csv", output_dir="data"): """Exporter la liste des clubs en CSV""" os.makedirs(output_dir, exist_ok=True) filepath = os.path.join(output_dir, filename) df = pd.DataFrame(clubs) df.to_csv(filepath, index=False, encoding='utf-8-sig') logging.info(f"Exporté {len(clubs)} clubs dans {filepath}") return filepath def main(): parser = argparse.ArgumentParser(description='Lister tous les clubs des résultats FFA') 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('--limit', type=int, help='Limiter le nombre de clubs affichés') parser.add_argument('--details', action='store_true', help='Afficher les détails (dpt, ligue, résultats)') parser.add_argument('--export', action='store_true', help='Exporter la liste en CSV') parser.add_argument('--output', default='data', help='Répertoire de sortie pour les données CSV') parser.add_argument('--export-filename', default='clubs_list_export.csv', help='Nom du fichier CSV exporté') args = parser.parse_args() # Choisir la source des données if args.live: print("\n⚠️ Mode live: récupération des données depuis le site FFA...") clubs = list_clubs_live() else: print(f"\n📂 Mode CSV: utilisation des fichiers dans {args.output}/") clubs = list_clubs_from_csv(args.output) # Afficher les résultats display_clubs(clubs, limit=args.limit, show_details=args.details) # Exporter si demandé if args.export and clubs: filepath = export_clubs_csv(clubs, args.export_filename, args.output) print(f"\n💾 Exporté dans: {filepath}") if __name__ == "__main__": main()