Vue lecture

Il y a de nouveaux articles disponibles, cliquez pour rafraîchir la page.

GNU TeXmacs - Écrivez vos équations comme dans Word

Ah, LaTeX...

Si vous avez un jour essayé de poser 3 équations dans un document sérieux, vous voyez le genre de galère que c'est. Le rendu est magnifique, les maths sont propres, mais faut d'abord digérer son langage de markup avant de réussir à imprimer la moindre intégrale. Heureusement, c'est là qu'arrive GNU TeXmacs , un éditeur scientifique libre qui fait pareil mais en WYSIWYG.

Ça tourne sur Linux, macOS et même des OS du passé comme Windows ^^ et ça devrait ravir étudiants en sciences, thésards, chercheurs, enseignants, ou autres curieux qui veulent voir à quoi ressemble un éditeur scientifique vraiment libre. Faut vous imaginer un Google Docs avec un mode maths natif, dans lequel vous tapez directement votre équation comme dans un bon vieux Word avec du gras (c'est bon le gras ^^ !), de l'italique, des fractions, ou encore des racines carrées que vous pouvez faire à la souris ou via des raccourcis clavier. Et le moteur vous sort alors une typographie de niveau publication académique. Comme ça, pas besoin de "recompiler" votre document à chaque correction car tout s'affiche en direct !

Une formule rendue directement dans l'éditeur, sans recompilation

Le truc qu'il faut comprendre, c'est que TeXmacs n'est PAS un frontend graphique pour LaTeX. C'est un moteur de typographie complètement indépendant, qui s'inspire des idées de TeX sans en recycler le code. Vous pouvez donc exporter vers du .tex si un collègue en a besoin, mais ce n'est pas ce qui tourne sous le capot pendant que vous écrivez.

L'autre truc sympa, c'est que TeXmacs sert aussi d'interface pour de nombreux systèmes de calcul formel libres tels que Maxima, Sage, Pari ou Axiom qui peuvent balancer leurs résultats directement dans votre document, formatés proprement. R et Octave sont aussi de la partie pour le côté stats et numérique.

TeXmacs servant d'interface à un système de calcul formel, le résultat tombe déjà formaté

Derrière le projet, y'a Joris van der Hoeven, un mathématicien néerlandais et Directeur de recherche au CNRS. Il bosse sur TeXmacs depuis la fin des années 90, et maintient en parallèle Mathemagix, un système de calcul formel libre qui se marie forcément bien avec. Le projet est sous licence GPL et fait partie du projet GNU . Ce n'est donc pas un truc vibe codé en un weekend just 4 fun !

TeXmacs reste quand même un logiciel de niche. Et gaffe en particulier à l'import depuis LaTeX, qui laissera tomber les fichiers de style custom et ne gèrera qu'un sous-ensemble du langage. L'interface a aussi un côté très années 2000 assumé, et la communauté est plus petite que celle de LaTeX.

Mais peu importe, moi ce qui me plaît dans la démarche, c'est cette indépendance assumée vis à vis de TeX avec un moteur refait à zéro et pas une surcouche contraignant comme LyX. Alors oui forcément, on perd un peu de compatibilité mais ça rend tellement service que c'est pas très grave.

Voili voilou, si vous êtes amateur de maths et de formules ou que vous voulez voir à quoi ressemble un éditeur scientifique vraiment WYSIWYG, ça vaut son petit téléchargement. Puis c'est gratuit alors foncez !

Archives de Korben - Plus de 20 ans d'articles en un clic

Retrouver un vieil article sur korben.info, c'est pas toujours simple. La home s'arrête à 5 pages (site statique oblige) et après, fallait se débrouiller avec les catégories ou le moteur de recherche. Alors pour vous faciliter un peu la vie, je vous ai mis à dispo des pages d'archives accessibles via le footer.

Ainsi, vous scrollez en bas de n'importe quelle page, vous cliquez sur "Archives" ou sur une année, et vous tombez sur un index chronologique complet. Chaque mois est listé avec tous ses jours, et pour chaque jour, un petit nombre entre parenthèses vous indique combien d'articles ont été publiés ce jour-là. Vous cliquez, vous avez tout.

C'est vrai qu'avec plus de 19 000 articles publiés depuis août 2004, soit 22 ans de blog, autant dire que les catégories seules, c'était un peu l'aiguille dans la botte de foin ! Vous verrez d'ailleurs que le rythme varie pas mal... certains jours y'a 1 seul article, d'autres y'a carrément 25 (genre mars 2026, c'était dense).

Ma meilleure année c'était 2008 avec 1668 articles ! Suivi de 2011 avec 1487 articles, 2012 avec 1410 article et plus récemment 2025 avec 1318 articles. C'est pour ça que quand je poste à peine 5 articles par jours et que les commentateurs habituels chouinent à base de "Sans IA tu pourrais jamais faire ça c'est pas possible humainement", je rigole fort ^^

Par contre attention, y'a pas de recherche par mot-clé sur cette page mais pour ça y'a toujours le champ de recherche du site .

Bref, c'est dans le footer. Allez fouiller !

Fuite Claude Code - 6 trucs à piquer pour vos hooks

Le code source de Claude Code a fuité hier, et au-delà du buzz, y'a, je trouve, quelques leçons concrètes à tirer de tout ça.

Alors rassurez-vous, je vais pas vous balancer du code TypeScript à copier-coller (on n'est pas des cochons), ni des leçons de morale sur ce qu'on peut ou pas pousser sur un dépôt Git, mais plutôt vous lister des patterns d'architecture / bonnes pratiques que vous pouvez implémenter dès maintenant dans votre fichier settings.json via le système de hooks de Claude Code .

Je reste vague techniquement, volontairement pour 2 raisons. D'abord parce qu'il y a eu fuite de code, donc je peux pas poster du code propriétaire ici. Et ensuite parce que chaque projet / boite à outil qu'on se crée dans Claude Code ou ailleurs est différente, donc ce sera à vous (ou à Claude en fait) d'adapter chacune de ces bonnes pratiques.

Concrètement, tout passe par le fichier .claude/settings.json de votre projet (ou ~/.claude/settings.json pour du global). Dedans, vous déclarez des hooks, c'est-à-dire des scripts .cjs ou .sh qui se déclenchent automatiquement à des moments précis : avant qu'un outil s'exécute (PreToolUse), quand vous tapez un message (UserPromptSubmit), après un commit (PostToolUse), etc.

Le script reçoit du JSON en stdin, fait son boulot, et renvoie un code de sortie : 0 pour laisser passer, 2 pour bloquer. Pas besoin de l'API Claude, pas besoin de tokens, ça tourne en local sur votre machine. Hé bien tout ce que vous allez lire ci-dessous, ce sera à vous de l'implémenter dans des scripts de ce type.

Et le plus simple pour ça, c'est de donner les parties de mon article qui vous intéressent à votre propre Claude Code pour qu'il aille lui-même faire les scripts cjs / sh et les bons appels de hooks dans le settings.json. Pourquoi se prendre la tête ?

Et encore une fois, j'insiste, il s'agit de concepts d'ingénierie logicielle, et pas de code propriétaire appartenant à Anthropic.

La première bonne pratique c'est le circuit breaker ou disjoncteur en français...

En gros, quand vos scripts JavaScript appellent des APIs genre l'endpoint chat/completions d'OpenAI ou generateContent de Gemini, ça peut parfois ne pas répondre, parce que la vie quoi... ^^

Et malheureusement, quand cela arrive, votre code continue de marteler l'endpoint en boucle, ce qui fait que vous cramez des tokens pour rien. Le fix est pourtant très simple : Après 3 échecs consécutifs, on coupe, et on passe au fallback. Netflix avait popularisé ça avec leur librairie Hystrix y'a 10 ans, et c'est ce type de protection qu'on retrouve aujourd'hui dans Claude Code. Concrètement, c'est un module Node.js de 40 lignes avec un compteur et un état ouvert/fermé et comme ça, fini les retry storms !

Deuxième pattern : le scanner de secrets en pre-commit.

Un git commit qui embarque une clé API dans un .env, ça arrive trop souvent (demandez à Anthropic et leur fichier .map de 60 Mo ^^). Le hook PreToolUse permet heureusement d'intercepter chaque git commit AVANT exécution. Votre script parcourt alors les fichiers stagés via git diff --cached, cherche les patterns sk-ant-api, ghp_, AKIA, -----BEGIN RSA PRIVATE KEY----- et renvoie un exit 2 pour bloquer.

Perso, j'ai dans ma boîte à outils IA, 18 regex dans un fichier .claude/hooks/secret-scanner.cjs qui couvrent Anthropic, OpenAI, AWS, GitHub, Slack, Stripe et les JWT. Par contre, attention aux faux positifs car un fichier contenant "sk-ant-api" dans un commentaire, ça bloquera tout. Ça m'est déjà arrivé et heureusement, l'IA est assez maligne pour comprendre d'où vient le blocage et éventuellement passer outre si ce n'est pas justifié.

Et troisième truc sympa : la détection de frustration.

En effet, un hook UserPromptSubmit se déclenche quand vous tapez un message de rageux. Ainsi, si votre prompt contient "putain", "ça marche pas" ou "wtf", le hook injecte via stdout un contexte qui dit à Claude d'aller droit au but. Comme ça, y'a plus de blabla et on part direct sur une solution concrète.

Et c'est pareil pour "continue" ou "finis" qui injecte "reprendre sans résumer" automatiquement. Franchement, c'est 30 lignes de JavaScript rikiki à mettre dans .claude/hooks/frustration-detector.cjs et ça change carrément la vie quand vous êtes en mode debug à 2h du mat avec un café dans la main gauche et un œil qui se ferme tout seul en tremblant !

Quatrième bonne pratique : les tags @[MODEL] dans vos skills.

Car vous le savez, certaines règles que vous avez mises en place existent uniquement à cause d'un biais du modèle actuel. Genre, Opus 4.6 qui colle ces putains de tirets cadratins (Unicode U+2014) partout. Du coup, ça oblige les gens à mettre dans leurs skills une règle du genre "0 em-dash". Sauf que le jour où Sonnet 5 ne les utilisera plus, cette règle ce sera du bruit inutile.

Alors en taguant @[OPUS-4.6] dans un commentaire HTML, vous pourrez ensuite faire facilement un grep -r "@\[OPUS" quand vous changez de modèle. C'est du tracking de dette technique pour le prompt engineering, quoi... et perso, je n'y avais pas pensé avant.

Cinquième pattern : les seuils numériques.

Votre "Fais des fonctions courtes" dans un CLAUDE.md, ça ne veut rien dire pour un agent et malheureusement, la plupart des gens écrivent encore "sois concis" ou "toi faire code propre" sans aucun chiffre alors qu'un "Max 50 lignes par fonction, couverture tests ≥ 80%, 0 warning ESLint" c'est vachement plus efficace car vérifiable par un script.

Enfin, dernier pattern : la consolidation mémoire.

Anthropic a mis en place un système nommé autoDream qui tourne pendant l'inactivité de Claude Code pour nettoyer la mémoire. Il vire les doublons, résout les contradictions, vérifie que les fichiers existent encore. Et même s'il ne le réclame pas parce qu'ils n'ont pas de bouche pour vous parler, vos CLAUDE.md de 200 lignes et vos JSON de 70 Ko ont besoin du même traitement ! Donc il faut que vous ajoutiez une phase genre "dream" en bash ou Node.js à la fin de vos workflows, comme ça, plutôt que de tout garder, le script scan le répertoire ~/.claude/, trie les entrées par date, et fusionne les doublons. C'est comme la consolidation pendant l'inactivité, mais en 5 secondes sur un Apple M4.

D'ailleurs, la communauté n'a pas perdu de temps. Un développeur a catalogué les 88 feature flags planqués dans le code, dont 54 qui compilent proprement (les autres dépendent de modules internes d'Anthropic). Et un autre a reconstitué 8 diagrammes d'architecture complets du pipeline : cycle de vie d'une requête, système de permissions, orchestration multi-agents... C'est la meilleure doc technique qui existe sur le fonctionnement interne de Claude Code, et elle ne vient pas d'Anthropic ^^

Architecture globale de Claude Code reconstituée par la communauté

Voilà et toutes ces pratiques, ça repose sur les 25 événements du système de hooks (PreToolUse, PostToolUse, UserPromptSubmit, Stop...) avec 3 types de handlers : command pour les scripts shell, prompt pour une évaluation LLM, et agent pour une vérification multi-étapes.

Après, si l'un de vos scripts plante comme une merde, le hook laissera passer des choses, donc pensez bien à tester chaque retour de script avec un echo '{}' | ./mon-hook.sh && echo $? avant de déployer.

Et voilà ! Je vous invite à lire mon article sur la fuite pour plus d'infos.

Sortie VGA sur un PIC18 : quand l'optimisation hardware devient un art

Générer un signal VGA avec un microcontrôleur 8 bits PIC18 est un défi technique de taille. Ce projet Hackaday montre comment détourner les ressources limitées d'un processeur rudimentaire pour produire une image stable. Une petite plongée dans le bit-banging pur et dur.

Le défi du timing analogique

Le standard VGA impose une rigueur chronométrique absolue à celui qui s'y frotte. Pour obtenir une image stable, typiquement en 640x480 à 60 Hz, le contrôleur doit générer des signaux de synchronisation horizontale (H-sync) et verticale (V-sync) avec une précision de l'ordre de la microseconde. Sur une architecture PIC18 cadencée à quelques dizaines de mégahertz, chaque cycle d'instruction est précieux. L'astuce réside ici dans l'utilisation intelligente des timers internes et des interruptions prioritaires pour maintenir cette cadence sans aucune dérive temporelle, sous peine de voir l'image se désynchroniser immédiatement.

Un DAC rudimentaire pour les couleurs

Côté matériel, la solution retenue est ultra simple (si on peut dire). Pour transformer les sorties numériques binaires du microcontrôleur en signaux analogiques exploitables par un moniteur CRT ou LCD, l'auteur a implémenté une échelle de résistances, aussi appelée DAC R-2R. Ce montage passif permet de convertir des combinaisons de bits en niveaux de tension spécifiques pour les canaux Rouge, Vert et Bleu. C'est une approche classique en électronique "low-cost" qui permet d'obtenir une palette de couleurs certes limitée, mais parfaitement fonctionnelle pour de l'affichage de texte ou de graphismes simples.

L'art du bit-banging et des périphériques détournés

L'envoi des données de pixels vers l'écran nécessite une bande passante que le CPU seul peinerait à fournir en mode pur "bit-banging". Pour optimiser le processus, le développeur détourne souvent le module SPI ou le port série synchrone (MSSP) du PIC pour envoyer les octets de données à la vitesse de l'horloge système. Cela permet de déléguer une partie de la charge de travail au hardware interne et de libérer quelques cycles processeur pour gérer la logique d'affichage. C'est un équilibre précaire où la moindre latence logicielle se traduit par des pixels décalés ou des lignes de travers. Chaud donc.

Ce projet illustre bien l'adage selon lequel la contrainte stimule la créativité. Là où nous utilisons aujourd'hui des processeurs multi-cœurs pour la moindre interface, ce hack prouve qu'un vieux microcontrôleur 8 bits peut encore faire le job. C’est une leçon d'architecture informatique qui permet de comprendre concrètement comment l'information devient image. C'est aussi une forme de résistance face à la démesure logicielle actuelle.

Source : Hackaday

Surfshark VPN : la couche réseau qui manque à votre stratégie de sécurité

-- Article en partenariat avec Surfshark --

Vous avez probablement déjà un gestionnaire de mots de passe. Vous avez activé la double authentification partout où c'est possible. Peut-être même que vous hébergez vos propres services sur un NAS, avec un pare-feu correctement configuré.

C'est excellent. Mais il manque encore une pièce au puzzle : la protection de votre trafic réseau. C'est exactement là qu'intervient un VPN comme Surfshark. Pas comme solution miracle, plutôt comme couche complémentaire dans une approche de défense en profondeur.

Je vous explique pourquoi cette couche compte et comment Surfshark s'intègre concrètement dans une infrastructure personnelle ou professionnelle.

La défense en profondeur, rappelée simplement

Le principe est connu de tous les survivalistes numériques  : ne jamais compter sur une seule barrière de protection. 1 c'est 0, 2 c'est 1, toussa. Si votre mot de passe fuit, le 2FA bloque l'intrusion. Si votre 2FA est contournée, le pare-feu limite l'accès. Si le pare-feu est franchi, la segmentation réseau contient les dégâts.

Mais dans cette chaîne, un maillon reste souvent négligé. Le trafic entre votre appareil et le reste d'internet. Sans VPN, votre FAI voit tout ce que vous faites. Sur un réseau public, un attaquant peut intercepter vos données non chiffrées. Même chez vous, des applications peuvent communiquer en clair avec des serveurs tiers. Un VPN chiffre l'intégralité de ce trafic et le fait transiter par un tunnel sécurisé. Ce n'est pas une protection supplémentaire au même niveau que les autres, c'est une protection à un niveau différent, réseau plutôt qu'application.

Ce que Surfshark apporte techniquement

Surfshark ne se contente pas de proposer un bouton "se connecter". Plusieurs fonctionnalités techniques méritent l'attention si vous construisez une stratégie de sécurité sérieuse. Le chiffrement AES-256-GCM est le standard, mais le choix du protocole compte tout autant. Surfshark privilégie WireGuard, qui offre de meilleures performances avec un audit de code plus simple que les solutions historiques. Pour les utilisateurs avancés, l'application permet de forcer le protocole, de configurer des règles de split-tunneling, ou d'activer le kill switch en mode strict.

La politique no-logs a été auditée à deux reprises par Deloitte, en 2024 et 2025, par SecuRing en 2026, etc. Les rapports sont publics et détaillent les méthodes de vérification. Ce n'est pas une déclaration d'intention, mais une preuve vérifiable.

Autre point important : l'infrastructure. Surfshark opère plus de 4 500 serveurs (dont une majorité en mode RAM-only) et certains serveurs, notamment aux Pays-Bas, tournent déjà à 100 Gbps. Aucune donnée ne peut persister sur disque, ce qui réduit drastiquement les risques en cas de compromission physique d'un nœud. Enfin, les fonctionnalités désormais habituelles comme le MultiHop (double saut VPN) ou le mode Camouflage (obfuscation du trafic VPN) permettent d'adapter le niveau de protection au contexte d'usage, sans complexifier l'expérience pour les utilisateurs non techniques (ça ne vous concerne pas je sais, vous êtes les plus forts, vous lisez mon site).

Intégrer Surfshark dans votre setup existant

Ajouter un VPN à une infrastructure déjà en place ne doit pas être une usine à gaz. Voici comment procéder de manière pragmatique. Si vous utilisez déjà un gestionnaire de mots de passe, commencez par y stocker vos identifiants Surfshark avec une entrée dédiée. Activez la 2FA sur votre compte VPN, en privilégiant une application d'authentification plutôt que les SMS.

Pour le déploiement, privilégiez l'installation sur le routeur si vous voulez protéger tous les appareils du réseau domestique. Sinon, installez l'application sur chaque endpoint critique (ordinateur principal, téléphone professionnel, tablette de voyage & co). Configurez le kill switch en mode strict pour éviter toute fuite d'IP en cas de déconnexion. Activez ensuite  CleanWeb pour bloquer les trackers et les domaines malveillants au niveau DNS. Et si vous travaillez avec des données sensibles, envisagez MultiHop pour ajouter une couche de routage supplémentaire.

Enfin, documentez votre configuration. Notez les serveurs que vous utilisez habituellement, les règles de split-tunneling et la procédure de secours en cas de problème. La sécurité ne vaut que si elle est reproductible et compréhensible par ceux qui doivent l'utiliser.

Mon avis sur l'approche

Ce qui distingue Surfshark dans le paysage des VPN, ce n'est pas une fonctionnalité isolée, mais la cohérence d'ensemble. L'outil ne cherche pas à tout faire, par contre il fait bien ce qui compte (chiffrer le trafic, protéger les identifiants, limiter l'exposition aux trackers, etc.).

Pour un particulier exigeant, un freelance ou une petite structure, c'est un compromis pertinent entre simplicité et robustesse. Est-ce que cela remplace une infrastructure professionnelle ? Non. Mais en combinant protection réseau et contrôle des données personnelles, Surfshark propose une brique de sécurité plus complète que la moyenne.

L'offre actuelle

En ce moment Surfshark casse un peu les prix et propose un engagement sur 27 mois (dont 3 supplémentaires) qui revient à 61€ TTC au total (2.26€/mois, moins cher qu'un café), et une garantie satisfait ou remboursé de 30 jours. L'abonnement couvre un nombre illimité d'appareils, ce qui facilite le déploiement sur l'ensemble de votre parc personnel/familial.

🔗 Profiter de l'offre Surfshark VPN ici

Note : ce lien est affilié. Cela ne change rien pour vous, mais cela me permet de continuer à produire ce type de contenu sans dépendre de la publicité intrusive.

La sécurité numérique ne se résume pas à empiler des outils. Il s'agit de comprendre ce que chacun protège, et comment ces protections s'articulent. Un VPN comme Surfshark n'est pas une fin en soi. Mais dans une stratégie de défense en profondeur, il représente la couche réseau qui manquait peut-être à votre dispositif. C'est pragmatique, efficace, et ça ne demande pas de devenir expert en cryptographie pour en tirer parti.

Questions fréquentes :

  • Le VPN remplace-t-il un pare-feu ? Non, il le complète en protégeant le trafic hors du réseau local.
  • Puis-je utiliser Surfshark sur mon routeur ? Oui, des tutoriels sont disponibles pour les modèles compatibles.
  • La politique no-logs est-elle vérifiable ? Oui, les audits Deloitte et SecuRing sont publics.

Comment j'ai rendu mon serveur Plex surpuissant et silencieux grâce à un Mac Mini et des SSD Lexar

– Ccontient des liens affiliés Amazon –

Après des années de galère avec un NAS bruyant puis un miniPC pas beaucoup mieux, j'ai fini par trouver la configuration Plex idéale. Un Mac Mini M4 , deux SSD Lexar SL500 , et le silence absolu. Retour d'expérience.

Le bruit, l'ennemi numéro un

J'ai un serveur Plex depuis des années. Un serveur que je partage avec ma famille et mes amis les plus proches, et qui me sert à stocker des films et des séries souvent introuvables sur les plateformes légales, ou des versions numérisées de DVD et Blu-Ray que j'ai achetés, mais que je veux pouvoir streamer sur mon Apple TV. Vous voyez l'idée. Pendant longtemps, tout ça tournait sur un NAS Synology d'entrée de gamme. Ça marchait, mais dès que je voulais transcoder un film pour le regarder à distance, c'était mort. Lecture directe obligatoire, avec les problèmes de débit que ça implique, surtout à l'époque où j'étais encore en ADSL. Il y a trois ou quatre ans, j'ai décidé de monter d'un cran en déportant le serveur Plex sur un miniPC Beelink. Plus de puissance, transcodage enfin possible, bien pratique pour moi à distance ou pour mes proches qui n'ont pas forcément la fibre.

Sauf que toutes ces solutions avaient le même défaut. Le bruit. Entre les disques durs mécaniques, le ventilateur du NAS Synology qui ronronnait en permanence et celui du miniPC Beelink qui se mettait à souffler dès qu'on lui demandait un peu d'effort, c'était toujours pénible. Et comme je n'ai jamais eu la place de planquer tout ça dans un bureau ou un placard technique, le serveur a toujours tourné dans mon salon. Autant dire que les soirs de film, l'ambiance était moyennement au rendez-vous.

Le Mac Mini M4, une bête silencieuse

Et puis il y a quelques semaines, j'ai tout changé. Adios le miniPC, filé à un ami, et place au Mac Mini M4. Ce petit machin tout mignon, complètement silencieux, est une vraie bête de course pour Plex. On parle de quatre à cinq transcodages simultanés sans broncher, avec une sollicitation processeur qui reste sous les 3 à 4%. C'est presque absurde. Le tout en restant frais, sans ventilateur qui se déclenche, sans bruit parasite. Rien. Le silence total.

Pour l'administration, pas besoin d'écran ni de clavier. Tout se fait à distance via l'application Partage d'écran de macOS. Le Mac Mini est branché directement sur ma Livebox, et ça tourne comme une horloge. Et comme bonus, ça me fait un second Mac pour faire des tests quand j'en ai besoin. Pas mal pour une machine qui fait à peine la taille d'une main.

Les SSD Lexar SL500 en remplacement du NAS

Pour compléter le tableau, j'ai déplacé mes données les plus consultées, les films et les séries que ma famille et moi regardons le plus souvent, sur deux SSD SL500 de chez Lexar. Et là, c'est le coup de grâce pour le bruit. Non seulement les ventilateurs ont disparu avec le Mac Mini, mais les vibrations et le ronronnement des disques mécaniques du NAS aussi. Le silence est total. J'ai quand même gardé un NAS Synology en arrière-plan pour stocker les données froides, mon Time Machine et les films que personne ne regarde jamais. Il reste accessible à Plex au cas où, mais il est si peu sollicité qu'on l'entend à peine.

Le résultat, c'est une configuration compacte, silencieuse, et qui gère sans effort tout ce que je lui demande. Le Mac Mini fait tourner Plex comme si de rien n'était, les SSD Lexar offrent des temps d'accès instantanés, et le NAS se contente de dormir dans son coin.

Franchement, si vous êtes du genre à soigner votre setup multimédia à la maison, ce genre de configuration change la vie. Ça a un coût, on ne va pas se mentir, un Mac Mini M4 plus deux SSD externes ce n'est pas donné. Mais le confort au quotidien est incomparable. Plus de bruit, des performances de dingue pour le transcodage, et une machine qui ne chauffe même pas. Si vous avez la possibilité de basculer votre serveur Plex sur un Mac Mini, n'hésitez pas trop longtemps. Moi en tout cas, je ne reviendrais pas en arrière.

Si vous voulez vous équiper, voilà ma config :

Sora ferme - Comment sauvegarder vos vidéos IA avant la coupure

Sora, c’est fini les amis !

Hé oui, cest chacals d'OpenAI ferment leur plateforme de vidéos IA, et franchement, ça me rend un peu triste. À vrai dire, même si c’était que de la vidéo générée à partir de prompts, moi je me marrais bien. C'était fun de regarder le produit de ses prompts mais aussi de regarder les conneries des autres. Les versions québécoises, aïe aïe aïe, c’était quelque chose quand même !

Mais bon, le plus urgent maintenant, c’est de sauvegarder vos vidéos avant que tout disparaisse. OpenAI n’a pas encore communiqué de date précise pour la coupure, juste un vague « on vous dira bientôt ». Du coup, autant ne pas traîner, parce que quand ce genre de service cloud ferme, en général c’est pas 6 mois de préavis qu’on vous file...

Depuis la fuite du modèle jusqu’à aujourd’hui, Sora aura fait parler de lui. Côté raisons, c’est Fidji Simo (la patronne de la division Applications) qui a lâché le morceau : ils éparpillent leurs efforts sur trop d’apps, d’API et de stacks serveur différents, et ça les ralentit. En gros, entre préparer une entrée en bourse pour fin 2026 et cramer du GPU H100 sur des vidéos de chats en IA, le choix est vite fait. L’équipe de recherche Sora, elle, continuera à bosser sur la simulation de mondes 3D... mais pour la robotique. Et le fameux deal à 1 milliard de dollars avec Disney pour des films et séries ? Pouf, magie magie, c'est envolé !!

Faut dire que les chiffres n’étaient pas glorieux non plus. Après un lancement en fanfare fin 2024 (et une app iOS lancée à l’automne 2025 qui avait cartonné dans les charts), les téléchargements sur l’App Store avaient plongé de 32% entre novembre et décembre 2025. La hype, ça dure qu’un temps.

Mais maintenant les gens, on passe aux choses sérieuses !

Sora Backup - le script qui sauve vos vidéos

Je n'avais absolument pas de temps aujourd'hui, mais j'ai quand même taffé pour vous développer un petit script JavaScript qui récupère TOUTES vos vidéos Sora d’un coup, avec les prompts et les métadonnées, et qui vous génère un joli ZIP prêt à archiver. Pas besoin d’installer quoi que ce soit, pas d’extension louche. Vous avez juste besoin d'être connecté à votre profil Sora et d'un navigateur.

Comment ça marche

Allez sur sora.com , connectez-vous à votre compte, puis ouvrez la console JavaScript de votre navigateur (F12 sur Chrome ou Firefox, onglet Console). Ensuite, glissez-déplacez ou collez le script ci-dessous dedans et appuyez sur Entrée.

Le script va automatiquement récupérer votre token d’authentification (pas besoin de le chercher vous-même), puis il va paginer sur votre profil Sora pour récupérer tous vos posts publiés. Pour chaque post, il extrait les vidéos attachées (MP4), les télécharge, et empaquette le tout dans un fichier ZIP directement dans votre navigateur.

Y’a même un fichier manifest.json dans le ZIP qui contient tous vos prompts, les dimensions, les durées, les permalinks, les dates de création... bref, tout ce qu’il faut pour retrouver vos petits. Le ZIP est généré en format STORE (pas compressé, parce que compresser du MP4 ça sert à rien), avec un calcul CRC32 maison et sans aucune librairie externe.

Le script complet

Voici le code à coller dans la console :

// ==========================================================
// SORA BACKUP - Sauvegarde complète vidéos + images + prompts par Korben
// ==========================================================
// Usage : Ouvrir https://sora.com, F12 > Console, coller ce script
// Les fichiers sont téléchargés via le navigateur (dossier Downloads)
// Un fichier manifest.json récapitule tout (prompts, metadata, URLs)
// ==========================================================

(async () => {
 // --- Mini ZIP builder (STORE, pas de lib externe) ---
 const crc32table = new Uint32Array(256);
 for (let i = 0; i < 256; i++) {
 let c = i;
 for (let j = 0; j < 8; j++) c = (c & 1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1);
 crc32table[i] = c;
 }
 function crc32(buf) {
 let c = 0xFFFFFFFF;
 for (let i = 0; i < buf.length; i++) c = crc32table[(c ^ buf[i]) & 0xFF] ^ (c >>> 8);
 return (c ^ 0xFFFFFFFF) >>> 0;
 }
 const zipFiles = []; // {name, data (Uint8Array), crc, size}

 const PAGE_SIZE = 50;
 const DELAY_MS = 1500;
 const manifest = [];
 let totalDownloaded = 0;
 let totalErrors = 0;

 // --- Auth : récupérer le Bearer token ---
 // OPTION 1 : Coller ton token ici (Network tab > Authorization header)
 // OPTION 2 : Laisser vide, le script tentera de le récupérer auto
 let AUTH_TOKEN = '';

 async function getAuthToken() {
 if (AUTH_TOKEN) return AUTH_TOKEN;

 // Auto-detect : endpoint session ChatGPT
 for (const path of ['/api/auth/session', '/backend-api/auth/session']) {
 try {
 const r = await fetch(path, { credentials: 'include' });
 if (r.ok) {
 const json = await r.json();
 if (json.accessToken) {
 AUTH_TOKEN = json.accessToken;
 console.log(' 🔑 Token récupéré automatiquement');
 return AUTH_TOKEN;
 }
 }
 } catch(e) {}
 }

 // Fallback : demander à l'utilisateur
 const input = prompt(
 'Token non trouvé automatiquement.\n\n' +
 'Pour le récupérer :\n' +
 '1. F12 > onglet Réseau\n' +
 '2. Rafraîchis la page\n' +
 '3. Clique sur une requête /backend/...\n' +
 '4. Copie le header Authorization\n\n' +
 'Colle le token ici (Bearer eyJ...):'
 );
 if (input) {
 AUTH_TOKEN = input.replace(/^Bearer\s+/i, '').trim();
 return AUTH_TOKEN;
 }

 console.error(' ❌ Pas de token. Annulation.');
 return null;
 }

 // --- Fetch API avec auth ---
 async function apiFetch(url) {
 const token = await getAuthToken();
 const headers = {};
 if (token) headers['Authorization'] = 'Bearer ' + token;

 // oai-device-id requis par certains endpoints
 const deviceId = localStorage.getItem('oai-did') || '';
 if (deviceId) headers['oai-device-id'] = deviceId;

 const resp = await fetch(url, {
 method: 'GET',
 credentials: 'include',
 headers
 });

 if (!resp.ok) throw new Error(`HTTP ${resp.status} for ${url}`);
 return resp.json();
 }

 // --- Pagination générique ---
 async function fetchAllPages(baseUrl, dataField = 'data', cursorParam = 'after', cursorField = 'last_id') {
 let allItems = [];
 let cursor = '';
 let page = 0;

 while (true) {
 let url = baseUrl;
 if (cursor) url += `&${cursorParam}=${cursor}`;

 console.log(` 📄 Page ${++page} (${allItems.length} items so far)...`);
 const json = await apiFetch(url);

 const items = json[dataField];
 if (!Array.isArray(items) || items.length === 0) break;

 allItems = allItems.concat(items);
 cursor = json[cursorField] || '';

 if (!json.has_more && !cursor) break;
 await sleep(DELAY_MS);
 }

 return allItems;
 }

 // Variante pour les endpoints project_y (cursor-based)
 async function fetchAllPagesCursor(baseUrl) {
 let allItems = [];
 let cursor = '';
 let page = 0;

 while (true) {
 let url = baseUrl;
 if (cursor) url += `&cursor=${cursor}`;

 console.log(` 📄 Page ${++page} (${allItems.length} items so far)...`);
 const json = await apiFetch(url);

 const items = json.items;
 if (!Array.isArray(items) || items.length === 0) break;

 allItems = allItems.concat(items);
 cursor = json.cursor || '';

 if (!cursor) break;
 await sleep(DELAY_MS);
 }

 return allItems;
 }

 function sleep(ms) { return new Promise(r => setTimeout(r, ms)); }

 // --- Extraire URL du média depuis une generation ---
 function getMediaUrl(gen) {
 return gen?.encodings?.source?.path
 || gen?.downloadable_url
 || gen?.url
 || '';
 }

 // --- Extraire le prompt (peut être dans actions, prompt, ou input_text) ---
 function getPrompt(item, gen) {
 // Prompt direct
 if (gen?.prompt) return gen.prompt;
 if (item?.prompt) return item.prompt;
 if (item?.input_text) return item.input_text;
 // Storyboard : les actions sont les descriptions des scènes
 if (item?.actions && typeof item.actions === 'object') {
 return Object.entries(item.actions)
 .sort((a,b) => Number(a[0]) - Number(b[0]))
 .map(([frame, desc]) => `[frame ${frame}] ${desc}`)
 .join(' | ');
 }
 if (gen?.actions && typeof gen.actions === 'object') {
 return Object.entries(gen.actions)
 .sort((a,b) => Number(a[0]) - Number(b[0]))
 .map(([frame, desc]) => `[frame ${frame}] ${desc}`)
 .join(' | ');
 }
 return '';
 }

 // --- Dérouler les items du profil Sora en items plats ---
 function flattenProfileItems(items) {
 const flat = [];
 for (const item of items) {
 const post = item.post || item;
 const attachments = post.attachments || [];
 if (attachments.length === 0) continue;

 for (const att of attachments) {
 const url = att.encodings?.source?.path || att.downloadable_url || att.url || '';
 if (!url) continue;

 flat.push({
 id: post.id || att.generation_id || '',
 generation_id: att.generation_id || '',
 task_id: att.task_id || '',
 title: att.title || post.discovery_phrase || '',
 prompt: post.text || '',
 emoji: post.emoji || '',
 type: att.generation_type || att.kind || '',
 width: att.width || 0,
 height: att.height || 0,
 duration_s: att.duration_s || 0,
 is_public: !!post.posted_to_public,
 created_at: post.posted_at ? new Date(post.posted_at * 1000).toISOString() : '',
 url: url,
 permalink: post.permalink || '',
 username: item.profile?.username || '',
 });
 }
 }
 return flat;
 }

 // --- Sanitize filename ---
 function sanitize(name) {
 return name.replace(/[<>:"\/\\|?*\x00-\x1f]/g, '_').substring(0, 100);
 }

 // --- Ajouter un fichier au ZIP ---
 async function addToZip(url, filename) {
 try {
 const resp = await fetch(url);
 if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
 const buf = await resp.arrayBuffer();
 const data = new Uint8Array(buf);
 zipFiles.push({ name: filename, data, crc: crc32(data), size: data.length });
 totalDownloaded++;
 return true;
 } catch(e) {
 console.warn(` ⚠️ Erreur ${filename}:`, e.message);
 totalErrors++;
 return false;
 }
 }

 // --- Déduire l'extension ---
 function getExt(url, type) {
 if (!url) return type === 'video' ? '.mp4' : '.png';
 const m = url.match(/\.(mp4|webm|mov|png|jpg|jpeg|webp|gif)/i);
 return m ? '.' + m[1].toLowerCase() : (type === 'video' ? '.mp4' : '.png');
 }

 // ==========================================================
 // MAIN
 // ==========================================================
 const origin = window.location.origin;
 console.log('🎬 SORA BACKUP - Démarrage');
 console.log('='.repeat(50));

 // 1. Mes posts Sora (profil)
 console.log('\n📦 1/2 - Récupération de mes posts Sora...');
 let myPosts = [];
 try {
 myPosts = await fetchAllPagesCursor(
 `${origin}/backend/project_y/profile_feed/me?limit=${PAGE_SIZE}&cut=nf2`
 );
 console.log(`  ${myPosts.length} posts de profil`);
 // Debug premier item
 if (myPosts.length > 0) {
 const first = myPosts[0];
 console.log(' 🔍 Premier item - clés:', Object.keys(first).join(', '));
 console.log(' 🔍 URL:', first.url?.substring(0, 80) || 'none');
 console.log(' 🔍 DL:', first.downloadable_url?.substring(0, 80) || 'none');
 console.log(' 🔍 ENC:', first.encodings?.source?.path?.substring(0, 80) || 'none');
 console.log(' 🔍 GENS:', first.generations?.length || 'none');
 console.log(' 🔍 TITLE:', first.title || 'none');
 }
 } catch(e) {
 console.warn(' ⚠️ profil failed:', e.message);
 }

 // 2. Mes likes sur Sora
 console.log('\n📦 2/2 - Récupération de mes likes Sora...');
 let myLikes = [];
 try {
 myLikes = await fetchAllPagesCursor(
 `${origin}/backend/project_y/profile_feed/me?limit=${PAGE_SIZE}&cut=appearances`
 );
 if (myCameos.length) console.log(`  ${myCameos.length} cameos trouvés`);
 } catch(e) {}

 // --- Dérouler les generations et dédupliquer ---
 console.log('\n🔄 Extraction des vidéos...');
 const rawAll = [...myPosts, ...myLikes];
 const flatItems = flattenProfileItems(rawAll);

 const seen = new Set();
 const allItems = [];
 for (const item of flatItems) {
 if (item.id && seen.has(item.id)) continue;
 // Filtrer : vidéos uniquement
 const isVideo = item.type === 'video_gen' || item.url.includes('/videos/') || item.url.includes('.mp4');
 if (!isVideo) continue;
 if (item.id) seen.add(item.id);
 allItems.push(item);
 }

 console.log(`📊 Total unique: ${allItems.length} vidéos à télécharger`);
 console.log('='.repeat(50));

 // --- Construire le manifest et télécharger ---
 console.log('\n⬇️ Téléchargement en cours...');
 console.log('(Les fichiers arrivent dans ton dossier Downloads)');

 for (let i = 0; i < allItems.length; i++) {
 const meta = allItems[i];
 const url = meta.url;

 if (!url) {
 console.log(` ⏭️ [${i+1}/${allItems.length}] ${meta.id} - pas d'URL, skip`);
 meta.downloaded = false;
 manifest.push(meta);
 continue;
 }

 const type = (meta.task_type === 'image_gen' || url.match(/\.(png|jpg|jpeg|webp|gif)/i)) ? 'image' : 'video';
 const ext = getExt(url, type);
 const nameBase = meta.title
 ? sanitize(meta.title)
 : (meta.prompt ? sanitize(meta.prompt.substring(0, 60)) : meta.id);
 const filename = `sora_${String(i+1).padStart(4,'0')}_${nameBase}${ext}`;

 console.log(` ⬇️ [${i+1}/${allItems.length}] ${filename}`);
 meta.filename = filename;
 meta.downloaded = await addToZip(url, filename);
 manifest.push(meta);

 // Pause entre downloads pour pas surcharger
 if (i < allItems.length - 1) await sleep(800);
 }

 // --- Ajouter le manifest au ZIP ---
 console.log('\n📝 Ajout du manifest au ZIP...');
 const manifestData = new TextEncoder().encode(JSON.stringify(manifest, null, 2));
 zipFiles.push({ name: 'manifest.json', data: manifestData, crc: crc32(manifestData), size: manifestData.length });

 // --- Générer le ZIP (format STORE, pas de compression) ---
 console.log('\n📦 Génération du ZIP...');
 const enc = new TextEncoder();
 const blobParts = [];
 const centralParts = [];
 let offset = 0;

 for (const f of zipFiles) {
 const nameBytes = enc.encode(f.name);
 // Local file header (30 bytes + name)
 const lh = new ArrayBuffer(30);
 const lv = new DataView(lh);
 lv.setUint32(0, 0x04034b50, true);
 lv.setUint16(4, 20, true);
 lv.setUint16(8, 0, true); // STORE
 lv.setUint32(14, f.crc, true);
 lv.setUint32(18, f.size, true);
 lv.setUint32(22, f.size, true);
 lv.setUint16(26, nameBytes.length, true);
 blobParts.push(new Uint8Array(lh), nameBytes, f.data);

 // Central directory entry (46 bytes + name)
 const ch = new ArrayBuffer(46);
 const cv = new DataView(ch);
 cv.setUint32(0, 0x02014b50, true);
 cv.setUint16(4, 20, true);
 cv.setUint16(6, 20, true);
 cv.setUint16(10, 0, true); // STORE
 cv.setUint32(16, f.crc, true);
 cv.setUint32(20, f.size, true);
 cv.setUint32(24, f.size, true);
 cv.setUint16(28, nameBytes.length, true);
 cv.setUint32(42, offset, true);
 centralParts.push(new Uint8Array(ch), nameBytes);

 offset += 30 + nameBytes.length + f.size;
 }

 const centralSize = centralParts.reduce((s, p) => s + p.length, 0);
 const eocd = new ArrayBuffer(22);
 const ev = new DataView(eocd);
 ev.setUint32(0, 0x06054b50, true);
 ev.setUint16(8, zipFiles.length, true);
 ev.setUint16(10, zipFiles.length, true);
 ev.setUint32(12, centralSize, true);
 ev.setUint32(16, offset, true);

 const zipBlob = new Blob([...blobParts, ...centralParts, new Uint8Array(eocd)], { type: 'application/zip' });

 const zipName = `sora_backup_${new Date().toISOString().split('T')[0]}.zip`;
 const a = document.createElement('a');
 a.href = URL.createObjectURL(zipBlob);
 a.download = zipName;
 document.body.appendChild(a);
 a.click();
 document.body.removeChild(a);
 URL.revokeObjectURL(a.href);

 // --- Résumé ---
 const sizeMB = (zipBlob.size / 1024 / 1024).toFixed(1);
 console.log('\n' + '='.repeat(50));
 console.log('🎬 SORA BACKUP TERMINÉ');
 console.log(`  Vidéos dans le ZIP : ${totalDownloaded}`);
 console.log(`  Erreurs : ${totalErrors}`);
 console.log(` 📦 Fichier : ${zipName} (${sizeMB} MB)`);
 console.log(` 📝 manifest.json inclus dans le ZIP`);
 console.log('='.repeat(50));
})();

Quelques précisions

Si le token n’est pas récupéré automatiquement (ça peut arriver selon votre config), le script vous demandera de le coller manuellement. Pour le trouver, c’est simple : F12 > onglet Réseau > rafraîchissez la page > cliquez sur n’importe quelle requête vers /backend/... > copiez le header Authorization.

D’ailleurs, si la vidéo IA vous branche toujours, Higgsfield propose des séries entièrement générées par IA. C’est pas la même approche que Sora, mais c’est un signe que la vidéo IA ne meurt pas avec la fermeture d’un seul service.

Bon, bref, c’est la fin d’un truc sympa. Moi je préférais largement scroller sur Sora sur d'aller sur TikTok ou Instagram parce qu'au moins c'était drôle !

Merci à mes Patreons qui me permettent de prendre le temps de développer ce genre de petits outils pour vous. Sans eux, j’aurais jamais pu me poser une après-midi pour coder ça.

Source

Ce détecteur de drones à 15 balles fonctionne avec un simple micro et un ESP32

Un développeur a mis au point un système de détection de drones qui tient dans la main et coûte moins de 15 dollars.

Le projet Batear utilise un microcontrôleur ESP32-S3 et un micro pour repérer les drones par le son de leurs hélices. Le tout est open source et fonctionne sans connexion internet.

Écouter les hélices plutôt que chercher un radar

Le principe de Batear est assez simple en fait. Plutôt que d'utiliser un radar ou une caméra, le système analyse le son ambiant pour y détecter les fréquences caractéristiques des moteurs de drones.

L'algorithme de Goertzel surveille six fréquences précises entre 200 et 4000 Hz, qui correspondent aux harmoniques habituelles des rotors.

Quand l'énergie sonore sur ces fréquences dépasse un certain seuil par rapport au bruit ambiant, le système déclenche une alerte, et le tour est joué.

Tout le traitement se fait en local sur l'ESP32-S3, dans ses 512 Ko de mémoire vive. Pas de cloud, pas de serveur, pas de données qui transitent quelque part. Simple, efficace.

Moins de 15 dollars de matériel

Côté composants, il faut un ESP32-S3 et un micro MEMS ICS-43434 avec interface I2S. Et puis c''est tout. Le micro enregistre le son à 16 kHz, l'ESP32 analyse 512 échantillons toutes les 100 millisecondes, et le système consomme si peu d'énergie qu'il peut tourner sur batterie ou panneau solaire.

Le créateur, qui se fait appeler TN666, a publié l'ensemble du code sur GitHub sous le nom Batear. Il s'est d'ailleurs inspiré des dispositifs acoustiques d'avant l'invention du radar, comme les fameux cornets géants japonais des années 1930 qui servaient à repérer les avions à l'oreille.

Quelques limites quand même

Le projet en est encore à ses débuts. Batear a été testé avec des enregistrements audio de drones, mais pas encore en conditions réelles en extérieur. Le vent, le bruit de fond, la distance et le type de drone sont autant de variables qui peuvent fausser la détection.

Le créateur recommande d'ailleurs d'utiliser une protection en mousse sur le micro pour limiter les interférences du vent. Il envisage aussi d'intégrer des modèles TensorFlow Lite pour améliorer la fiabilité, et invite la communauté à contribuer au projet.

Pour 15 dollars et un peu de soudure, c'est le genre de projet bricolage qu'on a bien envie de tester. Alors bien sûr, ça ne remplacera pas un système anti-drone militaire, mais pour surveiller un jardin ou un terrain privé, ça peut rendre service.

Et puis l'idée de revenir aux bonnes vieilles méthodes acoustiques pour détecter ce qui vole au-dessus de nos têtes, il y a quand même un côté un peu rétro qui ne manque pas de charme, non ?

Source : Hackaday

Un développeur fait tourner du code Arduino sur une puce de 1980

Un développeur vietnamien a trouvé le moyen de faire fonctionner du code Arduino sur un microcontrôleur 8051, une architecture conçue par Intel en 1980.

L'astuce repose sur un émulateur RISC-V intégré directement dans la puce, et le tout est disponible en open source sur GitHub.

Une puce de 45 ans qui refuse de mourir

Le 8051, c'est un microcontrôleur 8 bits qu'Intel a conçu en 1980. L'anecdote veut que son architecture ait été dessinée en un week-end par l'ingénieur John Wharton.

Depuis, Intel a vendu plus de 100 millions d'unités rien que sur la première décennie, et des variantes compatibles sont encore produites et utilisées un peu partout, des souris d'ordinateur aux puces Bluetooth.

La version ciblée ici, c'est le STC8H8K64U, un dérivé moderne fabriqué par le chinois STC Micro. Il coûte moins d'un dollar et reste populaire en Asie, mais les outils de développement modernes ne le prennent pas en charge. D'où l'idée du projet.

Un émulateur RISC-V dans un 8051

Bùi Trịnh Thế Viên n'a pas cherché à porter le compilateur Arduino directement sur l'architecture 8051, ce qui aurait été un chantier monstre.

Il a opté pour une approche détournée : intégrer un émulateur RISC-V (appelé rv51, écrit en assembleur 8051 par un autre développeur, cyrozap) dans la puce STC8. Le code Arduino est compilé pour RISC-V, puis exécuté via cet émulateur.

Le projet est disponible sur GitHub sous le nom STC_Arduino_Core.

Des limites assumées

L'émulation a un coût. L'émulateur consomme 8 Ko de mémoire flash sur la puce, et la vitesse d'exécution est divisée par 100 à 1 000 par rapport au code natif. Pour le code qui demande du temps réel, comme la gestion des interruptions, il faut repasser sur de l'assembleur 8051 classique.

Et puis il faut le dire, des microcontrôleurs RISC-V natifs existent et coûtent à peine plus cher. Le projet reste donc un exercice technique et pédagogique, pas une solution de production.

C'est le genre de bidouille qui fait sourire. Faire tourner du code Arduino sur une architecture de 1980 via un émulateur RISC-V coincé dans 8 Ko, il fallait quand même y penser.

Bon par contre, on ne va pas se raconter d'histoires, en pratique ça n'a pas beaucoup d'intérêt face à un vrai microcontrôleur RISC-V à 2 euros. Mais l'exercice a le mérite de prouver que le 8051 a encore de la ressource, 45 ans après sa création.

Source : Hackaday

Strix - Fini la galère des caméras IP sans RTSP

Vous avez des vieilles caméras de surveillance chinoises qui prennent la poussière parce qu'il vous est impossible de trouver leur flux vidéo ? Y'a pas de RTSP, y'a pas de doc, y'a juste un pauvre port 80 ouvert et une app Android en Mandarin qui est périmée depuis 2021 ?

JE VIENS VOUS SAUVER LES ZAMIS ! Hé oui, grace à Strix qui est capable de tester 102 787 patterns d'URL en 30 secondes et qui vous sort miraculeusement le bon flux vidéo qui marche, avec la config Frigate prête à être collée.

En fait, le principe est simple. Vous lancez un conteneur Docker, vous entrez l'IP de votre caméra et l'outil bombarde en parallèle toutes les URL connues pour ce type de matos. RTSP sur le port 554, MJPEG sur le 8080, snapshots JPEG sur le 80... et 30 à 60 secondes plus tard, vous avez la liste des flux qui répondent avec résolution, FPS et codec H.264 ou H.265.

L'installation tient en une ligne et l'interface web tourne sur le port 4567. Vous entrez l'IP, le login si besoin, et éventuellement le modèle de la caméra IP pour affiner la recherche. Après, même sans modèle, Strix se débrouille avec les 206 patterns les plus courants (sur les 102 787 de la base complète) + la découverte ONVIF . Du coup ça trouve un flux sur à peu près n'importe quoi, du Dahua au Foscam en passant par les marques fantômes d'AliExpress.

Un autre truc vraiment sympa aussi , c'est la génération de config. Vous collez votre fichier frigate.yml existant, même avec 500 caméras dedans, et l'outil ajoute proprement la 501ème sans rien casser ! Il configure automatiquement le flux HD 1080p pour l'enregistrement et le flux 640x480 pour la détection d'objets, le tout passant par go2rtc . Résultat, la conso CPU de Frigate peut carrément passer de 30% à 8%.

Et surtout, l'histoire derrière est assez dingue. Le dev derrière ce projet avait des vieux NVR chinois de 2016 qu'il voulait connecter à Frigate. Après 2 ans à tester toutes les URL possibles... rien. Snif... Tous les ports fermés sauf le 80. À vrai dire, ces machins ne parlaient même pas un protocole connu. Alors a fini par faire tout ce que fait un vrai bidouilleur quand il est énervé : Sniffer le trafic de l'app Android avec Wireshark !

Et grâce à cela, il a découvert un truc baptisé BUBBLE, tellement obscur que ça n'existe nulle part sur Google ! Cela lui a permis de construire une base de 67 288 modèles issus de 3 636 marques, des Hikvision jusqu'aux trucs sans nom d'AliExpress.

Et quand y'a pas de RTSP du tout (ce qui arrive souvent avec le matos chinois pas cher), l'outil se rabat sur les snapshots JPEG et les convertit en vrai flux vidéo via FFmpeg. C'est pas aussi clean qu'un vrai stream H.264 (et ça saccade un peu à 10 FPS), mais c'est largement suffisant pour de la détection de personnes ou de bagnoles.

Après, sachez le, ça ne marche qu'avec les caméras présentes sur votre réseau local. Les caméras cloud (Blink, Ring, Xiaomi) ne sont pas supportées. Et aussi, comme on n'est jamais trop prudent d'ailleurs, si vous branchez ce genre de vieux matos chinois, mettez-les dans un VLAN isolé sans accès Internet parce que côté sécurité, c'est la fête du slip sur ce genre de matos : Backdoors, mots de passe en clair sur le port 80, appels serveurs en Chine... va savoir ce qu'elles font quand personne ne regarde.

Strix a même tapé dans l'oeil du développeur de Frigate lui-même, qui a invité l'auteur à soumettre une PR officielle pour l'intégrer dans la doc officielle. Hé ben quelle classe ! Ah et y'a aussi un add-on Home Assistant en beta si vous êtes branchés domotique (pas forcément stable, le soft sous Docker reste plus fiable). Strix est écrit en Go, sous licence MIT, y'a une image Docker de 80-90 Mo sur Alpine Linux, avec FFmpeg et FFprobe embarqués, et ça tourne comme un charme sur AMD64 comme sur ARM64 (votre Raspberry Pi 4 suffit).

Bref, allez tester ça, car y'a clairement de quoi sauver pas mal de matos de la poubelle !

Dorso - L'app Mac qui floute votre écran quand vous faites le dos rond

En ce moment, j'ai une sciatique qui me rend dingue ! Du coup, entre deux grimaces sur ma chaise de bureau ergonomique, je me suis retrouvé à chercher des trucs pour améliorer ma posture devant l'écran... et je suis tombé sur Dorso, une petite app macOS qui surveille votre posture en temps réel et qui floute progressivement l'écran quand vous commencez à vous avachir.

Ainsi, votre Mac vous punit si vous vous tenez mal ! Vous lancez l'app, vous vous asseyez bien droit devant votre clavier, vous cliquez sur le bouton de calibration (aïe, mes vertèbres), et ensuite Dorso surveille votre position via la webcam de votre MacBook ou iMac grâce au framework Vision d'Apple.

Dès que votre tête commence à piquer du nez, l'écran se floute. Plus vous "slouchez", plus c'est flou. Du coup, soit vous vous redressez, soit vous bossez dans le brouillard comme un moine copiste myope. En tout cas, c'est redoutablement efficace pour corriger sa posture.

Sauf que la webcam, c'est pas le seul mode de détection. Si vous avez des AirPods Pro, Max ou 3e génération, Dorso peut utiliser les capteurs de mouvement de vos écouteurs pour détecter l'inclinaison de votre tête. Pas besoin de caméra, pas besoin de lumière... vos AirPods deviennent votre "coach posture" et quand vous les retirez des oreilles, l'app se met en pause toute seule. Par contre, attention, le mode AirPods nécessite macOS 14 minimum et l'autorisation "Motion & Fitness Activity" dans les réglages Confidentialité.

Côté vie privée, tout se passe en local sur votre machine. Aucune image n'est enregistrée, aucune donnée ne quitte votre Mac. Le flux vidéo de la webcam est traité en temps réel puis immédiatement supprimé et pour le flou, l'app utilise une API privée de CoreGraphics pour agir au niveau système, ce qui permet de flouter tous vos écrans d'un coup si vous avez un setup multi-moniteurs.

L'installation, c'est un brew install --cask dorso et hop, c'est réglé. Au premier lancement, il faudra autoriser l'accès caméra (mode webcam) ou Motion & Fitness (mode AirPods) dans les Réglages Système.

L'app se loge ensuite dans la barre de menu à côté de l'icône Bluetooth et vous pouvez régler la sensibilité sur 5 niveaux via un petit panneau de préférences. Y'a même une "dead zone" configurable pour que ça ne se déclenche pas au moindre mouvement de tête (genre quand vous regardez votre téléphone 2 secondes). Sans cette dead zone, la moindre gorgée de café vous vaut un écran tout flou, donc c'est indispensable !!

L'app s'appelait "Posturr" à l'origine mais une app iOS portait déjà ce nom et comme c'est complétement FDP de voler le nom des autres, il a trouvé un autre nom en lançant 30 agents Claude en parallèle pendant une heure... mais pour rien puisque c'est finalement lui qui a trouvé "Dorso" (Claude avait suggéré "Posturn", bof quoi). Comme quoi, même avec 30 IA qui bossent pour vous, le cerveau humain a encore son mot à dire !!

Perso, vu l'état de mon dos en ce moment, mon bureau debout ne suffit plus. Si vous aussi vous passez vos journées courbé devant votre écran comme Gollum devant son précieux, Dorso pourrait bien vous éviter de finir chez le kiné à 60 balles la séance. L'app tourne sous macOS 13+ (Intel et Apple Silicon), c'est sous licence MIT, et c'est gratuit !

Bref, y'a plus qu'à se redresser. Enfin... à essayer.

Il fabrique un robot qui joue tout seul au jeu du dinosaure de Chrome

Un bricoleur a assemblé un petit montage à base d'ATtiny85 qui joue automatiquement au jeu du dinosaure caché dans Google Chrome. Le tout pour moins de 10 euros de composants et avec un microcontrôleur pas plus grand qu'un pouce.

Deux capteurs et un microcontrôleur, c'est tout

Le projet est signé Albert David, et le principe est assez malin. Une carte Digispark ATtiny85, qui coûte entre 2 et 5 euros, est branchée en USB sur un PC et se fait passer pour un clavier grâce au protocole HID. Pour le reste, vous avez deux modules LM393 photorésistants qui sont collés directement sur l'écran, le premier au niveau du sol pour voir les cactus, et le second plus haut pour voir les oiseaux.

C'est au passage de chaque obstacle que la luminosité change, et donc que le capteur s'active pour envoyer la touche espace ou la flèche du bas pour sauter et baisser la tête, le tout à travers le microcontrôleur, et seulement 8 ko de mémoire flash.

Un système qui s'adapte à la vitesse du jeu

Encore plus fort, l'ensemble intègre un système de timing interactif, avec un firmware qui mesure la largeur des obstacles, et surtout conserve un historique de cinq mesures, pour estimer au mieux la vitesse du jeu.

Le délai entre la détection et l'appui sur la touche est recalculé en permanence, avec des bornes minimales et maximales pour éviter les ratés. Il y a aussi un délai de 400 millisecondes entre chaque action pour ne pas mitrailler les touches.

Côté calibration, il faut quand même un peu de patience. Les deux capteurs doivent être positionnés à 30-40 mm devant le dinosaure, et les potentiomètres des modules LM393 ajustés pour que le fond blanc de l'écran ne déclenche rien mais que les obstacles foncés soient bien détectés.

Albert David recommande de tester sur une vingtaine d'obstacles avant de considérer le réglage comme bon. Et si le jeu passe en mode nuit, une commande JavaScript dans la console du navigateur empêche l'inversion de contraste qui fausserait les capteurs.

Bref, vous l'avez compris, c'est le genre de projet qui ne sert strictement à rien, et c'est pour ça qu'on aime bien. Avec moins de 10 euros de composants, un bout de code en C et deux capteurs de luminosité scotchés sur un écran, on obtient un système qui joue au jeu du dinosaure mieux que la plupart d'entre nous.

Le code est disponible sur GitHub pour ceux qui voudraient essayer, et vous avez tous les détails ici . Tout ceci rappelle quand même que ce petit jeu caché de Chrome, que Google avait glissé là pour meubler les coupures internet, continue de mobiliser les bidouilleurs du dimanche.

Sources : Hackaday , Prolinix

WalkingPad - Bosser en marchant, les trucs à savoir sur le tapis de marche des geeks

En 2024, je me suis acheté un WalkingPad A1 Pro (lien affilié) et j'ai complétement oublié de vous en faire un petit retour ! Ce mot ne vous dit peut-être rien, mais c'est ce petit tapis de marche pliable qui se glisse sous votre bureau debout. 143 cm de long, 55 cm de large, 6 km/h max + une télécommande et une appli pour piloter le tout. L'engin pèse dans les 28 kg et se plie en deux pour se planquer sous mon bureau. Et comme maintenant j'ai un peu de recul, je peux vous dire qu'il y a quelques trucs à savoir avant de craquer.

Déjà, si vous faites plus de 100 kg (comme moi, oui je sais, beau bébé), attendez-vous à des petits à-coups au démarrage car c'est conçu pour supporter max 105 kg (quand je l'ai acheté sur la fiche produit c'était écrit 136 kg donc j'sais pas trop...).

En fait, le moteur et la bande ont besoin de chauffer 2-3 minutes avant de tourner rond. Rien de dramatique, mais les premiers pas c'est saccadé. Ensuite, une fois le rythme chopé, ça roule !

Après le piège classique, c'est de vouloir aller trop vite. Dès que vous dépassez 3 km/h, votre clavier mécanique commence à danser sur le plateau du bureau et là... bonne chance pour viser un pixel avec votre souris. Plus vous allez lentement, plus vous êtes précis avec la souris. Perso, je reste à 2-3 km/h max quand je bosse, parce que au-delà c'est ingérable. On n'est pas là pour un marathon !

Au début, c'est perturbant, j'avoue. Genre votre cerveau sait plus s'il doit lire l'écran ou gérer vos jambes. Ça dure quelques jours, pas plus et ensuite, vous n'y pensez même plus, ça devient naturel et du coup vous marchez sans y penser.

Et le truc cool, c'est que la procrastination baisse car quand vous êtes debout en mouvement, vous avez carrément moins envie de scroller Reddit pendant 45 minutes

Après côté entretien, y'a un truc que personne vous dit : la bande, ça se lubrifie !! Et ça part VITE donc achetez un spray au silicone lubrifiant (genre WD-40 Specialist Silicone, 5-6 EUR en magasin de bricolage) et remettez-en régulièrement, sinon ça couine comme un politique qu'on prend la main dans la caisse d'argent public. Et pensez à en remettre toutes les 2-3 semaines si vous marchez tous les jours.

Après, OUI J'AVOUE, je ne l'utilise pas tout le temps. Y'a des jours où j'ai besoin d'être posé OKLM dans mon siège ergonomique pour réfléchir, et d'autres où hop hop hop, je marche pendant 2-3h en enchaînant les emails et ma veille techno sur mon flux RSS.

En tout cas, si vous avez déjà un setup télétravail ergonomique , c'est un super complément. Même si c'est pas recommandé dans la documentation, pieds nus ça passe nickel, sauf si le sol vibre chez vous parce que vous avez acheté le parquet le moins cher de Leroy Merlin, mais bon, ça c'est un autre problème.

L'important en fait c'est de commencer votre séance à basse vitesse, genre 1,5-2 km/h. Et sachez que même à ce rythme là, vous brûlez entre 100 et 200 calories par heure et votre dos vous remercie. Combinez ça avec une bonne souris ergonomique et vous avez un poste de travail qui vous veut du bien.

Bref, ce WalkingPad fait très le taf (lien affilié). C'est pas parfait certes, mais ça fait bouger sans y penser !

Cloudflare /crawl - Aspirez un site entier en un seul appel API

Crawler un site entier, ça devrait pas être aussi compliqué. Et pourtant, entre les scripts maison qui cassent tous les 2 jours et les headless browsers qui bouffent de la RAM comme pas permis, c'est assez la galère ! Du coup, Cloudflare, dans sa grande bonté (lol) vient de sortir un endpoint /crawl (en open beta) dans la section Browser Rendering qui simplifie tout ça... vous balancez une URL dessus et hop, ça ASPIRE tout le site (oui oui).

En gros, vous envoyez une requête POST avec l'URL de départ, et le service se charge de découvrir les pages (via le sitemap, les liens internes, ou les deux), de les générer dans un navigateur headless, et de vous renvoyer le contenu en HTML, Markdown ou même en JSON structuré grâce à Workers AI. Le tout de manière asynchron ! Vous, vous récupérez juste un job ID et vous revenez plus tard chercher les résultats quand c'est prêt.

Créer votre token API

Avant toute chose, il vous faut un token API Cloudflare avec la permission "Browser Rendering - Edit". Rendez-vous dans votre dashboard Cloudflare, section API Tokens, et créez-en un nouveau. Notez aussi votre Account ID (visible dans l'URL du dashboard ou dans la section Overview de n'importe quel domaine).

Lancer un crawl

Là, ensuite c'est hyper simple. Un seul appel curl suffit :

curl -X POST "https://api.cloudflare.com/client/v4/accounts/VOTRE_ACCOUNT_ID/browser-rendering/crawl" \
 -H "Authorization: Bearer VOTRE_TOKEN" \
 -H "Content-Type: application/json" \
 -d '{"url": "https://example.com"}'

Et là, vous récupérez un job ID en retour (genre c7f8s2d9-a8e7-4b6e-...). Par défaut, le crawler va explorer 10 pages max avec une profondeur quasi illimitée. Mais bon, 10 pages c'est vite limité, du coup vous pouvez ajuster tout ça comme ceci :

curl -X POST "https://api.cloudflare.com/client/v4/accounts/VOTRE_ACCOUNT_ID/browser-rendering/crawl" \
 -H "Authorization: Bearer VOTRE_TOKEN" \
 -H "Content-Type: application/json" \
 -d '{
 "url": "https://example.com/docs",
 "limit": 50,
 "depth": 3,
 "formats": ["markdown"],
 "render": false,
 "options": {
 "includePatterns": ["https://example.com/docs/**"],
 "excludePatterns": ["**/changelog/**"]
 }
 }'

Le paramètre render: false permet de récupérer le HTML brut sans lancer de navigateur headless, c'est carrément plus rapide pour les sites statiques. Sachez quand même que pendant la beta, ce mode n'est pas facturé ! Youpi !

Récupérer les résultats

Une fois le crawl lancé, vous interrogez le job avec un GET :

curl "https://api.cloudflare.com/client/v4/accounts/VOTRE_ACCOUNT_ID/browser-rendering/crawl/VOTRE_JOB_ID" \
 -H "Authorization: Bearer VOTRE_TOKEN"

Vous obtenez alors le statut (running, completed, errored...) et la liste des pages crawlées avec leur contenu dans le format demandé. Si le résultat dépasse 10 Mo, un curseur de pagination est inclus pour récupérer la suite.

Les options qui tuent

Y'a quelques paramètres bien pensés pour les cas plus avancés :

  • modifiedSince et maxAge pour du crawling incrémental (ne re-crawler que les pages modifiées récemment)
  • source: "sitemaps" pour ne suivre que le sitemap au lieu de parser tous les liens
  • jsonOptions avec un prompt Workers AI pour extraire des données structurées automatiquement (genre récupérer le nom, le prix et le stock de 500 fiches produit d'un e-commerce en une seule passe)
  • rejectResourceTypes pour bloquer images, fonts et CSS et accélérer le crawl
  • authenticate pour les sites protégés par une auth HTTP basique

Attention quand même, y'a quelques subtilités à savoir. Un job peut tourner 7 jours max et les résultats sont conservés 14 jours seulement, du coup pensez à les récupérer vite. Le crawler respecte le robots.txt (y compris le crawl-delay), et si un site vous bloque, les URLs apparaissent comme "disallowed" dans les résultats. Sauf que ça ne vous dit pas pourquoi, faudra aller checker le robots.txt vous-même.

Voilà, cette "merveille" pour les scrappeurs fous est dispo sur les plans Free et Paid de Workers , et si vous voulez aller plus loin, Cloudflare propose aussi des endpoints pour les screenshots, les PDF et le scraping ciblé .

Voilà, un petit crawler inclus dans le plan Free de Workers, qui respecte le robots.txt et qui sort du Markdown ou du JSON structuré... je vais surveiller ça de près !

WebTerm - Apprendre le terminal Linux sans rien installer

Le terminal Linux / MacOS, ça fait encore flipper pas mal de monde et c'est exactement pour cette raison que des gens ont créé WebTerm , un petit site web qui simule un terminal directement dans le navigateur pour vous apprendre les commandes de base... sans risquer de claquer un rm -rf votre disque dur !

En gros, vous ouvrez le site dans Chrome ou Firefox, et vous avez un faux terminal devant vous avec des exercices progressifs. Ça part des trucs vraiment basiques genre pwd, ls, cd (oui, le B.A.-BA quoi) et ça monte jusqu'aux commandes plus costaudes comme grep, find, chmod ou carrément des tutos Git avec branches et commits. Y'a 8 modes d'apprentissage au total et une trentaine d'exercices, du débutant complet au "je veux maîtriser le versioning". En fait c'est plutôt bien découpé et chaque mode rajoute une couche de difficulté.

Le truc sympa c'est que tout se passe dans votre navigateur comme ça pas besoin d'installer Ubuntu, pas besoin de VirtualBox, pas besoin de WSL... vous ouvrez la page et vous tapez vos commandes dans un prompt bash comme un vrai sysadmin qui pue de la gueule (un classique !). Perso, pour quelqu'un qui n'a jamais touché à la ligne de commande, c'est quand même VACHEMENT moins flippant qu'un vrai terminal où une mauvaise manip peut vous foutre dans la mierda.

D'ailleurs si vous maîtrisez déjà un peu le sujet, y'a aussi un mode Free Play qui vous lâche dans la nature sans consignes. Vous tapez ce que vous voulez, vous expérimentez... un bac à sable quoi. Et comme sur un vrai shell Bash ou Zsh, vous avez la complétion par Tab et l'historique des commandes avec les flèches haut/bas.

Bon, c'est pas non plus un émulateur complet hein, donc faut pas s'attendre à pouvoir installer des paquets apt ou lancer des scripts bash complexes. Sauf si vous avez une vraie VM sous la main, mais là c'est plus le même délire. Par exemple, les pipes genre | entre commandes, ça passe pas non plus, et ça ne marche pas sur smartphone.

C'est desktop only... et dans le terminal, tout se fait au clavier, donc pas de souris. Et pour ceux qui se demandent, le site est dispo en anglais et en japonais (le projet vient d'une boîte japonaise qui s'appelle init Inc.), mais les commandes Linux c'est universel donc ça ne change rien sur l'apprentissage. Après si vous cherchez des tutos en français, là faudra aller voir ailleurs.

Et si vous voulez aller plus loin après avoir joué avec WebTerm, je vous recommande de jeter un oeil à mon article sur les raccourcis clavier Bash qui va vous faire gagner un temps de fou !

Voilà pour 15 minutes de pratique par jour c'est plutôt bien foutu et vous pourrez gagner en autonomie dans ce fichu terminal qui vous effraye depuis tant d'années.

iFetch - L'outil pour quitter iCloud sans rien perdre

iCloud, c'est sympa pour stocker vos photos et vos documents... jusqu'au jour où comme moi, vous décidez de vous barrer. Parce que récupérer vos 200 Go de fichiers en masse depuis le cloud d'Apple (plusieurs To pour moi), c'est pas vraiment ce qu'il y a de plus simple (genre, y'a pas de bouton "tout télécharger"). J'ai bien essayé de demander un export de mes datas à Apple et pour la partie iCloud Drive, j'ai juste eu des espèces de CSV bizarres mais pas mes documents.

Heureusement, pour s'extraire des griffes de l'entreprise de Cupertino, y'a un outil Python parfait pour ça.

iFetch , c'est un utilitaire en ligne de commande qui va se connecter à votre compte iCloud Drive et tout rapatrier en local. Le truc gère la 2FA (parce que bon, en 2026, si vous n'avez pas de 2FA activée quand c'est possible, vous méritez d'être envahi de puces de lit), les téléchargements parallèles avec 4 workers par défaut, et surtout les updates différentiels.

En gros, seuls les morceaux de fichiers qui ont changé sont re-téléchargés, du coup, sur un dossier de 50 Go déjà synchro, ça passe en quelques secondes au lieu de tout re-pomper. Et si ça plante au milieu, pas de panique, l'outil reprend là où il s'est arrêté grâce à un système de checkpointing.

Y'a aussi un truc malin, c'est le système de profils. Vous créez un fichier JSON avec des règles d'inclusion et d'exclusion, genre "tous les PDF du dossier Documents sauf ceux du dossier Private" et hop, en une commande et c'est plié.

Le support des dossiers partagés est aussi de la partie (le fameux --list-shared), y'a un système de plugins pour ceux qui veulent étendre le bazar, et même un historique de versions avec rollback automatique. Pas mal pour un outil libre !

Pour l'installer, après c'est du classique. Virtualenv Python, pip install pyicloud tqdm requests keyring, et vous stockez vos identifiants via icloud --[email protected] qui balance tout ça dans le trousseau système (Keychain sur macOS, libsecret sur Linux). D'ailleurs, si vous êtes du genre à sauvegarder vos dotfiles dans iCloud , c'est l'outil parfait pour faire le chemin inverse.

Côté utilisation, c'est super sobre :

python ifetch/cli.py Documents/Photos ~/Downloads/icloud-photos

...et ça mouline !! Vous pouvez même monter jusqu'à 8 workers pour aller plus vite (--max-workers=8), configurer les retries (--max-retries=5) ou juste lister le contenu sans rien télécharger avec --list. Attention, si vous avez des noms de fichiers avec des caractères spéciaux (genre des accents ou des espaces... merci macOS, groumpf), vérifiez bien que tout est passé après le transfert.

Alors oui, c'est CLI only, donc oubliez l'interface graphique. La doc mériterait un petit coup de polish et surtout, si votre session 2FA expire en plein transfert... faut relancer l'auth. Ça casse pas le téléchargement en cours, mais bon, c'est un peu "chiant".

Bon au final, pour un projet open source sous licence MIT, c'est plutôt du solide. Et si vous voulez chiffrer vos sauvegardes une fois récupérées en local, y'a des solutions pour ça aussi.

Bref, c'est simple, ça fait le job et c'est gratuit. Que demande le peuple à part du matos Apple moins cher, lool ?

Merci à Lorenper pour le lien !

Shells Unix - 5 redirections que vous copiez sans comprendre

2>&1, >, >>, 2>/dev/null... Si ces symboles dans votre terminal Linux ou macOS vous font autant flipper qu'un regex, respirez un grand coup ! Quand vous aurez lu cet article, vous verrez qu'en fait c'est super simple à comprendre, et en 5 minutes vous saurez enfin ce que vous copiez-collez depuis des années depuis StackOverflow.

En fait, dans les shells Unix (bash, zsh, etc.), y'a 3 canaux de base : stdin (entrée, numéro 0), stdout (sortie normale, numéro 1) et stderr (les erreurs, numéro 2). Tout le reste, de > à 2>/dev/null, découle de ces 3 numéros.

> - Écrire dans un fichier (et tout écraser)

echo "Salut" > fichier.txt

Ça redirige stdout vers fichier.txt. Si le fichier existe déjà... c'est mort, il est écrasé sans sommation. Du coup, faites gaffe avec vos logs, une commande mal placée et ce sont des heures de données qui disparaissent.

D'ailleurs, si vous êtes du genre parano (et oui, vous avez raison !), set -o noclobber dans votre .bashrc empêchera > d'écraser un fichier existant lors d'une commande tapée à la main. Pour y arriver, il faudra utiliser >| pour forcer.

>> - Ajouter à la suite

echo "Ligne 2" >> fichier.txt

Même principe que >, sauf que ça ajoute à la fin au lieu d'écraser. C'est ce que vous voulez 99% du temps pour des logs (sauf si vous voulez repartir de zéro, là > fait le job). Une lettre de différence entre "tout va bien" et "où sont passés mes logs, boudiouuu ???".

2> - Rediriger les erreurs

commande_foireuse 2> erreurs.log

Le 2 c'est stderr, en gros (y'a pas d'espace entre le 2 et le >, sinon bash croit que 2 est un argument). Tout ce qui sort en erreur finit dans erreurs.log au lieu de polluer votre terminal. Perso, je trouve ça super pratique pour garder une trace propre quand vous lancez des scripts via crontab -e.

Et 2>> existe aussi, pour cumuler les erreurs au fil du temps au lieu d'écraser le fichier à chaque exécution.

2>&1 - Fusionner erreurs et sortie normale

commande > output.log 2>&1

Le fameux ! Le &1 dit à bash "le 1 c'est un file descriptor, pas un fichier qui s'appelle littéralement 1". Du coup stderr (2) est redirigé vers le même endroit que stdout (1), ou plutôt vers là où stdout pointe au moment où bash évalue la ligne. Ça va, vous suivez toujours ? ^^

Attention, l'ordre compte ! Bash lit les redirections de gauche à droite. > output.log 2>&1, stdout pointe vers le fichier, puis stderr suit... tout va dans le fichier. 2>&1 > output.log, stderr copie stdout qui pointe ENCORE vers le terminal, puis stdout est redirigé vers le fichier. Résultat, les erreurs restent dans votre terminal. Le piège classique.

Et &> fait la même chose en plus court :

commande &> output.log

&> est super pratique, mais spécifique à bash / zsh donc pour la portabilité, préférez quand même > fichier 2>&1.

2>/dev/null - Le trou noir

find / -name "*.conf" 2>/dev/null

/dev/null, c'est le trou noir d'Unix. Tout ce que vous envoyez là-dedans disparaît. Super pratique avec find qui vous crache 200 "Permission denied" pour un seul résultat utile.

Et si vous voulez TOUT faire disparaître (stdout + stderr) ? Un petit &>/dev/null et c'est réglé. Pratique dans vos scripts /etc/cron.d/ quand vous voulez zéro bruit (bon, j'exagère un chouïa, je sais...).

Si vous aimez les raccourcis bash , j'ai aussi ce qu'il faut.

Bref, voilà ce sont juste 5 opérateurs à retenir, et avec ça vous couvrez à peu près tout. Donc la prochaine fois que vous copierez un 2>&1, au moins vous saurez pourquoi.

Source d'inspiration

sudo-rs - 40 ans de silence cassés par des astérisques

Si vous utilisez Ubuntu 26.04, vous avez peut-être remarqué un truc bizarre dernièrement en tapant votre mot de passe sudo... Ouiiiiii, y'a des petites étoiles qui apparaissent !! Pas de panique, c'est "normal". Enfin, c'est nouveau...

En effet, sudo-rs, la réécriture en Rust de la bonne vieille commande sudo, a décidé d'activer pwfeedback par défaut. En gros, quand vous faites un sudo apt install bidule, au lieu du trou noir habituel, vous voyez maintenant des ***** défiler pendant la saisie du mot de passe. C'est un changement qui casse une convention vieille de 40 ans... et ça, forcément, ça fait du bruit !

Pour rappel, Ubuntu a basculé sur sudo-rs (le remplaçant en Rust du bon vieux sudo en C) depuis la version 25.10. Ça fait partie du même mouvement de réécriture des outils système en Rust, comme les coreutils dont je vous avais parlé. Et la 26.04 vient de "cherry-picker" comme on dit, un patch upstream qui active le feedback visuel par défaut.

Un bug report sur Launchpad ( #2142721 ) est bien sûr arrivé direct, en mode vénère genre "*ÇA FAIT DES DÉCENNIES qu'on n'affiche pas la longueur du mot de passe pour empêcher le shoulder surfing ! C'est quoi ce bordel !!?? *"

Et la réponse des devs : Won't Fix. Circulez les relous !

En fait, leur argument c'est que le bénéfice sécurité est "infinitésimal". Parce que bon, votre mot de passe sudo c'est le même que celui de votre session (celui que vous tapez à l'écran de login, devant tout le monde). Et le bruit des touches trahit déjà la longueur de toute façon. Du coup, ils ont préféré régler le problème UX qui paume les débutants depuis le début des années 80.

D'ailleurs, en 2013 je vous expliquais comment activer ces étoiles manuellement avec sudo visudo (ça date de fou !!) et maintenant c'est l'inverse, faut expliquer comment les virer ! Linux Mint avait d'ailleurs déjà sauté le pas de son côté depuis un moment.

Perso, le truc qui me gonfle c'est pour les tutos vidéo. Quand vous faites un screencast, les astérisques révèlent la longueur de votre mot de passe à tous vos spectateurs. Du coup faut aller reparamétrer chaque machine avant de filmer ou faire du masquage en post prod. C'est pas la fin du monde, mais bon, la flemme...

Alors pour désactiver ces jolies zétoiles :

sudo visudo

Et ajoutez cette ligne à la fin de /etc/sudoers :

Defaults !pwfeedback

Sauvegardez (Ctrl+X sous nano), et c'est réglé. Attention, ne touchez à rien d'autre dans ce fichier, une erreur de typo et sudo ne marchera plus. Grâce à cette manip, ce sera retour au trou noir ! Youpi !

Source

Claude Code - Pilotez votre terminal depuis votre canapé

Claude Code tourne en local et c'est son gros avantage car ça permet par exemple d'agir sur votre machine, de lancer des scripts...etc. Mais c'est aussi sa grosse limite car à cause de ça, vous êtes cloué devant votre terminal. J'étais en quête depuis un moment d'une solution et je vous avais déjà parlé de Vibe Companion y'a pas longtemps mais tous ces outils vont disparaitre puisque Anthropic vient de sortir Remote Control, une feature qui transforme claude.ai ou l'app mobile en télécommande pour votre session locale. Comme ça, vos fichiers restent chez vous et seule l'interface voyage.

Votre ordi fait tourner Claude Code normalement, et vous, vous pouvez continuer à lui parler depuis votre iPhone, votre Android, votre iPad ou n'importe quel navigateur Chrome, Firefox, Safari... Pas de serveur exposé, pas de port ouvert, que du HTTPS sortant. C'est plutôt bien foutu vous allez voir !

Ce qu'il vous faut

Bon déjà, un abonnement Pro (Édit : ? on me dit que c'est pas encore actif pour les pro ?) ou Max (pas le choix, les clés API ne marchent pas et les plans Team/Enterprise sont exclus pour le moment). Ensuite, vérifiez que Claude Code est installé et que vous êtes connecté via /login. Acceptez ensuite le "workspace trust" dans votre projet et hop, c'est tout côté prérequis.

Lancer une session

Deux options s'offrent à vous ensuite... Soit vous démarrez une nouvelle session dédiée :

claude remote-control

Soit vous êtes déjà en train de bosser dans Claude Code et vous tapez /rc (alias de /remote-control). Avec claude remote-control, seule l'URL apparaît... donc appuyez sur espace pour afficher le joli QR code.

3 flags utiles (uniquement avec claude remote-control, pas /rc) : --verbose pour voir ce qui transite, --sandbox pour forcer le mode bac à sable (désactivé par défaut) et --no-sandbox pour le couper si vous l'avez activé dans votre config.

Se connecter depuis un autre appareil

Ensuite, la méthode la plus rapide c'est de scanner le QR code avec votre téléphone. Sinon, copiez l'URL affichée et collez-la dans n'importe quel navigateur. Dernière option, allez sur claude.ai/code et votre session apparaît dans la liste (les sessions actives ont un petit point vert).

Une fois connecté, vous récupérez votre conversation en cours, vos fichiers, votre contexte... tout. Vous pouvez envoyer des messages, voir les résultats, approuver les modifications de fichiers. Bref, comme si vous étiez devant votre terminal, sauf que vous êtes dans votre canapé, votre lit ou en train de pousser le caddie chez Auchan !

Activer par défaut

Maintenant, si vous voulez que CHAQUE session Claude Code soit automatiquement accessible à distance, tapez /config dans une session Claude Code, puis activez l'option "Enable Remote Control for all sessions". Et voilà, plus besoin d'y réfléchir ! Chaque claude lancé dans un terminal sera pilotable depuis votre navigateur ou l'app mobile.

Vos sessions prennent le nom de votre dernier message (ou "Remote Control session" par défaut), donc utilisez /rename mon-projet-cool pour les retrouver facilement dans la liste sur claude.ai/code.

Sinon, dans Claude Code avec /mobile vous pouvez aussi afficher directement le QR code pour télécharger l'app Claude sur iOS ou Android.

Les limites à connaître

Bon, après c'est pas non plus parfait car déjà, c'est cappé à UNE SEULE session à distance par instance de Claude Code (si vous en lancez une deuxième, la première se déconnecte). Par contre, plusieurs instances dans des terminaux différents peuvent chacune avoir leur session remote. Le terminal doit également rester ouvert (si vous le fermez, c'est fini). Mais bonne nouvelle quand même, si le laptop passe en veille ou que le réseau saute, ça se reconnectera tout seul au réveil. Le piège, c'est si la machine reste sans réseau plus de 10 minutes... là, la session expire et il faudra relancer claude remote-control.

Soyez rassurés quand même côté sécurité c'est propre (uniquement du HTTPS sortant sur le port 443, zéro port entrant et des identifiants éphémères), mais gardez en tête que Claude Code a accès à votre terminal donc sauf si vous activez --sandbox, il peut de ce fait exécuter n'importe quelle commande... donc les mêmes précautions qu'en local s'appliquent !

Du coup si vous en avez marre de rester scotché devant votre terminal, maintenant vous savez quoi faire.

Merci à Lorenper !

❌