Mets à jour la page en suivant strictement les règles définies dans /home/alan/SITE/WEB/AGENTS.md (section « Règles d'affichage des cartes »). Mets à jour la page odc-tv.html avec l'actualité récente d'ODC TV (Rachid Achachi). Objectif : recherche d'actualité (moins de 28 jours), max 25 cartes antéchronologiques. RÈGLE STRICTE DE TEMPS : exécution totale en MOINS DE 3 MINUTES. Max 3 appels bash, max 10 steps au total. Aucune itération de recherche : une seule collecte de données, puis édite immédiatement. Étapes : 1. Découverte — appels bash pour les 3 chaînes (pas de webfetch, pas de navigation) : Télécharger les 3 pages vidéos puis extraire avec python3. IMPORTANT : ne PAS spécifier de User-Agent (curl sans -A) — un User-Agent Chrome déclenche l'anti-bot YouTube (réponse vide de 0 octet). Sans -A, la page s'ouvre (~1,2 Mo) : curl -sL --max-time 12 "https://www.youtube.com/@odctvofficiel/videos" -o /tmp/opencode/odc-tv-officiel.html VÉRIFICATION : grep -o '[^<]*' /tmp/opencode/odc-tv-officiel.html | head -1 — le titre doit contenir « ODC TV ». Sinon : ÉCHEC_SOURCE, ne pas éditer. curl -sL --max-time 12 "https://www.youtube.com/@AchachiPodcast/videos" -o /tmp/opencode/odc-tv-achachi.html VÉRIFICATION : grep -o '<title>[^<]*' /tmp/opencode/odc-tv-achachi.html | head -1 — le titre doit contenir « Achachi ». Sinon : ÉCHEC_SOURCE, ne pas éditer. curl -sL --max-time 12 "https://www.youtube.com/@odcmaroc/videos" -o /tmp/opencode/odc-tv-maroc.html VÉRIFICATION : grep -o '<title>[^<]*' /tmp/opencode/odc-tv-maroc.html | head -1 — le titre doit contenir « ODC TV ». Sinon : ÉCHEC_SOURCE, ne pas éditer. puis pour CHAQUE fichier, extraire avec : python3 -c " import re,json for f in ['/tmp/opencode/odc-tv-officiel.html','/tmp/opencode/odc-tv-achachi.html','/tmp/opencode/odc-tv-maroc.html']: h=open(f,encoding='utf-8',errors='ignore').read() i=h.find('ytInitialData'); s=h.find('{',i) d=0;e=-1;q=False;sc=False for j,c in enumerate(h[s:s+4000000]): if q: if sc: sc=False elif c=='\\\\': sc=True elif c=='\"': q=False else: if c=='\"': q=True elif c=='{': d+=1 elif c=='}': d-=1 if d==0: e=j+1; break data=json.loads(h[s:s+e]) def walk(o,out): if isinstance(o,dict): if 'lockupViewModel' in o: v=o['lockupViewModel'] vid=None def fv(x): nonlocal vid if isinstance(x,dict): for k,val in x.items(): if k=='videoId' and isinstance(val,str) and vid is None: vid=val elif isinstance(val,(dict,list)): fv(val) elif isinstance(x,list): for it in x: fv(it) fv(v) t=v.get('metadata',{}).get('lockupMetadataViewModel',{}).get('title',{}).get('content','') rows=v.get('metadata',{}).get('lockupMetadataViewModel',{}).get('metadata',{}).get('contentMetadataViewModel',{}).get('metadataRows',[]) date='?' for r in rows: for p in r.get('metadataParts',[]): txt=p.get('text',{}).get('content','') if 'ago' in txt: date=txt out.append((vid,t,date)) for k in o: walk(o[k],out) elif isinstance(o,list): for it in o: walk(it,out) out=[]; walk(data,out) print('===',f,len(out)) for vid,t,d in out[:15]: print(vid,'|',d,'|',t) " C'est la SEULE source de découverte (les 3 chaînes : @odctvofficiel, @AchachiPodcast, @odcmaroc). Ne navigue pas ailleurs (pas de geopolitique-profonde.com, pas de Telegram, pas d'Odysee — les cartes existantes sont conservées telles quelles). N'écris PAS de nouveau script d'extraction : utilise exactement celui-ci (il fonctionne). Les dates relatives (« 13 hours ago », « 1 day ago ») : convertir par rapport à aujourd'hui 07/08/2026. Ne garder que les vidéos de moins de 28 jours. Les titres en anglais OU en arabe/darija : traduire en français pour les cartes. Si un téléchargement échoue (0 octet ou <100 Ko), réessaie UNE fois (2 tentatives max). Si les sources principales échouent, utilise le REPLI feed RSS (source secondaire) : curl -s --max-time 10 -A "Mozilla/5.0" "https://www.youtube.com/feeds/videos.xml?channel_id=UCRTNrUVjTtu9mF9wR3Qcsew" Le flux contient les dernières vidéos de la chaîne ODC TV - Ondes De Choc TV avec titres, IDs vidéo et dates de publication (<published>, format ISO 8601). Convertir les dates ISO 8601 en JJ/MM/2026. Ne garder que les vidéos de moins de 28 jours. Si le feed échoue aussi (réponse non XML valide), n'édite pas, ne conclus JAMAIS « page à jour » (interdit d'émettre VERDICT=PAGE_A_JOUR dans ce cas), et termine en signalant : ÉCHEC_SOURCE 2. Vérification des liens (30 s max, UN SEUL appel bash groupé) : - Les URLs viennent de l'extraction (https://www.youtube.com/watch?v=<videoId>). - Vérifier en parallèle (curl -o /dev/null -w "%{http_code}") les nouvelles URLs à ajouter. - 429 = lien valide (rate limit), ne pas retry. Codes acceptés : 200, 204, 302. - Dates : convertir les dates relatives en JJ/MM/2026. 3. Mise à jour de odc-tv.html : - Éditer uniquement <ul class="news-grid">. - Ajouter les nouvelles cartes .news-card au début (antéchronologique). - Supprimer les cartes dont la data-date dépasse 28 jours. - LIMITE STRICTE : 25 cartes au maximum. Si l'ajout dépasse 25, retirer les cartes datées les plus anciennes pour revenir à 25. - Conserver les cartes sans data-date (Telegram, Odysee, Facebook, Instagram, X/Twitter, GPTV) en fin de liste. - Classe src-youtube pour les vidéos, autres src-* conservées pour les cartes sans date. - favicon Google : https://www.google.com/s2/favicons?domain=youtube.com&sz=64 - news-tag : « Vidéo » pour les vidéos, « Chaîne »/« Telegram »/« Odysee »/« Facebook »/« Instagram »/« X / Twitter » pour les cartes sans date. - Titres : toujours en français (traduire si nécessaire, y compris depuis l'arabe) ; préserver la casse d'origine. Retirer les hashtags et emojis. - data-date au format JJ/MM/2026. - Ne pas modifier <section class="analysis">, le header, le footer, ni les scripts. 4. Vérifier l'ordre antéchronologique, la cohérence des dates, l'unicité des URLs, et que le total ne dépasse PAS 25 cartes. Terminer. IMPORTANT : si aucune carte n'a été ajoutée ni supprimée (page réellement à jour après analyse des données des sources), termine ta réponse par la ligne exacte : VERDICT=PAGE_A_JOUR IMPORTANT : TERMINE TOUJOURS ta réponse par ces 5 lignes exactes (aucune ligne après) : VERDICT=OK | PAGE_A_JOUR | ECHEC_SOURCE CARTES_AJOUTEES=<nombre de cartes ajoutees, 0 sinon> CARTES_SUPPRIMEES=<nombre de cartes supprimees, 0 sinon> CARTES_TOTAL=<nombre total de cartes apres edition> ERREURS=<nombre de problemes rencontres, 0 sinon>