commit
1538631d84
54 changed files with 20025 additions and 0 deletions
@ -0,0 +1,15 @@ |
|||
module.exports = { |
|||
env: { |
|||
browser: true, |
|||
commonjs: true, |
|||
es2021: true |
|||
}, |
|||
extends: [ |
|||
'standard' |
|||
], |
|||
parserOptions: { |
|||
ecmaVersion: 12 |
|||
}, |
|||
rules: { |
|||
} |
|||
} |
@ -0,0 +1,2 @@ |
|||
dist |
|||
node_modules |
@ -0,0 +1,5 @@ |
|||
{ |
|||
"extends": "stylelint-config-standard", |
|||
"ignoreFiles": ["**/*.min.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; |
|||
} |
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1 @@ |
|||
dev/ |
@ -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, ... |
File diff suppressed because it is too large
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -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} |
@ -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} |
@ -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} |
@ -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} |
|||
} |
|||
} |
|||
} |
|||
|
@ -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}} |
|||
} |
@ -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} |
|||
} |
|||
} |
|||
|
@ -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. |
|||
|
@ -0,0 +1,3 @@ |
|||
Littรฉrature, musique, jardinage, voyages. |
|||
\newline{} |
|||
Pratique du tir ร l'arc. |
@ -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 |
|||
} |
|||
} |
|||
}{} |
|||
|
@ -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}{}{} |
|||
} |
|||
}{} |
|||
|
@ -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. |
@ -0,0 +1 @@ |
|||
Pratiques agiles, UML. |
@ -0,0 +1 @@ |
|||
Internet (HTTP, IMAP, SMTP, \ldots), tรฉlรฉphonie (SIP, SDP), XMPP, CORBA. |
@ -0,0 +1 @@ |
|||
Connaissance approfondie des environnements GNU/Linux (en particulier Debian). |
@ -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 |
@ -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 $< $@ |
@ -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 |
@ -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 |
|||
|
@ -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 |
@ -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) |
@ -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> |
After Width: | Height: | Size: 7.2 KiB |
After Width: | Height: | Size: 8.0 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 20 KiB |
File diff suppressed because it is too large
@ -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> |
@ -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> |
@ -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 %} |
@ -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 %} |
File diff suppressed because it is too large
@ -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" |
|||
] |
|||
} |
|||
} |
@ -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 |
|||
} |
|||
} |
@ -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, |