Browse Source

Initial import.

master
David Soulayrol 2 months ago
commit
1538631d84
  1. 15
      .eslintrc.js
  2. 2
      .gitignore
  3. 5
      .stylelintrc.json
  4. 34
      assets/dev/css/ds.css
  5. 1
      assets/dev/css/simple.min.css
  6. BIN
      assets/dev/files/partitions/202010.pdf
  7. BIN
      assets/dev/files/partitions/202106.pdf
  8. BIN
      assets/dev/files/partitions/202107.pdf
  9. BIN
      assets/dev/fonts/Colombia-Rp0DV.ttf
  10. BIN
      assets/dev/fonts/ColombiaItalic-BWGZB.ttf
  11. 1
      assets/production
  12. 77
      content/cv/2000_cv_dsoulayrol.txt
  13. 2363
      content/cv/20051010_cv_dsoulayrol.pdf
  14. BIN
      content/cv/2012/2012_cv.pdf
  15. BIN
      content/cv/2012/2012_europass.pdf
  16. BIN
      content/cv/2012/2012_experiences.pdf
  17. 60
      content/cv/2012/cv.tex
  18. 65
      content/cv/2012/europass.tex
  19. 57
      content/cv/2012/experience.tex
  20. 169
      content/cv/2012/fragments/atlantide.tex
  21. 24
      content/cv/2012/fragments/contact.tex.in
  22. 52
      content/cv/2012/fragments/formation.tex
  23. 5
      content/cv/2012/fragments/interests.tex
  24. 3
      content/cv/2012/fragments/leisure.tex
  25. 38
      content/cv/2012/fragments/netcentrex.tex
  26. 22
      content/cv/2012/fragments/nexcom.tex
  27. 2
      content/cv/2012/fragments/skills_languages.tex
  28. 1
      content/cv/2012/fragments/skills_methods.tex
  29. 1
      content/cv/2012/fragments/skills_protocols.tex
  30. 1
      content/cv/2012/fragments/skills_systems.tex
  31. 3
      content/cv/2012/fragments/skills_tools.tex
  32. 38
      content/cv/2012/makefile
  33. 111
      content/cv/2022/2022_cv_dsoulayrol.ms
  34. 14
      content/cv/2022/README
  35. 99
      content/documents/hide-long-headers.md
  36. 108
      content/documents/identifying-contexts-in-logs.md
  37. 298
      content/documents/using-firefox-micro-summaries.md
  38. BIN
      content/documents/using-firefox-micro-summaries/screenshot-live_titles-1.png
  39. BIN
      content/documents/using-firefox-micro-summaries/screenshot-live_titles-2.png
  40. BIN
      content/documents/using-firefox-micro-summaries/screenshot-live_titles-3.png
  41. BIN
      content/documents/using-firefox-micro-summaries/screenshot-xpath-1.png
  42. BIN
      content/documents/using-firefox-micro-summaries/screenshot-xpath-2.png
  43. 1267
      content/documents/wonderful-26.md
  44. 53
      content/index.md
  45. 24
      layouts/default.njk
  46. 14
      layouts/document.njk
  47. 17
      layouts/footer.njk
  48. 14575
      package-lock.json
  49. 62
      package.json
  50. 20
      scripts/config.js
  51. 108
      scripts/metalsmith-helpers.js
  52. 63
      scripts/metalsmith-statistics-plugin.js
  53. 82
      scripts/metalsmith.js
  54. 71
      scripts/run.js

15
.eslintrc.js

@ -0,0 +1,15 @@
module.exports = {
env: {
browser: true,
commonjs: true,
es2021: true
},
extends: [
'standard'
],
parserOptions: {
ecmaVersion: 12
},
rules: {
}
}

2
.gitignore

@ -0,0 +1,2 @@
dist
node_modules

5
.stylelintrc.json

@ -0,0 +1,5 @@
{
"extends": "stylelint-config-standard",
"ignoreFiles": ["**/*.min.css"]
}

34
assets/dev/css/ds.css

@ -0,0 +1,34 @@
@font-face {
font-family: colombia;
src: url(/fonts/Colombia-Rp0DV.ttf);
}
@font-face {
font-family: colombia;
src: url(/fonts/ColombiaItalic-BWGZB.ttf);
font-style: italic;
}
body {
margin: 1em 0;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: colombia, sans-serif;
margin: 1em 0 0.4em 0;
padding: 0;
}
footer {
padding: 0;
}
p {
margin: 0 0 0.4em 0;
padding: 0;
}

1
assets/dev/css/simple.min.css

File diff suppressed because one or more lines are too long

BIN
assets/dev/files/partitions/202010.pdf

Binary file not shown.

BIN
assets/dev/files/partitions/202106.pdf

Binary file not shown.

BIN
assets/dev/files/partitions/202107.pdf

Binary file not shown.

BIN
assets/dev/fonts/Colombia-Rp0DV.ttf

Binary file not shown.

BIN
assets/dev/fonts/ColombiaItalic-BWGZB.ttf

Binary file not shown.

1
assets/production

@ -0,0 +1 @@
dev/

77
content/cv/2000_cv_dsoulayrol.txt

@ -0,0 +1,77 @@
David Soulayrol
Franรงais, 23 ans, cรฉlibataire.
Dรฉgagรฉ des obligations militaires.
60, Les Hauts de la fontaine
34980 - COMBAILLAUX
Tel.: 0 671 057 557
david.soulayrol@enib.fr
Ingรฉnieur en Dรฉveloppement Informatique
Expรฉrience professionnelle
==========================
* Stage en entreprise -- Ifremer, Centre de Brest. Durรฉe : 5 mois
Dรฉveloppement d'un logiciel de navigation en temps rรฉel pour le
positionnement de bouรฉes acoustiques sous-marines.
Le logiciel a รฉtรฉ rรฉalisรฉ sous LabVIEW de National Instruments. Il
comprend essentiellement trois parties : manipulation de donnรฉes GPS (ร 
l'aide d'une bibliothรจque de fonctions C), rรฉception et tri des donnรฉes
provenant de l'unitรฉ acoustique BENTHOS DS-7000 ร  travers une liaison sรฉrie
RS-232 et enfin intรฉgration de ces donnรฉes dans un algorithme de type
moindres carrรฉs.
Ce stage m'a permis de dรฉcouvrir les outils LabVIEW et MatLab. J'ai
en outre participรฉ ร  l'installation de Linux (SuSE 6.1) sur plusieurs PC,
ainsi qu'ร  leur intรฉgration dans le rรฉseau du laboratoire. Cela m'a permis
d'approfondir mes connaissances sur les systรจmes UNIX.
Formation
=========
Elรจve Ingรฉnieur
Actuellement en derniรจre annรฉe ร  l' Ecole Nationale d'Ingรฉnieurs de
Brest.
Projet de Fin d'รฉtudes : ARรฉVi
ARรฉVi est un outil de gestion et de navigation au sein
d'environnements virtuels orientรฉ agents. Il est dรฉveloppรฉ sous Visual C++.
Mon rรดle consistait ร  implรฉmenter une interface entre le logiciel et
des moteurs de synthรจse et de reconnaissance vocale. J'ai en outre portรฉ le
support de pรฉriphรฉriques (gant de donnรฉes) depuis une version Unix sur
Windows.
Modules d'approfondissement suivis :
* Systรจmes Temps Rรฉel
* Intelligence Artificielle
* Interfaces
* Rรฉalitรฉ virtuelle
Baccalaurรฉat Sรฉrie E
Lycรฉe Mas de Tesse, Montpellier (1994).
Connaissances acquises
======================
Langages maitrisรฉs :
C, C++, Prolog, Langage G de LabVIEW.
Langages abordรฉs :
Assembleur (sur MC68k et Intel x86), Java, Scheme, Perl, HTML,
JavaScript.
Systรจmes d'exploitation :
Unix (Linux, System V et BSD, Irix), Windows 9x/NT, DOS.
Systรจmes temps rรฉel :
VxWorks.
Langue vivante :
Anglais : lu+++, parlรฉ++, รฉcrit+++
Autres activitรฉs
================
* Administration des services rรฉseaux pour les รฉtudiants de l'Enib. Ce
rรฉseau comprend une dizaine de machines sous Linux.
* Participation au projet DreamOs (www.dreamos.fr.st).
* Musique (guitare), lecture...
* Activitรฉs de plein air : marche, cerf-volant, ...

2363
content/cv/20051010_cv_dsoulayrol.pdf

File diff suppressed because it is too large

BIN
content/cv/2012/2012_cv.pdf

Binary file not shown.

BIN
content/cv/2012/2012_europass.pdf

Binary file not shown.

BIN
content/cv/2012/2012_experiences.pdf

Binary file not shown.

60
content/cv/2012/cv.tex

@ -0,0 +1,60 @@
\documentclass[10pt,a4paper]{moderncv}
\usepackage{ucs}
\usepackage[utf8x]{inputenc}
\usepackage[frenchb]{babel}
\usepackage{ifthen}
% Type of document
\newboolean{europass}
\setboolean{europass}{false}
\newboolean{cv}
\setboolean{cv}{true}
\newboolean{details}
\setboolean{details}{false}
% Custom style
\addtolength{\textwidth}{2cm}
\addtolength{\hoffset}{-1cm}
\addtolength{\textheight}{1cm}
\addtolength{\voffset}{-1cm}
%\setlength{\parskip}{0.5cm}
\moderncvtheme[orange]{classic}
\AtBeginDocument{\recomputelengths}
% Personal data
\input{fragments/contact}
\begin{document}
\maketitle
\renewcommand{\labelitemi}{$\triangleright$ย }
\section{Expรฉrience professionnelle}
\input{fragments/nexcom}
\input{fragments/netcentrex}
\input{fragments/atlantide}
\section{Formation}
\input{fragments/formation}
\section{Compรฉtences}
\cvline{Langages}{\input{fragments/skills_languages}}
\cvline{Outils}{\input{fragments/skills_tools}}
\cvline{Protocoles}{\input{fragments/skills_protocols}}
\cvline{Systรจmes}{\input{fragments/skills_systems}}
\cvline{Mรฉthodologies}{\input{fragments/skills_methods}}
\section{Langues}
\cvlanguage{Anglais}{Courant}{}
\section{Intรฉrรชts}
\cvline{Logiciel Libre}{\input{fragments/interests}}
\cvline{Loisirs}{\input{fragments/leisure}}
\section{Addenda}
\cvlistitem[$\triangleright$ย ]{Nationalitรฉ Franรงaise}
\cvlistitem[$\triangleright$ย ]{Permis B}
\end{document}

65
content/cv/2012/europass.tex

@ -0,0 +1,65 @@
\documentclass[a4paper,french,arial,narrow]{europecv}
\usepackage{ucs}
\usepackage[T1]{fontenc}
\usepackage[utf8x]{inputenc}
\usepackage[frenchb]{babel}
\usepackage{graphicx} % Required to draw the logo
\usepackage[a4paper,top=1.27cm,left=1cm,right=1cm,bottom=2cm]{geometry}
\usepackage{url}
\usepackage{ifthen}
% Type of document
\newboolean{europass}
\setboolean{europass}{true}
\newboolean{cv}
\setboolean{cv}{false}
\newboolean{details}
\setboolean{details}{false}
% Define personal data.
\input{fragments/contact}
\begin{document}
\begin{europecv}
\ecvpersonalinfo[5pt]
%\ecvitem{\large\textbf{Desired employment/ Occupational~field}}{\large\textbf{(Remove if not relevant)}}
\ecvsection{Expรฉrience professionnelle}
\input{fragments/netcentrex}
\input{fragments/atlantide}
\ecvsection{ร‰ducation et formation}
\input{fragments/formation}
\ecvsection{Aptitudes et compรฉtences personnelles}
\ecvmothertongue[5pt]{franรงais}
\ecvitem{\large Autre(s) langue(s)}{}
\ecvlanguageheader{(*)}
\ecvlanguage{Anglais}{\ecvCOne}{\ecvCTwo}{\ecvBTwo}{\ecvCOne}{\ecvCTwo}
\ecvlanguagefooter[10pt]{(*)}
% \ecvitem[10pt]{\large Aptitudes et compรฉtences sociales}{}
% \ecvitem[10pt]{\large Aptitudes et compรฉtences organisationnelles}{}
% \ecvitem[10pt]{\large Aptitudes et compรฉtences techniques}{}
\ecvitem[10pt]{\large Aptitudes et compรฉtences informatiques}{
\begin{itemize}
\item \input{fragments/skills_languages}
\item \input{fragments/skills_protocols}
\item \input{fragments/skills_tools}
\item \input{fragments/skills_systems}
\item \input{fragments/skills_methods}
\end{itemize}
}
\ecvitem[10pt]{\large Aptitudes et compรฉtences artistiques}{
\begin{itemize}
\item pratique de la guitare
\end{itemize}
}
% \ecvitem[10pt]{\large Other skills and competences}{Replace this text by a description of these competences and indicate where they were acquired (remove if not relevant).}
\ecvitem{\large Permis de conduire}{B}
\ecvsection{Additional information}
\ecvitem{}{\textbf{Personal interests}}
\ecvitem{}{\input{fragments/interests}}
\end{europecv}
\end{document}

57
content/cv/2012/experience.tex

@ -0,0 +1,57 @@
\documentclass[10pt,a4paper]{moderncv}
\usepackage{ucs}
\usepackage[utf8x]{inputenc}
\usepackage[frenchb]{babel}
\usepackage{ifthen}
\usepackage{color}
% Type of document
\newboolean{europass}
\setboolean{europass}{false}
\newboolean{cv}
\setboolean{cv}{true}
\newboolean{details}
\setboolean{details}{true}
% Custom style
\addtolength{\textwidth}{2cm}
\addtolength{\hoffset}{-1cm}
\addtolength{\textheight}{1cm}
\addtolength{\voffset}{-1cm}
\definecolor{steel}{rgb}{0.9, 0.9, 1.0}
%% \newcommand*{\cvsubentry}[2]{%
%% \cvline{\small{#1}}{%
%% \newline{}\begin{minipage}[t]{\linewidth}\small#2\end{minipage}}}
\newcommand*{\cvsubentry}[2]{%
\cvline{\tiny{#1}}{%
\begin{minipage}[t]{\linewidth}\small{#2}\end{minipage}}}
\newcommand*{\skills}[1]{%
\vspace{3mm}%
\colorbox{steel}{%
\begin{minipage}{\maincolumnwidth}%
\textit{Environnement techniqueย :} #1\end{minipage}}}
\moderncvtheme[blue]{classic}
\AtBeginDocument{\recomputelengths}
% Personal data
\input{fragments/contact}
\begin{document}
\maketitle
\renewcommand{\labelitemi}{$\triangleright$ย }
\section{Expรฉrience professionnelle}
\input{fragments/nexcom}
\input{fragments/netcentrex}
\input{fragments/atlantide}
\section{Formation}
\input{fragments/formation}
\end{document}

169
content/cv/2012/fragments/atlantide.tex

@ -0,0 +1,169 @@
\newcommand{\job}{Ingรฉnieur Consultant}
% The following does not work:
% ! Extra alignment tab has been changed to \cr.
% <template> ...egin \relax \d@llarend \endtemplate
%
% l.35 }{}
\ifthenelse{\boolean{europass}}{
\ecvitem{Dates}{Septembre 2000 $\rightarrow$ Avril 2006}
\ecvitem{Fonction ou poste occupรฉ}{TODO}
\ecvitem{Principales activitรฉs et responsabilitรฉs}{TODO}
\ecvitem[15pt]{Nom et adresse de l'employeur}{
Atlantide --
Technopรดle Brest Iroise - Site du Vernis, 300 rue Pierre Rivoalon,
CS 23866, 29238 Brest Cedex 3 (France)
}
}{}
\ifthenelse{\boolean{cv}}{
\ifthenelse{\boolean{details}}{
\cventry{2004 -- 2006}{\job}{Thales Systรจmes Aรฉroportes}{pour Atlantide Brest}{}{
Le TIS est un \textit{framework} objet dรฉveloppรฉ par Thalรจs Systรจmes
Aรฉroportรฉs pour le dรฉveloppement et lโ€™exรฉcution des diffรฉrentes
fonctions de ses systรจmes. Le nouveau module de GSM sโ€™appuie sur
CARDAMOM, un produit opensource de SC2 procurant des services
CORBA. Le GSM doit รชtre capable de dรฉployer un systรจme, le
superviser, et lui apporter une tolรฉrance aux pannes logicielles
et matรฉrielles.
\\
\begin{itemize}
\item Prise en main de CARDAMOM et dรฉveloppement dโ€™une maquette
mettant en \oe{}uvre les diffรฉrentes fonctions du GSMย ;
\item spรฉcification, dรฉveloppement et supervision des parties
sous-traitรฉes, mise en place des tests du composant GSM.
\end{itemize}
\skills{Linux (Red Hat W.S. 3.0), C++, CORBA (ACE/TAO), CARDAMOM,
SGBDOO Versant, scripts}
}
\cventry{2000 -- 2004}{\job}{FRANCE TELECOM R\&D}{pour Atlantide Brest}{}{
}
\cvsubentry{2003 -- 2004}{
Dans le cadre de l'รฉvolution dโ€™une plateforme CTI
(\textit{Computer Telephony Interface}) de services
tรฉlรฉphoniques, crรฉation pour FT R\&D Caen dโ€™un pilote RFC2217
pour la gestion dโ€™un nouveau type de PRCG (PABX Remote Control
Gateway). La plateforme est constituรฉe de plusieurs serveurs
rรฉpartis communiquant par RMI-IIOP et sโ€™appuyant sur le serveur
dโ€™application J2EE JoNAS.
\\
\begin{itemize}
\item Conception et modรฉlisation UML, puis dรฉveloppement du nouveau pilote
en Java, et intรฉgration dans les serveurs existantย ;
\item mise ร  jour des services actuels, de lโ€™interface Web en JSP sur
Tomcat.
\end{itemize}
\skills{Windows et Linux (Red Hat), Java, JSP, Jakarta Commons-Net,
RMI-IIOP, Xerces, scripts}
}
\cvsubentry{2002 -- 2003}{
Dรฉveloppement ร  FT R\&D Lannion d'un Poste Opรฉrateur via la
protocole XMPP pour un \textit{proxy} H323. Le Poste Opรฉrateur
permet de superviser les appels en cours sur un site
d'entreprise, d'effectuer des transferts, de parquer et
reprendre des interlocuteurs.
\\
\begin{itemize}
\item Conception et modรฉlisation UMLย ;
\item dรฉveloppement en C++ d'un client Jabber pour รฉmuler les
diffรฉrents postes tรฉlรฉphoniques. Un serveur Jabber modifiรฉ est
utilisรฉ pour le routage des donnรฉes formatรฉes en XML (Le principe,
dans ce contexte, fait l'objet d'un brevet de la part de FT R\&D
Lannion)ย ;
\item รฉcriture de scripts de gestion de la plate-forme, de
crรฉation des paquetages RPM.
\end{itemize}
\skills{Linux (Mandrake, Sun Cobalt), C++, Jabber, scripts}
}
\cvsubentry{2001 -- 2002}{
Participation au dรฉveloppement pour FT R\&D Issy Les Moulineaux
des plate-formes de service tรฉlรฉphoniques et IM STAR puis eWork.
\\
La plate-forme STAR offre ร  un utilisateur nomade un bouquet de
services avancรฉs de tรฉlรฉphonie et de messagerie instantanรฉe,
configurables via un accรจs web. La Plate-forme eWork est une
extension de Star, offrant des services avancรฉs supplรฉmentaires
notamment dans le domaine de la messagerie instantanรฉeย : gestion
de la disponibilitรฉ et des contacts, partage de fichiers,
rรฉunion et confรฉrence chat ou tรฉlรฉphonique, ainsi quโ€™un couplage
avec Microsoft Exchange. Ces services restent configurables via
un accรจs Web mais sont รฉgalement accessibles ร  lโ€™aide dโ€™un
client Java.
\\
\begin{itemize}
\item Conception et dรฉveloppement dโ€™un serveur de donnรฉes distribuรฉ
sur CORBA et basรฉ sur le SGBD orientรฉ objet Versantย ;
\item gestion de la configuration du serveur ร  base de composants
XML (utilisation de lโ€™API Xerces du projet APACHE)ย ;
\item dรฉveloppement de fonctions pour JNI pour des lanceurs
dโ€™applications sous Windows.
\item modification des services existants et ajout de
nouvellesย fonctionnalitรฉs dans le serveur dโ€™applications et les
IHMs Webย ;
\item dรฉveloppement dโ€™un client Javaย ;
\item connexions ร  la plate-forme et รฉchanges sรฉcurisรฉs (SSL, HTTPS,
MD5).
\end{itemize}
\skills{Windows NT, Java, JSP, JNI, Javascript, HTML, XML, XmlRpc, Jabber,
JabberBeans, CORBA (Orbacus), SGBDOO Versant, UML}
}
\cventry{2001 -- 2002}{\job}{RFS Lannion}{pour Atlantide Brest}{}{}
\cvsubentry{2002}{
Mise ร  jour dโ€™un outil de simulation de cartes communiquant via le
port sรฉrie.
\\
\begin{itemize}
\item Refonte de lโ€™IHM et du modรจle du moteur de simulation en C++ย ;
\item rรฉรฉcriture des routines C de communication sรฉrie, mise ร 
jour du protocole sur port sรฉrie et augmentation des capacitรฉs
du simulateurย ;
\item documentation de lโ€™applicationย : Diagramme de classes UML.
\end{itemize}
\skills{C++, Rational Rose.}
}
\cvsubentry{2001}{
Dรฉveloppement d'un logiciel de \textit{monitoring} embarquรฉ sur
antenne GSM pour le projet DUAMCOF. La carte hรดte est destinรฉe ร 
surveiller le comportement des amplificateurs et autres
appareillages proches dโ€™une antenne GSM. Elle communique avec un
serveur par lโ€™intermรฉdiaire dโ€™un bus CAN.
\\
\begin{itemize}
\item Dรฉveloppement de la nouvelle version du logiciel DUAMCOFย ;
modification des messages sur bus CAN et introduction dโ€™une
communication par liaison sรฉrie vers dโ€™autres modulesย ;
\item dรฉveloppement dโ€™outils annexes en C pour le formatage du
programme et la simulation de communications sur le bus sรฉrie avec
les modules annexes.
\end{itemize}
\skills{C sur PC et Intel 505CA. Assembleur sur Intel 505CA, Bus CAN, CANAlyser}
}
\cventry{2000}{\job}{GIE SESAM VITALE}{pour Atlantide Brest}{}{
Dรฉveloppement de l'outil SIMPROGI permettant de tester les api
des services SESAM-VITALE.
\\
\begin{itemize}
\item ร‰criture de fonctions C avec JNI permettant lโ€™utilisation de
lโ€™API des services SESAM-Vitale depuis lโ€™application Javaย ;
\item mise ร  jour et portage de nouvelles fonctionnalitรฉs de
SIMPROGI sur plate-forme Windows 32 bitsย ;
\item conception de nombreuses interfaces homme-machine utilisant
les composants SWING.
\end{itemize}
\skills{Java, SWING, JNI}
}
}{
\cventry{sept.ย 2000 -- avrilย 2006}{\job}{Atlantide}{Brest}{}{
\begin{itemize}
\item Dรฉveloppement pour FT R\&D d'un poste opรฉrateur ร  l'aide du
protocole XMPP, d'un pilote RFC2217 pour la gestion d'un PRCG
(\textit{PABX Remote Control Gateway}), des plateformes de
services tรฉlรฉphoniques et de messagerie instantanรฉe STAR, puis
eWorkย ;
\item dรฉveloppement d'un module de supervision pour le framework
CORBA de Thalรจs AS.
\end{itemize}
}
}
}

24
content/cv/2012/fragments/contact.tex.in

@ -0,0 +1,24 @@
\ifthenelse{\boolean{europass}}{
\ecvname{\textbf{David Soulayrol}}
\ecvfootername{David Soulayrol}
%\ecvaddress{__EXT_STREET, __EXT_CITY (France)}
%\ecvtelephone[__EXT_MOBILE]{__EXT_PHONE}
\ecvemail{\url{david@soulayrol.name}}
\ecvnationality{Franรงaise}
\ecvdateofbirth{11 Mai 1976}
\ecvgender{Masculin}
\ecvfootnote{\url{http://david.soulayrol.name}}
}{
\firstname{David}
\familyname{Soulayrol}
\ifthenelse{\boolean{details}}{
\title{Expรฉriences}
}{
\title{Curriculum Vit\ae}
}
%\address{__EXT_STREET}{__EXT_CITY}
%\mobile{__EXT_MOBILE}
%\phone{__EXT_PHONE}
\email{david@soulayrol.name}
\extrainfo{\url{http://david.soulayrol.name}}
}

52
content/cv/2012/fragments/formation.tex

@ -0,0 +1,52 @@
\ifthenelse{\boolean{europass}}{
\ecvitem{Dates}{Septembre 1994 $\rightarrow$ Juin 2000}
\ecvitem{Intitulรฉ du certificat ou diplรดme dรฉlivrรฉ}{Diplรดme Ingรฉnieur ร‰NIB.}
\ecvitem{Principales matiรจres/compรฉtences couvertes}{
TODO Enib details}
\ecvitem{Nom et type de l'รฉtablissement d'enseignement ou de formation}{
ร‰cole Nationale d'Ingรฉnieurs de Brest (France)
}
}{}
\ifthenelse{\boolean{cv}}{
\ifthenelse{\boolean{details}}{
\cventry{2000}{Projet de fin d'รฉtudes}{}{Brest}{}{
Participation au portage d'ARร‰VI d'Unix vers Windows. ARร‰VI est
un outil de simulation et de navigation au sein dโ€™environnements
virtuels orientรฉs agents. Il est dรฉveloppรฉ en C++ et s'interface
avec plusieurs sortes de pรฉriphรฉriques d'immersion.
\\
\begin{itemize}
\item Implantation dโ€™une interface entre le logiciel et des moteurs de
synthรจse et de reconnaissance vocale Microsoft.
\item Portage du support d'un gant de donnรฉes et de capteurs de
positionnement magnรฉtiques (\textit{Flock of Birds}).
\end{itemize}
\skills{AIX, Windows, C++}
}
\cventry{1998 -- 1999}{Stagiaire}{Laboratoire de Physique des Ocรฉans, IFREMER}{Brest}{}{
Dรฉveloppement dโ€™un logiciel LabView de navigation en temps rรฉel pour le
positionnement de bouรฉes acoustiques sous-marines.
\\
\begin{itemize}
\item Interfaรงage du programme LabView avec les bibliothรจques de
fonctions C pour lโ€™accรจs aux donnรฉes GPSย ;
\item rรฉception et tri des donnรฉes provenant de lโ€™unitรฉ
acoustique BENTHOS DS-7000 ร  travers un liaison sรฉrie RS-232ย ;
\item intรฉgration de donnรฉes dans un algorithme de type moindres
carrรฉs.
\item Installation de Linux (SuSE 6.1) sur plusieurs PC.
\end{itemize}
\skills{Linux et Solaris, LabVIEW, Matlab, C, LaTeX}
}
}{
\cventry{1994 -- 2000}{Diplรดme d'ingรฉnieur}{ร‰cole Nationale d'Ingรฉnieurs}{Brest}{}{
Filiรจre Informatique industrielle, modules dโ€™approfondissementย :
Systรจmes Temps rรฉel, Intelligence artificielle, Interfaces
hommes machines, Rรฉalitรฉ virtuelle.
}
\cventry{1994}{Baccalaurรฉat}{Lycรฉe Mas de Tesse}{Montpellier}{}{Sรฉrie E}
}
}

5
content/cv/2012/fragments/interests.tex

@ -0,0 +1,5 @@
Membre de l'APRIL (\url{http://april.org}).
\newline{}
Participation ร  des projets libres divers, traduction dโ€™articles et
dโ€™applications libres.

3
content/cv/2012/fragments/leisure.tex

@ -0,0 +1,3 @@
Littรฉrature, musique, jardinage, voyages.
\newline{}
Pratique du tir ร  l'arc.

38
content/cv/2012/fragments/netcentrex.tex

@ -0,0 +1,38 @@
\newcommand*{\ncxsummary}{
\begin{itemize}
\item Membre de l'รฉquipe de dรฉveloppement du \textit{Session Border
Controller} SIP des solutions logicielles de NetCentrexย ;
\item proposition, mise en place et administration d'un
\textit{wiki} pour complรฉter la gestion documentaire du siteย ;
\item participation ร  la mise en place d'un serveur
d'intรฉgration continue pour projets hรฉtรฉrogรจnes avec
\textit{CruiseControl}.
\end{itemize}
}
\ifthenelse{\boolean{europass}}{
\ecvitem{Dates}{Avril 2006 $\rightarrow$ Novembre 2010}
\ecvitem{Fonction ou poste occupรฉ}{Ingรฉnieur en Recherche et Dรฉveloppement}
\ecvitem{Principales activitรฉs et responsabilitรฉs}{TODO}
\ecvitem[15pt]{Nom et adresse de l'employeur}{
NetCentrex -- 4 Rue Louis de Broglie, 22300 Lannion (France)}
}{}
\ifthenelse{\boolean{cv}}{
\ifthenelse{\boolean{details}}{
\cventry{2006 -- }{Ingรฉnieur R\&D}{NetCentrex}{Lannion}{}{
La sociรฉtรฉ NetCentrex dรฉveloppe \textit{proxies} SIP, H323 et
solutions pour c\oe{}urs de rรฉseau IMS. Le \textit{proxy} SIP
fonctionne aussi bien seul qu'insรฉrรฉ dans une plate-forme IMS
dans les rรดles du P-CSCF ou IBCF.
\\
\ncxsummary
\skills{Linux (CentOS), C++, protocole SIP, scripts}
}
}{
\cventry{avril 2006-- }{Ingรฉnieur R\&D}{NetCentrex}{Lannion}{}{
\ncxsummary
}
}
}{}

22
content/cv/2012/fragments/nexcom.tex

@ -0,0 +1,22 @@
\ifthenelse{\boolean{europass}}{
\ecvitem{Dates}{Dรฉcembre 2011 $\rightarrow$}
\ecvitem{Fonction ou poste occupรฉ}{Ingรฉnieur en Recherche et Dรฉveloppement}
\ecvitem{Principales activitรฉs et responsabilitรฉs}{TODO}
\ecvitem[15pt]{Nom et adresse de l'employeur}{
Nexcom Systems -- 4 Rue Ampรจre, BP30255, 22303 Lannion (France)}
}{}
\ifthenelse{\boolean{cv}}{
\ifthenelse{\boolean{details}}{
\cventry{2006 -- }{Ingรฉnieur R\&D}{NetCentrex}{Lannion}{}{
NEXCOM Systems est un cabinet dโ€™architecture technique, de
formation et de rรฉalisation logicielle spรฉcialisรฉ dans le
domaine des nouveaux rรฉseaux de tรฉlรฉcommunications.
\\
\skills{Linux (Debian), C, Java, protocole SIP, JSR289}
}
}{
\cventry{dรฉcembre 2010-- }{Ingรฉnieur R\&D}{Nexcom Systems}{Lannion}{}{}
}
}{}

2
content/cv/2012/fragments/skills_languages.tex

@ -0,0 +1,2 @@
Connaissance approfondie du C, C++, Python, XML. Bonne connaissance de
Java, JavaScript, Lisp, Lua, XHTML, XSLT, Vala et notions de Sed, Awk, PHP.

1
content/cv/2012/fragments/skills_methods.tex

@ -0,0 +1 @@
Pratiques agiles, UML.

1
content/cv/2012/fragments/skills_protocols.tex

@ -0,0 +1 @@
Internet (HTTP, IMAP, SMTP, \ldots), tรฉlรฉphonie (SIP, SDP), XMPP, CORBA.

1
content/cv/2012/fragments/skills_systems.tex

@ -0,0 +1 @@
Connaissance approfondie des environnements GNU/Linux (en particulier Debian).

3
content/cv/2012/fragments/skills_tools.tex

@ -0,0 +1,3 @@
GNU \textit{Autotools} et Make, bibliothรจques C GLib, GTK+, oSIP,
bibliothรจque standard C++, bibliothรจque standard Python et lxml,
Emacs, jQuery, Gestion de version (git, subversion, bazaar) \ldots

38
content/cv/2012/makefile

@ -0,0 +1,38 @@
FRAGMENTS := $(shell ls fragments/*.tex)
SCRIPT := ' \
/__EXT_\w*/ { \
while (match($$0, /__EXT_\w*/, m)) { \
if (!ENVIRON[m[0]]) { \
next \
} \
sub(/__EXT_\w*/, ENVIRON[m[0]]); \
} \
sub(/%/, ""); \
} \
{ print }'
.PHONY: all clean distclean
all:
rm -f fragments/contact.tex
$(MAKE) cv.pdf experience.pdf europass.pdf
clean:
rm -f *.aux *.log *.out
distclean: clean
rm -f *.dvi *.pdf fragments/contact.tex
fragments/contact.tex: fragments/contact.tex.in
awk -v ad_street="$(CV_ADDRESS_STREET)" \
-v ad_city="$(CV_ADDRESS_CITY)" \
-v ph_mobile="$(CV_PHONE_MOBILE)" \
-v ph_home="$(CV_PHONE_HOME)" \
$(SCRIPT) $< > $@
%.dvi: %.tex ${FRAGMENTS} fragments/contact.tex
latex $<
%.pdf: %.dvi
dvipdf $< $@

111
content/cv/2022/2022_cv_dsoulayrol.ms

@ -0,0 +1,111 @@
.fam LM
.\# TODO: Marges
.\#
.\# Dรฉfinition d'un titre de section
.de SECT
.sp .4
.LP
\s(12\fB\\$1\fP\s10
..
.\#
.TS
expand tab(|);
lp20 lIp10.
David Soulayrol|7 Allรฉe des ajoncs
\^|2200 Lannion
\^|+33 6 62 68 24 22
\^|david@soulayrol.name
_
.TE
.LP
.ps 10
Dรฉveloppeur expรฉrimentรฉ dans le dรฉveloppement d'interfaces structurรฉes et l'usage de protocoles de machine ร  machine dรฉsireux de travailler au plus prรจs de logiciels libres.
.SECT Compรฉtences
.IP โ€ข
Expertise sur une palette de langages impรฉratifs ou orientรฉs objet : C, C++, Java, JavaScript, Python. XML.
.IP โ€ข
Accoutumรฉ ร  l'usage d'outils, bibliothรจques ou techniques frรฉquentes : GNU Autotools et Make, GLib, Spring Boot, Maven, NodeJS, PostgreSQL, git
.IP โ€ข
Familier des protocoles Internet (HTTP, IMAP, SMTP, . . .), de tรฉlรฉphonie (SIP, SDP).
.IP โ€ข
Longue expรฉrience ร  tous les niveaux de la pile logicielle, depuis l'รฉcriture de logiciel embarquรฉ jusqu'au dรฉveloppement d'un front-end Web.
.IP โ€ข
Skilled experience with the various issues and pitfalls of maintaining legacy code and reducing technical debt.
.IP โ€ข
Dรฉvouรฉ aux bonnes pratiques d'รฉcriture et ร  la rรฉdaction de code clair et structurรฉ.
.SECT "Expรฉrience professionnelle"
.IP โ€ข
De mai 2014 ร  aujourd'hui, \fBAthemium / Avidsen (Lannion)\fP
.RS
.IP โ€”
Principal dรฉveloppeur des serveurs d'une solution domotique.
J'ai participรฉ au dรฉveloppement du logiciel permettant la communication avec les rรฉseaux Z-Wave, ZigBee et autres, et ร  celui du serveur supportant les comptes des utilisateurs et l'utilisation des objets communicants.
J'ai dรฉveloppรฉ une passerelle avec le protocole MQTT et d'autres รฉlรฉments, et conรงu diffรฉrentes interfaces d'inspiration REST pour la communication entre ces รฉlรฉments et avec les interfaces.
J'ai รฉgalement assurรฉ la maintenance des diffรฉrentes machines dรฉployรฉes.
.IP โ€”
J'ai participรฉ au dรฉveloppement du logiciel permettant la communication avec les rรฉseaux Z-Wave, ZigBee et autres.
.RE
.IP โ€ข
De dรฉcembre 2010 ร  mai 2014, \fBNexcom (Lannion)\fP
.RS
.IP โ€”
Participation au dรฉveloppement de solutions de tรฉlรฉcommunication basรฉes sur le protocole SIP et au dรฉveloppement du \fIframework\fP Cipango.
.RE
.IP โ€ข
D'avril 2006 ร  novembre 2010, \fBNetCentrex (Lannion)\fP
.RS
.IP โ€”
Membre de l'รฉquipe de dรฉveloppement du Session Border Controller SIP des solutions logicielles de NetCentrexย ;
proposition, mise en place et administration d'un wiki pour complรฉter la gestion documentaire du siteย ;
participation ร  la mise en place d'un serveur d'intรฉgration continue pour projets hรฉtรฉrogรจnes avec CruiseControl.
.RE
.IP โ€ข
De septembre 2000 ร  avril 2006, \fBAtlantide (Brest)\fP
.RS
.IP โ€”
J'ai participรฉ ร  la spรฉcification, au dรฉveloppement et ร  l'encadrement de prestataires pour un module de supervision s'inscrivant dans le \fIframework\fP complexe CORBA de Thalรจs Systรจmes Aรฉroportรฉs.
.IP โ€”
Pour FT R&D Caen, j'ai conรงu, modรฉlisรฉ et dรฉveloppรฉ un pilote RFC2217 en Java pour la gestion dโ€™un nouveau type de PRCG (\fIPABX Remote Control Gateway\fP) sur une plateforme constituรฉe de plusieurs serveurs (sur J2EE JoNAS) et communiquant par RMI-IIOP.
.IP โ€”
J'ai dรฉveloppรฉ pour FT R&D Lannion un poste opรฉrateur sur XMPP permettant de superviser les appels (transferts, parquage et reprise des interlocuteurs) sur un site d'entreprise.
.IP โ€”
J'ai conรงu et dรฉveloppรฉ un serveur de donnรฉes distribuรฉ sur CORBA et basรฉ sur le SGBD orientรฉ objet Versant pour les plate-formes de services tรฉlรฉphoniques et de messagerie STAR puis eWork de FT R&D Issy Les Moulineaux.
.IP โ€”
J'ai dรฉveloppรฉ un logiciel de supervision embarquรฉ sur antennes GSM permettant le contrรดle de cartes communicant sur le bus CAN, et suis intervenu sur un outil C++ de simulation de ces cartes pour RFS Lannion.
.IP โ€”
J'ai participรฉ au dรฉveloppement de l'outil SIMPROGI permettant de tester les interfaces de programmation des services SESAM-VITALE.
.RE
.sp .4
.SECT "Formation"
.IP โ€ข
2000, \fIDiplรดme dโ€™ingรฉnieur de l'ร‰cole Nationale dโ€™Ingรฉnieurs de Brest\fP
.br
Filiรจre Informatique industrielle, modules dโ€™approfondissement : Systรจmes Temps rรฉel, Intelligence artificielle, Interfaces hommes machines, Rรฉalitรฉ virtuelle.
.br
Projet de fin d'รฉtude portant sur le dรฉveloppement de l'outil d'environnement virtuel orientรฉ agents C++ ARร‰VI.
.br
Stage au Laboratoire de Physique des Ocรฉans de l'IFREMER ร  Brest portant sur le dรฉveloppement dโ€™un logiciel LabView de navigation en temps rรฉel pour le positionnement de bouรฉes acoustiques sous-marines.
.IP โ€ข
1994, \fIBaccalaurรฉat sรฉrie E\fP au lycรฉe Mas de Tesse, Montpellier
.sp .4
.SECT "Rรฉalisations et savoir-faires"
.IP โ€”
Membre de l'APRIL (http://april.org), j'ai participรฉ au dรฉveloppement ou ร  la traductions d'articles et de plusieurs logiciels libres depuis 2001.
https://github.com/dsoulayrol
https://apps.ti-nuage.fr/gitea/david
.IP โ€”
Membre et administrateur de Ti Nuage (https://ti-nuage.fr), un fournisseurs de services numรฉriques associatif.
.IP โ€”
Grand lecteur, j'ai co-fondรฉ et tenu le rรดle de prรฉsident de 2014 ร  2020 de l'association Scorfel qui organise un festival annuel dรฉdiรฉ ร  l'Imaginaire ร  Lannion.
Je suis membre actif de l'association NooSFere (https://www.noosfere.org) et du Club Prรฉsence d'Esprits (https://presences-d-esprits.com/), dรฉdiรฉes aux lectures de l'imaginaire. Je rรฉdige des chroniques pour l'une et l'autre. (https://www.noosfere.org/livres/auteur.asp?numauteur=2147204009)
.IP โ€”
Je joue du piano et de l'alto.
.IP โ€”
Je parle, lis et รฉcris l'anglais couramment.
.IP โ€”
I maintain a portfolio of personal work at
.CW https://david.soulayrol.name

14
content/cv/2022/README

@ -0,0 +1,14 @@
La gรฉnรฉration du document repose sur la police de caractรจres *Latin Modern* qui peut รชtre tรฉlรฉ-chargรฉe depuis l'adresse suivante.
http://www.gust.org.pl/projects/e-foundry/latin-modern
L'installation de la police pour `groff` est grandement facilitรฉe grรขce au script `install-font.sh` de Peter Schaffter (merci ร  lui).
http://www.schaffter.ca/mom/mom-06.html#install-font
Pour l'installation, copier le script dans le rรฉpertoire contenant les fichiers de l'archive, et entrer les lignes suivantes avec les droits de l'utilisateur `root`. Le processus est interactif : donner les rรฉponses proposรฉes par dรฉfaut aux deux questions. Le drapeau `-s` signifie une installation dans `/usr/share/groff`, alors que `-l` (par dรฉfaut) procรจde ร  une installation dans `/usr/local/share/groff`.
./install-font.sh -s -F LM -f +R lmroman12-regular.otf
./install-font.sh -s -F LM -f +B lmroman12-bold.otf
./install-font.sh -s -F LM -f +I lmroman12-italic.otf

99
content/documents/hide-long-headers.md

@ -0,0 +1,99 @@
---
title: "How to hide long C headers"
date: 2010-03-29
lang: en
layout: document.njk
---
The problem came out to me because some people or teams embed their
changelog in the source file headers.
---
This gives something like this:
/**
* @file MySource.cpp
* @desc a Foo objects protubazor.
* @date 29/03/2009
*
* MODIFICATIONS:
* 2009-04-02: jsmith: Removed a useless variable.
* 2009-04-03: jsmith: Simplified the protubazor algorithm.
* 2009-06-10: jdoe: Fixed compilation warning.
*/
They will argue that this is the best way to check why a line has
changed in the past for example. I disagree with this. First, there
should be a file dedicated to the whole project history to trace
important updates. In GNU project, this is the **ChangeLog**
file. But above all, sources tracking is the very *raison d'รชtre* of
version control. Every commit should be atomic and provide a
meaningful comment. If commits are correctly described, writing a
changelog inside the source is, at best, duplication of information,
and I *hate* that.
Besides, I think this is a very annoying habit because this
information will grow with time and eventually become as large as the
useful part of your source file. At last, working on these files will
involve lots of scrolling just to find the beginning of the code.
Anyway, there are those situations where I have no choice but to obey,
or to adapt myself. The solution I found is to hide these annoying
lines until I get forced to edit them (and then quickly hide them
again). To achieve this, I've written a function to customize the
**[hideshow minor mode][HS]** from **[emacs][EMACS]** behaviour on
file headers. It can be loaded this way for example:
(load-library "hideshow")
(add-hook 'c++-mode-hook 'hs-minor-mode)
(add-hook 'c-mode-hook 'hs-minor-mode)
**[hideshow][HS]** allows you to hide blocks of code. The meaning of
*blocks* depends on the language you are editing, I mean the current
major-mode. When hidden, the block is replaced by an ellipsis by
default, but the `hs-set-up-overlay` function can be used to customize
what is drawn inside a hidden block.
In the following implementation, I tweak the hideshow overlay so as to
indicate the number of missing lines in hidden blocks. If I detect
that the given block is a kind of comment and is at the beginning of
the file, I also search for the **MODIFICATIONS:** token, which is used to
introduced those damn changelogs. If I found it, I don't really hide
the block, but display its content minus everything following the
token (which I replace with the count of hidden lines).
(setq hs-set-up-overlay
(defun ds-lib-hs-overlay (ov)
(let ((content (format " [%d lines]..."
(count-lines (overlay-start ov)
(overlay-end ov)))))
(when (and (< (overlay-start ov) 80) (eq 'comment (overlay-get ov 'hs)))
(goto-char (point-min))
(goto-char (point-min))
(when (search-forward " MODIFICATIONS:" (overlay-end ov) t)
(setq content (format "%s [%d lines]...\n */ "
(buffer-substring (overlay-start ov) (point))
(- (count-lines (point) (overlay-end ov)) 2)))))
(overlay-put ov 'display content))))
(add-hook 'c++-mode-hook 'hs-hide-block t)
(add-hook 'c-mode-hook 'hs-hide-block t)
Thus, the sample given in the beginning would be displayed this way:
/**
* @file MySource.cpp
* @desc a Foo objects protubazor.
* @date 29/03/2009
*
* MODIFICATIONS: [3 lines]...
*/
Note that even if it seems to be displayed because I draw a large part
of it, the block is actually in an hidden state. That means that it
must be showed again before it can be edited at all.
[EMACS]: http://www.gnu.org/software/emacs/
[HS]: http://www.gnu.org/software/emacs/manual/html_node/emacs/Hideshow.html

108
content/documents/identifying-contexts-in-logs.md

@ -0,0 +1,108 @@
---
title: Identifying logical contexts in logs
date: 2012-05-05
lang: en
layout: document.njk
---
Some months ago, I had to track a bug for which appeared on one SIP
call, in a pre-production environment. So I had to dig a very lengthy
log file, with lots of information about many mixed calls.
This situation is not really a problem if you know exactly the call
you are tracking, thanks to its Call-ID or indirectly with a From or
To tag for example. Hopefully, your program already offers interesting
logs to address the problem, or you can provide a modified program to
gather more information. If not, you know the rest of the week will be
a pain.
---
In this case, I was lucky enough to have the opportunity to provide a
new binary with lots of logs in the area which caused the bug, but I
still had to search through thousand of lines to identify the path
which lead one call to trigger the error.
So I came up with a simple **[python](http://python.org)** script which
parsed the file for me and built a map from the logs I was interested
in. Each entry of the map was identified by an ID which was unique to
a call, and contained all the logs for this call in order of
appearance in the file. To achieve this, the script relied on a
regular expression which identified the logs I had added. At last, the
script dumped those contexts, which were far easier to read than the
initial file.
Then I got a new job, and I forgot this...
Until this week, when I had to identify in a very long file some
sixteen calls out of more than one thousand which were behaving
differently. So I wrote the following script in the vein of the
previous one. It can be quite easily adapted to other problems by
modifying the `PATTERN` constant. It can read multiple log files, and
it can output the number of contexts found, the number of lines read
for each one of these contexts, and dump them. I think it is self
explanatory, and it comes with inline help.
#!/usr/bin/env python
# argparse means Python 2.7 is required.
import argparse
import re
# The pattern can be customized to adapt the program behaviour to the
# kind of logs to be analysed. It must provide a group named `key'
# which will be used to identify the logs belonging to a same context.
PATTERN = '.+ \[INFO\] .* with Call-ID = (?P<key>[a-zA-Z0-9@\.-]+)'
def build_contexts(filenames):
contexts = {}
for n in filenames:
with open(n) as f:
e = re.compile(PATTERN)
while True:
l = f.readline()
if '' == l:
break
m = e.match(l)
if not m is None:
k = m.group('key')
if not k in contexts:
contexts[k] = []
contexts[k].append(l.strip())
return contexts
def display_context(contexts, key, cmd):
print '%s: %s' % (key, str(len(contexts[key])) + ' lines.' if cmd.summary else '')
if cmd.list:
for l in contexts[key]:
print '\t', l
def handle_contexts(contexts, cmd):
if not cmd.key is None:
if cmd.key in contexts:
display_context(contexts, cmd.key, cmd)
elif cmd.list or cmd.summary:
for key in contexts:
display_context(contexts, key, cmd)
print 'Total:', len(contexts), 'contexts'
# Main
parser = argparse.ArgumentParser(
description='Correlates log lines.',
epilog='See the PATTERN variable in the code to suit your needs')
parser.add_argument('files', metavar='file', type=str, nargs='+',
help='the file to inspect')
parser.add_argument('--get', action='store', dest='key',
help='search only the context with this key')
parser.add_argument('--list', action='store_true',
help='dump the contexts content')
parser.add_argument('--summary', action='store_true',
help='print a summary for each context found')
args = parser.parse_args()
handle_contexts(build_contexts(args.files), args)

298
content/documents/using-firefox-micro-summaries.md

@ -0,0 +1,298 @@
---
title: Using Firefox Micro-Summaries
date: 2007-04-29
lang: en
layout: document.njk
---
What are you doing when you're a geek and a nice girl is crying for
her own refurbed Apple laptop ? Yes, you find a way to monitor the
Store so as to be the first to be ready to buy next time.
---
## When geeks can be useful too
Karine recently decided that she wanted a laptop. I cannot remember
why, but she also decided that a MacBook would be definitively
cool. So we went to town and had a look at the hardware. Karine took
the time to search for benchmarks and tests to be comforted in her
choice. We started to track [eBay][] and Apple
*Refurb*. In the end, she realized that the *Refurb* offered the
warranties that she was looking for, with an interesting price saving.
Once the choice was made, began the time of the [Apple Store][] *Page
Refresh Syndrom*. The drama occured the day she was having a break,
and then the *one-click* susbscription refused to work before all the
nice MacBook had found new happy owners.
## Remember your greatest quality is laziness
There are many ways to monitor a page and to be notified when it is
updated. The easiest solution is to rely on what you can
find. Remember: *never reinvent the wheel* (or only if it's fun).
We first tried to find a plugin for *Firefox* that would show up a
notification when a page is updated and we installed [Notify][]. But
the plugin was sending far too false positive notifications (and
actually, it continues to do so while I'm writing this). I don't
pretend it does not work, but it didn't the job we wanted out of the
box, so we tried to find something else.
I could have written some Python script to crawl the *Refurb* for us
and provide us some summary of the available laptops. The most
difficult part of this solution would have been to handle the
notification: Karine was mainly using MS Windows both at work and at
home, and I didn't want to search for a graphical solution on this
platform. The notification could have been sent by mail, but I didn't
enjoy this solution at the moment, thinking it was too slow for our
need (I am not sure I have the same opinion today).
Then Karine found a short description about the *Live Titles*, or
*Micro Summaries* of *Firefox*. After some search, I found out that
this was in fact a way to define a dynamic bookmark label. I first
found [some samples](http://userstyles.org/livetitle) and later some
documentation to start with. I decided that I wanted to know more
about it.
You could say (will you ?) that this kind of notification is a very
shy one, and we have to check frequently the *Firefox* window to see
it some good news happened. And you would be right. But please
consider that for someone using a lot its computer and the web
browser, it's more interesting to have a quick glance at a label on
the windows than to have to refresh a page from a somewhat loaded
server. And *that* was what scratched my itch at this very moment,
nothing else.
## Time to write some code
### Micro Summaries... What's this?
Micro summaries simply consist of one XSL stylesheet which will be
associated to all bookmarked pages matching a given pattern. When you
bookmark a page whose URL matches a micro summary definition, the *Add
Bookmark* dialog provides you a combo box to define the title instead
of a text field, thus giving you the choice to set a static label or
to use the existing dynamic one.
[This page](http://wiki.mozilla.org/Microsummaries) introduces the
*Firefox* *micro summaries*, but
[this one](http://developer.mozilla.org/en/docs/Creating_a_Microsummary)
is far more interesting when it comes to the moment you have to write
your own.
At first, I was worried by the fact that all the provided samples were
very simple. They were often composed of one or two labels and some
values easely extracted from the bookmarked page. Then I realized that
they were XSLT documents after all, and that I probably could use all
the power of XSL transformations to build the label I wanted.
### Let's dive into it
First, micro summaries are XML documents, and they make use of XML
namespaces. It is very important to know about namespaces because a
micro summary document contains at least tags from two distinct ones:
`microsummaries`, and `XSL` of course.
A micro summary definition needs very few information. The root tag is
`generator`, from the `microsummaries` namespace, and has a name
attribute. The root tag has at least two children.
- `transform` holds the XSL sheet. The XSL namespace
must be present here.
- `pages` provides one or more `include` tags, each one
holding a regular expression that will be used to match a page URL
for which the micro summary can be used.
An additional `update` tag which specifies that the Summary will have
to be refreshed every five minutes. The update involves retrieving the
data from the website of course. You will find some other tags in
documentation which I confess I didn't try to study. All I needed was
there.
::XML
<?xml version="1.0" encoding="UTF-8"?>
<generator xmlns="http://www.mozilla.org/microsummaries/0.1" name="Applestore">
<template>
<transform xmlns="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!-- All XSLT code goes here -->
</transform>
</template>
<pages>
<include>http://store\.apple\.com/Apple/WebObjects/francestore\.woa/.*</include>
</pages>
<update interval="5" />
</generator>
### Now, the AppleStore application
What I tried to retrieve first was some value to determine if MacBook
laptops were available. This could be done by searching the lines
announcing the refurbed products and looking for the one displaying
MacBook. So, I sit down and managed to remember the syntax of XPath
expressions to produce something like this:
/html/body//form/table[@id='rep']/tbody/tr/td/b
Which gave me the following result.
![Firefox displaying the result of the first XPath expression][screenshot-1]
**Caution:** Note that the XPath expressions given here rely on the
french refurb pages. They shall be adapted to get something
operational in other languages.
Of course, in the end, I would have kept only the text and get rid of
pictures (but it was cool to display this for the screenshot, and it
helps to understand what I have extracted from the page).
From there I thought I only had to search the lines where I could find
the string MacBook. But I realized that I needed to differentiate
MacBook and MacBook Pro. And I didn't know how to write some condition
with these inputs to distinguish both of them.
So I tried to gather another source of information in the page.
Meanwhile, I also decided to not only detect if MacBook laptops were
available but also to count how many there were. Finally, I wrote the
following expression.
/html/body//form/table[@id='rep']/tbody/tr/td/span/b[contains(normalize-space(.), 'Refurb')]
And this time, I got:
![Firefox displaying the result of the final XPath expression][screenshot-2]
From these strings, all I had to do was to select the ones related to
MacBooks and to count them. To extract these lines, I chose to use the
*White* and *Black* words, which only appeared in lines concerning
MacBooks.
To make sure the method was correct, I also decided to count the lines
related to MacBook Pro, and then even the ones for iMacs. In these
cases, I simply had to search for *MacBook Pro* and *iMac* terms on
the lines.
Counting the lines is a bit tricky because XLST does not provide
*lvalues*. There is no way to define anything else than constants. So
computing values can be achieved using recursivity only. In the
following template, `nodes` is the list of gathered strings, `item` is
the pattern we are looking for. The inner variable `count` is used to
carry the temporary value of the result count through iterative calls.
::XML
<template name="count">
<param name="nodes" />
<param name="item" />
<choose>
<when test="$nodes">
<variable name="node" select="$nodes[1]" />
<variable name="count">
<call-template name="count">
<with-param name="nodes" select="$nodes[position() != 1]" />
<with-param name="item" select="$item" />
</call-template>
</variable>
<choose>
<when test="contains($node, $item)">
<value-of select="$count + 1" />
</when>
<otherwise>
<value-of select="$count" />
</otherwise>
</choose>
</when>
<otherwise>0</otherwise>
</choose>
</template>
### Building the label
Counting lines containing a given item is only a matter of calling the
previous template with the list of lines and the wanted pattern. The
result of the call gives the count value. Here is an excerpt of the
code showing how is displayed the count of white MacBook laptops. Note
the `text` element to display some text around the value computed.
::XML
<text>MacBooks: </text>
<variable name="count-macbooks-w">
<call-template name="count">
<with-param name="nodes" select="$entries" />
<with-param name="item" select="string('White')" />
</call-template>
</variable>
<value-of select="$count-macbooks-w" />
<text>w </text>
### Registering the micro summary
If no micro summary is registered in your browser, or if the `pages`
directives do not match the page you are currently watching, then
trying to bookmark will raise the following dialog.
![The default Add bookmark dialog][screenshot-3]
Micro summaries can be registered using a simple script. Its main job
will be to check that the browser can register the sheet, and then a
simple line will suffice.
::HTML
<script>
const warning = "Sorry, you need a microsummary-enabled browser like Firefox 2.0";
function addGenerator(url) {
if (typeof window.sidebar == "object" &&
typeof window.sidebar.addMicrosummaryGenerator == "function")
window.sidebar.addMicrosummaryGenerator(url);
else
alert(warning);
}
</script>
<button onclick="addGenerator('http://10.165.16.164/applestore.xml')">
Install the Apple Store MacBook microsummary!</button>
Again, there is more than one way to do this. But remember it was only
a quick hack to monitor the store and a nice way have an overview of
the technology.
Now, if you used the previous script, and are trying to bookmark a
page, then your *Add Bookmark* dialog is updated so that you can
choose the *live title* instead of typing a static one. Hey Karine,
there are laptops available!
![The updated Add bookmark dialog][screenshot-4]
The complete micro summary code for the Apple store can be downloaded
[here](/objects/files/micro_summaries). Note that the short script I
used to register it needs its complete location.
## Waiting for kisses
As said before, micro summaries are a very tiny way to notify
something to the user. If the content of the title is rather
important, the best use is probably to store it on your personal
toolbar.
![The micro summary in action][screenshot-5]
To conclude, I shall add that I discovered quite recently that micro
summaries were stored in your Firefox profile under the
`microsummary-generators` directory (I am using Firefox under Debian
to do this). It is very easy to remove a generator simply by deleting
the XML file stored there.
For the record, a week later the Apple Store offered many refurbed
laptops and Karine bought her MacBook. And after that, she still tells
I'm staying too much in front of my computer!
[Apple Store]: <http://store.apple.com>
[eBay]: <http://www.ebay.fr>
[Notify]: <https://addons.mozilla.org/en-US/firefox/addon/3149>
[screenshot-1]: <screenshot-xpath-1.png>
[screenshot-2]: <screenshot-xpath-2.png>
[screenshot-3]: <screenshot-live_titles-1.png>
[screenshot-4]: <screenshot-live_titles-2.png>
[screenshot-5]: <screenshot-live_titles-3.png>

BIN
content/documents/using-firefox-micro-summaries/screenshot-live_titles-1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

BIN
content/documents/using-firefox-micro-summaries/screenshot-live_titles-2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

BIN
content/documents/using-firefox-micro-summaries/screenshot-live_titles-3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
content/documents/using-firefox-micro-summaries/screenshot-xpath-1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
content/documents/using-firefox-micro-summaries/screenshot-xpath-2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

1267
content/documents/wonderful-26.md

File diff suppressed because it is too large

53
content/index.md

@ -0,0 +1,53 @@
---
title: "Accueil"
permalink: false
---
Je suis ingรฉnieur diplรดmรฉ de l'[ร‰cole Nationale d'Ingรฉnieurs de Brest][ENIB]. Je travaille actuellement dans le domaine de la domotique, ร  [Lannion][LANNION].
Je suis passionnรฉ d'informatique, de littรฉrature et de musique. Je suis adhรฉrent ร  l'[April][APRIL], [nooSFere][NOOSFERE] et au [Club Prรฉsences d'Esprits][CPE]. Je suis le prรฉsident de l'association [Pรฉrรฉgrine][PEREGRINE] ร  Lannion et membre du bureau de l'hรฉbergeur alternatif et solidaire [Ti Nuage][TINUAGE].
Dans une autre vie, j'ai vรฉcu ร  [Montpellier][Montpellier], [Brest][BREST] ou prรจs de [Blois](https://fr.wikipedia.org/wiki/Blois). J'ai pratiquรฉ la danse sur glace et le tir ร  l'arc. Plus rรฉcemment, j'ai รฉtรฉ co-fondateur et prรฉsident de l'association [Scorfel][SCORFEL].
## Curriculum Vitae
Mon parcours professionel est dรฉtaillรฉ ร  [cette adresse](cv/2022/2022_cv_dsoulayrol.pdf) ([sources](cv/2022) pour [groff](https://www.gnu.org/software/groff/)).
Des itรฉrations passรฉes sont toujours disponibles :
- ร  la sortie de l'รฉcole en [2000](cv/2000_cv_dsoulayrol.txt)
- au moment oรน je m'apprรชte ร  quitter Atlantide pour Lannion, [fin 2005](cv/20051010_cv_dsoulayrol.pdf)
- En 2012, lorsque je suis chez Nexcom, j'expรฉrimente diffรฉrents modรจles avec [LaTeX](https://www.latex-project.org/) et je produis un [CV](cv/2012/2012_cv.pdf), un document dรฉtaillant mes [expรฉriences professionnelle](cv/2012/2012_experiences.pdf), et un ยซ [europass](cv/2012/2012_europass.pdf) ยป ([sources](cv/2012)).
## Contact
Je peux facilement รชtre joint aux adresses suivantes.
* <a href="mailto:david@soulayrol.name">david@soulayrol.name</a>
* <a href="xmpp:david@ti-nuage.fr">david@ti-nuage.fr</a> sur XMPP.
* <a href="https://pouet.chapril.org/@ds">@ds@pouet.chapril.org</a> sur Mastodon.
Le code que je produis de nos jours est stockรฉ chez l'hรฉbergeur alternatif Ti Nuage, et de temps en temps par nรฉcessitรฉ chez Github.
* [Ti-Nuage](https://apps.ti-nuage.fr/gitea/david)
* [Github](https://github.com/dsoulayrol)
## Archives
Les documents que j'ai conservรฉs, ou que j'exhume ร  l'occasion de mon disque dur...
* [La traduction](documents/le-monde-merveilleux-de-linux-2.6) du document [Wonderful World of Linux 2.6](http://www.kniggit.net/wwol26.html), Copyright 2003, Joseph Pranevich (jpranevich AT kniggit.net).
* [Un article sur l'utilisation des *micro-summaries* dans Firefox en 2007](documents/using-firefox-micro-summaries), en anglais.
* [Un script Python pour isoler des blocs dans un long fichier de *logs* ](documents/identifying-logical-contexts-in-logs), en anglais.
* [Une astuce pour masquer les longs entรชtes d'un fichier source dans Emacs](documents/how-to-hide-long-c-headers) en anglais.
[APRIL]: <https://april.org>
[BREST]: <https://fr.wikipedia.org/wiki/Brest>
[CPE]: <http://www.presences-d-esprits.com>
[ENIB]: <http://www.enib.fr>
[LANNION]: <http://fr.wikipedia.org/wiki/Lannion>
[MONTPELLIER]: <https://fr.wikipedia.org/wiki/Montpellier>
[NOOSFERE]: <https://noosfere.org>
[PEREGRINE]: <https://www.associations.lannion.bzh/index.php?option=com_content&view=article&id=135:peregrine>
[SCORFEL]: <httsp://scorfel.fr>
[TINUAGE]: <https://ti-nuage.fr>

24
layouts/default.njk

@ -0,0 +1,24 @@
<!DOCTYPE HTML>
{% import "footer.njk" as footer %}
{% if lang == undefined %}{% set lang = 'fr' %}{% endif %}
{% set lang = moment.locale(lang) %}
<html lang="{{ lang }}">
<head>
<title>{{ site.title }} | {{ title }}</title>
<meta charset="utf-8">
<meta name="author" content="David Soulayrol">
<meta name="generator" content="Metalsmith" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/css/simple.min.css">
<link rel="stylesheet" href="/css/ds.css">
</head>
<body>
{% block content %}
{{ contents | safe }}
{% endblock %}
<footer>
{{ footer.mentions(lang) }}
{{ footer.generated(lang) }}
</footer>
</body>
</html>

14
layouts/document.njk

@ -0,0 +1,14 @@
{% extends "default.njk" %}
{% block content %}
<article>
<header>
<h1>{{ title }}</h1>
<p>{% if date %}
{% if lang == 'en' %}Published:{% else %}Publiรฉ le :{% endif %}
<time datetime="{{ moment(date).format() }}">{{ moment(date).format('LL') }}</time>
{% endif %}</p>
</header>
{{ contents | safe }}
</article>
{% endblock %}

17
layouts/footer.njk

@ -0,0 +1,17 @@
{% macro mentions(lang) %}
{% if lang == 'en' %}
<p>Unless stated otherwise, all this website content belongs to its author and can be redistributed using the <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA 2.0</a> license.</p>
<p>Style is based on <a href="https://simplecss.org">SimpleCSS</a>. Titles font is <a href="https://www.fontspace.com/colombia-font-f45636">Colombia by Sandylukee</a>.
{% else %}
<p>Sauf mentions contraires, le contenu de ce site appartient ร  l'auteur et peut รชtre distribuรฉ sous licence <a href="https://creativecommons.org/licenses/by-sa/2.0/fr/">CC-BY-SA 2.0</a>.</p>
<p>Le style repose sur <a href="https://simplecss.org">SimpleCSS</a>. La police des inter-titres est <a href="https://www.fontspace.com/colombia-font-f45636">Colombia par Sandylukee</a>.
{% endif %}
{% endmacro %}
{% macro generated(lang) %}
{% if lang == 'en' %}
<p>Generated with <a href="https://metalsmith.io">Metalsmith</a> (<a href="https://apps.ti-nuage.fr/gitea/david/david.soulayrol.name">Sources</a>).</p>
{% else %}
<p>Gรฉnรฉrรฉ avec <a href="https://metalsmith.io">Metalsmith</a> (<a href="https://apps.ti-nuage.fr/gitea/david/david.soulayrol.name">Sources</a>).</p>
{% endif %}
{% endmacro %}

14575
package-lock.json

File diff suppressed because it is too large

62
package.json

@ -0,0 +1,62 @@
{
"name": "david.soulayrol.name",
"version": "2022.06",
"private": true,
"description": "The sources for <http://david.soulayrol.name>",
"main": "",
"scripts": {
"build": "DEBUG=metalsmith* npm run clean && npm run build:metalsmith",
"build:prod": "NODE_ENV=production npm run build",
"build:metalsmith": "node scripts/run.js build",
"clean": "rimraf dist",
"dev": "npm run build && DEBUG=metalsmith* nodemon scripts/run.js serve",
"server": "npm run build && http-server dist",
"lint": "npm run lint:js && npm run lint:css",
"lint:js": "eslint scripts",
"lint:css": "stylelint assets/**/*.css",
"test": "npm run lint && npm run build"
},
"author": "David Soulayrol <david@soulayrol.name>",
"devDependencies": {
"@metalsmith/layouts": "2.4.0",
"@metalsmith/permalinks": "^2.4.0",
"browser-sync": "^2.27.5",
"bs-fullscreen-message": "^1.1.0",
"clean-css": "^5.1.5",
"cli-table2": "^0.2.0",
"debug": "^4.3.2",
"eslint": "^8.18.0",
"eslint-config-standard": "^17.0.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-n": "^15.2.3",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^6.0.0",
"eslint-plugin-standard": "4.1.0",
"filesize": "^8.0.0",
"http-server": "^13.0.1",
"jstransformer-nunjucks": "^1.0.0",
"metalsmith": "^2.4.0",
"metalsmith-assets": "^0.1.0",
"metalsmith-clean-css": "^6.1.3",
"metalsmith-groff": "^0.3.0",
"metalsmith-markdownit": "^0.5.0",
"metalsmith-rename": "^1.0.0",
"metalsmith-sitemap": "^1.2.2",
"moment": "^2.29.1",
"nodemon": "^2.0.12",
"rimraf": "^3.0.2",
"slug": "^5.1.0",
"stylelint": "^13.13.1",
"stylelint-config-standard": "^22.0.0"
},
"nodemonConfig": {
"delay": 2500,
"ignore": [
"test/*",
"docs/*"
],
"watch": [
"scripts"
]
}
}

20
scripts/config.js

@ -0,0 +1,20 @@
const { resolve, join } = require('path')
const hostname = 'https://david.soulayrol.name'
const projectRoot = resolve(__dirname, '..')
const distribution = join(projectRoot, 'dist')
module.exports = {
hostname,
paths: {
projectRoot,
/* Nodes */
nodeModules: join(projectRoot, 'node_modules'),
/* Metalsmith */
metalsmithSource: 'content',
metalsmithDestination: distribution,
/* Server */
serverRoot: distribution
}
}

108
scripts/metalsmith-helpers.js

@ -0,0 +1,108 @@
const path = require('path')
const Table = require('cli-table2')
const filesize = require('filesize')
function generateFileMap (files) {
return Object.keys(files).reduce((map, filename) => {
const file = files[filename]
const parsedFilename = path.parse(filename)
const ext = parsedFilename.ext.substr(1)
const extFiles = map[ext] || []
return {
...map,
[ext]: [
...extFiles,
{
file,
filename
}
]
}
}, {})
}
export function StatisticsPlugin (options) {
return (files, metalsmith, done) => {
const fileMap = generateFileMap(files)
const fileTypes = Object.keys(fileMap)
// File overview table
fileTypes.forEach((filetype) => {
const fileTypeFiles = fileMap[filetype]
const count = fileTypeFiles.length
const size = fileTypeFiles.reduce((totalsize, entry) => {
// Some plugins (eg. metalsmith-data-markdown) replace the Buffer by a string
if (typeof entry.file.contents === 'string') {
return totalsize + entry.file.contents.length
} else {
return totalsize + entry.file.contents.byteLength
}
}, 0)
const filenamesTable = new Table({
head: [`${count} ${filetype}-${count > 1 ? 'files' : 'file'} with total ${filesize(size)}`, 'File size'],
wordWrap: true,
colWidths: [process.stdout.columns - 16, 12]
})
fileTypeFiles.forEach((entry) => {
let size = 0
// Some plugins (eg. metalsmith-data-markdown) replace the Buffer by a string
if (typeof entry.file.contents === 'string') {
size = entry.file.contents.length
} else {
size = entry.file.contents.byteLength
}
filenamesTable.push([entry.filename, size])
})
console.log(filenamesTable.toString())
})
done()
}
}
export function DebugPlugin (options) {
function sanitizeTableContent (content) {
const length = content.length
content = content.replace(/\s+/g, ' ').slice(0, config.maxContentLength)
if (length > config.maxContentLength) {
content = content.trim() + '...'
}
return content
}
const defaultOptions = {
maxContentLength: 1000
}
const config = {
...defaultOptions,
...options
}
return (files, metalsmith, done) => {
const fileMap = generateFileMap(files)
const fileTypes = Object.keys(fileMap)
fileTypes.forEach((filetype) => {
const fileTypeFiles = fileMap[filetype]
fileTypeFiles.forEach((entry) => {
const content = sanitizeTableContent(entry.file.contents.toString())
const size = filesize(entry.file.contents.byteLength)
const metadata = {
...entry.file
}
delete metadata.contents
const fileTable = new Table({
head: [`${entry.filename} @ ${size}`],
wordWrap: true,