BADGER
WORKS

BADGER WORKS

GithubLinkedinMon parcoursAujourd'huiProjets personnelsJeux / homebrews

Cette page est à mi-chemin entre portfolio et CV. Je l’utilise pour montrer mes projets (quand bien même la plupart ne seraient plus maintenus), parlé de mon parcours et des choses que je voudrais explorer. Depuis plusieurs années je fais très majoritairement des projets web, surtout avec React et/ou Rails que je considère comme ma stack de référence.

Par ailleurs, j’ai aussi pas mal d’expérience avec Node et C et j’ai eu l’occasion d’utiliser pas mal de services AWS (Lamba, SQS, S3, SES, RDS, Route53, Cloudfront, pour ne citer que les plus courants) ainsi que la plupart des services utilisés dans une stack classique comme Nginx, PostgreSQL, Redis ou ElasticSearch.

Ces derniers mois je m’intéresse beaucoup à l’embarqué et à la programmation de vieilles consoles, particulièrement l’Atari 2600 qui me fascine pas mal. J’essaye aussi de faire des petits projets embarqués même si je n’ai rien de particulièrement excitant à montrer pour l’instant. Je suis aussi désespérément à la recherche d’un projet à faire avec Elixir.

À coté de ça je participe à l’organisation d’évènements, à la production de contenu et aux animations de l’association Les bulles de poils. Je suis aussi consultant bénévole sur un projet d’intégration de technologies embarquées sur des cosplays et fursuits.

Je suis actuellement en poste et je ne suis pas à l’écoute du marché. Néanmoins, si vous correspondez à un de ces critères, je suis ouvert à la discussion :

  • vous êtes une entreprise ou une association qui fait des choses un peu hors-norme ;
  • ou vous cherchez des professeurs ou des intervenants à temps partiel  ;
  • ou vous proposez une rémunération outrancière, voire scandaleuse ;
  • et vous ne faites rien qui touche aux blockchains / NFTs, qui sont des domaines qui ne m’intéressent pas du tout.

Mon parcours

J’ai commencé à m’intéresser à la création et à la programmation à 12 ans en créant des niveaux pour Duke Nukem 3D, j’ai ensuite fait du QBasic (et fait tester absolument toutes mes créations à mes frères) avant de passer des heures sur ma Ti89.

Après le lycée je suis entré à Epitech et j’y suis resté pendant cinq ans, c’est une formation assez intensive avec beaucoup de défauts, mais pour un nerd comme moi c’étais assez idéal j’en garde un très bon souvenir. C’est aussi à cette période que je me suis formé à Ruby on Rails en autodidacte, en commencant par la version 1.2.

J’ai eu l’occasion de faire quelques stages pendant ma formation où j’ai eu l’occasion de faire toutes les erreurs qu’un stagiaire peut faire, entre l’excés de confiance, la sur-optimisation (ie, le meilleur moyen d’immobiliser un projet pendant des jours) et les interventions ratées en prod. Malgré tout, celà m’a donné une bien meilleur idée de comment mener des projets.

Après les études je suis parti travailler pendant 4 ans avec la merveilleuse équipe de AF83, une agence web très pointu techniquement à l’époque. J’ai commencé par y faire de l’Erlang pendant un an et demi pour un projet de recherche (qui a fini par donner naissance à la startup Stormz), participé en tant que prestataire à la campagne présidentielle de Francois Hollande, essayé d’optimiser le traitement de données chez RueDuCommerce, géré la communication de MonAlbumPhoto avec les imprimeurs et un peu d’IoT pour EDF.

En 2014, j’ai souhaité me lancer dans l’aventure d’une startup avec Weroom, mes collègues étaient super mais ça n’a pas bien marché, la boîte s’est séparée de son équipe technique alors je suis parti rejoindre un ami pour travailler pendant 5 mois à Pékin. À mon retour j’ai rejoint Precogs qui est une startup spécialisée dans la vente automatisée de composants électroniques pour les industriels, j’y suis resté un peu moins de 2 ans avant de laissé la main à un autre CTO.

Ces trois années précédentes étaient intéressantes mais assez décevantes professionnellement, j’ai donc décidé de quitter cette univers des startups pour rejoindre Amuse Animation, une jeune filiale de Millimages spécialisée dans la production de dessins animés pour Youtube. Là bas j’ai travaillé pendant 4 ans sur les outils web internes de production et de diffusion de contenu. C’étais vraiment une super expérience de pouvoir travailler au service des artistes et de l’équipe de distribution, les problèmes à résoudre étaient concrets et réels et nos solutions efficaces. J’ai pu construire une petite équipe et apprendre énormément sur la manière de mener un projet efficacement.

Aujourd'hui

Depuis 2020 je suis CTO de KlaraRH, une startup RH spécialisée dans la remonté d’information des collaborateurs·trices. J’ai été le premier salarié et j’ai pu y construire à la fois mon équipe et le produit. La boîte à bien grandi depuis, nous sommes maintenant une entreprise de 35 personnes, dont cinq techs.

Nous travaillons avec une méthode proche de Shape-up qui permet de prendre le temps de faire évoluer le projet de manière à la fois constante et ambitieuse. Nous nous attachons à avoir le minimum de dette technique et de complexité.

Mes projets personnels

À coté de mon travail j’apprécie de bosser sur des choses différentes, avec plus ou moins de succés. Soit j’essaye de mettre en pratique ce que je connais le mieux pour monter des services utiles, soit j’essaye d’explorer des idées que je trouve originales.

Comme vous pourrez le remarquer quelques-uns de mes projets concernent des communautés queer comme les furries. Je n’appartiens pas forcément à toutes ces communautés mais je suis dans tout les cas très proche de beaucoup de leurs membres. Si le sujet vous intéresse vous pouvez aller lire ce que j’ai écrit sur le site de notre association.

Printogram

(2020)
RailsTelegramWaifu2X

Si il y a bien une chose que Telegram fait mieux que les autres c’est les stickers mignons, Printogram est donc un service qui permet d’imprimer ces stickers et de les recevoir chez soi.

Toute l’application est basée sur un chatbot Telegram qui permet d’envoyer ses stickers, de prévisualiser le résultat et de payer. Un certain nombre de passes de modifications et de corrections automatiques des stickers sont effectuées pour leurs permettre d’être imprimés et coupés correctement, notamment de l’upscaling grâce à Waifu2X. L’impression et l’envoi sont ensuite géré par Prodigi.

Pour économiser sur les coûts fixes d’hébergement j’ai écris un petit wrapper autour de Amazon SQS (que j’ai baptisé Arthropod) pour effectuer toutes les tâches d’upscaling et de transformation sur un serveur hébergé chez moi plutôt que de louer une machine avec une carte graphique qui supporterais CUDA (avec dans l’idée de migrer sur une solution plus pérenne si le service commence à être rentrable, ce qui n’a jamais été le cas.)

Howlr

(2018)
RailsReact NativeGraphQLPostGIS

De loin mon projet qui a le mieux fonctionné. Howlr était une application de rencontre amicale pour les communautés Furry, Browny et Puppy. Bien qu’il s’agisse d’un projet de groupe c’est moi qui ai écrit 99% de l’application et du backend et pris en charge une bonne partie de la modération sous les traits de Sushi, la loutre bleue.

L’application était disponible pour iOS et Android et a été maintenu pendant environ 4 ans avant qu’on ne décide de se retirer pour faire de la place à des alternatives plus abouties comme Barq. À la fin de sa vie, en mars 2022, l’application comptais 80,000 utilisateurs et utilisatrices.

Nous sommes fiers de savoir que cette application a changé la vie de beaucoup de gens, certaines personnes y ont rencontré leurs meilleur.es ami.es et se sont même mariés ! Nous avons eu des retours qui font chaud au cœur :

Your app is invaluable to this community, I know I speak on the behalf of tons of people when I say that! ^v^

L’application est écrite en React Native et utilise Expo. À l’époque de la première release, Expo était vraiment très expérimental, loin de ce qu’il est devenu maintenant, mais nous avons pu faire plusieurs rapports de bugs et en parallèle Expo s’est amélioré au fil du temps, l’application est devenu de plus en plus stable, notamment grâce à une réécriture complète et un passage de l’API en GraphQL en 2020.

Nous avons du faire beaucoup de chose par nous même pour conserver un coût modéré : un hébergement bare-metal peu cher, une gestion des VMs avec Dokku, notre propre service de reverse-geolocation, un stockage des fichiers avec Minio et un système d’authentification custom basé sur Telegram (qui est l’application de messagerie que la plupart des furries utilisent.)

M***tube

(2018)
RailsReactMaterial UIGraphQLffmpegnsfw

Projet un peu particulier puisqu’il s’agit d’un site pornographique amateur, communautaire, inclusif, gratuit et sans publicité. Même si je l’ai écrit je n’ai jamais géré ce site, c’étais néanmoins pour moi l’occasion d’apprendre à utiliser GraphQL ainsi que deux ou trois choses sur la diffusion de contenu. À noté que ce service a été récemment réécrit en Rails (sans React, API GraphQL, etc) par un autre développeur.

Aujourd’hui ce service compte plus de 3,500 vidéos, 11,000 utilisateurs et utilisatrices et atteint facilement les 10,000 visites journalières

Par ailleurs le service est très apprécié, là encore un commentaire sympa trouvé sur un blog :

Personally, a big draw for me is that M***tube is queer and trans as fuck! No, seriously, the vast majority of content there is hella gay, which is honestly a really nice change from other tube sites heavily dominated by cisgender and heterosexual scenes with queer and trans content often held on either a separate sub-site, or categorized as a niche fetish. Like how there’s XVideos and then there is XVideos Gay (which even has the little rainbow added to the corner of the main logo to signify it’s different) because god forbid that heterosexuals see any queer content while looking through there front page of illegally uploaded and stolen porn there.

 

With M***tube not only is all of the content ethically uploaded by their actual creators, as in it’s not stolen, and is stored and hosted with privacy and easy deletion in mind, but there is also no separation between "gay" and "straight". It’s all just porn presented as is and it’s fucking glorious! As a pansexual person myself (meaning I dig all genders and genital conbos), I really love just scrolling through videos and picking what looks hot without having bodies and sexualities filtered out for me by cisnormative and heteronormative algorithms.

 

I honestly can’t recommend this shit enough!

Comme pour Howlr ce genre de projet communautaire doit pouvoir fonctionner avec des coûts réduits, au final le service ne coute actuellement qu’une trentaine d’euros par mois avec une disponiblité tout à fait acceptable et de bonne performances.

FurryMart

(2016)
Rails

Plateforme web écrite en Ruby pour mettre en relation des artistes et des commissionneurs, les artistes peuvent poster leurs annonces de commissions, gérer leurs files d’attente et leurs factures. Les acheteurs peuvent conserver une trace de leurs commandes et facilement générer des pages de description pour leurs OC.

Les plus petits projets

asm6502

(2021)
RubyASM

Il s’agit d’un assembleur pour le mythique proceseur 6502 avec la particularité importante que le code assembleur est directement écrit en Ruby. Par exemple le code ci-dessous est à la fois du Ruby parfaitement valide, mais aussi quelque chose de très proche de ce à quoi ressemble habituellement du code assembleur 6502 :

# Calcule 3 * 9 # Chaque opcode est en réalité une fonction # Ruby qui va populate un buffer # avec du code machine, à la fin il suffit # d’écrire ce buffer dans un fichier # pour obtenir du code exécutable. lda 0 ldx 3 Label[:mult_loop] adc 9 dex bne :mult_loop

L’avantage de cette approche est que je n’ai pas eu à écrire de parseur, de système de macro ou autres subtilités qu’on retrouve généralement dans un assembleur. Si on compte la définition des opcodes, le code ne dépasse pas 150 lignes de Ruby.

Daily

(2021)
Ruby

Comme 99.9% des gens [reference required] je ne sais pas gérer mon argent correctement alors j’ai écrit une petite application qui m’indique combien j’ai le droit de dépenser par jour en prenant en compte les coûts fixes, les jours où j’ai moins (ou trop) dépensé.

Comme je fais de temps en temps, pour l’exercice, cette application n’utilise pas du tout de Javascript.

pinout.css

(2021)
CSS

Petite bibliothèque CSS pour faire des schémas de puces électroniques. Au final je la trouve un peu verbeuse et pas très souple, à refaire je partirais plutôt sur une implémentation en React avec canvas.

Punjab

(2021)
Node

Punjab est une implémentation des principes de Pundit en Node. En substance il s’agit d’une collection de helpers et une proposition d’organisation de classes de politique d’autorisations, l’idée est pouvoir facilement répondre à des questions du genre « Est-ce que l’utilisateur X à le droit de faire l’action Y sur un objet Z ? »

class PostPolicy { constructor(user, post) { this.user = user; this.post = post; } canUpdate() { this.user.isAdmin || !this.post.published } }

Le fait d’écrire la logique d’autorisation dans des classes à part du reste du code permet de rendre celles-ci plus robuste, plus testable et de simplifier énormément la maintenance.

node-sps

(2019)
NodePostgreSQL

Node SPS est une implémentation naive de spatial publish/subscribe. Le fonctionnement est basé sur les geometries de Postgis et le système de LISTEN/NOTIFY de PostreSQL.

Le publish/subscribe spatial fonctionne comme du pub/sub classique, Node SPS possède donc un systèmes de topic, de messages et de listeners, mais contrairement à un système classique les publications et souscriptions peuvent être limité à un polygone de forme arbitaire dans un espèce 3D.

Un tel système peut permettre de simplifier l’écriture de jeu, en limitant par exemple la réception d’évènement à une pièce particulière ou au cône de vision du joueur.

zipper-stream-express

(2019)
Node

Dans la longue tradition des projets Node dont le nom veut dire exactement ce qu’il y a dedans, zipper-stream-express est un serveur (basé sur Express) qui génère un fichier ZIP à partir d’une liste d’URLs et le stream directement à l’utilisateur. C’est particulìerement utile pour gérer le téléchargement de plusieurs fichiers en évitant les hacks et incompabilités entre navigateurs.

Comme le code est basé sur des streams et des pipes d’un bout à l’autre il est extrèmement simple, bufferize très peu, ne consomme pas d’espace disque et est normalement très scalable.

Arthropod

(2019)
RubySQS

Dès qu’on a envie d’héberger un petit projet qui fait de l’encodage de vidéo ou qui doit utiliser CUDA on se retrouve rapidement à choisir entre louer une machine à plusieurs centaines d’euros par mois ou passer beaucoup de temps à essayer de faire fonctionner son code sur un service cloud (alors que dans un petit projet perso on veut du fun). J’ai donc écrit un petit outil qui permet à n’importe lequel de mes petits serveurs d’appeler une machine chez moi pour lui demander de faire des traitements lourds ou qui nécessitent une carte graphique.

Une différence importante avec d’autres service du type est que le traitement est synchrone (et donc facilement wrappable dans une simple méthode).

Arthropod utilise Amazon SQS et fonctionne déjà bien sur une de mes applications qui déporte tout son traitement de vidéo en utilisant arthropod-hls-video-encoder.

url_of_the_video = "https://domain/video.mp4" response = Arthropod::Client.push(queue_name: "video_encoding", body: { url: url_of_the_video }) puts response.body # => "https://domain/reencoded_video.mp4"

Mite

(2019)
RubyRackSQS

Mite est un serveur rack basé sur Arthropod, il permet d’appeler une application basé sur rack (une application Ruby on Rails par exemple) même si celle-ci n’est pas exposée sur Internet. Pour simplifier on peut considérer ça un peu comme du HTTP-over-SQS.

L’idée pour moi étant de pouvoir héberger certains pet-projects chez moi sans avoir à louer un serveur ou ouvrir des ports et pour pouvoir les faire tourner sur plusieurs machines sans avoir à mettre un proxy pour router les requêtes.

En pratique il faut quand même avoir une machine qui récupère les requêtes HTTP et les push sur SQS, pour ça il est possible d’utiliser mite-lambda-proxy.

Spiky

(2019)
Nodeffmpeg

Mon truc en ce moment c’est de profiter un peu de la puissance des streams et pipes de Node pour faire des micro-APIs qui font des trucs un peu compliqués, mais pas en plus d’une dizaines lignes de code. Le dernier projet du genre est Spiky, c’est un petit serveur basé sur Express et qui réeencode des vidéos à la volée.

Pour être très honnête, contrairement à zipper-stream-express et à Sharper, Spiky ne fonctionne vraiment pas très bien et j’ai des gros doutes sur sa sécurité. Mais c’étais un POC amusant à écrire.

Sharper

(2019)
NodeSharp

Comme Spiky mais pour les images. C’est une API très simple pour modifier et redimensionner des images à la volée.

Geogeo

(2019)
RubyPostGIS

Je voulais toucher un peu plus extensivement à PostGIS, du coup je trouvais intéressant de refaire une petite API de reverse-geolocation en exploitant les données de WhosOnFirst. La qualité des données est vraiment très variable, obligeant à faire pas mal de traitements alternatifs pour trouver une réponse correcte (voire politiquement correcte) pour certaines localisations.

Artfeed

(2018)
React NativeRubyPuppeteer

Application React Native qui liste automatiquement des propositions de commissions d’artistes en scrappant FurAffinity avec Puppeteer. Depuis j’en ai plutôt fait un bot Telegram, ce qui est nettement plus simple à maintenir.

Chronofage

(2017)
Ruby

Petit backend ActiveJob qui exécute les tâches avec un script rake à lancer quand vous voulez. Ça paraît très rustique comme ça mais ça a plusieurs avantages pour les jobs très longs (genre réencodage de vidéos ou rendu de scènes 3D) : chaque job est dans un processus indépendant et ne se fait pas tuer au déploiement, vous pouvez ajouter autant de machines que vous voulez et utiliser simplement cron ou le planificateur de tâches de tâche de Windows pour lancer les jobs.

C’est très alpha mais ça tourne sans trop de problèmes en production.

Nanotube

(2017)
RubyNginx

Un petit service d’hosting de vidéos qui peut tourner sur une Raspberry Pi Zero, si vous êtes patient. Il supporte l’upload de très gros fichiers grâce à nginx-upload-module, le transcodage avec "ffmpeg" et le tout fonctionne sans Javascript parce que je trouvais ça marrant comme contrainte.

C’est une plaie à installer par contre.

fafuse

(2017)
RubyFuse

Wrapper Fuse pour accéder sous forme d’un système de fichiers aux galleries de FurAffinity.

Je pense que le code ne fonctionne plus maintenant à cause des techniques anti-bots qui ont été misent en place.

lolnes

(2012)
C6502

À la base je voulais écrire un émulateur NES en C mais il n’a jamais été bien fini et à plutôt évolué vers un débuggeur capable de faire du pas-à-pas et d’observer la mémoire, l’état des registres, etc.

Le résultat est très buggué et est probablement complètement inutilisable, mais ça m’a permi d’apprendre pas mal de choses sur la manière dont fonctionne ce genre de vieilles consoles.

node-epeg

(2012)
C++Node

Binding de libepeg pour NodeJS pour redimensionner des images JPEG très rapidement et sans passer par l’étape de compression.

Le projet est abandonné depuis un moment mais d’autres gens l’ont repris.

Mes jeux / homebrews

Super Condor

(2020)
ASMAtari 2600

Mon second jeu pour Atari 2600, cette fois ci je suis plutôt fier du résultat.

Vous êtes un SUPER CONDOR dans un template Inca et vous devez récupérer le SCEPTRE DE FEU dans chaque niveau pour pouvoir pouvoir accéder au niveau suivant. Attention au maléfique ŒIL DU DESTIN !

Même si le jeu est très court et n’a pas de musique j’ai quand même réussi à faire un playfield de droite qui ne soit pas juste un miroir ou une copie du playfield de gauche (ce qui demande de timer précisément l’exécution des instructions, ce qu’on appelle communément "racing the beam") et le jeu comprends 6 routines d’affichage — ou kernel — différents (dont 5 sont présents sur le screenshot ci-dessous.)

Flappy2600

(2020)
ASMAtari 2600

Mon premier jeu pour Atari 2600, le code est horrible et le jeu est buggué, mais je suis content d’être arrivé à quelque chose.

Tiger Pong

(2019)
CGBA

Un petit jeu pour Game Boy Advance que j’ai fait pour l’anniversaire d’un ami (vous avez déjà recu un jeu GBA en votre honneur pour votre anniversaire ? Lui oui). Bon après c’est juste un pong et c’est mon premier jeu GBA, donc rien de magnifique non plus, mais intéressant à faire. (Je ne sais pas faire de GIF correct par contre, le jeu est normalement 4 fois plus rapide.)

Twitter Chess

(2017)
RubyTwitter API

Un jeu d’échec sur Twitter, vous pouviez prendre n’importe quel partie en cours de route en cliquant sur le lien du Tweet, jouer votre coup (qui sera automatiquement posté sur Twitter) et laisser les autre joueurs vous répondre (transformant ainsi une partie d’échec en un arbre de coups plutôt qu’une suite linéaire.)

Je ne liste ici que les projets que je considère comme publiable, comme tout le monde j’ai commencé plein de choses que je n’ai jamais fini, tout est sur mon Github.

See you soon!