Code By
Lucas Mouilleron

An Open Source selection - 40 projects
Private repositories are not fully showcased for obvious reasons :)

+ simpleWebFolder2

Python 57.8% - Mako 37.3% - CSS 4.4% - JavaScript 0.5%
Last update : 28/02/2022 - 10:43



  • List files and folders
  • Nice layout
  • Password protection:
    • drop a .password file containing the desired password in folders (and subfolders) you want to protect
    • drop a .nopassword file in folders (and subfolders) you want to deprotect (in case of protected parent)
  • Listing protection: drop a .nolist file in folders you want to forbid the listing of
  • Show protection: drop a .noshow file in folders you don't want to appear in their parents
  • Download folder as a zip
  • files in folders are interpreted and displayed on top
  • Shares: expiration, path obfuscation, tracking
  • Tracking: optional tracking


  • Pytohn 3
  • pip install -r _sf/requirements.txt
  • Copy _sf/assets/style.sample.css to _sf/assets/style.css
  • Copy _sf/config/config.sample.json to _sf/config/config.json
  • Drop _sf folder in the root folder you want to expose


  • Edit _sf/config.json
  • Edit _sf/assets/style.css


  • Clean shares
  • Better locks
  • Clean locks
  • Track and clean tracking periodicly to file (and not on the fly)

+ Survival

Shell 64.6% - Lua 34.3% - Vim script 1.1%
Last update : 22/02/2022 - 15:12


Nice minimal setup for hostile environments :)

Install - Debian / Ubuntu

  • From root or sudo user:usermod -aG sudo username
  • From user username: sudo ls
  • From user username: export SSH_PASSPHRASE="12345" if SSH passphrase desired (more than 5 characters)
  • From user username: cd $HOME;sh <(wget -o /dev/null -qO-

Install - macOS

  • From root or sudo user:usermod -aG sudo username
  • From user username: sudo ls
  • From user username: export SSH_PASSPHRASE="12345" if SSH passphrase desired (more than 5 characters)
  • From user username: cd $HOME;sh <(wget -o /dev/null -qO-

Install - Others


+ stupidCMS

PHP 69.5% - JavaScript 19.5% - CSS 6.3% - HTML 4.7%
Last update : 15/02/2022 - 13:21


stupidCMS is a flat file stupid CMS with nice templating and caching engines.


  • Drop all files (including .htaccess) at the site root
  • Create the file ./config.php and override default config (cf Overridable Configuration)

Stupid Pages (SP)

  • Stupid Pages files extensions is .html
  • In Stupid Pages, paths are relative to the site root
  • To link from a page to another page, use
  • They use the Stupid Micro Templating Engine (SMTE) allowing administrable content declaration

Stupid Micro Templating Engine (SMTE)

  • Administrable contents : {{CNT:content-name}}
  • Administrable files : <img src="{{FILE:file-name.jpg}}"/> or <a href="{{FILE:file-name.pdf}}">the file</a>
  • Include another page in a page : {{INC:page-name-without-html-extension}}
  • Definitions : {{DEF:CONSTANT_NAME}} (for example SITE_URL)
  • If : {{IF:php expression}}content{{EIF}}

Studid Dynamic Page (SDP)

  • Stupid Pages files extensions can be .php
  • In this case the page is a Stupid Dynamic Page (SDP)
  • Custom php scripting can be addded
  • <?php global $stupid;?> must be called to make the stupid engine available
  • Sutpid API available :
    • $stupid->__inc("page-name-without-html-extension")
    • $stupid->__cnt("content-name")
    • $stupid->__file("file-name")
  • No CSPC cache is applied (it is applied only for included contents)

Compiled Stupid Pages Caching (CSPC)

  • Compiled Stupid Pages are cached for performance optimization
  • The cache engine is selectable in /config.php
  • Three engines are available :
    • None cache engine : no cache, all pages and contents are loaded from original files (not recommended)
    • File cache engine : cache files are located in /__cache
    • Redis cache engine : redis port is configurable in ___stupid/libs/stupidDefinitions.php
  • In DEVELOPMENT_MODE, the cache is disabled

Stupid Backend (SB)

  • stupidCMS comes with a stupid backend
  • Open in browser
  • Content editing :
    • Add contents in pages using the SMTE format
    • Run a Scan to populate the backend interface
    • Edit and save contents
    • Tips :
      • Contents are SMTE compatible, which means you can use the SMTE tags
      • Contents can be written in Markdown format :
  • Files editing :
    • Add files in pages using the SMTE format
    • Run a Scan to populate the backend interface
    • Edit and save files
  • Pages editing :
    • All SP and SDP can be edited from the backend
    • Templates can be used for scaffholding (templates are defined in /__templates)
    • /config.php is editable as well
  • Scan :
    • If SMTE administrable content are not visible, run Scan
    • Scan contents scans for contents and files
  • Clear :
    • If new contents or files don't appear, run Clear, to clear the cache
    • In DEVELOPMENT_MODE, cache is disabled, therefore Clear is not needed
  • Clean : TODO

Administration - Overview

  • Pages are created from backend or manually in root folder (html or php)
  • Reference administrable contents of files with {{CNT:the-content-name}} or {{FILE:the-file-name.pdf}}
  • Scan contents in pages, then edit the contents in the backend
  • Contents : edit contents
  • Files : edit files
  • Scan : scan for new contents or files referenced in pages
  • Pages : add or edit pages

Administration - Contents

  • Scan : scan for new files referenced in pages
  • Go to Contents
  • Edit the relevant content
  • Edit one content at the time (the Save button (or ctrl+shift+enter) save only the current content)
  • To use Markdown syntax, the first line of content must be ***

Administration - Files

  • Scan : scan for new files referenced in pages
  • Go to Files
  • Upload the relevant file with the Replace button

Overridable configuration

  • Defined in ___stupid/libs/stupidDefinitions.php
  • DEBUG_MODE (true): displays hints
  • DEVELOPMENT_MODE (false): no cache for easier development
  • ADMIN_PASSWORD ("password"): has to be changed
  • SITE_URL ("http://localhost"): has to be set to the site root url
  • PAGE_404 (false): false or the name of the 404 page (without extension)
  • NO_SCAN_FOLDERS (none): folders not to scan when finding contents and files
  • SMTE_CACHE_ENGINE ("file"): file | redis | none


  • Install composer : curl -sS | php && mv composer.phar /usr/local/bin/composer
  • Install dependencies : cd ___stupid && composer install
  • Underlying cotents in ./__contents
  • Underlying files in ./__files


  • sub folder index
  • guidlines



+ lucasmouilleron

PHP 67.2% - JavaScript 18.6% - CSS 11.4% - HTML 2.7%
Last update : 15/02/2022 - 13:21

My personal website.


+ sshForFriends

Shell 100%
Last update : 15/02/2022 - 13:18


Temporally give ssh access to your friends.

sshForFriends uses friends public keys to give them access to the computer.
When sshForFriends has finished running, public keys are cleaned and friends can't access the computer anymore.
Public keys are fetched from known identity providers.

Tested on macOS and Ubuntu.

No password, no hastle, 100% SSH.


  • sshForFriends [OPTIONS] friendUsername
  • friendUsername is the friend username which will be granted access (identity provider username)
  • sshForFriends -h for more usage help

Identity providers

  • id_rsa: key from cat $HOME/.ssh/ on your friend's machine (-r RSA_PUB_KEY)
  • Github : keys from$USER_NAME.keys (-g, -i github)
  • Keybase : keys from https://$ (-k, -i keybase)

Behind a firewall

  • If the computer being accessed is behind a firewall, sshForFriends can use a public server for ssh forwading.
  • See params -x, -l, -m and -n
  • On the public server, make sure GatewayPorts yes is set in the /etc/ssh/sshd_config file
  • See examples below


  • macOS, enable ssh server : sudo systemsetup -setremotelogin on


  • Give access from a machine to lucasmouilleron in one line : curl -sL -o $HOME/sshForFriends ; chmod a+x $HOME/sshForFriends ; $HOME/sshForFriends -g lucasmouilleron
  • Give access from a machine to lucasmouilleron in one line : curl -sL -o $HOME/sshForFriends ; chmod a+x $HOME/sshForFriends ; $HOME/sshForFriends -k lucasmouilleron
  • Give access from a machine behind a firewall to lucasmouilleron in one line : curl -sL -o $HOME/sshForFriends ; chmod a+x $HOME/sshForFriends ; $HOME/sshForFriends -g -x -l sshtunnel -m 10022 lucasmouilleron
  • Give access from a machine behind a firewall to a friend with pub key in one line : curl -sL -o $HOME/sshForFriends ; chmod a+x $HOME/sshForFriends ; $HOME/sshForFriends -r "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDqN4/IlNfY8I5AUYYnj9mieJ9Uyx4rMbZjxyukmwM1nqSpTmFBs5xdqtE1Qi1DDb6V0Nphua80GUxXfIiKmbJVuOnrBjX2qInwMPtFxJ0gr8adXYIamcCVylcCPm2qO418KQpuHNM1es5s0a2hzuuRCtw6trysq/SCSIp6o05OEdHP8CbfCdFA+P7sy99XHG3yGzqHdU0D04ScDePzm1buSOXqQRCrSkuLmRMBhtRQSj7UAI3IlRcF3tEFPqAywjwnZVIvv6fUoXnpJuoCzBPuJv5D5lo06xixwIvHc39t1r4Tv/OrD+EyWfPsmCpLGfEkMRBqmj/ds5c4y6NjO9cl" -x -l sshtunnel -m 10022 yourfriendname


  • Inspired by

+ sparkBoilerplate

Java 100%
Last update : 15/02/2022 - 13:18

A simple Spark REST boilerplate.



  • Install JDK 8
  • Install Apache Ant
  • Install Apache Ivy
  • Get dependencies : ant getDependencies

Run and test

  • Run : ant run
  • https://localhost:8087/hello


  • JWT
  • Generate keys :
    • Private key : openssl genrsa -out private_key.pem 2048
    • Private key java format : openssl pkcs8 -topk8 -inform PEM -outform DER -in private_key.pem -out private_key.der -nocrypt
    • Public key java format : openssl rsa -in private_key.pem -pubout -outform DER -out public_key.der
  • Get token : curl -k https://localhost:8080/login/ilovekate
  • Acces restricted area : curl -k --header "token: eyJhbGciOiJSUzI1NiJ9.eyJuYW1lIjoidXNlcm5hbWUiLCJkYXRlIjoxNDQzNzgwODU3NDcyfQ.A6b6Hg1QyYgYUV8J9wff6SvclX90Ydmx6sd8OzTAXYJ6gLpkXMBaHvOLtyxu35hSiiVwrOljnfLSg__tlbzh6PG8KrMuezwCQHttnQzowfp5CxNWM5mEXcMjHiCMLGW3X_p5MV6hm7pe7M8aBDKlZj__OHEMPogFGSga5HhnRDnRfzY49cW9CgzdtfCY3c-wWwabyoy75kQTk5GG2KUOZPy5xKT9EJvL1JLlGKkCl4Il8zNGm2cpP68_hIqCohLqEfbMXjBdccYU7DsjQowBxtjQcZD92pu-6rHKhWcJVlNC32BqvPQXn5laKCm9Dpq703Km_IWvEPz0LPXDtIZ9Gg" https://localhost:8080/protected


  • enableCORS()
  • Beware in filters, bypass OPTIONS requests so it works


  • Generate keystore :
    • keytool -genkey -keyalg RSA -alias sparkBoilerplate -keystore keystore -validity 3600 -keysize 2048
    • "What is your first and last name?" has to be the domain name
  • Self signing : keytool -export -alias sparkBoilerplate -file certificate.crt -keystore keystore
  • CA signing :
    • Generate CSR (certificate request) : keytool -keystore keystore -certreq -alias sparkBoilerplate -keyalg rsa -file certificate.csr
    • Get from CA the certificate.crt file
  • Generate trustore : keytool -import -file certificate.crt -alias sparkBoilerplate -keystore truststore
  • Test keystore : keytool -list -v -keystore keystore
  • In this boilerplate, password is password and host is localhost

+ nicolasrainaud

PHP 79.7% - CSS 8.4% - HTML 7.5% - JavaScript 4.4%
Last update : 15/02/2022 - 13:17

Nicolas Rainaud website, built with my stupidCMS.


+ riverworldBeings

Python 98.1% - CSS 1.9%
Last update : 13/03/2021 - 08:33


Characterisation of the population of beings of Riverworld.

Riverworld is a fictional planet and the setting for a series of sci-fi books written by Philip José Farmer.
Riverworld is an artificial environment where all humans (and pre-humans) ever born who died after reaching 5 years old are reconstructed.
Most of the resurrected awaken in a body equivalent to that of their 25 year old selves, in perfect health and free of any previous genetic or acquired defects.

A friend of mine made fun of the book concept and claimed half of the beings ressucitated would be prehistorical.

This project is proving him wrong.


  • Begining of mankind : Homo Erectus, -1500K, assuming all beings on Riverworld can walk
  • End of mankind : 2016. In the book, all people die in 1983 after interacting with an alien civilisation.
  • Child Mortality CM : death of infants and children under the age of 5
  • Infant Mortality IM : death of infants and children under the age of 1
  • Life Expectancy LE : average time a being is expected to live
  • Life Adult Expectancy LAE : average time a being is expected to live if he reachs 5 years old


  • Dataset compiled amongst considered sources :
    • until now, conservative estimations for pre modern times : ./data/population-min.csv
    • until now, optimistic estimations for pre modern times : ./data/population-max.csv
    • until now, average estimations for pre modern times : ./data/population-avg.csv
    • including 2070 projections ./data/population-future.csv
  • The dataset consists of Point In Times (PIT)
  • For each PIT, these metrics are available : year, beings count in millions, LE, LAE, CM and continental proportions
  • Depending on sources, CM, IM, LE and/or LAE are provided or not. Some datas have been extrapolated. Underlying model : LE = CM * 5/2 + LAE * (1 - CM)
  • Case of beings count in prehistorical times :
    • Beings counts estimation flucuates a lot. They can go as low as 1K individuals up to 100K
    • We have 3 milestones in our dataset : -1500K (lower paleolithic), -50K (higher paleolithic) and -10K (begining of history)
    • For -10K, the poulation count is within the magnitude of the millions according to most of the sources. We kept the McEvedy estimation of 4 millions.
    • For -50K, we kept the higher estimation of Jean-Pierre Bocquet-Appel from his study of upper paleolithical meta populations in Europe. He found 15K individuals in the Aurignacien (-30K). Wordlwide, we estimated, as a minimum, we timed this result by 5. As a maximum by 10.
    • For -1500K, we've assumed the population could not be higher than in -50K. We assumed the population at that time would be the population of -50K / 2.
  • Case of LE et CM for prehistorical times :
    • As for beings counts, the LE estimations vary greatly
    • The Kaplan study suggest hunter gatherer modern societies tell us how prehistoric men lived and died. The study suggests the ALE is around 50 years and the CM around 0.5
    • For reference, the CM of 1900 is 0.4 and the Scheidel estimation of Classic Rome CM is 0.5
    • We cowardly derived the CM of pre Roman times to 0.6


  • Linearity in between PITs :
    • The underlying assumption is that the PIT metrics evolve linearly in between two PITs
    • This assumption can be considered true from -1500K to 1700, from 1700 to 1900, from 1900 to 1950 and from 1950 to today
    • The PIT resolution in the dataset is consistent with this observation
    • We then assume numerical midpoint integration is a reasonable estimation
  • For the period PIT 1 => PIT 2
  • AB yx = Amount of Beings for year x
  • Elapsed Time ET = y2 - y1
  • Average Amount of Beings for Period AABP = (AB y2 + AB y1) / 2
  • LAE for Period LAEP = (LAE y1 + LAE y2) / 2
  • Proportion of Adult Beings To Be for Period PABTBP = 1 - ((CM y1 + CM y2) / 2)
  • Thus Amount of Beings who were Born for Period ABP = ET * AABP / LAEP
  • Thus Amount of Adult Beings who were Born for Period AABP = ET * AABP * PABTBP / LEP
  • Another calculus method is to use a simpe model of population growth :
    • AB y1 = Ce^(r * y1) and AB y2 = Ce^(r * y2)
    • By integration, ABP = ET * (AB y2 - AB y1) / (ln(AB y2) - ln(AB y1)) / LEP
    • This method proved to be very similar to the naïve numerical integration we selected (cf Report - Figure 6)


  • The last report : ./output/(min|max|future)/report.pdf
  • The last plots : ./output



  • pip install --upgrade pip
  • pip install -r requirements.txt --user
  • Fonts used in this project : ./resources/fonts
  • PDF dependencies :
    • mac : brew cask install wkhtmltopdf
    • linux : apt-get install wkhtmltopdf


  • Configuration is loaded from config.ini
  • python min|max|avg|future
  • all at once : python min;python max;python avg;python future


+ youtubeToMeme

PHP 95.6% - JavaScript 4.4%
Last update : 13/03/2021 - 08:28


Youtube to animated meme generator.


  • Downloads a Youtube video, converts it to an animated gif and adds a custom meme text on top of it
  • Colors, auto linebreak
  • Based on nodejs youtube-dl and gifify
  • PHP image magick gif frame annotation


  • Install NodeJS :
  • ffmpeg : brew install ffmpeg
  • libtool : brew install libtool
  • imagemagick : brew install imagemagick --build-from-source
  • giflossy :
    • brew install automake
    • git clone && cd giflossy && autoreconf -i && ./configure && make && make install
  • imagick php :
    • sudo pecl install imagick
    • vi /etc/php.ini and add
  • cd libs/youtubeToGif && npm install


  • php cmd.php A7TaY8HWYd8 71 5 "PRETTY GOOD JUNIOR" 500 BOTTOM
  • php cmd.php 6Hn8qnsucwo 30 5 "PRETTY ... PRETTY ... PRETTY ... PRETTY ... PRETTY GOOD" 500 TOP
  • php cmd.php puo1Enh9h5k 49 2 "ROMANO LE RELOU" 500 BOTTOM


  • minimal UI
  • Linux install
  • POSITION_BOTTOM flickers

+ twitter2Emulator

JavaScript 90.7% - HTML 7.2% - Python 2.1%
Last update : 13/03/2021 - 08:26



  • Download an emulator (snes9X)
  • Download some ROMs
  • cd server
  • npm install


  • Start the emulator and a ROM
  • node server/app.js
  • Go with to clientController/index.html with your browser for additionnal controlling and logging