Files
LettresJulesBerton/read_excel_metadata.py
MrRaph_ 3af796f9c4 feat: Add main analysis script and Excel metadata reader
- Implemented main.py to orchestrate the analysis of Jules Berton's letters collection.
- Added read_excel_metadata.py to read and analyze the Excel file containing letter metadata.
- Included functions for reading Excel files, analyzing structure, extracting letter information, and saving data to JSON.
- Added error handling and user feedback for file operations and analysis steps.
- Provided a summary of the analysis results and instructions for further usage.
2025-09-04 08:54:05 +02:00

254 lines
8.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Script pour lire et analyser le fichier Excel contenant les métadonnées
des lettres de Jules Berton.
Auteur: Assistant IA
Date: Septembre 2025
"""
import pandas as pd
import os
import json
from pathlib import Path
from datetime import datetime
def read_excel_file(excel_path):
"""
Lit le fichier Excel et retourne un DataFrame avec les métadonnées des lettres.
Args:
excel_path (str): Chemin vers le fichier Excel
Returns:
pandas.DataFrame: DataFrame contenant les données du fichier Excel
"""
try:
# Essayer de lire avec différents moteurs
try:
df = pd.read_excel(excel_path, engine='openpyxl')
print(f"✓ Fichier Excel lu avec succès (moteur: openpyxl)")
except:
try:
df = pd.read_excel(excel_path, engine='xlrd')
print(f"✓ Fichier Excel lu avec succès (moteur: xlrd)")
except:
df = pd.read_excel(excel_path)
print(f"✓ Fichier Excel lu avec succès (moteur par défaut)")
print(f"📊 Dimensions du fichier: {df.shape[0]} lignes × {df.shape[1]} colonnes")
return df
except FileNotFoundError:
print(f"❌ Erreur: Le fichier '{excel_path}' n'a pas été trouvé.")
return None
except Exception as e:
print(f"❌ Erreur lors de la lecture du fichier Excel: {e}")
return None
def analyze_excel_structure(df):
"""
Analyse la structure du DataFrame et affiche des informations sur les colonnes.
Args:
df (pandas.DataFrame): DataFrame à analyser
"""
if df is None:
return
print("\n📋 STRUCTURE DU FICHIER EXCEL")
print("=" * 50)
# Informations générales
print(f"Nombre total de lignes: {len(df)}")
print(f"Nombre total de colonnes: {len(df.columns)}")
# Liste des colonnes
print("\n📝 COLONNES DISPONIBLES:")
for i, col in enumerate(df.columns, 1):
print(f"{i:2d}. {col}")
# Aperçu des premières lignes
print("\n👀 APERÇU DES PREMIÈRES LIGNES:")
print(df.head().to_string())
# Informations sur les types de données
print("\n🔢 TYPES DE DONNÉES:")
for col in df.columns:
print(f"{col}: {df[col].dtype}")
# Statistiques sur les valeurs manquantes
print("\n❓ VALEURS MANQUANTES:")
missing_data = df.isnull().sum()
for col in df.columns:
if missing_data[col] > 0:
percentage = (missing_data[col] / len(df)) * 100
print(f"{col}: {missing_data[col]} ({percentage:.1f}%)")
def extract_letter_info(df):
"""
Extrait et structure les informations sur chaque lettre.
Args:
df (pandas.DataFrame): DataFrame contenant les métadonnées
Returns:
list: Liste de dictionnaires contenant les informations de chaque lettre
"""
if df is None:
return []
letters_info = []
print("\n📮 EXTRACTION DES INFORMATIONS DES LETTRES")
print("=" * 50)
for index, row in df.iterrows():
letter_info = {}
# Parcourir toutes les colonnes et extraire les données
for col in df.columns:
value = row[col]
# Nettoyer les valeurs NaN
if pd.isna(value):
value = None
elif isinstance(value, str):
value = value.strip()
letter_info[col] = value
letter_info['index'] = index
letters_info.append(letter_info)
print(f"{len(letters_info)} lettres extraites")
return letters_info
def save_to_json(data, output_path):
"""
Sauvegarde les données extraites en format JSON.
Args:
data (list): Données à sauvegarder
output_path (str): Chemin de sortie pour le fichier JSON
"""
try:
with open(output_path, 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=2, default=str)
print(f"✓ Données sauvegardées dans: {output_path}")
except Exception as e:
print(f"❌ Erreur lors de la sauvegarde: {e}")
def check_files_existence(letters_info, base_path):
"""
Vérifie l'existence des fichiers de transcription et d'images pour chaque lettre.
Args:
letters_info (list): Liste des informations des lettres
base_path (str): Chemin de base du projet
"""
print("\n🔍 VÉRIFICATION DE L'EXISTENCE DES FICHIERS")
print("=" * 50)
transcriptions_path = Path(base_path) / "transcriptions"
images_path = Path(base_path) / "lettres_scannees"
for letter in letters_info:
# Essayer d'identifier la date dans les données
date_found = None
# Chercher une colonne qui pourrait contenir la date
for key, value in letter.items():
if value and isinstance(value, (str, datetime)):
if isinstance(value, datetime):
date_found = value.strftime("%Y-%m-%d")
break
elif isinstance(value, str) and len(value) >= 8:
# Essayer de parser différents formats de date
try:
# Format YYYY-MM-DD
if '-' in value and len(value.split('-')) == 3:
parts = value.split('-')
if len(parts[0]) == 4:
date_found = value[:10] # Prendre les 10 premiers caractères
break
except:
continue
if date_found:
# Vérifier transcription
transcription_file = transcriptions_path / f"{date_found}.md"
has_transcription = transcription_file.exists()
# Vérifier images
image_pattern = f"{date_found} *.jpg"
image_files = list(images_path.glob(image_pattern))
has_images = len(image_files) > 0
letter['date_parsed'] = date_found
letter['has_transcription'] = has_transcription
letter['has_images'] = has_images
letter['image_count'] = len(image_files)
status = "📝" if has_transcription else ""
status += " 🖼️" if has_images else ""
print(f"{date_found}: {status} (images: {len(image_files)})")
else:
letter['date_parsed'] = None
letter['has_transcription'] = False
letter['has_images'] = False
letter['image_count'] = 0
print(f"Ligne {letter['index']}: ❌ Date non identifiée")
def main():
"""Fonction principale du script."""
# Chemin du fichier Excel
excel_file = "Jules Berton - lettres, dates et lieux.xlsx"
base_path = Path(__file__).parent
excel_path = base_path / excel_file
print("🔍 LECTURE DES MÉTADONNÉES DES LETTRES DE JULES BERTON")
print("=" * 60)
print(f"📁 Répertoire de travail: {base_path}")
print(f"📊 Fichier Excel: {excel_file}")
# Vérifier que le fichier existe
if not excel_path.exists():
print(f"❌ Le fichier {excel_file} n'existe pas dans le répertoire courant.")
print(f" Chemin recherché: {excel_path}")
return
# Lire le fichier Excel
df = read_excel_file(excel_path)
if df is None:
return
# Analyser la structure
analyze_excel_structure(df)
# Extraire les informations des lettres
letters_info = extract_letter_info(df)
# Vérifier l'existence des fichiers
check_files_existence(letters_info, base_path)
# Sauvegarder en JSON
output_json = base_path / "lettres_metadata.json"
save_to_json(letters_info, output_json)
# Statistiques finales
print(f"\n📊 STATISTIQUES FINALES")
print("=" * 30)
total_letters = len(letters_info)
with_transcription = sum(1 for l in letters_info if l.get('has_transcription', False))
with_images = sum(1 for l in letters_info if l.get('has_images', False))
print(f"Total des lettres dans Excel: {total_letters}")
print(f"Lettres avec transcription: {with_transcription}")
print(f"Lettres avec images: {with_images}")
print(f"Lettres complètes (texte + images): {sum(1 for l in letters_info if l.get('has_transcription', False) and l.get('has_images', False))}")
if __name__ == "__main__":
main()