#!/usr/bin/env python3 """ Script de diagnostic des métadonnées Open Graph Vérifie que les métadonnées sont correctes pour le partage LinkedIn """ import os import sys import django # Configuration Django os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'duhaz_blog.settings') django.setup() from blog.models import Blog from blog.seo_helpers import SEOMetadata from django.test import RequestFactory def test_og_metadata(): """Teste les métadonnées Open Graph d'un article""" # Créer une fausse requête factory = RequestFactory() request = factory.get('/') # Récupérer le premier article publié article = Blog.objects.filter(b_publier=True).first() if not article: print("❌ Aucun article publié trouvé dans la base de données") return print("=" * 70) print("📊 DIAGNOSTIC DES MÉTADONNÉES OPEN GRAPH") print("=" * 70) print(f"\n📝 Article testé : {article.b_titre}") print(f"🔗 Slug : {article.b_titre_slugify}") print() # Générer les métadonnées seo_helper = SEOMetadata(request, article) metadata = seo_helper.get_blog_metadata(article) # Afficher les métadonnées principales print("=" * 70) print("🔍 MÉTADONNÉES GÉNÉRÉES") print("=" * 70) print(f"Titre : {metadata['og']['title']}") print(f"Description : {metadata['og']['description'][:80]}...") print(f"URL : {metadata['og']['url']}") print(f"Image URL : {metadata['og']['image']}") print(f"Image Alt : {metadata['og'].get('image_alt', 'N/A')}") print(f"Image Width : {metadata['og']['image_width']}px") print(f"Image Height : {metadata['og']['image_height']}px") print(f"Image Type : {metadata['og'].get('image_type', 'N/A')}") print(f"Site Name : {metadata['og']['site_name']}") print(f"Locale : {metadata['og']['locale']}") print() # Vérifications LinkedIn print("=" * 70) print("✅ VÉRIFICATIONS LINKEDIN") print("=" * 70) checks_passed = 0 checks_total = 0 # Check 1: URL absolue checks_total += 1 if metadata['og']['image'].startswith('https://'): print("✅ Image URL est absolue (commence par https://)") checks_passed += 1 else: print(f"❌ Image URL doit être absolue. Actuelle : {metadata['og']['image']}") # Check 2: Largeur minimale checks_total += 1 width = int(metadata['og']['image_width']) if width >= 1200: print(f"✅ Largeur suffisante : {width}px (minimum 1200px)") checks_passed += 1 else: print(f"❌ Largeur insuffisante : {width}px (minimum requis : 1200px)") # Check 3: Hauteur minimale checks_total += 1 height = int(metadata['og']['image_height']) if height >= 627: print(f"✅ Hauteur suffisante : {height}px (minimum 627px)") checks_passed += 1 else: print(f"❌ Hauteur insuffisante : {height}px (minimum requis : 627px)") # Check 4: Type d'image spécifié checks_total += 1 if 'image_type' in metadata['og'] and metadata['og']['image_type']: print(f"✅ Type d'image spécifié : {metadata['og']['image_type']}") checks_passed += 1 else: print("⚠️ Type d'image non spécifié (recommandé pour LinkedIn)") # Check 5: Alt text présent checks_total += 1 if 'image_alt' in metadata['og'] and metadata['og']['image_alt']: print(f"✅ Texte alternatif présent") checks_passed += 1 else: print("⚠️ Texte alternatif manquant (recommandé pour l'accessibilité)") # Check 6: Toutes les balises essentielles checks_total += 1 required_fields = ['type', 'title', 'description', 'url', 'image'] missing_fields = [f for f in required_fields if f not in metadata['og'] or not metadata['og'][f]] if not missing_fields: print("✅ Toutes les balises essentielles sont présentes") checks_passed += 1 else: print(f"❌ Balises manquantes : {', '.join(missing_fields)}") # Résumé print() print("=" * 70) print("📈 RÉSUMÉ") print("=" * 70) print(f"Tests réussis : {checks_passed}/{checks_total}") if checks_passed == checks_total: print("\n🎉 Excellent ! Vos métadonnées sont optimales pour LinkedIn") elif checks_passed >= checks_total - 1: print("\n👍 Bon ! Quelques améliorations mineures possibles") else: print("\n⚠️ Attention ! Des corrections sont nécessaires pour LinkedIn") # Instructions de test print() print("=" * 70) print("🔧 PROCHAINES ÉTAPES") print("=" * 70) print("\n1. Démarrez le serveur :") print(" ./start.sh") print() print("2. Testez avec LinkedIn Post Inspector :") print(" https://www.linkedin.com/post-inspector/") print() print("3. URL à tester :") print(f" https://www.duhaz.fr/blog/{article.b_titre_slugify}") print() print("4. Si LinkedIn met en cache l'ancienne version :") print(" - Utilisez le Post Inspector pour forcer le rafraîchissement") print(" - Attendez quelques minutes et réessayez") print() # Informations supplémentaires sur l'image if article.b_description_img: print("=" * 70) print("🖼️ INFORMATIONS SUR L'IMAGE") print("=" * 70) print(f"URL de l'image dans la BDD : {article.b_description_img}") print() if not article.b_description_img.startswith(('http://', 'https://')): print("⚠️ L'URL de l'image est relative.") print(" Elle sera convertie en URL absolue par le helper SEO.") print() print("💡 Vérifiez que cette image :") print(" - Fait au moins 1200x630 pixels") print(" - Est accessible publiquement (pas de login requis)") print(" - Pèse moins de 5 MB") print(" - Est au format JPG ou PNG") else: print("=" * 70) print("⚠️ ATTENTION") print("=" * 70) print("Aucune image spécifiée pour cet article.") print("L'image par défaut sera utilisée.") print("\n" + "=" * 70) if __name__ == "__main__": try: test_og_metadata() except Exception as e: print(f"\n❌ Erreur lors du test : {e}") import traceback traceback.print_exc() sys.exit(1)